<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    
    <title>Disenone&#39;s Wiki</title>
    <description>无止境</description>
    <link>https://wiki.disenone.site/</link>
    <atom:link href="https://wiki.disenone.site/feed_rss_created.xml" rel="self" type="application/rss+xml" />

    
    <managingEditor>Disenone</managingEditor>
    <docs>https://github.com/disenone/wiki_blog</docs>
    <language>ar</language>

    
    <pubDate>Tue, 17 Feb 2026 04:32:19 -0000</pubDate>
    <lastBuildDate>Tue, 17 Feb 2026 04:32:19 -0000</lastBuildDate>
    <ttl>1440</ttl>

    
    <generator>MkDocs RSS plugin - v1.17.1</generator>

    
    
    <image>
      <url>https://upload.wikimedia.org/wikipedia/commons/thumb/4/43/Feed-icon.svg/128px-Feed-icon.svg.png</url>
      <title>Disenone's Wiki</title>
      <link>https://wiki.disenone.site/</link>
    </image>
    

    
    
    <item>
      <title>Blog</title>
      
      
      
      
      <description>&lt;h1 id=&#34;blog&#34;&gt;Blog&lt;/h1&gt;</description>
      <link>https://wiki.disenone.site/ko/blog/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Tue, 17 Feb 2026 04:33:08 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ko/blog/</guid>
      
    </item>
    
    <item>
      <title>Blog</title>
      
      
      
      
      <description>&lt;h1 id=&#34;blog&#34;&gt;Blog&lt;/h1&gt;</description>
      <link>https://wiki.disenone.site/ar/blog/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Tue, 17 Feb 2026 04:32:17 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ar/blog/</guid>
      
    </item>
    
    <item>
      <title>Blog</title>
      
      
      
      
      <description>&lt;h1 id=&#34;blog&#34;&gt;Blog&lt;/h1&gt;</description>
      <link>https://wiki.disenone.site/fr/blog/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Tue, 17 Feb 2026 04:24:38 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/fr/blog/</guid>
      
    </item>
    
    <item>
      <title>Blog</title>
      
      
      
      
      <description>&lt;h1 id=&#34;blog&#34;&gt;Blog&lt;/h1&gt;</description>
      <link>https://wiki.disenone.site/de/blog/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Tue, 17 Feb 2026 04:20:25 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/de/blog/</guid>
      
    </item>
    
    <item>
      <title>Blog</title>
      
      
      
      
      <description>&lt;h1 id=&#34;blog&#34;&gt;Blog&lt;/h1&gt;</description>
      <link>https://wiki.disenone.site/ja/blog/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Tue, 17 Feb 2026 04:16:12 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ja/blog/</guid>
      
    </item>
    
    <item>
      <title>Blog</title>
      
      
      
      
      <description>&lt;h1 id=&#34;blog&#34;&gt;Blog&lt;/h1&gt;</description>
      <link>https://wiki.disenone.site/es/blog/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Tue, 17 Feb 2026 04:11:54 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/es/blog/</guid>
      
    </item>
    
    <item>
      <title>Blog</title>
      
      
      
      
      <description>&lt;h1 id=&#34;blog&#34;&gt;Blog&lt;/h1&gt;</description>
      <link>https://wiki.disenone.site/en/blog/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Tue, 17 Feb 2026 04:07:36 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/en/blog/</guid>
      
    </item>
    
    <item>
      <title>Blog</title>
      
      
      
      
      <description>&lt;h1 id=&#34;blog&#34;&gt;Blog&lt;/h1&gt;</description>
      <link>https://wiki.disenone.site/zh-Hant/blog/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Tue, 17 Feb 2026 04:03:24 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/zh-Hant/blog/</guid>
      
    </item>
    
    <item>
      <title>Blog</title>
      
      
      
      
      <description>&lt;h1 id=&#34;blog&#34;&gt;Blog&lt;/h1&gt;</description>
      <link>https://wiki.disenone.site/blog/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Tue, 17 Feb 2026 04:02:34 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/blog/</guid>
      
    </item>
    
    <item>
      <title>CllamaServer (llama.cpp server)</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 插件 AIChatPlus 使用说明 - 蓝图篇 - CllamaServer (llama.cpp server)&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;-cllamaserver-llamacpp-server&#34;&gt;蓝图篇 - CllamaServer (llama.cpp server)&lt;/h1&gt;
&lt;!-- 需要图片：展示 CllamaServer 相关的所有蓝图节点概览，类似其他文档的 xxx_all.png --&gt;
&lt;p&gt;&lt;img alt=&#34;blueprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllamaserver_all.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_1&#34;&gt;概述&lt;/h2&gt;
&lt;p&gt;CllamaServer 是基于 llama.cpp 的 Server 模式实现的，可以在本地启动一个兼容 OpenAI API 的服务器，支持多种功能：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;本地推理服务&lt;/strong&gt;: 在本地启动 AI 推理服务器，无需依赖外部 API&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;兼容 OpenAI API&lt;/strong&gt;: 使用 OpenAI 兼容的 API 格式，方便迁移和集成&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多会话支持&lt;/strong&gt;: 支持多个并发请求&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tool Calling&lt;/strong&gt;: 支持函数调用功能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;语音转文字&lt;/strong&gt;: 支持 Speech-to-Text 功能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可视化管理&lt;/strong&gt;: 编辑器内置 Server 管理界面&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;与 Cllama 的区别：
* &lt;strong&gt;Cllama&lt;/strong&gt;: 直接在进程内加载模型进行推理，单次只能处理一个请求
* &lt;strong&gt;CllamaServer&lt;/strong&gt;: 启动独立的 HTTP 服务器，可以处理多个并发请求，API 兼容 OpenAI 格式&lt;/p&gt;
&lt;h2 id=&#34;_2&#34;&gt;准备工作&lt;/h2&gt;
&lt;p&gt;由于是本地运行，需要先准备好离线模型文件，例如从 HuggingFace 下载：&lt;a href=&#34;https://huggingface.co/second-state/Qwen1.5-1.8B-Chat-GGUF/resolve/main/Qwen1.5-1.8B-Chat-Q8_0.gguf&#34;&gt;Qwen1.5-1.8B-Chat-Q8_0.gguf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;把模型放在某个文件夹下面，譬如放在游戏项目的目录 &lt;code&gt;Content/LLAMA&lt;/code&gt; 下。&lt;/p&gt;
&lt;h2 id=&#34;cllamaserver&#34;&gt;创建 CllamaServer&lt;/h2&gt;
&lt;h3 id=&#34;server&#34;&gt;使用蓝图创建 Server&lt;/h3&gt;
&lt;p&gt;在蓝图中右键创建节点 &lt;code&gt;Create Cllama Server In World&lt;/code&gt;&lt;/p&gt;
&lt;!-- 需要图片：展示在蓝图中右键搜索 &#34;Create Cllama Server&#34; 并创建节点的截图 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllamaserver_create_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;server_1&#34;&gt;配置 Server 参数&lt;/h3&gt;
&lt;p&gt;创建 &lt;code&gt;Cllama Server Param&lt;/code&gt; 节点，并配置关键参数：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Model&lt;/strong&gt;: 模型文件路径（必填）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Port&lt;/strong&gt;: 服务器端口（0 表示自动分配）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Host&lt;/strong&gt;: 监听地址，默认 &lt;code&gt;127.0.0.1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NGpuLayers&lt;/strong&gt;: GPU 层数（-1 表示全部使用 GPU）&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- 需要图片：展示创建 FAIChatPlus_CllamaServerParam 节点，设置 Model 路径、Port、NGpuLayers 等参数的截图 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllamaserver_create_2.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_3&#34;&gt;绑定回调事件&lt;/h3&gt;
&lt;p&gt;绑定 Server 的回调事件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;On Started&lt;/strong&gt;: Server 启动成功时触发&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;On Stopped&lt;/strong&gt;: Server 停止时触发&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;On Failed&lt;/strong&gt;: Server 启动失败时触发&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- 需要图片：展示绑定 OnStartedListeners、OnStoppedListeners、OnFailedListeners 事件的蓝图 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllamaserver_create_3.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_4&#34;&gt;完整的创建蓝图&lt;/h3&gt;
&lt;p&gt;完整的 Server 创建蓝图如下：&lt;/p&gt;
&lt;!-- 需要图片：展示完整的 Server 创建蓝图全貌，包括参数设置、创建节点、回调绑定 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllamaserver_create_4.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;运行蓝图后，Server 启动成功会触发 &lt;code&gt;On Started&lt;/code&gt; 事件。&lt;/p&gt;
&lt;!-- 需要图片：展示 Server 启动成功后的运行结果，显示启动成功的日志或屏幕输出 --&gt;
&lt;!-- ![guide bludprint](assets/img/2024-ue-aichatplus/usage/blueprint/cllamaserver_create_5.png) --&gt;

&lt;h2 id=&#34;server_2&#34;&gt;Server 参数详解&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;FAIChatPlus_CllamaServerParam&lt;/code&gt; 结构体包含以下参数：&lt;/p&gt;
&lt;h3 id=&#34;_5&#34;&gt;常用参数&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;参数&lt;/th&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;默认值&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Model&lt;/td&gt;
&lt;td&gt;FString&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;模型文件路径（必填）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Port&lt;/td&gt;
&lt;td&gt;int32&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;监听端口，0 表示自动分配&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Host&lt;/td&gt;
&lt;td&gt;FString&lt;/td&gt;
&lt;td&gt;127.0.0.1&lt;/td&gt;
&lt;td&gt;监听地址&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NGpuLayers&lt;/td&gt;
&lt;td&gt;int32&lt;/td&gt;
&lt;td&gt;-1&lt;/td&gt;
&lt;td&gt;GPU 层数，-1 表示全部&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bUseJinja&lt;/td&gt;
&lt;td&gt;bool&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;使用 Jinja 模板&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MMProj&lt;/td&gt;
&lt;td&gt;FString&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;多模态投影文件路径&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Temperature&lt;/td&gt;
&lt;td&gt;float&lt;/td&gt;
&lt;td&gt;0.8&lt;/td&gt;
&lt;td&gt;采样温度&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;_6&#34;&gt;推理参数&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;参数&lt;/th&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;默认值&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CtxSize&lt;/td&gt;
&lt;td&gt;int32&lt;/td&gt;
&lt;td&gt;4096&lt;/td&gt;
&lt;td&gt;上下文大小&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NPredict&lt;/td&gt;
&lt;td&gt;int32&lt;/td&gt;
&lt;td&gt;-1&lt;/td&gt;
&lt;td&gt;预测 Token 数，-1 表示无限&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Threads&lt;/td&gt;
&lt;td&gt;int32&lt;/td&gt;
&lt;td&gt;-1&lt;/td&gt;
&lt;td&gt;CPU 线程数，-1 表示自动&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BatchSize&lt;/td&gt;
&lt;td&gt;int32&lt;/td&gt;
&lt;td&gt;2048&lt;/td&gt;
&lt;td&gt;批处理大小&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;_7&#34;&gt;采样参数&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;参数&lt;/th&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;默认值&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TopK&lt;/td&gt;
&lt;td&gt;int32&lt;/td&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;td&gt;Top-K 采样&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TopP&lt;/td&gt;
&lt;td&gt;float&lt;/td&gt;
&lt;td&gt;0.9&lt;/td&gt;
&lt;td&gt;Top-P 采样&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MinP&lt;/td&gt;
&lt;td&gt;float&lt;/td&gt;
&lt;td&gt;0.1&lt;/td&gt;
&lt;td&gt;Min-P 采样&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RepeatPenalty&lt;/td&gt;
&lt;td&gt;float&lt;/td&gt;
&lt;td&gt;1.0&lt;/td&gt;
&lt;td&gt;重复惩罚&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;_8&#34;&gt;服务器参数&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;参数&lt;/th&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;默认值&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ApiKey&lt;/td&gt;
&lt;td&gt;FString&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;API 密钥（可选）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Timeout&lt;/td&gt;
&lt;td&gt;int32&lt;/td&gt;
&lt;td&gt;600&lt;/td&gt;
&lt;td&gt;超时时间（秒）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parallel&lt;/td&gt;
&lt;td&gt;int32&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;并行序列数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bNoWebUI&lt;/td&gt;
&lt;td&gt;bool&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;禁用 Web UI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bVerbose&lt;/td&gt;
&lt;td&gt;bool&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;详细日志&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;cllamaserver_1&#34;&gt;使用 CllamaServer 进行聊天&lt;/h2&gt;
&lt;h3 id=&#34;chat-request&#34;&gt;创建 Chat Request&lt;/h3&gt;
&lt;p&gt;Server 启动成功后，可以使用 &lt;code&gt;Send CllamaServer Chat Request&lt;/code&gt; 节点发送聊天请求。&lt;/p&gt;
&lt;!-- 需要图片：展示在蓝图中右键搜索 &#34;CllamaServer Chat Request&#34; 并创建节点的截图 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllamaserver_chat_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;chat-options&#34;&gt;配置 Chat Options&lt;/h3&gt;
&lt;p&gt;创建 &lt;code&gt;CllamaServer Chat Request Options&lt;/code&gt; 节点，设置 BaseUrl 为 Server 地址。&lt;/p&gt;
&lt;p&gt;可以通过 &lt;code&gt;Get Server Info By ID&lt;/code&gt; 节点获取 Server 信息。&lt;/p&gt;
&lt;!-- 需要图片：展示创建 FAIChatPlus_CllamaServerChatRequestOptions 节点，使用 Get Http Address 获取 Server 地址并设置到 BaseUrl 的蓝图 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllamaserver_chat_2.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;messages&#34;&gt;创建 Messages&lt;/h3&gt;
&lt;p&gt;创建 Messages 数组，添加 System Message 和 User Message。&lt;/p&gt;
&lt;!-- 需要图片：展示创建 Messages 数组，包含 System Message（设置助手角色）和 User Message（用户问题）的蓝图 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllamaserver_chat_3.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_9&#34;&gt;绑定回调处理响应&lt;/h3&gt;
&lt;p&gt;绑定 &lt;code&gt;On Message&lt;/code&gt; 或 &lt;code&gt;On Message Finished&lt;/code&gt; 事件来接收模型响应。&lt;/p&gt;
&lt;!-- 需要图片：展示绑定 OnMessageListeners 事件，并在回调中打印消息到屏幕的蓝图 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllamaserver_chat_4.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_10&#34;&gt;完整的聊天蓝图&lt;/h3&gt;
&lt;p&gt;完整的聊天蓝图如下：&lt;/p&gt;
&lt;!-- 需要图片：展示完整的聊天蓝图全貌，包括创建 Server、等待启动、发送聊天请求、处理响应的完整流程 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllamaserver_chat_5.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_11&#34;&gt;运行结果&lt;/h3&gt;
&lt;p&gt;运行蓝图，可以看到模型返回的消息显示在屏幕上。&lt;/p&gt;
&lt;!-- 需要图片：展示聊天运行结果，屏幕上显示模型返回的回复内容 --&gt;
&lt;!-- ![guide bludprint](assets/img/2024-ue-aichatplus/usage/blueprint/cllamaserver_chat_6.png) --&gt;

&lt;h2 id=&#34;server_3&#34;&gt;Server 管理&lt;/h2&gt;
&lt;h3 id=&#34;server_4&#34;&gt;获取 Server 信息&lt;/h3&gt;
&lt;p&gt;使用 &lt;code&gt;Get Server Info&lt;/code&gt; 节点获取 Server 的详细信息。&lt;/p&gt;
&lt;!-- 需要图片：展示使用 Get Server Info 节点获取 FAIChatPlus_CllamaServerInfo 的蓝图，并 Break 显示各字段 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllamaserver_info_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Server Info 包含以下信息：
* &lt;strong&gt;ServerID&lt;/strong&gt;: 服务器唯一 ID
* &lt;strong&gt;Host&lt;/strong&gt;: 监听地址
* &lt;strong&gt;Port&lt;/strong&gt;: 监听端口
* &lt;strong&gt;Address&lt;/strong&gt;: 完整地址（host:port）
* &lt;strong&gt;HttpAddress&lt;/strong&gt;: HTTP 地址（http://host:port）
* &lt;strong&gt;bIsRunning&lt;/strong&gt;: 是否正在运行
* &lt;strong&gt;Param&lt;/strong&gt;: 服务器参数&lt;/p&gt;
&lt;h3 id=&#34;server_5&#34;&gt;停止 Server&lt;/h3&gt;
&lt;p&gt;使用 &lt;code&gt;Stop Server By ID&lt;/code&gt; 节点停止当前 Server。&lt;/p&gt;
&lt;!-- 需要图片：展示调用 Stop Cllama Server 节点的蓝图 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllamaserver_stop_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_12&#34;&gt;静态管理函数&lt;/h3&gt;
&lt;p&gt;AIChatPlus 提供了一系列静态函数用于管理所有 Server：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Is Server Valid (Static)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查 Server 是否有效&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Is Server Running (Static)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查 Server 是否运行中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Stop Server By ID&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;通过 ID 停止指定 Server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Stop All Servers&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;停止所有 Server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Get Server Info By ID&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;通过 ID 获取 Server 信息&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Get All Server IDs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取所有 Server ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Get Server By ID&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;通过 ID 获取 Server 实例&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;!-- 需要图片：展示使用 Get All Server IDs 和 Stop All Servers 等静态管理函数的蓝图示例 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllamaserver_static_1.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_13&#34;&gt;多模态支持&lt;/h2&gt;
&lt;p&gt;CllamaServer 支持多模态模型（如 Moondream、Qwen2-VL 等）。&lt;/p&gt;
&lt;h3 id=&#34;_14&#34;&gt;配置多模态参数&lt;/h3&gt;
&lt;p&gt;在 Server 参数中设置 &lt;code&gt;MMProj&lt;/code&gt;（多模态投影文件路径）：&lt;/p&gt;
&lt;!-- 需要图片：展示在 Server Param 中设置 Model 和 MMProj 两个路径的蓝图 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllamaserver_vision_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_15&#34;&gt;发送图片消息&lt;/h3&gt;
&lt;p&gt;在 Messages 中添加图片：&lt;/p&gt;
&lt;!-- 需要图片：展示读取图片文件，创建包含图片的 Message，通过 CllamaServer 发送请求的蓝图 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllamaserver_vision_2.png&#34; /&gt;&lt;/p&gt;
&lt;!-- ### 运行结果 --&gt;

&lt;!-- 需要图片：展示图片识别的运行结果，屏幕显示模型对图片内容的描述 --&gt;
&lt;!-- ![guide bludprint](assets/img/2024-ue-aichatplus/usage/blueprint/cllamaserver_vision_3.png) --&gt;

&lt;h2 id=&#34;tool-calling&#34;&gt;Tool Calling&lt;/h2&gt;
&lt;p&gt;CllamaServer 支持 Tool Calling（函数调用）功能，用法与 OpenAI 类似。&lt;/p&gt;
&lt;p&gt;详细用法请参考 &lt;a href=&#34;../ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-ToolCall/&#34;&gt;Tool Call&lt;/a&gt; 文档。&lt;/p&gt;
&lt;p&gt;使用 CllamaServer 进行 Tool Call 时，需要：
1. 在 Server 参数中设置 &lt;code&gt;bUseJinja = true&lt;/code&gt;
2. 在 Chat Options 的 Tools 字段中定义工具&lt;/p&gt;
&lt;!-- 需要图片：展示 CllamaServer Tool Call 的完整蓝图，包括 bUseJinja=true 的设置和 Tools 定义 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllamaserver_tool_1.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;server_6&#34;&gt;编辑器 Server 管理&lt;/h2&gt;
&lt;p&gt;AIChatPlus 在编辑器工具中提供了可视化的 CllamaServer 管理界面，方便创建、监控和管理多个 Server。&lt;/p&gt;
&lt;p&gt;打开编辑器工具：&lt;code&gt;Tools -&amp;gt; AIChatPlus -&amp;gt; AIChat&lt;/code&gt;，打开 Cllama Server Manager 标签页。&lt;/p&gt;
&lt;!-- 需要图片：展示编辑器中 CllamaServer 管理界面的截图，显示 Server 列表、创建按钮、状态信息等 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllamaserver_editor_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;在编辑器中可以：
* 创建新的 Server
* 查看运行中的 Server 状态
* 停止指定的 Server
* 配置 Server 参数
* Server 配置会自动保存&lt;/p&gt;
&lt;!-- 需要图片：展示编辑器中创建新 Server 的界面，显示参数配置面板 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllamaserver_editor_2.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;api&#34;&gt;与其他 API 的关系&lt;/h2&gt;
&lt;p&gt;由于 CllamaServer 兼容 OpenAI API 格式，你也可以使用 OpenAI 的 Chat Request 节点来与 CllamaServer 通信，只需将 &lt;code&gt;BaseUrl&lt;/code&gt; 设置为 CllamaServer 的地址即可。&lt;/p&gt;
&lt;!-- 需要图片：展示使用 OpenAI Chat Request 节点，但 BaseUrl 设置为 CllamaServer 地址的蓝图示例 --&gt;
&lt;!-- ![guide bludprint](assets/img/2024-ue-aichatplus/usage/blueprint/cllamaserver_openai_1.png) --&gt;

&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-CllamaServer/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 12 Feb 2026 08:03:39 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-CllamaServer/</guid>
      
    </item>
    
    <item>
      <title>Json 操作</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 插件 AIChatPlus 使用说明 - 蓝图篇 - Json 操作&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;-json&#34;&gt;蓝图篇 - Json 操作&lt;/h1&gt;
&lt;!-- 需要图片：展示 Json 相关的所有蓝图节点概览，包括 JsonObject、JsonArray、JsonLibrary 分类下的节点 --&gt;
&lt;p&gt;&lt;img alt=&#34;blueprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_all.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_1&#34;&gt;概述&lt;/h2&gt;
&lt;p&gt;AIChatPlus 提供了完整的 JSON 蓝图操作支持，方便在蓝图中处理 JSON 数据。主要包含三个类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;UAIChatPlus_JsonObject&lt;/strong&gt;: JSON 对象操作类，用于处理 &lt;code&gt;{}&lt;/code&gt; 格式的 JSON&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UAIChatPlus_JsonArray&lt;/strong&gt;: JSON 数组操作类，用于处理 &lt;code&gt;[]&lt;/code&gt; 格式的 JSON&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UAIChatPlus_JsonLibrary&lt;/strong&gt;: JSON 工具函数库，提供静态工具函数&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些类支持：
* 创建、解析、序列化 JSON
* 读取和设置字段值
* 嵌套路径查询
* JSON 与 USTRUCT 互转
* 文件读写
* 链式调用&lt;/p&gt;
&lt;h2 id=&#34;jsonobject&#34;&gt;JsonObject 基础操作&lt;/h2&gt;
&lt;h3 id=&#34;jsonobject_1&#34;&gt;创建 JsonObject&lt;/h3&gt;
&lt;p&gt;使用 &lt;code&gt;Create Json Object&lt;/code&gt; 创建一个空的 JSON 对象：&lt;/p&gt;
&lt;!-- 需要图片：展示在蓝图中右键搜索 &#34;Create Json Object&#34; 并创建节点的截图 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_create_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_2&#34;&gt;从字符串解析&lt;/h3&gt;
&lt;p&gt;使用 &lt;code&gt;Parse Json Object&lt;/code&gt; 从 JSON 字符串创建对象：&lt;/p&gt;
&lt;!-- 需要图片：展示 Parse Json Object 节点，输入一个 JSON 字符串如 &#39;{&#34;name&#34;:&#34;test&#34;,&#34;value&#34;:123}&#39;，输出 JsonObject、bSuccess、ErrorMessage --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_parse_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_3&#34;&gt;设置字段值&lt;/h3&gt;
&lt;p&gt;JsonObject 提供了多种 Set 方法，支持链式调用：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Set String Field&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置字符串字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Set Number Field&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置浮点数字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Set Integer Field&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置整数字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Set Boolean Field&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置布尔字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Set Object Field&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置嵌套对象字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Set Array Field&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置数组字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Set Null Field&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置 null 字段&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;!-- 需要图片：展示链式调用设置多个字段的蓝图，如 Create Json Object -&gt; Set String Field(&#34;name&#34;, &#34;player1&#34;) -&gt; Set Integer Field(&#34;level&#34;, 10) -&gt; Set Boolean Field(&#34;active&#34;, true) --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_set_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_4&#34;&gt;获取字段值&lt;/h3&gt;
&lt;p&gt;JsonObject 提供了多种 Get 方法：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Get String Field&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取字符串字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Get Number Field&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取浮点数字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Get Integer Field&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取整数字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Get Boolean Field&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取布尔字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Get Object Field&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取嵌套对象字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Get Array Field&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取数组字段&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;!-- 需要图片：展示从 JsonObject 获取字段值的蓝图，使用 Get String Field 获取 &#34;name&#34; 字段，显示 DefaultValue 和 bSuccess 参数 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_get_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_5&#34;&gt;字段检查&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Has Field&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查字段是否存在&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Get Field Type&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取字段类型&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Get Field Names&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取所有字段名&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Remove Field&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;删除字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Clear&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;清空所有字段&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;!-- 需要图片：展示使用 Has Field 检查字段是否存在，Get Field Type 获取字段类型的蓝图 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_check_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_6&#34;&gt;序列化为字符串&lt;/h3&gt;
&lt;p&gt;使用 &lt;code&gt;To Json String&lt;/code&gt; 将 JsonObject 转换为字符串：&lt;/p&gt;
&lt;!-- 需要图片：展示 To Json String 节点，输入 JsonObject，bPrettyPrint 参数，输出格式化的 JSON 字符串 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_tostring_1.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;jsonarray&#34;&gt;JsonArray 基础操作&lt;/h2&gt;
&lt;h3 id=&#34;jsonarray_1&#34;&gt;创建 JsonArray&lt;/h3&gt;
&lt;p&gt;使用 &lt;code&gt;Create Json Array&lt;/code&gt; 创建一个空的 JSON 数组：&lt;/p&gt;
&lt;!-- 需要图片：展示在蓝图中创建 Create Json Array 节点的截图 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_array_create_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_7&#34;&gt;添加元素&lt;/h3&gt;
&lt;p&gt;JsonArray 提供了多种 Add 方法，支持链式调用：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Add String&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;添加字符串元素&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Add Number&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;添加浮点数元素&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Add Integer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;添加整数元素&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Add Boolean&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;添加布尔元素&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Add Object&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;添加对象元素&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Add Array&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;添加数组元素&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Add Null&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;添加 null 元素&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;!-- 需要图片：展示链式调用添加多个元素的蓝图，如 Create Json Array -&gt; Add String(&#34;a&#34;) -&gt; Add String(&#34;b&#34;) -&gt; Add Integer(123) --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_array_add_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_8&#34;&gt;获取元素&lt;/h3&gt;
&lt;p&gt;JsonArray 提供了按索引获取元素的方法：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Get String&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取字符串元素&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Get Number&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取浮点数元素&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Get Integer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取整数元素&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Get Boolean&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取布尔元素&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Get Object&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取对象元素&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Get Array&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取数组元素&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;!-- 需要图片：展示使用 Get Object 按索引获取数组中的对象元素的蓝图 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_array_get_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_9&#34;&gt;数组操作&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Length&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取数组长度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Is Valid Index&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查索引是否有效&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Get Element Type&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取元素类型&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Remove At&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;删除指定索引的元素&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Clear&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;清空数组&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;!-- 需要图片：展示使用 Length 获取数组长度，配合 For Loop 遍历数组的蓝图 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_array_loop_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_10&#34;&gt;批量转换&lt;/h3&gt;
&lt;p&gt;JsonArray 支持与 UE 数组的批量转换：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;From String Array&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从字符串数组创建&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;To String Array&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;转换为字符串数组&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;From Integer Array&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从整数数组创建&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;To Integer Array&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;转换为整数数组&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;!-- 需要图片：展示 From String Array 和 To String Array 的使用示例 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_array_batch_1.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_11&#34;&gt;路径查询&lt;/h2&gt;
&lt;p&gt;JsonObject 支持使用点分隔的路径访问嵌套数据，如 &lt;code&gt;player.inventory.gold&lt;/code&gt;。&lt;/p&gt;
&lt;h3 id=&#34;_12&#34;&gt;按路径获取值&lt;/h3&gt;
&lt;p&gt;使用 &lt;code&gt;Get String By Path&lt;/code&gt; 按路径获取字符串值：&lt;/p&gt;
&lt;div class=&#34;language-json highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;quot;player&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34; href=&#34;#__codelineno-0-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;Hero&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-4&#34; name=&#34;__codelineno-0-4&#34; href=&#34;#__codelineno-0-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;quot;inventory&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-5&#34; name=&#34;__codelineno-0-5&#34; href=&#34;#__codelineno-0-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;quot;gold&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-6&#34; name=&#34;__codelineno-0-6&#34; href=&#34;#__codelineno-0-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-7&#34; name=&#34;__codelineno-0-7&#34; href=&#34;#__codelineno-0-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-8&#34; name=&#34;__codelineno-0-8&#34; href=&#34;#__codelineno-0-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;!-- 需要图片：展示使用 Get String By Path 节点，Path 设置为 &#34;player.name&#34;，获取嵌套值的蓝图 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_path_get_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_13&#34;&gt;按路径设置值&lt;/h3&gt;
&lt;p&gt;使用 &lt;code&gt;Set String By Path&lt;/code&gt; 按路径设置值：&lt;/p&gt;
&lt;!-- 需要图片：展示使用 Set String By Path 节点设置嵌套路径值的蓝图，显示 FAIChatPlus_JsonPathOptions 参数（bCaseSensitive、bCreateMissing） --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_path_set_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_14&#34;&gt;查询结果&lt;/h3&gt;
&lt;p&gt;路径查询返回 &lt;code&gt;FAIChatPlus_JsonQueryResult&lt;/code&gt; 结构，包含：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;bSuccess&lt;/strong&gt;: 查询是否成功&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ValueType&lt;/strong&gt;: 返回值的类型&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ErrorMessage&lt;/strong&gt;: 错误信息（如果失败）&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- 需要图片：展示 Break FAIChatPlus_JsonQueryResult 节点，显示 bSuccess、ValueType、ErrorMessage 字段 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_path_result_1.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;json-ustruct&#34;&gt;JSON 与 USTRUCT 转换&lt;/h2&gt;
&lt;p&gt;AIChatPlus 支持 JSON 与 USTRUCT 之间的转换，方便与蓝图结构体配合使用。&lt;/p&gt;
&lt;h3 id=&#34;json-ustruct_1&#34;&gt;JSON 字符串转 USTRUCT&lt;/h3&gt;
&lt;p&gt;使用 &lt;code&gt;Json String To Struct&lt;/code&gt; 将 JSON 字符串直接转换为 USTRUCT：&lt;/p&gt;
&lt;!-- 需要图片：展示 Json String To Struct 节点，输入 JSON 字符串，输出参数连接到一个自定义的 USTRUCT 变量（如 FAIChatPlus_OpenAIChatRequestOptions） --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_struct_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;ustruct-json&#34;&gt;USTRUCT 转 JSON 字符串&lt;/h3&gt;
&lt;p&gt;使用 &lt;code&gt;Struct To Json String&lt;/code&gt; 将 USTRUCT 转换为 JSON 字符串：&lt;/p&gt;
&lt;!-- 需要图片：展示 Struct To Json String 节点，输入一个 USTRUCT 变量，bPrettyPrint 参数，输出 JSON 字符串 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_struct_2.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;jsonobject-ustruct&#34;&gt;JsonObject 转 USTRUCT&lt;/h3&gt;
&lt;p&gt;使用 JsonObject 的 &lt;code&gt;To Struct&lt;/code&gt; 方法：&lt;/p&gt;
&lt;!-- 需要图片：展示 JsonObject 的 To Struct 节点用法 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_struct_3.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;ustruct-jsonobject&#34;&gt;USTRUCT 转 JsonObject&lt;/h3&gt;
&lt;p&gt;使用 &lt;code&gt;From Struct&lt;/code&gt; 静态方法从 USTRUCT 创建 JsonObject：&lt;/p&gt;
&lt;!-- 需要图片：展示 From Struct 节点，输入 USTRUCT，输出 JsonObject --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_struct_4.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;jsonlibrary&#34;&gt;JsonLibrary 工具函数&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;UAIChatPlus_JsonLibrary&lt;/code&gt; 提供了一系列静态工具函数。&lt;/p&gt;
&lt;h3 id=&#34;_15&#34;&gt;快速创建&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Make Json Object With String Field&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;快速创建带单个字段的 JsonObject&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Make Json Object From String Map&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从 Map 创建 JsonObject&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;!-- 需要图片：展示使用 Make Json Object From String Map，输入 TMap&lt;FString, FString&gt;，输出 JsonObject 的蓝图 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_lib_make_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_16&#34;&gt;验证&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Validate Json String&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;验证 JSON 字符串是否有效&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Is Json Object&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查是否为 JSON 对象&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Is Json Array&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查是否为 JSON 数组&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;!-- 需要图片：展示使用 Validate Json String 验证 JSON 字符串的蓝图 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_lib_validate_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_17&#34;&gt;格式化&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Prettify Json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;格式化 JSON（添加缩进换行）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Minify Json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;压缩 JSON（移除空白）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;!-- 需要图片：展示使用 Prettify Json 格式化 JSON 字符串，显示输入的压缩 JSON 和输出的格式化 JSON --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_lib_format_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_18&#34;&gt;文件操作&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Load Json Object From File&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从文件加载 JsonObject&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Save Json Object To File&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;保存 JsonObject 到文件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Load Json Array From File&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从文件加载 JsonArray&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Save Json Array To File&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;保存 JsonArray 到文件&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;!-- 需要图片：展示 Save Json Object To File 和 Load Json Object From File 的使用示例 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_lib_file_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_19&#34;&gt;比较&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Equals Json Object&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;比较两个 JsonObject 是否相等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Equals Json Array&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;比较两个 JsonArray 是否相等&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;!-- 需要图片：展示使用 Equals Json Object 比较两个 JsonObject 的蓝图 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_lib_compare_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_20&#34;&gt;高级路径查询&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Query String By Path&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;按路径查询字符串（支持数组索引，如 &lt;code&gt;items[0].name&lt;/code&gt;）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Query Object By Path&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;按路径查询对象&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Query Array By Path&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;按路径查询数组&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;!-- 需要图片：展示使用 Query String By Path 查询带数组索引的路径，如 &#34;data.items[0].name&#34; --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_lib_query_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_21&#34;&gt;批量操作&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;函数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Set String Fields From Map&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;批量设置字符串字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Get String Fields To Map&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;批量获取字符串字段&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;!-- 需要图片：展示使用 Set String Fields From Map 批量设置字段的蓝图 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_lib_batch_1.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_22&#34;&gt;其他操作&lt;/h2&gt;
&lt;h3 id=&#34;jsonobject_2&#34;&gt;合并 JsonObject&lt;/h3&gt;
&lt;p&gt;使用 &lt;code&gt;Merge&lt;/code&gt; 方法合并两个 JsonObject：&lt;/p&gt;
&lt;!-- 需要图片：展示 Merge 节点，将两个 JsonObject 合并，显示 bOverwrite 参数 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;assets/img/2024-ue-aichatplus/usage/blueprint/json_merge_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;jsonobject_3&#34;&gt;复制 JsonObject&lt;/h3&gt;
&lt;p&gt;使用 &lt;code&gt;Duplicate&lt;/code&gt; 方法深拷贝 JsonObject：&lt;/p&gt;
&lt;!-- 需要图片：展示 Duplicate 节点复制 JsonObject 的蓝图 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;assets/img/2024-ue-aichatplus/usage/blueprint/json_dup_1.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_23&#34;&gt;实际应用示例&lt;/h2&gt;
&lt;h3 id=&#34;api&#34;&gt;解析 API 响应&lt;/h3&gt;
&lt;p&gt;从 AI 聊天响应中提取 Tool Call 的参数：&lt;/p&gt;
&lt;!-- 需要图片：展示完整的解析示例蓝图：从 FunctionArguments 字符串 Parse 成 JsonObject，然后使用 Get String Field 获取参数值 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_example_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_24&#34;&gt;构建请求参数&lt;/h3&gt;
&lt;p&gt;使用 JsonObject 构建复杂的请求参数：&lt;/p&gt;
&lt;!-- 需要图片：展示构建嵌套 JSON 结构的蓝图，创建 JsonObject 设置多个字段，包含嵌套的 JsonObject 和 JsonArray --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_example_2.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_25&#34;&gt;配置文件读写&lt;/h3&gt;
&lt;p&gt;从 JSON 文件加载配置，修改后保存：&lt;/p&gt;
&lt;!-- 需要图片：展示完整的配置读写流程：Load Json Object From File -&gt; 修改字段 -&gt; Save Json Object To File --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_example_3.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_26&#34;&gt;类型枚举&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;EAIChatPlus_JsonValueType&lt;/code&gt; 枚举定义了 JSON 值的类型：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;枚举值&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;None&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;未知类型&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Null&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;null 值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;String&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;字符串&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Number&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;数字&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Boolean&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;布尔值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Array&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;数组&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Object&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;对象&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;!-- 需要图片：展示使用 Switch 节点根据 JsonValueType 进行不同处理的蓝图 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/json_type_1.png&#34; /&gt;&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-Json/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 12 Feb 2026 08:03:39 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-Json/</guid>
      
    </item>
    
    <item>
      <title>Tool Call</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 插件 AIChatPlus 使用说明 - 蓝图篇 - Tool Call&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;-tool-call&#34;&gt;蓝图篇 - Tool Call&lt;/h1&gt;
&lt;p&gt;Tool Call（工具调用）也被称为 Function Calling（函数调用），是指大模型可以根据对话内容，判断是否需要调用外部工具/函数来获取信息或执行操作。模型会返回需要调用的函数名称和参数，由开发者执行实际调用后，将结果返回给模型继续对话。&lt;/p&gt;
&lt;p&gt;AIChatPlus 支持以下平台的 Tool Call 功能：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OpenAI&lt;/li&gt;
&lt;li&gt;Claude&lt;/li&gt;
&lt;li&gt;Gemini&lt;/li&gt;
&lt;li&gt;Ollama&lt;/li&gt;
&lt;li&gt;CllamaServer（llama.cpp server）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;_1&#34;&gt;核心概念&lt;/h2&gt;
&lt;h3 id=&#34;tool&#34;&gt;Tool 定义&lt;/h3&gt;
&lt;p&gt;Tool 的定义包含以下关键字段：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;/strong&gt;: 工具类型，目前仅支持 &lt;code&gt;Function&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Name&lt;/strong&gt;: 函数名称，必须由 a-z、A-Z、0-9、下划线或连字符组成，最大长度 64&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Description&lt;/strong&gt;: 函数描述，模型会根据此描述判断何时调用该函数&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Properties&lt;/strong&gt;: 函数参数列表，每个参数包含 Name、Description、Type、Required 等属性&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;tool-call&#34;&gt;Tool Call 流程&lt;/h3&gt;
&lt;p&gt;Tool Call 的完整流程如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;发送请求&lt;/strong&gt;: 向模型发送包含 Tools 定义的聊天请求&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;模型判断&lt;/strong&gt;: 模型根据对话内容判断是否需要调用工具&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;返回 Tool Calls&lt;/strong&gt;: 如果需要调用，模型返回要调用的函数名和参数&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;执行函数&lt;/strong&gt;: 开发者根据返回信息执行实际的函数调用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;返回结果&lt;/strong&gt;: 将函数执行结果作为新消息发送给模型&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;继续对话&lt;/strong&gt;: 模型根据函数结果生成最终回复&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;openai-tool-call&#34;&gt;OpenAI Tool Call 示例&lt;/h2&gt;
&lt;p&gt;下面以 OpenAI 为例，演示如何使用 Tool Call 功能。&lt;/p&gt;
&lt;h3 id=&#34;1-tool&#34;&gt;1. 定义 Tool&lt;/h3&gt;
&lt;p&gt;首先创建 Tool 定义。本例中我们定义一个获取快递包裹送达时间的函数 &lt;code&gt;get_delivery_date&lt;/code&gt;。&lt;/p&gt;
&lt;!-- 需要图片：展示创建 FAIChatPlus_ChatRequestTool 节点，设置 Type=Function, Name=&#34;get_current_weather&#34;, Description=&#34;Get the current weather in a given location&#34; --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/toolcall_openai_1.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;2-tool&#34;&gt;2. 定义 Tool 参数&lt;/h3&gt;
&lt;p&gt;为 Tool 添加 Properties（参数）。本例中添加一个 &lt;code&gt;order_id&lt;/code&gt; 参数，类型为 &lt;code&gt;string&lt;/code&gt;，设置为必填。&lt;/p&gt;
&lt;!-- 需要图片：展示创建 FAIChatPlus_ChatRequestToolProperty 节点，设置 Name=&#34;location&#34;, Description=&#34;The city and state, e.g. San Francisco, CA&#34;, Type=&#34;string&#34;, Required=true，并通过 Make Array 连接到 Tool 的 Properties 字段 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/toolcall_openai_2.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;3-options&#34;&gt;3. 配置 Options&lt;/h3&gt;
&lt;p&gt;创建 &lt;code&gt;OpenAI Chat Request Options&lt;/code&gt; 节点，设置 API Key 和 Model，并将 Tools 数组连接到 Options。&lt;/p&gt;
&lt;!-- 需要图片：展示创建 OpenAI Chat Request Options 节点，设置 ApiKey, Model=&#34;gpt-4o-mini&#34;, 通过 Make Array 将上面的 Tool 连接到 Tools 字段 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/toolcall_openai_3.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;4-messages&#34;&gt;4. 创建 Messages&lt;/h3&gt;
&lt;p&gt;创建用户消息，询问快递包裹相关的问题。&lt;/p&gt;
&lt;!-- 需要图片：展示创建 Messages 数组，添加一条 User Message，Content 设置为 &#34;What&#39;s the weather like in Boston today?&#34; --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/toolcall_openai_4.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;5-tool-call&#34;&gt;5. 发送请求并处理 Tool Call&lt;/h3&gt;
&lt;p&gt;创建 &lt;code&gt;Send OpenAI Chat Request In World&lt;/code&gt; 节点，绑定 &lt;code&gt;On Message Finished&lt;/code&gt; 事件。在事件回调中，从 Payload 获取 ToolCalls 数组。&lt;/p&gt;
&lt;p&gt;当模型决定调用工具时，ToolCalls 数组不为空。遍历数组获取每个 Tool Call 的信息：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Id&lt;/strong&gt;: Tool Call 的唯一标识符&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FunctionName&lt;/strong&gt;: 要调用的函数名&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FunctionArguments&lt;/strong&gt;: 函数参数（JSON 字符串格式）&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- 需要图片：展示完整的发送请求蓝图，创建 Send OpenAI Chat Request In World 节点，连接 Options 和 Messages，绑定 On Message Finished 事件，在事件回调中使用 Break 节点获取 Payload 中的 ToolCalls --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/toolcall_openai_5.png&#34; /&gt;&lt;/p&gt;
&lt;!-- 需要图片：展示遍历 ToolCalls 数组的蓝图，使用 For Each Loop 遍历，对每个元素使用 Break 节点获取 Id, FunctionName, FunctionArguments 字段，并将其打印输出 --&gt;
&lt;!-- ![guide bludprint](assets/img/2024-ue-aichatplus/usage/blueprint/toolcall_openai_6.png) --&gt;

&lt;h3 id=&#34;6&#34;&gt;6. 执行函数并返回结果&lt;/h3&gt;
&lt;p&gt;根据 FunctionName 执行对应的函数逻辑（本例中模拟获取快递包裹送达时间），然后将结果作为 ToolCallResult 类型的消息返回给模型。&lt;/p&gt;
&lt;p&gt;创建新的 Message，需要设置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Role&lt;/strong&gt;: 设置为 &lt;code&gt;Tool&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Content&lt;/strong&gt;: 函数执行的结果&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ToolCallResults&lt;/strong&gt;: 添加一个 &lt;code&gt;FAIChatPlus_ChatRequestToolCallResult&lt;/code&gt;，设置 Id（使用之前的 Tool Call Id）、FunctionName 和 FunctionResult&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- 需要图片：展示创建 Tool 角色消息的蓝图，创建新的 Message，Role=Tool，Content 设置为模拟的天气数据如 &#39;{&#34;temperature&#34;: &#34;22&#34;, &#34;unit&#34;: &#34;celsius&#34;, &#34;description&#34;: &#34;Sunny&#34;}&#39;，并在 ToolCallResults 中添加对应的结果信息 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/toolcall_openai_7.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;7&#34;&gt;7. 继续对话&lt;/h3&gt;
&lt;p&gt;将包含 ToolCallResult 结果的消息添加到历史消息中，再次发送请求。模型会根据函数返回的结果生成最终的自然语言回复。&lt;/p&gt;
&lt;!-- 需要图片：展示完整的第二次请求蓝图，将原始的 User Message、模型返回的 Assistant Message（包含 ToolCalls）、以及 Tool 结果 Message 组合成新的 Messages 数组，再次调用 Send OpenAI Chat Request In World --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/toolcall_openai_8.png&#34; /&gt;&lt;/p&gt;
&lt;!-- ### 9. 完整蓝图 --&gt;

&lt;!-- 完整的 Tool Call 蓝图看起来是这样的： --&gt;

&lt;!-- 需要图片：展示完整的 Tool Call 流程蓝图全貌，包含 Tool 定义、第一次请求、Tool Call 处理、第二次请求的完整流程 --&gt;
&lt;!-- ![guide bludprint](assets/img/2024-ue-aichatplus/usage/blueprint/toolcall_openai_9.png) --&gt;

&lt;!-- ### 10. 运行结果 --&gt;

&lt;!-- 运行蓝图，可以看到模型返回了包含天气信息的自然语言回复。 --&gt;

&lt;!-- 需要图片：展示运行结果截图，屏幕上显示模型的最终回复，类似 &#34;The current weather in Boston is sunny with a temperature of 22°C.&#34; --&gt;
&lt;!-- ![guide bludprint](assets/img/2024-ue-aichatplus/usage/blueprint/toolcall_openai_10.png) --&gt;

&lt;h2 id=&#34;_2&#34;&gt;高级用法&lt;/h2&gt;
&lt;h3 id=&#34;tools&#34;&gt;多个 Tools&lt;/h3&gt;
&lt;p&gt;可以同时定义多个 Tools，模型会根据需要选择调用哪个或哪些函数。&lt;/p&gt;
&lt;!-- 需要图片：展示定义多个 Tools 的蓝图，例如同时定义 get_current_weather 和 get_stock_price 两个 Tool，通过 Make Array 组合成 Tools 数组 --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/toolcall_multi_tools.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_3&#34;&gt;复杂参数类型&lt;/h3&gt;
&lt;p&gt;Tool 参数支持多种类型，可以通过 &lt;code&gt;ExtraJsonString&lt;/code&gt; 或 &lt;code&gt;ExtraJsonObject&lt;/code&gt; 字段添加更复杂的参数定义，例如枚举类型：&lt;/p&gt;
&lt;div class=&#34;language-json highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;quot;enum&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;Beijing&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;HongKong&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;!-- 需要图片：展示使用 ExtraJsonString 设置枚举参数的蓝图，在 Property 节点的 ExtraJsonString 字段中填入 &#39;{&#34;enum&#34;: [&#34;celsius&#34;, &#34;fahrenheit&#34;]}&#39; --&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/toolcall_extra_json.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_4&#34;&gt;其他平台&lt;/h3&gt;
&lt;p&gt;Claude、Gemini、Ollama 和 CllamaServer 的 Tool Call 用法与 OpenAI 类似，只需替换相应的 Request 和 Options 节点即可。各平台的核心数据结构（&lt;code&gt;FAIChatPlus_ChatRequestTool&lt;/code&gt;、&lt;code&gt;FAIChatPlus_ChatResponseToolCall&lt;/code&gt; 等）是通用的。&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-ToolCall/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 12 Feb 2026 08:03:39 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-ToolCall/</guid>
      
    </item>
    
    <item>
      <title>Claude</title>
      
      
      
      
      <description>&lt;h1 id=&#34;macro-syntax-error&#34;&gt;&lt;em&gt;Macro Syntax Error&lt;/em&gt;&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;File&lt;/em&gt;: &lt;code&gt;zh/ue-插件-AIChatPlus-Usage-Source-Claude.md&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Line 250 in Markdown file:&lt;/em&gt; &lt;strong&gt;expected token &#39;end of print statement&#39;, got &#39;:&#39;&lt;/strong&gt;
&lt;div class=&#34;language-markdown highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;        {{TEXT(&amp;quot;What&amp;#39;s the weather like in Paris?&amp;quot;), EAIChatPlus_ChatRole::User}});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-Claude/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 12 Feb 2026 08:03:39 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-Claude/</guid>
      
    </item>
    
    <item>
      <title>Cllama(已废弃)</title>
      
      
      
      
      <description>&lt;h1 id=&#34;macro-syntax-error&#34;&gt;&lt;em&gt;Macro Syntax Error&lt;/em&gt;&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;File&lt;/em&gt;: &lt;code&gt;zh/ue-插件-AIChatPlus-Usage-Source-Cllama.md&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Line 367 in Markdown file:&lt;/em&gt; &lt;strong&gt;expected token &#39;end of print statement&#39;, got &#39;:&#39;&lt;/strong&gt;
&lt;div class=&#34;language-markdown highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;        {{TEXT(&amp;quot;Write a short poem.&amp;quot;), EAIChatPlus_ChatRole::User}});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-Cllama/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 12 Feb 2026 08:03:39 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-Cllama/</guid>
      
    </item>
    
    <item>
      <title>CllamaServer</title>
      
      
      
      
      <description>&lt;h1 id=&#34;macro-syntax-error&#34;&gt;&lt;em&gt;Macro Syntax Error&lt;/em&gt;&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;File&lt;/em&gt;: &lt;code&gt;zh/ue-插件-AIChatPlus-Usage-Source-CllamaServer.md&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Line 672 in Markdown file:&lt;/em&gt; &lt;strong&gt;expected token &#39;end of print statement&#39;, got &#39;:&#39;&lt;/strong&gt;
&lt;div class=&#34;language-markdown highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;        {{TEXT(&amp;quot;Hello!&amp;quot;), EAIChatPlus_ChatRole::User}});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-CllamaServer/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 12 Feb 2026 08:03:39 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-CllamaServer/</guid>
      
    </item>
    
    <item>
      <title>Gemini</title>
      
      
      
      
      <description>&lt;h1 id=&#34;macro-syntax-error&#34;&gt;&lt;em&gt;Macro Syntax Error&lt;/em&gt;&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;File&lt;/em&gt;: &lt;code&gt;zh/ue-插件-AIChatPlus-Usage-Source-Gemini.md&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Line 244 in Markdown file:&lt;/em&gt; &lt;strong&gt;expected token &#39;end of print statement&#39;, got &#39;:&#39;&lt;/strong&gt;
&lt;div class=&#34;language-markdown highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;        {{TEXT(&amp;quot;What&amp;#39;s the weather like in Tokyo?&amp;quot;), EAIChatPlus_ChatRole::User}});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-Gemini/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 12 Feb 2026 08:03:39 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-Gemini/</guid>
      
    </item>
    
    <item>
      <title>Ollama</title>
      
      
      
      
      <description>&lt;h1 id=&#34;macro-syntax-error&#34;&gt;&lt;em&gt;Macro Syntax Error&lt;/em&gt;&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;File&lt;/em&gt;: &lt;code&gt;zh/ue-插件-AIChatPlus-Usage-Source-Ollama.md&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Line 519 in Markdown file:&lt;/em&gt; &lt;strong&gt;expected token &#39;end of print statement&#39;, got &#39;:&#39;&lt;/strong&gt;
&lt;div class=&#34;language-markdown highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;        {{TEXT(&amp;quot;Hello!&amp;quot;), EAIChatPlus_ChatRole::User}});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-Ollama/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 12 Feb 2026 08:03:39 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-Ollama/</guid>
      
    </item>
    
    <item>
      <title>OpenAI / Azure</title>
      
      
      
      
      <description>&lt;h1 id=&#34;macro-syntax-error&#34;&gt;&lt;em&gt;Macro Syntax Error&lt;/em&gt;&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;File&lt;/em&gt;: &lt;code&gt;zh/ue-插件-AIChatPlus-Usage-Source-OpenAI.md&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Line 218 in Markdown file:&lt;/em&gt; &lt;strong&gt;expected token &#39;end of print statement&#39;, got &#39;:&#39;&lt;/strong&gt;
&lt;div class=&#34;language-markdown highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;        Options, {{TEXT(&amp;quot;You are a game analyst.&amp;quot;), EAIChatPlus_ChatRole::System}, ImageMessage});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-OpenAI/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 12 Feb 2026 08:03:39 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-OpenAI/</guid>
      
    </item>
    
    <item>
      <title>API Reference</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 插件 AIChatPlus 使用说明 - C++ 篇 - API Reference&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;c-api-reference&#34;&gt;C++ 篇 - API Reference&lt;/h1&gt;
&lt;p&gt;本文档提供 AIChatPlus 插件的 C++ API 参考，包含所有公开类、结构体、枚举和关键方法的说明。&lt;/p&gt;
&lt;h2 id=&#34;_1&#34;&gt;目录&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;##枚举类型&#34;&gt;枚举类型&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;##核心基类&#34;&gt;核心基类&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;##handler-类&#34;&gt;Handler 类&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;##request-类&#34;&gt;Request 类&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;##工具类&#34;&gt;工具类&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;##json-类&#34;&gt;JSON 类&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2 id=&#34;_2&#34;&gt;枚举类型&lt;/h2&gt;
&lt;h3 id=&#34;eaichatplus_chatapiprovider&#34;&gt;EAIChatPlus_ChatApiProvider&lt;/h3&gt;
&lt;p&gt;AI 聊天 API 提供商枚举。&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;enum&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;EAIChatPlus_ChatApiProvider&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint8&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34; href=&#34;#__codelineno-0-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OpenAI&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// OpenAI API&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-4&#34; name=&#34;__codelineno-0-4&#34; href=&#34;#__codelineno-0-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Azure&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Azure OpenAI API&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-5&#34; name=&#34;__codelineno-0-5&#34; href=&#34;#__codelineno-0-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Claude&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Anthropic Claude API&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-6&#34; name=&#34;__codelineno-0-6&#34; href=&#34;#__codelineno-0-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Gemini&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Google Gemini API&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-7&#34; name=&#34;__codelineno-0-7&#34; href=&#34;#__codelineno-0-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Ollama&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Ollama 本地服务&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-8&#34; name=&#34;__codelineno-0-8&#34; href=&#34;#__codelineno-0-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Cllama&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// llama.cpp 直接调用（已废弃）&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-9&#34; name=&#34;__codelineno-0-9&#34; href=&#34;#__codelineno-0-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CllamaServer&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// llama.cpp 服务器模式&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-10&#34; name=&#34;__codelineno-0-10&#34; href=&#34;#__codelineno-0-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;eaichatplus_imageapiprovider&#34;&gt;EAIChatPlus_ImageApiProvider&lt;/h3&gt;
&lt;p&gt;图片生成 API 提供商枚举。&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;enum&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;EAIChatPlus_ImageApiProvider&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint8&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-2&#34; name=&#34;__codelineno-1-2&#34; href=&#34;#__codelineno-1-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-3&#34; name=&#34;__codelineno-1-3&#34; href=&#34;#__codelineno-1-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OpenAI&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// OpenAI DALL-E&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-4&#34; name=&#34;__codelineno-1-4&#34; href=&#34;#__codelineno-1-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Azure&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Azure OpenAI DALL-E&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-5&#34; name=&#34;__codelineno-1-5&#34; href=&#34;#__codelineno-1-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;eaichatplus_chatrole&#34;&gt;EAIChatPlus_ChatRole&lt;/h3&gt;
&lt;p&gt;消息角色枚举。&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-2-1&#34; name=&#34;__codelineno-2-1&#34; href=&#34;#__codelineno-2-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;enum&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;EAIChatPlus_ChatRole&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint8&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-2&#34; name=&#34;__codelineno-2-2&#34; href=&#34;#__codelineno-2-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-3&#34; name=&#34;__codelineno-2-3&#34; href=&#34;#__codelineno-2-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;System&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 系统指令（旧模型）&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-4&#34; name=&#34;__codelineno-2-4&#34; href=&#34;#__codelineno-2-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;User&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 用户消息&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-5&#34; name=&#34;__codelineno-2-5&#34; href=&#34;#__codelineno-2-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Assistant&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// AI 回复&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-6&#34; name=&#34;__codelineno-2-6&#34; href=&#34;#__codelineno-2-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Developer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 开发者指令（o1+ 模型）&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-7&#34; name=&#34;__codelineno-2-7&#34; href=&#34;#__codelineno-2-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Tool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 工具调用结果&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-8&#34; name=&#34;__codelineno-2-8&#34; href=&#34;#__codelineno-2-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;eaichatplus_imagechattype&#34;&gt;EAIChatPlus_ImageChatType&lt;/h3&gt;
&lt;p&gt;图片操作类型枚举。&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-3-1&#34; name=&#34;__codelineno-3-1&#34; href=&#34;#__codelineno-3-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;enum&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;EAIChatPlus_ImageChatType&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint8&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-2&#34; name=&#34;__codelineno-3-2&#34; href=&#34;#__codelineno-3-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-3&#34; name=&#34;__codelineno-3-3&#34; href=&#34;#__codelineno-3-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Generation&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 图片生成&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-4&#34; name=&#34;__codelineno-3-4&#34; href=&#34;#__codelineno-3-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Edit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 图片编辑&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-5&#34; name=&#34;__codelineno-3-5&#34; href=&#34;#__codelineno-3-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Variation&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 图片变体&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-6&#34; name=&#34;__codelineno-3-6&#34; href=&#34;#__codelineno-3-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;eaichatplus_jsonvaluetype&#34;&gt;EAIChatPlus_JsonValueType&lt;/h3&gt;
&lt;p&gt;JSON 值类型枚举。&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-4-1&#34; name=&#34;__codelineno-4-1&#34; href=&#34;#__codelineno-4-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;enum&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;EAIChatPlus_JsonValueType&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint8&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-2&#34; name=&#34;__codelineno-4-2&#34; href=&#34;#__codelineno-4-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-3&#34; name=&#34;__codelineno-4-3&#34; href=&#34;#__codelineno-4-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 无效&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-4&#34; name=&#34;__codelineno-4-4&#34; href=&#34;#__codelineno-4-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 空值&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-5&#34; name=&#34;__codelineno-4-5&#34; href=&#34;#__codelineno-4-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 字符串&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-6&#34; name=&#34;__codelineno-4-6&#34; href=&#34;#__codelineno-4-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Number&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 数字&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-7&#34; name=&#34;__codelineno-4-7&#34; href=&#34;#__codelineno-4-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Boolean&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 布尔&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-8&#34; name=&#34;__codelineno-4-8&#34; href=&#34;#__codelineno-4-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 数组&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-9&#34; name=&#34;__codelineno-4-9&#34; href=&#34;#__codelineno-4-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Object&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 对象&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-10&#34; name=&#34;__codelineno-4-10&#34; href=&#34;#__codelineno-4-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h2 id=&#34;_3&#34;&gt;核心基类&lt;/h2&gt;
&lt;h3 id=&#34;uaichatplus_requestbase&#34;&gt;UAIChatPlus_RequestBase&lt;/h3&gt;
&lt;p&gt;所有请求的基类（抽象类）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;关键方法：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SendRequest()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;发送请求&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;StopRequest()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;停止请求&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Activate()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;激活请求对象&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IsActivated()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查是否已激活&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SetIsAutoDestroy(bool)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置完成后自动销毁&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;委托：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;委托名&lt;/th&gt;
&lt;th&gt;签名&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OnStartedListeners&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;请求开始&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OnMessageListeners&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void(const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;收到流式消息&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OnFinishedListeners&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void(const FAIChatPlus_PointerWrapper&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;请求完成&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OnFailedListeners&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void(const FAIChatPlus_PointerWrapper&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;请求失败&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;uaichatplus_chatrequestbase&#34;&gt;UAIChatPlus_ChatRequestBase&lt;/h3&gt;
&lt;p&gt;聊天请求基类，继承自 &lt;code&gt;UAIChatPlus_RequestBase&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;静态工厂方法：&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-5-1&#34; name=&#34;__codelineno-5-1&#34; href=&#34;#__codelineno-5-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// 按 Provider 创建请求&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-2&#34; name=&#34;__codelineno-5-2&#34; href=&#34;#__codelineno-5-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_ChatRequestBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CreateByApi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EAIChatPlus_ChatApiProvider&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InApiProvider&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-3&#34; name=&#34;__codelineno-5-3&#34; href=&#34;#__codelineno-5-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_ChatRequestBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CreateByApiInWorld&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EAIChatPlus_ChatApiProvider&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InApiProvider&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InWorldContext&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;关键方法：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SetMessages(const TArray&amp;lt;FAIChatPlus_ChatRequestMessage&amp;gt;&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置消息列表&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetFullUrl()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取完整请求 URL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetModelText()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取模型名称&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetTokenUsageText()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取 Token 用量描述&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetApiProvider()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;EAIChatPlus_ChatApiProvider&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取 API Provider 类型&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;uaichatplus_imagerequestbase&#34;&gt;UAIChatPlus_ImageRequestBase&lt;/h3&gt;
&lt;p&gt;图片请求基类，继承自 &lt;code&gt;UAIChatPlus_RequestBase&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;静态工厂方法：&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-6-1&#34; name=&#34;__codelineno-6-1&#34; href=&#34;#__codelineno-6-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_ImageRequestBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CreateByApi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EAIChatPlus_ImageApiProvider&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InApiProvider&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-2&#34; name=&#34;__codelineno-6-2&#34; href=&#34;#__codelineno-6-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_ImageRequestBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CreateByApiInWorld&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EAIChatPlus_ImageApiProvider&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InApiProvider&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InWorldContext&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;关键方法：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SetPrompt(const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置图片生成提示词&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SetImages(const TArray&amp;lt;UAIChatPlus_Texture*&amp;gt;&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置输入图片（编辑/变体）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetModelText()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取模型名称&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetStyleText()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取风格名称&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetRevisedPrompt()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取修正后的提示词&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetImageChatType()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取图片操作类型&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;uaichatplus_modelrequestbase&#34;&gt;UAIChatPlus_ModelRequestBase&lt;/h3&gt;
&lt;p&gt;模型列表请求基类，继承自 &lt;code&gt;UAIChatPlus_RequestBase&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;静态工厂方法：&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-7-1&#34; name=&#34;__codelineno-7-1&#34; href=&#34;#__codelineno-7-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_ModelRequestBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CreateByApi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EAIChatPlus_ChatApiProvider&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InApiProvider&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-2&#34; name=&#34;__codelineno-7-2&#34; href=&#34;#__codelineno-7-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_ModelRequestBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CreateByApiInWorld&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EAIChatPlus_ChatApiProvider&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InApiProvider&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InWorldContext&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h2 id=&#34;handler&#34;&gt;Handler 类&lt;/h2&gt;
&lt;h3 id=&#34;uaichatplus_handlerbase&#34;&gt;UAIChatPlus_HandlerBase&lt;/h3&gt;
&lt;p&gt;所有 Handler 的基类。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;关键方法：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SetIsAutoDestroy(bool)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置自动销毁&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AutoDestroy()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;执行自动销毁&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Destroy()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;立即销毁&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;uaichatplus_chathandlerbase&#34;&gt;UAIChatPlus_ChatHandlerBase&lt;/h3&gt;
&lt;p&gt;聊天请求 Handler，继承自 &lt;code&gt;UAIChatPlus_HandlerBase&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;静态工厂方法：&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-8-1&#34; name=&#34;__codelineno-8-1&#34; href=&#34;#__codelineno-8-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_ChatHandlerBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;New&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;绑定方法：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BindChatRequest(UAIChatPlus_ChatRequestBase*)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;绑定聊天请求&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BindImageRequest(UAIChatPlus_ImageRequestBase*)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;绑定图片请求&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BindModelRequest(UAIChatPlus_ModelRequestBase*)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;绑定模型请求&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ClearDelegates()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;清除所有委托绑定&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;委托：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;委托名&lt;/th&gt;
&lt;th&gt;签名&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OnStarted&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;请求开始&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OnStopped&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;请求停止&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OnMessage&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void(const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;流式消息&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OnMessageFinished&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void(const FAIChatPlus_MessageFinishedPayload&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;消息完成&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OnUpdated&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void(const FAIChatPlus_PointerWrapper&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;请求更新&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OnFinished&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void(const FAIChatPlus_PointerWrapper&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;请求完成&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OnFailed&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void(const FAIChatPlus_PointerWrapper&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;请求失败&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OnImages&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void(const TArray&amp;lt;UTexture2D*&amp;gt;&amp;amp;, bool)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;图片生成&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OnModels&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void(const TArray&amp;lt;FString&amp;gt;&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;模型列表&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;uaichatplus_cllamaserverhandler&#34;&gt;UAIChatPlus_CllamaServerHandler&lt;/h3&gt;
&lt;p&gt;CllamaServer 专用 Handler。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;静态工厂方法：&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-9-1&#34; name=&#34;__codelineno-9-1&#34; href=&#34;#__codelineno-9-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_CllamaServerHandler&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CreateHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;委托：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;委托名&lt;/th&gt;
&lt;th&gt;签名&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OnServerStarted&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void(FGuid)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;服务器启动&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OnServerStopped&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void(FGuid)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;服务器停止&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OnServerFailed&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void(FGuid, const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;服务器失败&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2 id=&#34;request&#34;&gt;Request 类&lt;/h2&gt;
&lt;p&gt;所有 Provider 的 Request 类都遵循相同的工厂方法模式：&lt;/p&gt;
&lt;h3 id=&#34;_4&#34;&gt;通用工厂方法模式&lt;/h3&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-10-1&#34; name=&#34;__codelineno-10-1&#34; href=&#34;#__codelineno-10-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// 以 OpenAI 为例，其他 Provider 类似&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-2&#34; name=&#34;__codelineno-10-2&#34; href=&#34;#__codelineno-10-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_OpenAIChatRequest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Create&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-3&#34; name=&#34;__codelineno-10-3&#34; href=&#34;#__codelineno-10-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_OpenAIChatRequest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CreateWithOptions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_OpenAIChatRequestOptions&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InOptions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-4&#34; name=&#34;__codelineno-10-4&#34; href=&#34;#__codelineno-10-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_OpenAIChatRequest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CreateWithOptionsAndMessages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-5&#34; name=&#34;__codelineno-10-5&#34; href=&#34;#__codelineno-10-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_OpenAIChatRequestOptions&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InOptions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-6&#34; name=&#34;__codelineno-10-6&#34; href=&#34;#__codelineno-10-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_ChatRequestMessage&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InMessages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-7&#34; name=&#34;__codelineno-10-7&#34; href=&#34;#__codelineno-10-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_OpenAIChatRequest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CreateInWorld&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InWorldContext&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-8&#34; name=&#34;__codelineno-10-8&#34; href=&#34;#__codelineno-10-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_OpenAIChatRequest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CreateInWorldWithOptions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-9&#34; name=&#34;__codelineno-10-9&#34; href=&#34;#__codelineno-10-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InWorldContext&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-10&#34; name=&#34;__codelineno-10-10&#34; href=&#34;#__codelineno-10-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_OpenAIChatRequestOptions&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InOptions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-11&#34; name=&#34;__codelineno-10-11&#34; href=&#34;#__codelineno-10-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_OpenAIChatRequest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CreateInWorldWithOptionsAndMessages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-12&#34; name=&#34;__codelineno-10-12&#34; href=&#34;#__codelineno-10-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InWorldContext&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-13&#34; name=&#34;__codelineno-10-13&#34; href=&#34;#__codelineno-10-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_OpenAIChatRequestOptions&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InOptions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-14&#34; name=&#34;__codelineno-10-14&#34; href=&#34;#__codelineno-10-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_ChatRequestMessage&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InMessages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;_5&#34;&gt;通用静态方法&lt;/h3&gt;
&lt;p&gt;所有 Request 类都提供 &lt;code&gt;CastWrapperToResponse&lt;/code&gt; 方法用于类型转换：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-11-1&#34; name=&#34;__codelineno-11-1&#34; href=&#34;#__codelineno-11-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// 从 PointerWrapper 提取响应数据&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-2&#34; name=&#34;__codelineno-11-2&#34; href=&#34;#__codelineno-11-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_XXXResponseBody&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CastWrapperToResponse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_PointerWrapper&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InWrapper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-3&#34; name=&#34;__codelineno-11-3&#34; href=&#34;#__codelineno-11-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_PointerWrapper&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CastResponseToWrapper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_XXXResponseBody&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InResponse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;uaichatplus_openaichatrequest&#34;&gt;UAIChatPlus_OpenAIChatRequest&lt;/h3&gt;
&lt;p&gt;OpenAI 聊天请求。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;头文件：&lt;/strong&gt; &lt;code&gt;Common_OpenAI/AIChatPlus_OpenAIChatRequest.h&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Options 类型：&lt;/strong&gt; &lt;code&gt;FAIChatPlus_OpenAIChatRequestOptions&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Response 类型：&lt;/strong&gt; &lt;code&gt;FAIChatPlus_OpenAIChatResponseBody&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;uaichatplus_azurechatrequest&#34;&gt;UAIChatPlus_AzureChatRequest&lt;/h3&gt;
&lt;p&gt;Azure OpenAI 聊天请求。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;头文件：&lt;/strong&gt; &lt;code&gt;Common_Azure/AIChatPlus_AzureChatRequest.h&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Options 类型：&lt;/strong&gt; &lt;code&gt;FAIChatPlus_AzureChatRequestOptions&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Response 类型：&lt;/strong&gt; &lt;code&gt;FAIChatPlus_AzureChatResponseBody&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;uaichatplus_claudechatrequest&#34;&gt;UAIChatPlus_ClaudeChatRequest&lt;/h3&gt;
&lt;p&gt;Claude 聊天请求。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;头文件：&lt;/strong&gt; &lt;code&gt;Common_Claude/AIChatPlus_ClaudeChatRequest.h&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Options 类型：&lt;/strong&gt; &lt;code&gt;FAIChatPlus_ClaudeChatRequestOptions&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Response 类型：&lt;/strong&gt; &lt;code&gt;FAIChatPlus_ClaudeChatResponseBody&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;uaichatplus_geminichatrequest&#34;&gt;UAIChatPlus_GeminiChatRequest&lt;/h3&gt;
&lt;p&gt;Gemini 聊天请求。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;头文件：&lt;/strong&gt; &lt;code&gt;Common_Gemini/AIChatPlus_GeminiChatRequest.h&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Options 类型：&lt;/strong&gt; &lt;code&gt;FAIChatPlus_GeminiChatRequestOptions&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Response 类型：&lt;/strong&gt; &lt;code&gt;FAIChatPlus_GeminiChatResponseBody&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;uaichatplus_ollamachatrequest&#34;&gt;UAIChatPlus_OllamaChatRequest&lt;/h3&gt;
&lt;p&gt;Ollama 聊天请求。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;头文件：&lt;/strong&gt; &lt;code&gt;Common_Ollama/AIChatPlus_OllamaChatRequest.h&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Options 类型：&lt;/strong&gt; &lt;code&gt;FAIChatPlus_OllamaChatRequestOptions&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Response 类型：&lt;/strong&gt; &lt;code&gt;FAIChatPlus_OllamaChatResponseBody&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;uaichatplus_ollamamodelrequest&#34;&gt;UAIChatPlus_OllamaModelRequest&lt;/h3&gt;
&lt;p&gt;Ollama 模型列表请求。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;头文件：&lt;/strong&gt; &lt;code&gt;Common_Ollama/AIChatPlus_OllamaModelRequest.h&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Options 类型：&lt;/strong&gt; &lt;code&gt;FAIChatPlus_OllamaModelRequestOptions&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Response 类型：&lt;/strong&gt; &lt;code&gt;FAIChatPlus_OllamaModelResponseBody&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;特有方法：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetModelNames()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TArray&amp;lt;FString&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取模型名称列表&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;uaichatplus_cllamachatrequest&#34;&gt;UAIChatPlus_CllamaChatRequest（已废弃）&lt;/h3&gt;
&lt;p&gt;Cllama 离线聊天请求（已废弃，推荐使用 CllamaServer）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;头文件：&lt;/strong&gt; &lt;code&gt;Common_Cllama/AIChatPlus_CllamaChatRequest.h&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Options 类型：&lt;/strong&gt; &lt;code&gt;FAIChatPlus_CllamaChatRequestOptions&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Response 类型：&lt;/strong&gt; &lt;code&gt;FAIChatPlus_CllamaChatResponseBody&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;uaichatplus_cllamaserverchatrequest&#34;&gt;UAIChatPlus_CllamaServerChatRequest&lt;/h3&gt;
&lt;p&gt;CllamaServer 聊天请求。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;头文件：&lt;/strong&gt; &lt;code&gt;Common_CllamaServer/AIChatPlus_CllamaServerChatRequest.h&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Options 类型：&lt;/strong&gt; &lt;code&gt;FAIChatPlus_CllamaServerChatRequestOptions&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Response 类型：&lt;/strong&gt; &lt;code&gt;FAIChatPlus_CllamaServerChatResponseBody&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;uaichatplus_openaiimagerequest&#34;&gt;UAIChatPlus_OpenAIImageRequest&lt;/h3&gt;
&lt;p&gt;OpenAI 图片生成请求。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;头文件：&lt;/strong&gt; &lt;code&gt;Common_OpenAI/AIChatPlus_OpenAIImageRequest.h&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Options 类型：&lt;/strong&gt; &lt;code&gt;FAIChatPlus_OpenAIImageRequestOptions&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Response 类型：&lt;/strong&gt; &lt;code&gt;FAIChatPlus_OpenAIImageResponseBody&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;uaichatplus_azureimagerequest&#34;&gt;UAIChatPlus_AzureImageRequest&lt;/h3&gt;
&lt;p&gt;Azure 图片生成请求。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;头文件：&lt;/strong&gt; &lt;code&gt;Common_Azure/AIChatPlus_AzureImageRequest.h&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Options 类型：&lt;/strong&gt; &lt;code&gt;FAIChatPlus_AzureImageRequestOptions&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Response 类型：&lt;/strong&gt; &lt;code&gt;FAIChatPlus_AzureImageResponseBody&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;uaichatplus_cllamaserver&#34;&gt;UAIChatPlus_CllamaServer&lt;/h3&gt;
&lt;p&gt;CllamaServer 服务器管理类。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;头文件：&lt;/strong&gt; &lt;code&gt;Common_CllamaServer/AIChatPlus_CllamaServer.h&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;静态工厂方法：&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-12-1&#34; name=&#34;__codelineno-12-1&#34; href=&#34;#__codelineno-12-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_CllamaServer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CreateServer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-2&#34; name=&#34;__codelineno-12-2&#34; href=&#34;#__codelineno-12-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_CllamaServerParam&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InParams&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-3&#34; name=&#34;__codelineno-12-3&#34; href=&#34;#__codelineno-12-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FGuid&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InServerID&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FGuid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-4&#34; name=&#34;__codelineno-12-4&#34; href=&#34;#__codelineno-12-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_CllamaServer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CreateServerInWorld&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-5&#34; name=&#34;__codelineno-12-5&#34; href=&#34;#__codelineno-12-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InWorldContext&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-6&#34; name=&#34;__codelineno-12-6&#34; href=&#34;#__codelineno-12-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_CllamaServerParam&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InParams&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-7&#34; name=&#34;__codelineno-12-7&#34; href=&#34;#__codelineno-12-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FGuid&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InServerID&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FGuid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-8&#34; name=&#34;__codelineno-12-8&#34; href=&#34;#__codelineno-12-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_CllamaServer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CreateServerWithHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-9&#34; name=&#34;__codelineno-12-9&#34; href=&#34;#__codelineno-12-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_CllamaServerParam&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InParams&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-10&#34; name=&#34;__codelineno-12-10&#34; href=&#34;#__codelineno-12-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_CllamaServerHandler&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-11&#34; name=&#34;__codelineno-12-11&#34; href=&#34;#__codelineno-12-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FGuid&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InServerID&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FGuid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;实例方法：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Activate()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;启动服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;StopServer()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;停止服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IsRunning()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查是否运行中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetServerID()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FGuid&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取服务器 ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetHost()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取主机地址&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetAddress()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取完整地址&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetServerInfo(FAIChatPlus_CllamaServerInfo&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取服务器信息&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;静态管理方法：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IsServerValid(const FGuid&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查服务器是否有效&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IsServerRunning(const FGuid&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查服务器是否运行中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;StopServerByID(const FGuid&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;按 ID 停止服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;StopAllServers()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;停止所有服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetServerByID(const FGuid&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_CllamaServer*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;按 ID 获取服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetAllServerIDs()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TArray&amp;lt;FGuid&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取所有服务器 ID&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2 id=&#34;_6&#34;&gt;工具类&lt;/h2&gt;
&lt;h3 id=&#34;uaichatplus_util&#34;&gt;UAIChatPlus_Util&lt;/h3&gt;
&lt;p&gt;通用工具类，提供各种静态辅助方法。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;头文件：&lt;/strong&gt; &lt;code&gt;Common/AIChatPlus_Util.h&lt;/code&gt;&lt;/p&gt;
&lt;h4 id=&#34;_7&#34;&gt;日志相关&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SetInternalLogVerbosity(EAIChatPlus_LogVerbosityType)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置内部日志级别&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&#34;wrapper&#34;&gt;Wrapper 转换&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CastWrapperToError(const FAIChatPlus_PointerWrapper&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FAIChatPlus_ResponseErrorBase&amp;amp;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;提取错误信息&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CastWrapperToResponse(const FAIChatPlus_PointerWrapper&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FAIChatPlus_ChatResponseBodyBase&amp;amp;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;提取响应数据&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetErrorWrapperDescription(const FAIChatPlus_PointerWrapper&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取错误描述&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetResponseWrapperMessage(const FAIChatPlus_PointerWrapper&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取响应消息&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&#34;_8&#34;&gt;图片工具&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LoadImage(const FString&amp;amp;, bool)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UTexture2D*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从文件加载图片&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SaveImage(UTexture2D*, const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;保存图片到文件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ImageToB64(UTexture2D*, int32)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;图片转 Base64&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CopyTexture2D(UTexture2D*, UObject*, FName, EObjectFlags)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UTexture2D*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;复制纹理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FitImageSize(const FVector2D&amp;amp;, const FVector2D&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FVector2D&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;计算适配尺寸&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CopyTexture2DToClipboard(UTexture2D*)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;复制到剪贴板&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IsCanCopyTexture2DToClipboard()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查是否支持&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&#34;_9&#34;&gt;音频工具&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LoadSoundWav(const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;USoundWave*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从文件加载音频&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SaveSoundWav(USoundWave*, const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;保存音频到文件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SoundToB64(USoundWave*)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;音频转 Base64&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CopySoundWave(const USoundWave*, UObject*, FName)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;USoundWave*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;复制音频&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;WavDataToSoundWave(const TArray&amp;lt;uint8&amp;gt;&amp;amp;, bool, bool)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;USoundWave*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;WAV 数据转音频&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetSoundWavePCMData(USoundWave*)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TArray&amp;lt;uint8&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取 PCM 数据&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&#34;json&#34;&gt;JSON 工具&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;MergeJsonObjects(const FString&amp;amp;, const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;合并 JSON 字符串&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LoadJsonString(const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TSharedPtr&amp;lt;FJsonObject&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;解析 JSON 字符串&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ToJsonString(const TSharedPtr&amp;lt;FJsonObject&amp;gt;&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;转为 JSON 字符串&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&#34;cllama&#34;&gt;Cllama 工具&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Cllama_IsValid()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查 Cllama 是否可用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Cllama_IsSupportGpu()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查是否支持 GPU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Cllama_GetSupportBackends()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TArray&amp;lt;FString&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取支持的后端&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Cllama_PrepareModelPathFromPak(const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从 Pak 准备模型路径&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&#34;_10&#34;&gt;模型信息&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetOpenAIChatDefaultModels()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;const TArray&amp;lt;FName&amp;gt;&amp;amp;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OpenAI 默认模型列表&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetOpenAIChatModelInfo(const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FAIChatPlus_ChatModelInfo&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取 OpenAI 模型信息&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetClaudeChatDefaultModels()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;const TArray&amp;lt;FName&amp;gt;&amp;amp;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Claude 默认模型列表&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetClaudeChatModelInfo(const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FAIChatPlus_ChatModelInfo&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取 Claude 模型信息&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetGeminiChatDefaultModels()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;const TArray&amp;lt;FName&amp;gt;&amp;amp;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Gemini 默认模型列表&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetGeminiChatModelInfo(const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FAIChatPlus_ChatModelInfo&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取 Gemini 模型信息&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;uaichatplus_texture&#34;&gt;UAIChatPlus_Texture&lt;/h3&gt;
&lt;p&gt;图片包装类，支持异步加载和 Base64 转换。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;头文件：&lt;/strong&gt; &lt;code&gt;Common/AIChatPlus_Texture.h&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;静态工厂方法：&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-13-1&#34; name=&#34;__codelineno-13-1&#34; href=&#34;#__codelineno-13-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Texture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;New&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;nullptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSourcePath&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-13-2&#34; name=&#34;__codelineno-13-2&#34; href=&#34;#__codelineno-13-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Texture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CreateInBlueprint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WorldContextObject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;方法：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LoadFromFile(const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从文件加载（同步）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LoadFromFileAsync(const FString&amp;amp;, Callback)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FLoadingTaskType*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从文件加载（异步）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LoadFromAsset(UObject*, const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从资产加载（同步）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LoadFromAssetAsync(UObject*, Callback, const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FLoadingTaskType*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从资产加载（异步）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ToB64()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;const FString&amp;amp;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;转为 Base64（同步）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ToB64Async(Callback)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FLoadingTaskType*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;转为 Base64（异步）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetBrush(bool)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;const FSlateBrush*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取 Slate 笔刷&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetBrushCopy(bool)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FSlateBrush&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取笔刷副本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetSize()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FIntVector2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取尺寸&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetSize2D()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FVector2D&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取尺寸（浮点）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IsValid()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查是否有效&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IsLoading()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查是否加载中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Reset()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;重置&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;WaitLoadingComplete()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;等待加载完成&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;uaichatplus_sound&#34;&gt;UAIChatPlus_Sound&lt;/h3&gt;
&lt;p&gt;音频包装类，支持异步加载和 Base64 转换。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;头文件：&lt;/strong&gt; &lt;code&gt;Common/AIChatPlus_Sound.h&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;静态工厂方法：&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-14-1&#34; name=&#34;__codelineno-14-1&#34; href=&#34;#__codelineno-14-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Sound&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;New&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;USoundWave&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSound&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;nullptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSourcePath&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-2&#34; name=&#34;__codelineno-14-2&#34; href=&#34;#__codelineno-14-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Sound&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CreateInBlueprint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WorldContextObject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;USoundWave&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSound&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;方法：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LoadFromFile(const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从文件加载（同步）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LoadFromFileAsync(const FString&amp;amp;, Callback)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FLoadingTaskType*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从文件加载（异步）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LoadFromAsset(UObject*, const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从资产加载（同步）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LoadFromAssetAsync(UObject*, Callback, const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FLoadingTaskType*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从资产加载（异步）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ToB64()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;const FString&amp;amp;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;转为 Base64（同步）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ToB64Async(Callback)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FLoadingTaskType*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;转为 Base64（异步）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IsValid()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查是否有效&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IsLoading()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查是否加载中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Reset()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;重置&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;WaitLoadingComplete()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;等待加载完成&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PlayInEditor()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;在编辑器中播放&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2 id=&#34;json_1&#34;&gt;JSON 类&lt;/h2&gt;
&lt;h3 id=&#34;uaichatplus_jsonobject&#34;&gt;UAIChatPlus_JsonObject&lt;/h3&gt;
&lt;p&gt;JSON 对象包装类。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;头文件：&lt;/strong&gt; &lt;code&gt;Common/Json/AIChatPlus_JsonObject.h&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;静态工厂方法：&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-15-1&#34; name=&#34;__codelineno-15-1&#34; href=&#34;#__codelineno-15-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Create&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-15-2&#34; name=&#34;__codelineno-15-2&#34; href=&#34;#__codelineno-15-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Parse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ErrorMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-15-3&#34; name=&#34;__codelineno-15-3&#34; href=&#34;#__codelineno-15-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;FromStruct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Struct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// CustomThunk&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;设置字段方法（支持链式调用）：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SetStringField(const FString&amp;amp;, const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonObject*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置字符串字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SetNumberField(const FString&amp;amp;, float)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonObject*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置数字字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SetIntegerField(const FString&amp;amp;, int32)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonObject*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置整数字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SetBooleanField(const FString&amp;amp;, bool)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonObject*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置布尔字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SetObjectField(const FString&amp;amp;, UAIChatPlus_JsonObject*)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonObject*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置对象字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SetArrayField(const FString&amp;amp;, UAIChatPlus_JsonArray*)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonObject*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置数组字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SetNullField(const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonObject*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置空字段&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;获取字段方法：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetStringField(const FString&amp;amp;, const FString&amp;amp;, bool&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取字符串&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetNumberField(const FString&amp;amp;, float, bool&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;float&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取数字&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetIntegerField(const FString&amp;amp;, int32, bool&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;int32&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取整数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetBooleanField(const FString&amp;amp;, bool, bool&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取布尔&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetObjectField(const FString&amp;amp;, bool&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonObject*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取对象&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetArrayField(const FString&amp;amp;, bool&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonArray*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取数组&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;其他方法：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;HasField(const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查字段存在&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetFieldType(const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;EAIChatPlus_JsonValueType&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取字段类型&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;RemoveField(const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonObject*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;移除字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Clear()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonObject*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;清空所有字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ToString(bool)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;转为字符串&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ToStruct(int32&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;转为结构体&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Merge(UAIChatPlus_JsonObject*, bool)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonObject*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;合并对象&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Duplicate()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonObject*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;复制对象&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IsValid()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查有效性&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;路径查询方法：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SetStringByPath(const FString&amp;amp;, const FString&amp;amp;, const FAIChatPlus_JsonPathOptions&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonObject*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;按路径设置字符串&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetStringByPath(const FString&amp;amp;, const FString&amp;amp;, FAIChatPlus_JsonQueryResult&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;按路径获取字符串&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;uaichatplus_jsonarray&#34;&gt;UAIChatPlus_JsonArray&lt;/h3&gt;
&lt;p&gt;JSON 数组包装类。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;头文件：&lt;/strong&gt; &lt;code&gt;Common/Json/AIChatPlus_JsonArray.h&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;静态工厂方法：&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-16-1&#34; name=&#34;__codelineno-16-1&#34; href=&#34;#__codelineno-16-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Create&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-2&#34; name=&#34;__codelineno-16-2&#34; href=&#34;#__codelineno-16-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Parse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ErrorMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-3&#34; name=&#34;__codelineno-16-3&#34; href=&#34;#__codelineno-16-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;FromStringArray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Values&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-4&#34; name=&#34;__codelineno-16-4&#34; href=&#34;#__codelineno-16-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;FromIntegerArray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Values&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;添加元素方法（支持链式调用）：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AddString(const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonArray*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;添加字符串&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AddNumber(float)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonArray*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;添加数字&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AddInteger(int32)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonArray*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;添加整数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AddBoolean(bool)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonArray*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;添加布尔&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AddObject(UAIChatPlus_JsonObject*)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonArray*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;添加对象&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AddArray(UAIChatPlus_JsonArray*)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonArray*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;添加数组&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AddNull()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonArray*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;添加空值&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;获取元素方法：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetString(int32, const FString&amp;amp;, bool&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取字符串&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetNumber(int32, float, bool&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;float&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取数字&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetInteger(int32, int32, bool&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;int32&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取整数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetBoolean(int32, bool, bool&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取布尔&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetObject(int32, bool&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonObject*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取对象&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetArray(int32, bool&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonArray*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取数组&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;其他方法：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Length()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;int32&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取长度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetElementType(int32)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;EAIChatPlus_JsonValueType&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取元素类型&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SetString(int32, const FString&amp;amp;, bool&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonArray*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置字符串&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SetObject(int32, UAIChatPlus_JsonObject*, bool&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonArray*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设置对象&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;RemoveAt(int32, bool&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonArray*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;移除元素&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Clear()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonArray*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;清空数组&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ToString(bool)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;转为字符串&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Duplicate()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonArray*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;复制数组&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IsValid()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查有效性&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;uaichatplus_jsonlibrary&#34;&gt;UAIChatPlus_JsonLibrary&lt;/h3&gt;
&lt;p&gt;JSON 静态工具库。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;头文件：&lt;/strong&gt; &lt;code&gt;Common/Json/AIChatPlus_JsonLibrary.h&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;创建方法：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;MakeJsonObjectWithStringField(const FString&amp;amp;, const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonObject*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;创建单字段对象&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;MakeJsonObjectFromStringMap(const TMap&amp;lt;FString, FString&amp;gt;&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonObject*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从 Map 创建对象&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;验证方法：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ValidateJsonString(const FString&amp;amp;, FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;验证 JSON 字符串&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IsJsonObject(const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查是否为对象&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IsJsonArray(const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查是否为数组&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;格式化方法：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PrettifyJson(const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;美化 JSON&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;MinifyJson(const FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;压缩 JSON&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;结构体转换（CustomThunk）：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;JsonStringToStruct(const FString&amp;amp;, int32&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;JSON 转结构体&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;StructToJsonString(const int32&amp;amp;, bool)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;结构体转 JSON&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;文件操作：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LoadJsonObjectFromFile(const FString&amp;amp;, bool&amp;amp;, FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonObject*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从文件加载对象&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SaveJsonObjectToFile(UAIChatPlus_JsonObject*, const FString&amp;amp;, bool, FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;保存对象到文件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LoadJsonArrayFromFile(const FString&amp;amp;, bool&amp;amp;, FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonArray*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从文件加载数组&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SaveJsonArrayToFile(UAIChatPlus_JsonArray*, const FString&amp;amp;, bool, FString&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;保存数组到文件&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;比较方法：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;EqualsJsonObject(UAIChatPlus_JsonObject*, UAIChatPlus_JsonObject*)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;比较对象&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;EqualsJsonArray(UAIChatPlus_JsonArray*, UAIChatPlus_JsonArray*)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;比较数组&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;路径查询：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;返回类型&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;QueryStringByPath(UAIChatPlus_JsonObject*, const FString&amp;amp;, const FString&amp;amp;, FAIChatPlus_JsonQueryResult&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FString&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;按路径查询字符串&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;QueryObjectByPath(UAIChatPlus_JsonObject*, const FString&amp;amp;, FAIChatPlus_JsonQueryResult&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonObject*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;按路径查询对象&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;QueryArrayByPath(UAIChatPlus_JsonObject*, const FString&amp;amp;, FAIChatPlus_JsonQueryResult&amp;amp;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UAIChatPlus_JsonArray*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;按路径查询数组&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-Reference/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 12 Feb 2026 08:03:39 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-Reference/</guid>
      
    </item>
    
    <item>
      <title>Utils</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 插件 AIChatPlus 使用说明 - C++ 篇 - Utils&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;c-utils&#34;&gt;C++ 篇 - Utils&lt;/h1&gt;
&lt;p&gt;本文档介绍 AIChatPlus 提供的工具类，包括 JSON 操作、图片处理和音频处理等功能。&lt;/p&gt;
&lt;h2 id=&#34;_1&#34;&gt;准备工作&lt;/h2&gt;
&lt;p&gt;在项目的 &lt;code&gt;.Build.cs&lt;/code&gt; 文件中添加模块依赖：&lt;/p&gt;
&lt;div class=&#34;language-csharp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PublicDependencyModuleNames&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddRange&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34; href=&#34;#__codelineno-0-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;AIChatPlusCommon&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-4&#34; name=&#34;__codelineno-0-4&#34; href=&#34;#__codelineno-0-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;包含必要的头文件：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;quot;Common/AIChatPlus_Util.h&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-2&#34; name=&#34;__codelineno-1-2&#34; href=&#34;#__codelineno-1-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;quot;Common/Json/AIChatPlus_JsonObject.h&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-3&#34; name=&#34;__codelineno-1-3&#34; href=&#34;#__codelineno-1-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;quot;Common/Json/AIChatPlus_JsonArray.h&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;json&#34;&gt;JSON 操作&lt;/h2&gt;
&lt;p&gt;AIChatPlus 提供了 Blueprint 友好的 JSON 操作类，支持链式调用和类型安全操作。&lt;/p&gt;
&lt;h3 id=&#34;uaichatplus_jsonobject-json&#34;&gt;UAIChatPlus_JsonObject - JSON 对象&lt;/h3&gt;
&lt;h4 id=&#34;_2&#34;&gt;创建和解析&lt;/h4&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-2-1&#34; name=&#34;__codelineno-2-1&#34; href=&#34;#__codelineno-2-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;quot;Common/Json/AIChatPlus_JsonObject.h&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-2&#34; name=&#34;__codelineno-2-2&#34; href=&#34;#__codelineno-2-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-3&#34; name=&#34;__codelineno-2-3&#34; href=&#34;#__codelineno-2-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::JsonObjectBasics&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-4&#34; name=&#34;__codelineno-2-4&#34; href=&#34;#__codelineno-2-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-5&#34; name=&#34;__codelineno-2-5&#34; href=&#34;#__codelineno-2-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 创建空 JSON 对象&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-6&#34; name=&#34;__codelineno-2-6&#34; href=&#34;#__codelineno-2-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Create&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-7&#34; name=&#34;__codelineno-2-7&#34; href=&#34;#__codelineno-2-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-8&#34; name=&#34;__codelineno-2-8&#34; href=&#34;#__codelineno-2-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 从字符串解析&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-9&#34; name=&#34;__codelineno-2-9&#34; href=&#34;#__codelineno-2-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;R&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;dl&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{&amp;quot;name&amp;quot;: &amp;quot;John&amp;quot;, &amp;quot;age&amp;quot;: 30, &amp;quot;active&amp;quot;: true}&lt;/span&gt;&lt;span class=&#34;dl&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-10&#34; name=&#34;__codelineno-2-10&#34; href=&#34;#__codelineno-2-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-11&#34; name=&#34;__codelineno-2-11&#34; href=&#34;#__codelineno-2-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ErrorMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-12&#34; name=&#34;__codelineno-2-12&#34; href=&#34;#__codelineno-2-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ParsedObj&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Parse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ErrorMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-13&#34; name=&#34;__codelineno-2-13&#34; href=&#34;#__codelineno-2-13&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-14&#34; name=&#34;__codelineno-2-14&#34; href=&#34;#__codelineno-2-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-15&#34; name=&#34;__codelineno-2-15&#34; href=&#34;#__codelineno-2-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-16&#34; name=&#34;__codelineno-2-16&#34; href=&#34;#__codelineno-2-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Parsed successfully&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-17&#34; name=&#34;__codelineno-2-17&#34; href=&#34;#__codelineno-2-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-18&#34; name=&#34;__codelineno-2-18&#34; href=&#34;#__codelineno-2-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-19&#34; name=&#34;__codelineno-2-19&#34; href=&#34;#__codelineno-2-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-20&#34; name=&#34;__codelineno-2-20&#34; href=&#34;#__codelineno-2-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Parse error: %s&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ErrorMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-21&#34; name=&#34;__codelineno-2-21&#34; href=&#34;#__codelineno-2-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-22&#34; name=&#34;__codelineno-2-22&#34; href=&#34;#__codelineno-2-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&#34;_3&#34;&gt;设置字段（链式调用）&lt;/h4&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-3-1&#34; name=&#34;__codelineno-3-1&#34; href=&#34;#__codelineno-3-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::SetJsonFields&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-2&#34; name=&#34;__codelineno-3-2&#34; href=&#34;#__codelineno-3-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-3&#34; name=&#34;__codelineno-3-3&#34; href=&#34;#__codelineno-3-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Create&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-4&#34; name=&#34;__codelineno-3-4&#34; href=&#34;#__codelineno-3-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-5&#34; name=&#34;__codelineno-3-5&#34; href=&#34;#__codelineno-3-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 链式设置字段&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-6&#34; name=&#34;__codelineno-3-6&#34; href=&#34;#__codelineno-3-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetStringField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;John&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-7&#34; name=&#34;__codelineno-3-7&#34; href=&#34;#__codelineno-3-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetIntegerField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;age&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;30&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-8&#34; name=&#34;__codelineno-3-8&#34; href=&#34;#__codelineno-3-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetBooleanField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;active&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-9&#34; name=&#34;__codelineno-3-9&#34; href=&#34;#__codelineno-3-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetNumberField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;score&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;95.5f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-10&#34; name=&#34;__codelineno-3-10&#34; href=&#34;#__codelineno-3-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetNullField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;extra&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-11&#34; name=&#34;__codelineno-3-11&#34; href=&#34;#__codelineno-3-11&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-12&#34; name=&#34;__codelineno-3-12&#34; href=&#34;#__codelineno-3-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 设置嵌套对象&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-13&#34; name=&#34;__codelineno-3-13&#34; href=&#34;#__codelineno-3-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddressObj&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Create&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-14&#34; name=&#34;__codelineno-3-14&#34; href=&#34;#__codelineno-3-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddressObj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetStringField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;city&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Tokyo&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-15&#34; name=&#34;__codelineno-3-15&#34; href=&#34;#__codelineno-3-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetStringField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;country&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Japan&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-16&#34; name=&#34;__codelineno-3-16&#34; href=&#34;#__codelineno-3-16&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-17&#34; name=&#34;__codelineno-3-17&#34; href=&#34;#__codelineno-3-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetObjectField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;address&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddressObj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-18&#34; name=&#34;__codelineno-3-18&#34; href=&#34;#__codelineno-3-18&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-19&#34; name=&#34;__codelineno-3-19&#34; href=&#34;#__codelineno-3-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 输出&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-20&#34; name=&#34;__codelineno-3-20&#34; href=&#34;#__codelineno-3-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Result&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ToString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// true = 格式化输出&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-21&#34; name=&#34;__codelineno-3-21&#34; href=&#34;#__codelineno-3-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;%s&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-22&#34; name=&#34;__codelineno-3-22&#34; href=&#34;#__codelineno-3-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&#34;_4&#34;&gt;获取字段&lt;/h4&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-4-1&#34; name=&#34;__codelineno-4-1&#34; href=&#34;#__codelineno-4-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::GetJsonFields&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-2&#34; name=&#34;__codelineno-4-2&#34; href=&#34;#__codelineno-4-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-3&#34; name=&#34;__codelineno-4-3&#34; href=&#34;#__codelineno-4-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;R&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;dl&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{&amp;quot;name&amp;quot;: &amp;quot;John&amp;quot;, &amp;quot;age&amp;quot;: 30, &amp;quot;scores&amp;quot;: [85, 90, 95]}&lt;/span&gt;&lt;span class=&#34;dl&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-4&#34; name=&#34;__codelineno-4-4&#34; href=&#34;#__codelineno-4-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bParseSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-5&#34; name=&#34;__codelineno-4-5&#34; href=&#34;#__codelineno-4-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ErrorMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-6&#34; name=&#34;__codelineno-4-6&#34; href=&#34;#__codelineno-4-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Parse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bParseSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ErrorMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-7&#34; name=&#34;__codelineno-4-7&#34; href=&#34;#__codelineno-4-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-8&#34; name=&#34;__codelineno-4-8&#34; href=&#34;#__codelineno-4-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bParseSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-9&#34; name=&#34;__codelineno-4-9&#34; href=&#34;#__codelineno-4-9&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-10&#34; name=&#34;__codelineno-4-10&#34; href=&#34;#__codelineno-4-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-11&#34; name=&#34;__codelineno-4-11&#34; href=&#34;#__codelineno-4-11&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-12&#34; name=&#34;__codelineno-4-12&#34; href=&#34;#__codelineno-4-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 获取字符串字段&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-13&#34; name=&#34;__codelineno-4-13&#34; href=&#34;#__codelineno-4-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Name&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetStringField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Unknown&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-14&#34; name=&#34;__codelineno-4-14&#34; href=&#34;#__codelineno-4-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-15&#34; name=&#34;__codelineno-4-15&#34; href=&#34;#__codelineno-4-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-16&#34; name=&#34;__codelineno-4-16&#34; href=&#34;#__codelineno-4-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Name: %s&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-17&#34; name=&#34;__codelineno-4-17&#34; href=&#34;#__codelineno-4-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-18&#34; name=&#34;__codelineno-4-18&#34; href=&#34;#__codelineno-4-18&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-19&#34; name=&#34;__codelineno-4-19&#34; href=&#34;#__codelineno-4-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 获取整数字段&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-20&#34; name=&#34;__codelineno-4-20&#34; href=&#34;#__codelineno-4-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Age&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetIntegerField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;age&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-21&#34; name=&#34;__codelineno-4-21&#34; href=&#34;#__codelineno-4-21&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-22&#34; name=&#34;__codelineno-4-22&#34; href=&#34;#__codelineno-4-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 获取布尔字段&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-23&#34; name=&#34;__codelineno-4-23&#34; href=&#34;#__codelineno-4-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bActive&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetBooleanField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;active&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-24&#34; name=&#34;__codelineno-4-24&#34; href=&#34;#__codelineno-4-24&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-25&#34; name=&#34;__codelineno-4-25&#34; href=&#34;#__codelineno-4-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 获取数组字段&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-26&#34; name=&#34;__codelineno-4-26&#34; href=&#34;#__codelineno-4-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Scores&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetArrayField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;scores&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-27&#34; name=&#34;__codelineno-4-27&#34; href=&#34;#__codelineno-4-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Scores&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-28&#34; name=&#34;__codelineno-4-28&#34; href=&#34;#__codelineno-4-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-29&#34; name=&#34;__codelineno-4-29&#34; href=&#34;#__codelineno-4-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Scores&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Length&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-30&#34; name=&#34;__codelineno-4-30&#34; href=&#34;#__codelineno-4-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-31&#34; name=&#34;__codelineno-4-31&#34; href=&#34;#__codelineno-4-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Score&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Scores&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetInteger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-32&#34; name=&#34;__codelineno-4-32&#34; href=&#34;#__codelineno-4-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Score[%d]: %d&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Score&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-33&#34; name=&#34;__codelineno-4-33&#34; href=&#34;#__codelineno-4-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-34&#34; name=&#34;__codelineno-4-34&#34; href=&#34;#__codelineno-4-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-35&#34; name=&#34;__codelineno-4-35&#34; href=&#34;#__codelineno-4-35&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-36&#34; name=&#34;__codelineno-4-36&#34; href=&#34;#__codelineno-4-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 获取嵌套对象字段&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-37&#34; name=&#34;__codelineno-4-37&#34; href=&#34;#__codelineno-4-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddressObj&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetObjectField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;address&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-38&#34; name=&#34;__codelineno-4-38&#34; href=&#34;#__codelineno-4-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddressObj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-39&#34; name=&#34;__codelineno-4-39&#34; href=&#34;#__codelineno-4-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-40&#34; name=&#34;__codelineno-4-40&#34; href=&#34;#__codelineno-4-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;City&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddressObj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetStringField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;city&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-41&#34; name=&#34;__codelineno-4-41&#34; href=&#34;#__codelineno-4-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-42&#34; name=&#34;__codelineno-4-42&#34; href=&#34;#__codelineno-4-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&#34;_5&#34;&gt;字段检查和管理&lt;/h4&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-5-1&#34; name=&#34;__codelineno-5-1&#34; href=&#34;#__codelineno-5-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::ManageJsonFields&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-2&#34; name=&#34;__codelineno-5-2&#34; href=&#34;#__codelineno-5-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-3&#34; name=&#34;__codelineno-5-3&#34; href=&#34;#__codelineno-5-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Create&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-4&#34; name=&#34;__codelineno-5-4&#34; href=&#34;#__codelineno-5-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetStringField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;John&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-5&#34; name=&#34;__codelineno-5-5&#34; href=&#34;#__codelineno-5-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetIntegerField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;age&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;30&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-6&#34; name=&#34;__codelineno-5-6&#34; href=&#34;#__codelineno-5-6&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-7&#34; name=&#34;__codelineno-5-7&#34; href=&#34;#__codelineno-5-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 检查字段是否存在&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-8&#34; name=&#34;__codelineno-5-8&#34; href=&#34;#__codelineno-5-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;HasField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-9&#34; name=&#34;__codelineno-5-9&#34; href=&#34;#__codelineno-5-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-10&#34; name=&#34;__codelineno-5-10&#34; href=&#34;#__codelineno-5-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Field &amp;#39;name&amp;#39; exists&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-11&#34; name=&#34;__codelineno-5-11&#34; href=&#34;#__codelineno-5-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-12&#34; name=&#34;__codelineno-5-12&#34; href=&#34;#__codelineno-5-12&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-13&#34; name=&#34;__codelineno-5-13&#34; href=&#34;#__codelineno-5-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 获取字段类型&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-14&#34; name=&#34;__codelineno-5-14&#34; href=&#34;#__codelineno-5-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EAIChatPlus_JsonValueType&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FieldType&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetFieldType&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;age&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-15&#34; name=&#34;__codelineno-5-15&#34; href=&#34;#__codelineno-5-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// FieldType == EAIChatPlus_JsonValueType::Number&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-16&#34; name=&#34;__codelineno-5-16&#34; href=&#34;#__codelineno-5-16&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-17&#34; name=&#34;__codelineno-5-17&#34; href=&#34;#__codelineno-5-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 获取所有字段名&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-18&#34; name=&#34;__codelineno-5-18&#34; href=&#34;#__codelineno-5-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FieldNames&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetFieldNames&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-19&#34; name=&#34;__codelineno-5-19&#34; href=&#34;#__codelineno-5-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Name&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FieldNames&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-20&#34; name=&#34;__codelineno-5-20&#34; href=&#34;#__codelineno-5-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-21&#34; name=&#34;__codelineno-5-21&#34; href=&#34;#__codelineno-5-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Field: %s&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-22&#34; name=&#34;__codelineno-5-22&#34; href=&#34;#__codelineno-5-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-23&#34; name=&#34;__codelineno-5-23&#34; href=&#34;#__codelineno-5-23&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-24&#34; name=&#34;__codelineno-5-24&#34; href=&#34;#__codelineno-5-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 删除字段&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-25&#34; name=&#34;__codelineno-5-25&#34; href=&#34;#__codelineno-5-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RemoveField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;age&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-26&#34; name=&#34;__codelineno-5-26&#34; href=&#34;#__codelineno-5-26&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-27&#34; name=&#34;__codelineno-5-27&#34; href=&#34;#__codelineno-5-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 清空所有字段&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-28&#34; name=&#34;__codelineno-5-28&#34; href=&#34;#__codelineno-5-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Clear&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-29&#34; name=&#34;__codelineno-5-29&#34; href=&#34;#__codelineno-5-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&#34;_6&#34;&gt;路径查询（嵌套访问）&lt;/h4&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-6-1&#34; name=&#34;__codelineno-6-1&#34; href=&#34;#__codelineno-6-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::PathQuery&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-2&#34; name=&#34;__codelineno-6-2&#34; href=&#34;#__codelineno-6-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-3&#34; name=&#34;__codelineno-6-3&#34; href=&#34;#__codelineno-6-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;R&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;dl&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-4&#34; name=&#34;__codelineno-6-4&#34; href=&#34;#__codelineno-6-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;s&#34;&gt;        &amp;quot;player&amp;quot;: {&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-5&#34; name=&#34;__codelineno-6-5&#34; href=&#34;#__codelineno-6-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;s&#34;&gt;            &amp;quot;inventory&amp;quot;: {&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-6&#34; name=&#34;__codelineno-6-6&#34; href=&#34;#__codelineno-6-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;s&#34;&gt;                &amp;quot;gold&amp;quot;: 1000,&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-7&#34; name=&#34;__codelineno-6-7&#34; href=&#34;#__codelineno-6-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;s&#34;&gt;                &amp;quot;items&amp;quot;: [&amp;quot;sword&amp;quot;, &amp;quot;shield&amp;quot;]&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-8&#34; name=&#34;__codelineno-6-8&#34; href=&#34;#__codelineno-6-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;s&#34;&gt;            }&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-9&#34; name=&#34;__codelineno-6-9&#34; href=&#34;#__codelineno-6-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;s&#34;&gt;        }&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-10&#34; name=&#34;__codelineno-6-10&#34; href=&#34;#__codelineno-6-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;s&#34;&gt;    }&lt;/span&gt;&lt;span class=&#34;dl&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-11&#34; name=&#34;__codelineno-6-11&#34; href=&#34;#__codelineno-6-11&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-12&#34; name=&#34;__codelineno-6-12&#34; href=&#34;#__codelineno-6-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bParseSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-13&#34; name=&#34;__codelineno-6-13&#34; href=&#34;#__codelineno-6-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ErrorMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-14&#34; name=&#34;__codelineno-6-14&#34; href=&#34;#__codelineno-6-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Parse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bParseSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ErrorMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-15&#34; name=&#34;__codelineno-6-15&#34; href=&#34;#__codelineno-6-15&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-16&#34; name=&#34;__codelineno-6-16&#34; href=&#34;#__codelineno-6-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 通过路径获取值&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-17&#34; name=&#34;__codelineno-6-17&#34; href=&#34;#__codelineno-6-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_JsonQueryResult&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-18&#34; name=&#34;__codelineno-6-18&#34; href=&#34;#__codelineno-6-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Gold&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetStringByPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;player.inventory.gold&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-19&#34; name=&#34;__codelineno-6-19&#34; href=&#34;#__codelineno-6-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Gold = &amp;quot;1000&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-20&#34; name=&#34;__codelineno-6-20&#34; href=&#34;#__codelineno-6-20&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-21&#34; name=&#34;__codelineno-6-21&#34; href=&#34;#__codelineno-6-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 通过路径设置值&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-22&#34; name=&#34;__codelineno-6-22&#34; href=&#34;#__codelineno-6-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_JsonPathOptions&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PathOptions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-23&#34; name=&#34;__codelineno-6-23&#34; href=&#34;#__codelineno-6-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetStringByPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;player.inventory.gold&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;2000&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PathOptions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-24&#34; name=&#34;__codelineno-6-24&#34; href=&#34;#__codelineno-6-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&#34;_7&#34;&gt;合并和复制&lt;/h4&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-7-1&#34; name=&#34;__codelineno-7-1&#34; href=&#34;#__codelineno-7-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::MergeAndDuplicate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-2&#34; name=&#34;__codelineno-7-2&#34; href=&#34;#__codelineno-7-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-3&#34; name=&#34;__codelineno-7-3&#34; href=&#34;#__codelineno-7-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Obj1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Create&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-4&#34; name=&#34;__codelineno-7-4&#34; href=&#34;#__codelineno-7-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Obj1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetStringField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;John&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-5&#34; name=&#34;__codelineno-7-5&#34; href=&#34;#__codelineno-7-5&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-6&#34; name=&#34;__codelineno-7-6&#34; href=&#34;#__codelineno-7-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Obj2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Create&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-7&#34; name=&#34;__codelineno-7-7&#34; href=&#34;#__codelineno-7-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Obj2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetIntegerField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;age&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;30&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-8&#34; name=&#34;__codelineno-7-8&#34; href=&#34;#__codelineno-7-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetStringField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Jane&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 覆盖 name&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-9&#34; name=&#34;__codelineno-7-9&#34; href=&#34;#__codelineno-7-9&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-10&#34; name=&#34;__codelineno-7-10&#34; href=&#34;#__codelineno-7-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 合并（bOverwrite = true 时覆盖已存在的字段）&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-11&#34; name=&#34;__codelineno-7-11&#34; href=&#34;#__codelineno-7-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Obj1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Merge&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Obj2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-12&#34; name=&#34;__codelineno-7-12&#34; href=&#34;#__codelineno-7-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Obj1 现在包含 {&amp;quot;name&amp;quot;: &amp;quot;Jane&amp;quot;, &amp;quot;age&amp;quot;: 30}&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-13&#34; name=&#34;__codelineno-7-13&#34; href=&#34;#__codelineno-7-13&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-14&#34; name=&#34;__codelineno-7-14&#34; href=&#34;#__codelineno-7-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 深拷贝&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-15&#34; name=&#34;__codelineno-7-15&#34; href=&#34;#__codelineno-7-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Copy&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Obj1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Duplicate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-16&#34; name=&#34;__codelineno-7-16&#34; href=&#34;#__codelineno-7-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&#34;ustruct&#34;&gt;与 UStruct 互转&lt;/h4&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-8-1&#34; name=&#34;__codelineno-8-1&#34; href=&#34;#__codelineno-8-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;USTRUCT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BlueprintType&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-2&#34; name=&#34;__codelineno-8-2&#34; href=&#34;#__codelineno-8-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;FMyData&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-3&#34; name=&#34;__codelineno-8-3&#34; href=&#34;#__codelineno-8-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-4&#34; name=&#34;__codelineno-8-4&#34; href=&#34;#__codelineno-8-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GENERATED_BODY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-5&#34; name=&#34;__codelineno-8-5&#34; href=&#34;#__codelineno-8-5&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-6&#34; name=&#34;__codelineno-8-6&#34; href=&#34;#__codelineno-8-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UPROPERTY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-7&#34; name=&#34;__codelineno-8-7&#34; href=&#34;#__codelineno-8-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-8&#34; name=&#34;__codelineno-8-8&#34; href=&#34;#__codelineno-8-8&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-9&#34; name=&#34;__codelineno-8-9&#34; href=&#34;#__codelineno-8-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UPROPERTY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-10&#34; name=&#34;__codelineno-8-10&#34; href=&#34;#__codelineno-8-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-11&#34; name=&#34;__codelineno-8-11&#34; href=&#34;#__codelineno-8-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-12&#34; name=&#34;__codelineno-8-12&#34; href=&#34;#__codelineno-8-12&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-13&#34; name=&#34;__codelineno-8-13&#34; href=&#34;#__codelineno-8-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::StructConversion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-14&#34; name=&#34;__codelineno-8-14&#34; href=&#34;#__codelineno-8-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-15&#34; name=&#34;__codelineno-8-15&#34; href=&#34;#__codelineno-8-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// UStruct 转 JsonObject&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-16&#34; name=&#34;__codelineno-8-16&#34; href=&#34;#__codelineno-8-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMyData&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-17&#34; name=&#34;__codelineno-8-17&#34; href=&#34;#__codelineno-8-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Name&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;John&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-18&#34; name=&#34;__codelineno-8-18&#34; href=&#34;#__codelineno-8-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Age&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;30&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-19&#34; name=&#34;__codelineno-8-19&#34; href=&#34;#__codelineno-8-19&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-20&#34; name=&#34;__codelineno-8-20&#34; href=&#34;#__codelineno-8-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromStruct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-21&#34; name=&#34;__codelineno-8-21&#34; href=&#34;#__codelineno-8-21&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-22&#34; name=&#34;__codelineno-8-22&#34; href=&#34;#__codelineno-8-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// JsonObject 转 UStruct&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-23&#34; name=&#34;__codelineno-8-23&#34; href=&#34;#__codelineno-8-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMyData&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OutData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-24&#34; name=&#34;__codelineno-8-24&#34; href=&#34;#__codelineno-8-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ToStruct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OutData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-25&#34; name=&#34;__codelineno-8-25&#34; href=&#34;#__codelineno-8-25&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-26&#34; name=&#34;__codelineno-8-26&#34; href=&#34;#__codelineno-8-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-27&#34; name=&#34;__codelineno-8-27&#34; href=&#34;#__codelineno-8-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-28&#34; name=&#34;__codelineno-8-28&#34; href=&#34;#__codelineno-8-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Name: %s, Age: %d&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OutData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OutData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-29&#34; name=&#34;__codelineno-8-29&#34; href=&#34;#__codelineno-8-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-30&#34; name=&#34;__codelineno-8-30&#34; href=&#34;#__codelineno-8-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;uaichatplus_jsonarray-json&#34;&gt;UAIChatPlus_JsonArray - JSON 数组&lt;/h3&gt;
&lt;h4 id=&#34;_8&#34;&gt;创建和操作&lt;/h4&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-9-1&#34; name=&#34;__codelineno-9-1&#34; href=&#34;#__codelineno-9-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;quot;Common/Json/AIChatPlus_JsonArray.h&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-2&#34; name=&#34;__codelineno-9-2&#34; href=&#34;#__codelineno-9-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-3&#34; name=&#34;__codelineno-9-3&#34; href=&#34;#__codelineno-9-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::JsonArrayBasics&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-4&#34; name=&#34;__codelineno-9-4&#34; href=&#34;#__codelineno-9-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-5&#34; name=&#34;__codelineno-9-5&#34; href=&#34;#__codelineno-9-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 创建空数组&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-6&#34; name=&#34;__codelineno-9-6&#34; href=&#34;#__codelineno-9-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonArray&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Create&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-7&#34; name=&#34;__codelineno-9-7&#34; href=&#34;#__codelineno-9-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-8&#34; name=&#34;__codelineno-9-8&#34; href=&#34;#__codelineno-9-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 添加元素（链式调用）&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-9&#34; name=&#34;__codelineno-9-9&#34; href=&#34;#__codelineno-9-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;apple&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-10&#34; name=&#34;__codelineno-9-10&#34; href=&#34;#__codelineno-9-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;banana&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-11&#34; name=&#34;__codelineno-9-11&#34; href=&#34;#__codelineno-9-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddInteger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;42&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-12&#34; name=&#34;__codelineno-9-12&#34; href=&#34;#__codelineno-9-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddBoolean&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-13&#34; name=&#34;__codelineno-9-13&#34; href=&#34;#__codelineno-9-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddNull&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-14&#34; name=&#34;__codelineno-9-14&#34; href=&#34;#__codelineno-9-14&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-15&#34; name=&#34;__codelineno-9-15&#34; href=&#34;#__codelineno-9-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 添加对象元素&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-16&#34; name=&#34;__codelineno-9-16&#34; href=&#34;#__codelineno-9-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ItemObj&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Create&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-17&#34; name=&#34;__codelineno-9-17&#34; href=&#34;#__codelineno-9-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ItemObj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetStringField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;sword&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-18&#34; name=&#34;__codelineno-9-18&#34; href=&#34;#__codelineno-9-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddObject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ItemObj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-19&#34; name=&#34;__codelineno-9-19&#34; href=&#34;#__codelineno-9-19&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-20&#34; name=&#34;__codelineno-9-20&#34; href=&#34;#__codelineno-9-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 添加嵌套数组&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-21&#34; name=&#34;__codelineno-9-21&#34; href=&#34;#__codelineno-9-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NestedArray&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Create&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-22&#34; name=&#34;__codelineno-9-22&#34; href=&#34;#__codelineno-9-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NestedArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddInteger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddInteger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddInteger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-23&#34; name=&#34;__codelineno-9-23&#34; href=&#34;#__codelineno-9-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddArray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NestedArray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-24&#34; name=&#34;__codelineno-9-24&#34; href=&#34;#__codelineno-9-24&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-25&#34; name=&#34;__codelineno-9-25&#34; href=&#34;#__codelineno-9-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 输出&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-26&#34; name=&#34;__codelineno-9-26&#34; href=&#34;#__codelineno-9-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Result&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ToString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-27&#34; name=&#34;__codelineno-9-27&#34; href=&#34;#__codelineno-9-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;%s&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-28&#34; name=&#34;__codelineno-9-28&#34; href=&#34;#__codelineno-9-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&#34;_9&#34;&gt;获取元素&lt;/h4&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-10-1&#34; name=&#34;__codelineno-10-1&#34; href=&#34;#__codelineno-10-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::GetArrayElements&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-2&#34; name=&#34;__codelineno-10-2&#34; href=&#34;#__codelineno-10-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-3&#34; name=&#34;__codelineno-10-3&#34; href=&#34;#__codelineno-10-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;R&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;dl&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;[&amp;quot;apple&amp;quot;, &amp;quot;banana&amp;quot;, 42, true, {&amp;quot;name&amp;quot;: &amp;quot;item&amp;quot;}]&lt;/span&gt;&lt;span class=&#34;dl&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-4&#34; name=&#34;__codelineno-10-4&#34; href=&#34;#__codelineno-10-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bParseSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-5&#34; name=&#34;__codelineno-10-5&#34; href=&#34;#__codelineno-10-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ErrorMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-6&#34; name=&#34;__codelineno-10-6&#34; href=&#34;#__codelineno-10-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonArray&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Parse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bParseSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ErrorMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-7&#34; name=&#34;__codelineno-10-7&#34; href=&#34;#__codelineno-10-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-10-8&#34; name=&#34;__codelineno-10-8&#34; href=&#34;#__codelineno-10-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bParseSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-9&#34; name=&#34;__codelineno-10-9&#34; href=&#34;#__codelineno-10-9&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-10-10&#34; name=&#34;__codelineno-10-10&#34; href=&#34;#__codelineno-10-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-11&#34; name=&#34;__codelineno-10-11&#34; href=&#34;#__codelineno-10-11&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-10-12&#34; name=&#34;__codelineno-10-12&#34; href=&#34;#__codelineno-10-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 获取字符串元素&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-13&#34; name=&#34;__codelineno-10-13&#34; href=&#34;#__codelineno-10-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Fruit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// &amp;quot;apple&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-14&#34; name=&#34;__codelineno-10-14&#34; href=&#34;#__codelineno-10-14&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-10-15&#34; name=&#34;__codelineno-10-15&#34; href=&#34;#__codelineno-10-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 获取整数元素&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-16&#34; name=&#34;__codelineno-10-16&#34; href=&#34;#__codelineno-10-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Number&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetInteger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 42&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-17&#34; name=&#34;__codelineno-10-17&#34; href=&#34;#__codelineno-10-17&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-10-18&#34; name=&#34;__codelineno-10-18&#34; href=&#34;#__codelineno-10-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 获取布尔元素&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-19&#34; name=&#34;__codelineno-10-19&#34; href=&#34;#__codelineno-10-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bValue&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetBoolean&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// true&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-20&#34; name=&#34;__codelineno-10-20&#34; href=&#34;#__codelineno-10-20&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-10-21&#34; name=&#34;__codelineno-10-21&#34; href=&#34;#__codelineno-10-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 获取对象元素&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-22&#34; name=&#34;__codelineno-10-22&#34; href=&#34;#__codelineno-10-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Obj&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetObject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-23&#34; name=&#34;__codelineno-10-23&#34; href=&#34;#__codelineno-10-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-24&#34; name=&#34;__codelineno-10-24&#34; href=&#34;#__codelineno-10-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-25&#34; name=&#34;__codelineno-10-25&#34; href=&#34;#__codelineno-10-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Name&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Obj&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetStringField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-26&#34; name=&#34;__codelineno-10-26&#34; href=&#34;#__codelineno-10-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-27&#34; name=&#34;__codelineno-10-27&#34; href=&#34;#__codelineno-10-27&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-10-28&#34; name=&#34;__codelineno-10-28&#34; href=&#34;#__codelineno-10-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 遍历数组&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-29&#34; name=&#34;__codelineno-10-29&#34; href=&#34;#__codelineno-10-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Length&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-30&#34; name=&#34;__codelineno-10-30&#34; href=&#34;#__codelineno-10-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-31&#34; name=&#34;__codelineno-10-31&#34; href=&#34;#__codelineno-10-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EAIChatPlus_JsonValueType&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetElementType&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-32&#34; name=&#34;__codelineno-10-32&#34; href=&#34;#__codelineno-10-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Element[%d] type: %d&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;static_cast&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-33&#34; name=&#34;__codelineno-10-33&#34; href=&#34;#__codelineno-10-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-34&#34; name=&#34;__codelineno-10-34&#34; href=&#34;#__codelineno-10-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&#34;_10&#34;&gt;数组操作&lt;/h4&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-11-1&#34; name=&#34;__codelineno-11-1&#34; href=&#34;#__codelineno-11-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::ArrayOperations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-2&#34; name=&#34;__codelineno-11-2&#34; href=&#34;#__codelineno-11-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-3&#34; name=&#34;__codelineno-11-3&#34; href=&#34;#__codelineno-11-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonArray&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Create&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-4&#34; name=&#34;__codelineno-11-4&#34; href=&#34;#__codelineno-11-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-5&#34; name=&#34;__codelineno-11-5&#34; href=&#34;#__codelineno-11-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-6&#34; name=&#34;__codelineno-11-6&#34; href=&#34;#__codelineno-11-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;c&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-7&#34; name=&#34;__codelineno-11-7&#34; href=&#34;#__codelineno-11-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-8&#34; name=&#34;__codelineno-11-8&#34; href=&#34;#__codelineno-11-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 获取长度&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-9&#34; name=&#34;__codelineno-11-9&#34; href=&#34;#__codelineno-11-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Len&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Length&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 3&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-10&#34; name=&#34;__codelineno-11-10&#34; href=&#34;#__codelineno-11-10&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-11&#34; name=&#34;__codelineno-11-11&#34; href=&#34;#__codelineno-11-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 检查索引是否有效&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-12&#34; name=&#34;__codelineno-11-12&#34; href=&#34;#__codelineno-11-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bValid&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IsValidIndex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// true&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-13&#34; name=&#34;__codelineno-11-13&#34; href=&#34;#__codelineno-11-13&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-14&#34; name=&#34;__codelineno-11-14&#34; href=&#34;#__codelineno-11-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 设置元素&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-15&#34; name=&#34;__codelineno-11-15&#34; href=&#34;#__codelineno-11-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-16&#34; name=&#34;__codelineno-11-16&#34; href=&#34;#__codelineno-11-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;B&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-17&#34; name=&#34;__codelineno-11-17&#34; href=&#34;#__codelineno-11-17&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-18&#34; name=&#34;__codelineno-11-18&#34; href=&#34;#__codelineno-11-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 删除元素&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-19&#34; name=&#34;__codelineno-11-19&#34; href=&#34;#__codelineno-11-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RemoveAt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-20&#34; name=&#34;__codelineno-11-20&#34; href=&#34;#__codelineno-11-20&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-21&#34; name=&#34;__codelineno-11-21&#34; href=&#34;#__codelineno-11-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 清空数组&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-22&#34; name=&#34;__codelineno-11-22&#34; href=&#34;#__codelineno-11-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Clear&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-23&#34; name=&#34;__codelineno-11-23&#34; href=&#34;#__codelineno-11-23&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-24&#34; name=&#34;__codelineno-11-24&#34; href=&#34;#__codelineno-11-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 深拷贝&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-25&#34; name=&#34;__codelineno-11-25&#34; href=&#34;#__codelineno-11-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Copy&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Duplicate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-26&#34; name=&#34;__codelineno-11-26&#34; href=&#34;#__codelineno-11-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&#34;_11&#34;&gt;批量转换&lt;/h4&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-12-1&#34; name=&#34;__codelineno-12-1&#34; href=&#34;#__codelineno-12-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::BatchConversion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-2&#34; name=&#34;__codelineno-12-2&#34; href=&#34;#__codelineno-12-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-3&#34; name=&#34;__codelineno-12-3&#34; href=&#34;#__codelineno-12-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 从字符串数组创建&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-4&#34; name=&#34;__codelineno-12-4&#34; href=&#34;#__codelineno-12-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;StringArray&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;c&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)};&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-5&#34; name=&#34;__codelineno-12-5&#34; href=&#34;#__codelineno-12-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonArray&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromStringArray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;StringArray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-6&#34; name=&#34;__codelineno-12-6&#34; href=&#34;#__codelineno-12-6&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-12-7&#34; name=&#34;__codelineno-12-7&#34; href=&#34;#__codelineno-12-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 转回字符串数组&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-8&#34; name=&#34;__codelineno-12-8&#34; href=&#34;#__codelineno-12-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-9&#34; name=&#34;__codelineno-12-9&#34; href=&#34;#__codelineno-12-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OutArray&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ToStringArray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-10&#34; name=&#34;__codelineno-12-10&#34; href=&#34;#__codelineno-12-10&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-12-11&#34; name=&#34;__codelineno-12-11&#34; href=&#34;#__codelineno-12-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 从整数数组创建&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-12&#34; name=&#34;__codelineno-12-12&#34; href=&#34;#__codelineno-12-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IntArray&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-13&#34; name=&#34;__codelineno-12-13&#34; href=&#34;#__codelineno-12-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IntJsonArray&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_JsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromIntegerArray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IntArray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-14&#34; name=&#34;__codelineno-12-14&#34; href=&#34;#__codelineno-12-14&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-12-15&#34; name=&#34;__codelineno-12-15&#34; href=&#34;#__codelineno-12-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 转回整数数组&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-16&#34; name=&#34;__codelineno-12-16&#34; href=&#34;#__codelineno-12-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OutIntArray&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IntJsonArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ToIntegerArray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSuccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-17&#34; name=&#34;__codelineno-12-17&#34; href=&#34;#__codelineno-12-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;uaichatplus_util-json&#34;&gt;UAIChatPlus_Util - JSON 辅助函数&lt;/h3&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-13-1&#34; name=&#34;__codelineno-13-1&#34; href=&#34;#__codelineno-13-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::JsonUtilFunctions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-13-2&#34; name=&#34;__codelineno-13-2&#34; href=&#34;#__codelineno-13-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-13-3&#34; name=&#34;__codelineno-13-3&#34; href=&#34;#__codelineno-13-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 合并两个 JSON 字符串&lt;/span&gt;
&lt;a id=&#34;__codelineno-13-4&#34; name=&#34;__codelineno-13-4&#34; href=&#34;#__codelineno-13-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Json1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;R&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;dl&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{&amp;quot;name&amp;quot;: &amp;quot;John&amp;quot;}&lt;/span&gt;&lt;span class=&#34;dl&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-13-5&#34; name=&#34;__codelineno-13-5&#34; href=&#34;#__codelineno-13-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Json2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;R&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;dl&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{&amp;quot;age&amp;quot;: 30, &amp;quot;name&amp;quot;: &amp;quot;Jane&amp;quot;}&lt;/span&gt;&lt;span class=&#34;dl&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-13-6&#34; name=&#34;__codelineno-13-6&#34; href=&#34;#__codelineno-13-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Merged&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MergeJsonObjects&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Json1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Json2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-13-7&#34; name=&#34;__codelineno-13-7&#34; href=&#34;#__codelineno-13-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Merged = {&amp;quot;name&amp;quot;: &amp;quot;Jane&amp;quot;, &amp;quot;age&amp;quot;: 30}&lt;/span&gt;
&lt;a id=&#34;__codelineno-13-8&#34; name=&#34;__codelineno-13-8&#34; href=&#34;#__codelineno-13-8&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-9&#34; name=&#34;__codelineno-13-9&#34; href=&#34;#__codelineno-13-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 加载 JSON 字符串为对象&lt;/span&gt;
&lt;a id=&#34;__codelineno-13-10&#34; name=&#34;__codelineno-13-10&#34; href=&#34;#__codelineno-13-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSharedPtr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FJsonObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LoadJsonString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Json1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-13-11&#34; name=&#34;__codelineno-13-11&#34; href=&#34;#__codelineno-13-11&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-12&#34; name=&#34;__codelineno-13-12&#34; href=&#34;#__codelineno-13-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 对象转字符串&lt;/span&gt;
&lt;a id=&#34;__codelineno-13-13&#34; name=&#34;__codelineno-13-13&#34; href=&#34;#__codelineno-13-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ToJsonString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JsonObj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-13-14&#34; name=&#34;__codelineno-13-14&#34; href=&#34;#__codelineno-13-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;_12&#34;&gt;图片工具&lt;/h2&gt;
&lt;h3 id=&#34;_13&#34;&gt;加载和保存图片&lt;/h3&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-14-1&#34; name=&#34;__codelineno-14-1&#34; href=&#34;#__codelineno-14-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;quot;Common/AIChatPlus_Util.h&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-2&#34; name=&#34;__codelineno-14-2&#34; href=&#34;#__codelineno-14-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-14-3&#34; name=&#34;__codelineno-14-3&#34; href=&#34;#__codelineno-14-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::ImageLoadSave&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-4&#34; name=&#34;__codelineno-14-4&#34; href=&#34;#__codelineno-14-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-5&#34; name=&#34;__codelineno-14-5&#34; href=&#34;#__codelineno-14-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 从文件加载图片&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-6&#34; name=&#34;__codelineno-14-6&#34; href=&#34;#__codelineno-14-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ImagePath&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FPaths&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ProjectContentDir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Images/sample.png&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-7&#34; name=&#34;__codelineno-14-7&#34; href=&#34;#__codelineno-14-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Texture&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LoadImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ImagePath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// true = 完成编译&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-8&#34; name=&#34;__codelineno-14-8&#34; href=&#34;#__codelineno-14-8&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-14-9&#34; name=&#34;__codelineno-14-9&#34; href=&#34;#__codelineno-14-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Texture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-10&#34; name=&#34;__codelineno-14-10&#34; href=&#34;#__codelineno-14-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-11&#34; name=&#34;__codelineno-14-11&#34; href=&#34;#__codelineno-14-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Image loaded: %dx%d&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-12&#34; name=&#34;__codelineno-14-12&#34; href=&#34;#__codelineno-14-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Texture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetSizeX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Texture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetSizeY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-13&#34; name=&#34;__codelineno-14-13&#34; href=&#34;#__codelineno-14-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-14&#34; name=&#34;__codelineno-14-14&#34; href=&#34;#__codelineno-14-14&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-14-15&#34; name=&#34;__codelineno-14-15&#34; href=&#34;#__codelineno-14-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 保存图片到文件&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-16&#34; name=&#34;__codelineno-14-16&#34; href=&#34;#__codelineno-14-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SavePath&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FPaths&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ProjectSavedDir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;output.png&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-17&#34; name=&#34;__codelineno-14-17&#34; href=&#34;#__codelineno-14-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSaved&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SaveImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Texture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SavePath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-18&#34; name=&#34;__codelineno-14-18&#34; href=&#34;#__codelineno-14-18&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-14-19&#34; name=&#34;__codelineno-14-19&#34; href=&#34;#__codelineno-14-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSaved&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-20&#34; name=&#34;__codelineno-14-20&#34; href=&#34;#__codelineno-14-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-21&#34; name=&#34;__codelineno-14-21&#34; href=&#34;#__codelineno-14-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Image saved to: %s&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SavePath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-22&#34; name=&#34;__codelineno-14-22&#34; href=&#34;#__codelineno-14-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-23&#34; name=&#34;__codelineno-14-23&#34; href=&#34;#__codelineno-14-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;base64&#34;&gt;图片转 Base64&lt;/h3&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-15-1&#34; name=&#34;__codelineno-15-1&#34; href=&#34;#__codelineno-15-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::ImageToBase64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-15-2&#34; name=&#34;__codelineno-15-2&#34; href=&#34;#__codelineno-15-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-15-3&#34; name=&#34;__codelineno-15-3&#34; href=&#34;#__codelineno-15-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Texture&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LoadImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;D:/image.png&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-15-4&#34; name=&#34;__codelineno-15-4&#34; href=&#34;#__codelineno-15-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-15-5&#34; name=&#34;__codelineno-15-5&#34; href=&#34;#__codelineno-15-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 转换为 Base64 字符串&lt;/span&gt;
&lt;a id=&#34;__codelineno-15-6&#34; name=&#34;__codelineno-15-6&#34; href=&#34;#__codelineno-15-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// InQuality: 0 = PNG, 1-100 = JPEG 质量&lt;/span&gt;
&lt;a id=&#34;__codelineno-15-7&#34; name=&#34;__codelineno-15-7&#34; href=&#34;#__codelineno-15-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;B64String&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ImageToB64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Texture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// PNG 格式&lt;/span&gt;
&lt;a id=&#34;__codelineno-15-8&#34; name=&#34;__codelineno-15-8&#34; href=&#34;#__codelineno-15-8&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-15-9&#34; name=&#34;__codelineno-15-9&#34; href=&#34;#__codelineno-15-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Base64 length: %d&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;B64String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-15-10&#34; name=&#34;__codelineno-15-10&#34; href=&#34;#__codelineno-15-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;_14&#34;&gt;复制图片&lt;/h3&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-16-1&#34; name=&#34;__codelineno-16-1&#34; href=&#34;#__codelineno-16-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::CopyTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-2&#34; name=&#34;__codelineno-16-2&#34; href=&#34;#__codelineno-16-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-3&#34; name=&#34;__codelineno-16-3&#34; href=&#34;#__codelineno-16-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Original&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LoadImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;D:/image.png&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-4&#34; name=&#34;__codelineno-16-4&#34; href=&#34;#__codelineno-16-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-16-5&#34; name=&#34;__codelineno-16-5&#34; href=&#34;#__codelineno-16-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 复制纹理&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-6&#34; name=&#34;__codelineno-16-6&#34; href=&#34;#__codelineno-16-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Copy&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CopyTexture2D&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-7&#34; name=&#34;__codelineno-16-7&#34; href=&#34;#__codelineno-16-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Original&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-8&#34; name=&#34;__codelineno-16-8&#34; href=&#34;#__codelineno-16-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;nullptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Outer（nullptr = GetTransientPackage()）&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-9&#34; name=&#34;__codelineno-16-9&#34; href=&#34;#__codelineno-16-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NAME_None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 名称&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-10&#34; name=&#34;__codelineno-16-10&#34; href=&#34;#__codelineno-16-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RF_NoFlags&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 标志&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-11&#34; name=&#34;__codelineno-16-11&#34; href=&#34;#__codelineno-16-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-12&#34; name=&#34;__codelineno-16-12&#34; href=&#34;#__codelineno-16-12&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-16-13&#34; name=&#34;__codelineno-16-13&#34; href=&#34;#__codelineno-16-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Blueprint 版本（带默认标志）&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-14&#34; name=&#34;__codelineno-16-14&#34; href=&#34;#__codelineno-16-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BPCopy&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CopyTexture2DInBlueprint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Original&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-15&#34; name=&#34;__codelineno-16-15&#34; href=&#34;#__codelineno-16-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;url&#34;&gt;从 URL 获取图片&lt;/h3&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-17-1&#34; name=&#34;__codelineno-17-1&#34; href=&#34;#__codelineno-17-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::GetImageFromUrl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-2&#34; name=&#34;__codelineno-17-2&#34; href=&#34;#__codelineno-17-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-3&#34; name=&#34;__codelineno-17-3&#34; href=&#34;#__codelineno-17-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ImageUrl&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;https://example.com/image.png&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-4&#34; name=&#34;__codelineno-17-4&#34; href=&#34;#__codelineno-17-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-17-5&#34; name=&#34;__codelineno-17-5&#34; href=&#34;#__codelineno-17-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetImageFromUrl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ImageUrl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-6&#34; name=&#34;__codelineno-17-6&#34; href=&#34;#__codelineno-17-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OnImageCreated&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([](&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Texture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-7&#34; name=&#34;__codelineno-17-7&#34; href=&#34;#__codelineno-17-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-8&#34; name=&#34;__codelineno-17-8&#34; href=&#34;#__codelineno-17-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Texture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-9&#34; name=&#34;__codelineno-17-9&#34; href=&#34;#__codelineno-17-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-10&#34; name=&#34;__codelineno-17-10&#34; href=&#34;#__codelineno-17-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Image downloaded: %dx%d&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-11&#34; name=&#34;__codelineno-17-11&#34; href=&#34;#__codelineno-17-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Texture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetSizeX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Texture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetSizeY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-12&#34; name=&#34;__codelineno-17-12&#34; href=&#34;#__codelineno-17-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-13&#34; name=&#34;__codelineno-17-13&#34; href=&#34;#__codelineno-17-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-14&#34; name=&#34;__codelineno-17-14&#34; href=&#34;#__codelineno-17-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-15&#34; name=&#34;__codelineno-17-15&#34; href=&#34;#__codelineno-17-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Download failed: %s&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-16&#34; name=&#34;__codelineno-17-16&#34; href=&#34;#__codelineno-17-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-17&#34; name=&#34;__codelineno-17-17&#34; href=&#34;#__codelineno-17-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}));&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-18&#34; name=&#34;__codelineno-17-18&#34; href=&#34;#__codelineno-17-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;base64_1&#34;&gt;从 Base64 获取图片&lt;/h3&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-18-1&#34; name=&#34;__codelineno-18-1&#34; href=&#34;#__codelineno-18-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::GetImageFromBase64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-2&#34; name=&#34;__codelineno-18-2&#34; href=&#34;#__codelineno-18-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-3&#34; name=&#34;__codelineno-18-3&#34; href=&#34;#__codelineno-18-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;B64String&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;iVBORw0KGgoAAAANSUhEUg...&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Base64 数据&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-4&#34; name=&#34;__codelineno-18-4&#34; href=&#34;#__codelineno-18-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-18-5&#34; name=&#34;__codelineno-18-5&#34; href=&#34;#__codelineno-18-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetImageFromB64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;B64String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-6&#34; name=&#34;__codelineno-18-6&#34; href=&#34;#__codelineno-18-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OnImageCreated&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([](&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Texture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-7&#34; name=&#34;__codelineno-18-7&#34; href=&#34;#__codelineno-18-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-8&#34; name=&#34;__codelineno-18-8&#34; href=&#34;#__codelineno-18-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Texture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-9&#34; name=&#34;__codelineno-18-9&#34; href=&#34;#__codelineno-18-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-10&#34; name=&#34;__codelineno-18-10&#34; href=&#34;#__codelineno-18-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Image decoded successfully&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-11&#34; name=&#34;__codelineno-18-11&#34; href=&#34;#__codelineno-18-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-12&#34; name=&#34;__codelineno-18-12&#34; href=&#34;#__codelineno-18-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-13&#34; name=&#34;__codelineno-18-13&#34; href=&#34;#__codelineno-18-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-14&#34; name=&#34;__codelineno-18-14&#34; href=&#34;#__codelineno-18-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Decode failed: %s&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-15&#34; name=&#34;__codelineno-18-15&#34; href=&#34;#__codelineno-18-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-16&#34; name=&#34;__codelineno-18-16&#34; href=&#34;#__codelineno-18-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}));&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-17&#34; name=&#34;__codelineno-18-17&#34; href=&#34;#__codelineno-18-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;_15&#34;&gt;复制图片到剪贴板&lt;/h3&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-19-1&#34; name=&#34;__codelineno-19-1&#34; href=&#34;#__codelineno-19-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::CopyToClipboard&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-19-2&#34; name=&#34;__codelineno-19-2&#34; href=&#34;#__codelineno-19-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-19-3&#34; name=&#34;__codelineno-19-3&#34; href=&#34;#__codelineno-19-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Texture&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LoadImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;D:/image.png&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-19-4&#34; name=&#34;__codelineno-19-4&#34; href=&#34;#__codelineno-19-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-19-5&#34; name=&#34;__codelineno-19-5&#34; href=&#34;#__codelineno-19-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 检查是否支持&lt;/span&gt;
&lt;a id=&#34;__codelineno-19-6&#34; name=&#34;__codelineno-19-6&#34; href=&#34;#__codelineno-19-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IsCanCopyTexture2DToClipboard&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;a id=&#34;__codelineno-19-7&#34; name=&#34;__codelineno-19-7&#34; href=&#34;#__codelineno-19-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-19-8&#34; name=&#34;__codelineno-19-8&#34; href=&#34;#__codelineno-19-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CopyTexture2DToClipboard&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Texture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-19-9&#34; name=&#34;__codelineno-19-9&#34; href=&#34;#__codelineno-19-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Image copied to clipboard&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-19-10&#34; name=&#34;__codelineno-19-10&#34; href=&#34;#__codelineno-19-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-19-11&#34; name=&#34;__codelineno-19-11&#34; href=&#34;#__codelineno-19-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;_16&#34;&gt;音频工具&lt;/h2&gt;
&lt;h3 id=&#34;wav&#34;&gt;加载 WAV 文件&lt;/h3&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-20-1&#34; name=&#34;__codelineno-20-1&#34; href=&#34;#__codelineno-20-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::LoadWavFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-2&#34; name=&#34;__codelineno-20-2&#34; href=&#34;#__codelineno-20-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-3&#34; name=&#34;__codelineno-20-3&#34; href=&#34;#__codelineno-20-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WavPath&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FPaths&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ProjectContentDir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Audio/sample.wav&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-4&#34; name=&#34;__codelineno-20-4&#34; href=&#34;#__codelineno-20-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;USoundWave&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Sound&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LoadSoundWav&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WavPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-5&#34; name=&#34;__codelineno-20-5&#34; href=&#34;#__codelineno-20-5&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-20-6&#34; name=&#34;__codelineno-20-6&#34; href=&#34;#__codelineno-20-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Sound&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-7&#34; name=&#34;__codelineno-20-7&#34; href=&#34;#__codelineno-20-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-8&#34; name=&#34;__codelineno-20-8&#34; href=&#34;#__codelineno-20-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Sound loaded: Duration=%.2f, Channels=%d, SampleRate=%d&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-9&#34; name=&#34;__codelineno-20-9&#34; href=&#34;#__codelineno-20-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Sound&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Duration&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-10&#34; name=&#34;__codelineno-20-10&#34; href=&#34;#__codelineno-20-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Sound&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NumChannels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-11&#34; name=&#34;__codelineno-20-11&#34; href=&#34;#__codelineno-20-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Sound&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetSampleRateForCurrentPlatform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-12&#34; name=&#34;__codelineno-20-12&#34; href=&#34;#__codelineno-20-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-13&#34; name=&#34;__codelineno-20-13&#34; href=&#34;#__codelineno-20-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;wav_1&#34;&gt;保存音频为 WAV 文件&lt;/h3&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-21-1&#34; name=&#34;__codelineno-21-1&#34; href=&#34;#__codelineno-21-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::SaveWavFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-21-2&#34; name=&#34;__codelineno-21-2&#34; href=&#34;#__codelineno-21-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-21-3&#34; name=&#34;__codelineno-21-3&#34; href=&#34;#__codelineno-21-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 假设 Sound 是已有的 USoundWave&lt;/span&gt;
&lt;a id=&#34;__codelineno-21-4&#34; name=&#34;__codelineno-21-4&#34; href=&#34;#__codelineno-21-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;USoundWave&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Sound&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;/* 获取音频 */&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-21-5&#34; name=&#34;__codelineno-21-5&#34; href=&#34;#__codelineno-21-5&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-21-6&#34; name=&#34;__codelineno-21-6&#34; href=&#34;#__codelineno-21-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SavePath&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FPaths&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ProjectSavedDir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;output.wav&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-21-7&#34; name=&#34;__codelineno-21-7&#34; href=&#34;#__codelineno-21-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSaved&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SaveSoundWav&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Sound&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SavePath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-21-8&#34; name=&#34;__codelineno-21-8&#34; href=&#34;#__codelineno-21-8&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-21-9&#34; name=&#34;__codelineno-21-9&#34; href=&#34;#__codelineno-21-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bSaved&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-21-10&#34; name=&#34;__codelineno-21-10&#34; href=&#34;#__codelineno-21-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-21-11&#34; name=&#34;__codelineno-21-11&#34; href=&#34;#__codelineno-21-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Sound saved to: %s&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SavePath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-21-12&#34; name=&#34;__codelineno-21-12&#34; href=&#34;#__codelineno-21-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-21-13&#34; name=&#34;__codelineno-21-13&#34; href=&#34;#__codelineno-21-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;base64_2&#34;&gt;音频转 Base64&lt;/h3&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-22-1&#34; name=&#34;__codelineno-22-1&#34; href=&#34;#__codelineno-22-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::SoundToBase64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-22-2&#34; name=&#34;__codelineno-22-2&#34; href=&#34;#__codelineno-22-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-22-3&#34; name=&#34;__codelineno-22-3&#34; href=&#34;#__codelineno-22-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;USoundWave&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Sound&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LoadSoundWav&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;D:/audio.wav&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-22-4&#34; name=&#34;__codelineno-22-4&#34; href=&#34;#__codelineno-22-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-22-5&#34; name=&#34;__codelineno-22-5&#34; href=&#34;#__codelineno-22-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 转换为 Base64 字符串&lt;/span&gt;
&lt;a id=&#34;__codelineno-22-6&#34; name=&#34;__codelineno-22-6&#34; href=&#34;#__codelineno-22-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;B64String&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SoundToB64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Sound&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-22-7&#34; name=&#34;__codelineno-22-7&#34; href=&#34;#__codelineno-22-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-22-8&#34; name=&#34;__codelineno-22-8&#34; href=&#34;#__codelineno-22-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Audio Base64 length: %d&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;B64String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-22-9&#34; name=&#34;__codelineno-22-9&#34; href=&#34;#__codelineno-22-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;wav-soundwave&#34;&gt;WAV 数据转 SoundWave&lt;/h3&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-23-1&#34; name=&#34;__codelineno-23-1&#34; href=&#34;#__codelineno-23-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::WavDataToSound&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-23-2&#34; name=&#34;__codelineno-23-2&#34; href=&#34;#__codelineno-23-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-23-3&#34; name=&#34;__codelineno-23-3&#34; href=&#34;#__codelineno-23-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 从文件读取原始数据&lt;/span&gt;
&lt;a id=&#34;__codelineno-23-4&#34; name=&#34;__codelineno-23-4&#34; href=&#34;#__codelineno-23-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint8&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RawData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-23-5&#34; name=&#34;__codelineno-23-5&#34; href=&#34;#__codelineno-23-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FFileHelper&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LoadFileToArray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RawData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;D:/audio.wav&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-23-6&#34; name=&#34;__codelineno-23-6&#34; href=&#34;#__codelineno-23-6&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-23-7&#34; name=&#34;__codelineno-23-7&#34; href=&#34;#__codelineno-23-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 转换为 SoundWave&lt;/span&gt;
&lt;a id=&#34;__codelineno-23-8&#34; name=&#34;__codelineno-23-8&#34; href=&#34;#__codelineno-23-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;USoundWave&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Sound&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WavDataToSoundWave&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-23-9&#34; name=&#34;__codelineno-23-9&#34; href=&#34;#__codelineno-23-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RawData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-23-10&#34; name=&#34;__codelineno-23-10&#34; href=&#34;#__codelineno-23-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// bIsAmbiX&lt;/span&gt;
&lt;a id=&#34;__codelineno-23-11&#34; name=&#34;__codelineno-23-11&#34; href=&#34;#__codelineno-23-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// bIsFuMa&lt;/span&gt;
&lt;a id=&#34;__codelineno-23-12&#34; name=&#34;__codelineno-23-12&#34; href=&#34;#__codelineno-23-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-23-13&#34; name=&#34;__codelineno-23-13&#34; href=&#34;#__codelineno-23-13&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-23-14&#34; name=&#34;__codelineno-23-14&#34; href=&#34;#__codelineno-23-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Sound&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-23-15&#34; name=&#34;__codelineno-23-15&#34; href=&#34;#__codelineno-23-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-23-16&#34; name=&#34;__codelineno-23-16&#34; href=&#34;#__codelineno-23-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Sound created from data&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-23-17&#34; name=&#34;__codelineno-23-17&#34; href=&#34;#__codelineno-23-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-23-18&#34; name=&#34;__codelineno-23-18&#34; href=&#34;#__codelineno-23-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;soundwave&#34;&gt;复制 SoundWave&lt;/h3&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-24-1&#34; name=&#34;__codelineno-24-1&#34; href=&#34;#__codelineno-24-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::CopySoundWave&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-24-2&#34; name=&#34;__codelineno-24-2&#34; href=&#34;#__codelineno-24-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-24-3&#34; name=&#34;__codelineno-24-3&#34; href=&#34;#__codelineno-24-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;USoundWave&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Original&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LoadSoundWav&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;D:/audio.wav&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-24-4&#34; name=&#34;__codelineno-24-4&#34; href=&#34;#__codelineno-24-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-24-5&#34; name=&#34;__codelineno-24-5&#34; href=&#34;#__codelineno-24-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 复制音频&lt;/span&gt;
&lt;a id=&#34;__codelineno-24-6&#34; name=&#34;__codelineno-24-6&#34; href=&#34;#__codelineno-24-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;USoundWave&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Copy&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CopySoundWave&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-24-7&#34; name=&#34;__codelineno-24-7&#34; href=&#34;#__codelineno-24-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Original&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-24-8&#34; name=&#34;__codelineno-24-8&#34; href=&#34;#__codelineno-24-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;nullptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Outer&lt;/span&gt;
&lt;a id=&#34;__codelineno-24-9&#34; name=&#34;__codelineno-24-9&#34; href=&#34;#__codelineno-24-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NAME_None&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 名称&lt;/span&gt;
&lt;a id=&#34;__codelineno-24-10&#34; name=&#34;__codelineno-24-10&#34; href=&#34;#__codelineno-24-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-24-11&#34; name=&#34;__codelineno-24-11&#34; href=&#34;#__codelineno-24-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;pcm&#34;&gt;获取原始 PCM 数据&lt;/h3&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-25-1&#34; name=&#34;__codelineno-25-1&#34; href=&#34;#__codelineno-25-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::GetPCMData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-2&#34; name=&#34;__codelineno-25-2&#34; href=&#34;#__codelineno-25-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-3&#34; name=&#34;__codelineno-25-3&#34; href=&#34;#__codelineno-25-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;USoundWave&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Sound&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LoadSoundWav&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;D:/audio.wav&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-4&#34; name=&#34;__codelineno-25-4&#34; href=&#34;#__codelineno-25-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-25-5&#34; name=&#34;__codelineno-25-5&#34; href=&#34;#__codelineno-25-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 获取原始 PCM 数据&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-6&#34; name=&#34;__codelineno-25-6&#34; href=&#34;#__codelineno-25-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint8&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PCMData&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetSoundWavePCMData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Sound&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-7&#34; name=&#34;__codelineno-25-7&#34; href=&#34;#__codelineno-25-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-25-8&#34; name=&#34;__codelineno-25-8&#34; href=&#34;#__codelineno-25-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;PCM data size: %d bytes&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PCMData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Num&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-9&#34; name=&#34;__codelineno-25-9&#34; href=&#34;#__codelineno-25-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;soundwave_1&#34;&gt;从录音数据创建 SoundWave&lt;/h3&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-26-1&#34; name=&#34;__codelineno-26-1&#34; href=&#34;#__codelineno-26-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::RecorderDataToSound&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-26-2&#34; name=&#34;__codelineno-26-2&#34; href=&#34;#__codelineno-26-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-26-3&#34; name=&#34;__codelineno-26-3&#34; href=&#34;#__codelineno-26-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 假设从 Audio Capture 获取的录音数据&lt;/span&gt;
&lt;a id=&#34;__codelineno-26-4&#34; name=&#34;__codelineno-26-4&#34; href=&#34;#__codelineno-26-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RecorderData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 音频采样数据&lt;/span&gt;
&lt;a id=&#34;__codelineno-26-5&#34; name=&#34;__codelineno-26-5&#34; href=&#34;#__codelineno-26-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NumChannels&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 单声道&lt;/span&gt;
&lt;a id=&#34;__codelineno-26-6&#34; name=&#34;__codelineno-26-6&#34; href=&#34;#__codelineno-26-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SampleRate&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;16000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 采样率&lt;/span&gt;
&lt;a id=&#34;__codelineno-26-7&#34; name=&#34;__codelineno-26-7&#34; href=&#34;#__codelineno-26-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-26-8&#34; name=&#34;__codelineno-26-8&#34; href=&#34;#__codelineno-26-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;USoundWave&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Sound&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RecorderDataToSoundWave&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-26-9&#34; name=&#34;__codelineno-26-9&#34; href=&#34;#__codelineno-26-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RecorderData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-26-10&#34; name=&#34;__codelineno-26-10&#34; href=&#34;#__codelineno-26-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NumChannels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-26-11&#34; name=&#34;__codelineno-26-11&#34; href=&#34;#__codelineno-26-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SampleRate&lt;/span&gt;
&lt;a id=&#34;__codelineno-26-12&#34; name=&#34;__codelineno-26-12&#34; href=&#34;#__codelineno-26-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-26-13&#34; name=&#34;__codelineno-26-13&#34; href=&#34;#__codelineno-26-13&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-26-14&#34; name=&#34;__codelineno-26-14&#34; href=&#34;#__codelineno-26-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Sound&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-26-15&#34; name=&#34;__codelineno-26-15&#34; href=&#34;#__codelineno-26-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-26-16&#34; name=&#34;__codelineno-26-16&#34; href=&#34;#__codelineno-26-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Sound created from recorder data&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-26-17&#34; name=&#34;__codelineno-26-17&#34; href=&#34;#__codelineno-26-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-26-18&#34; name=&#34;__codelineno-26-18&#34; href=&#34;#__codelineno-26-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;_17&#34;&gt;日志控制&lt;/h2&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-27-1&#34; name=&#34;__codelineno-27-1&#34; href=&#34;#__codelineno-27-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::ControlLogging&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-2&#34; name=&#34;__codelineno-27-2&#34; href=&#34;#__codelineno-27-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-3&#34; name=&#34;__codelineno-27-3&#34; href=&#34;#__codelineno-27-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 设置内部日志级别&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-4&#34; name=&#34;__codelineno-27-4&#34; href=&#34;#__codelineno-27-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetInternalLogVerbosity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EAIChatPlus_LogVerbosityType&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Verbose&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-5&#34; name=&#34;__codelineno-27-5&#34; href=&#34;#__codelineno-27-5&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-27-6&#34; name=&#34;__codelineno-27-6&#34; href=&#34;#__codelineno-27-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 可用级别：&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-7&#34; name=&#34;__codelineno-27-7&#34; href=&#34;#__codelineno-27-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// - NoLogging&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-8&#34; name=&#34;__codelineno-27-8&#34; href=&#34;#__codelineno-27-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// - Fatal&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-9&#34; name=&#34;__codelineno-27-9&#34; href=&#34;#__codelineno-27-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// - Error&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-10&#34; name=&#34;__codelineno-27-10&#34; href=&#34;#__codelineno-27-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// - Warning&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-11&#34; name=&#34;__codelineno-27-11&#34; href=&#34;#__codelineno-27-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// - Display&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-12&#34; name=&#34;__codelineno-27-12&#34; href=&#34;#__codelineno-27-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// - Log&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-13&#34; name=&#34;__codelineno-27-13&#34; href=&#34;#__codelineno-27-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// - Verbose&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-14&#34; name=&#34;__codelineno-27-14&#34; href=&#34;#__codelineno-27-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// - VeryVerbose&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-15&#34; name=&#34;__codelineno-27-15&#34; href=&#34;#__codelineno-27-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;_18&#34;&gt;响应包装器辅助函数&lt;/h2&gt;
&lt;p&gt;在回调中处理响应时，需要将 &lt;code&gt;FAIChatPlus_PointerWrapper&lt;/code&gt; 转换为具体类型：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-28-1&#34; name=&#34;__codelineno-28-1&#34; href=&#34;#__codelineno-28-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::HandleCallbackResponse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-2&#34; name=&#34;__codelineno-28-2&#34; href=&#34;#__codelineno-28-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-3&#34; name=&#34;__codelineno-28-3&#34; href=&#34;#__codelineno-28-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 在 OnFinished 回调中&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-4&#34; name=&#34;__codelineno-28-4&#34; href=&#34;#__codelineno-28-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OnFinishedListeners&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([](&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_PointerWrapper&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ResponseWrapper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-5&#34; name=&#34;__codelineno-28-5&#34; href=&#34;#__codelineno-28-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-6&#34; name=&#34;__codelineno-28-6&#34; href=&#34;#__codelineno-28-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 获取响应消息&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-7&#34; name=&#34;__codelineno-28-7&#34; href=&#34;#__codelineno-28-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Message&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetResponseWrapperMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ResponseWrapper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-8&#34; name=&#34;__codelineno-28-8&#34; href=&#34;#__codelineno-28-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Message: %s&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-9&#34; name=&#34;__codelineno-28-9&#34; href=&#34;#__codelineno-28-9&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-28-10&#34; name=&#34;__codelineno-28-10&#34; href=&#34;#__codelineno-28-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 或者转换为基础响应类型&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-11&#34; name=&#34;__codelineno-28-11&#34; href=&#34;#__codelineno-28-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_ChatResponseBodyBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Response&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CastWrapperToResponse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ResponseWrapper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-12&#34; name=&#34;__codelineno-28-12&#34; href=&#34;#__codelineno-28-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-13&#34; name=&#34;__codelineno-28-13&#34; href=&#34;#__codelineno-28-13&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-28-14&#34; name=&#34;__codelineno-28-14&#34; href=&#34;#__codelineno-28-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 在 OnFailed 回调中&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-15&#34; name=&#34;__codelineno-28-15&#34; href=&#34;#__codelineno-28-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OnFailedListeners&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([](&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_PointerWrapper&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ErrorWrapper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-16&#34; name=&#34;__codelineno-28-16&#34; href=&#34;#__codelineno-28-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-17&#34; name=&#34;__codelineno-28-17&#34; href=&#34;#__codelineno-28-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 获取错误描述&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-18&#34; name=&#34;__codelineno-28-18&#34; href=&#34;#__codelineno-28-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ErrorDesc&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetErrorWrapperDescription&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ErrorWrapper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-19&#34; name=&#34;__codelineno-28-19&#34; href=&#34;#__codelineno-28-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Error: %s&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ErrorDesc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-20&#34; name=&#34;__codelineno-28-20&#34; href=&#34;#__codelineno-28-20&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-28-21&#34; name=&#34;__codelineno-28-21&#34; href=&#34;#__codelineno-28-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 或者转换为错误类型&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-22&#34; name=&#34;__codelineno-28-22&#34; href=&#34;#__codelineno-28-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_ResponseErrorBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Error&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CastWrapperToError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ErrorWrapper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-23&#34; name=&#34;__codelineno-28-23&#34; href=&#34;#__codelineno-28-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-24&#34; name=&#34;__codelineno-28-24&#34; href=&#34;#__codelineno-28-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;_19&#34;&gt;模型信息查询&lt;/h2&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-29-1&#34; name=&#34;__codelineno-29-1&#34; href=&#34;#__codelineno-29-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::QueryModelInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-2&#34; name=&#34;__codelineno-29-2&#34; href=&#34;#__codelineno-29-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-3&#34; name=&#34;__codelineno-29-3&#34; href=&#34;#__codelineno-29-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 获取 OpenAI 默认模型列表&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-4&#34; name=&#34;__codelineno-29-4&#34; href=&#34;#__codelineno-29-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FName&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OpenAIModels&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetOpenAIChatDefaultModels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-5&#34; name=&#34;__codelineno-29-5&#34; href=&#34;#__codelineno-29-5&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-29-6&#34; name=&#34;__codelineno-29-6&#34; href=&#34;#__codelineno-29-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 获取特定模型信息&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-7&#34; name=&#34;__codelineno-29-7&#34; href=&#34;#__codelineno-29-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_ChatModelInfo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ModelInfo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetOpenAIChatModelInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;gpt-4o&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-8&#34; name=&#34;__codelineno-29-8&#34; href=&#34;#__codelineno-29-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Model: %s, MaxTokens: %d, SupportImage: %s&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-9&#34; name=&#34;__codelineno-29-9&#34; href=&#34;#__codelineno-29-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ModelInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ToString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-10&#34; name=&#34;__codelineno-29-10&#34; href=&#34;#__codelineno-29-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ModelInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MaxTokens&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-11&#34; name=&#34;__codelineno-29-11&#34; href=&#34;#__codelineno-29-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ModelInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IsSupportSendImage&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Yes&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;No&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-12&#34; name=&#34;__codelineno-29-12&#34; href=&#34;#__codelineno-29-12&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-29-13&#34; name=&#34;__codelineno-29-13&#34; href=&#34;#__codelineno-29-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Claude 模型&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-14&#34; name=&#34;__codelineno-29-14&#34; href=&#34;#__codelineno-29-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FName&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ClaudeModels&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetClaudeChatDefaultModels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-15&#34; name=&#34;__codelineno-29-15&#34; href=&#34;#__codelineno-29-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_ChatModelInfo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ClaudeInfo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetClaudeChatModelInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;claude-3-5-sonnet&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-16&#34; name=&#34;__codelineno-29-16&#34; href=&#34;#__codelineno-29-16&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-29-17&#34; name=&#34;__codelineno-29-17&#34; href=&#34;#__codelineno-29-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Gemini 模型&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-18&#34; name=&#34;__codelineno-29-18&#34; href=&#34;#__codelineno-29-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FName&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GeminiModels&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetGeminiChatDefaultModels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-19&#34; name=&#34;__codelineno-29-19&#34; href=&#34;#__codelineno-29-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_ChatModelInfo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GeminiInfo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetGeminiChatModelInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;gemini-1.5-pro&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-20&#34; name=&#34;__codelineno-29-20&#34; href=&#34;#__codelineno-29-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;cllama&#34;&gt;Cllama 辅助函数&lt;/h2&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-30-1&#34; name=&#34;__codelineno-30-1&#34; href=&#34;#__codelineno-30-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::CllamaUtilities&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-2&#34; name=&#34;__codelineno-30-2&#34; href=&#34;#__codelineno-30-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-3&#34; name=&#34;__codelineno-30-3&#34; href=&#34;#__codelineno-30-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 检查 Cllama 是否可用&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-4&#34; name=&#34;__codelineno-30-4&#34; href=&#34;#__codelineno-30-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Cllama_IsValid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-5&#34; name=&#34;__codelineno-30-5&#34; href=&#34;#__codelineno-30-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-6&#34; name=&#34;__codelineno-30-6&#34; href=&#34;#__codelineno-30-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Cllama is available&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-7&#34; name=&#34;__codelineno-30-7&#34; href=&#34;#__codelineno-30-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-8&#34; name=&#34;__codelineno-30-8&#34; href=&#34;#__codelineno-30-8&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-30-9&#34; name=&#34;__codelineno-30-9&#34; href=&#34;#__codelineno-30-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 检查 GPU 支持&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-10&#34; name=&#34;__codelineno-30-10&#34; href=&#34;#__codelineno-30-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Cllama_IsSupportGpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-11&#34; name=&#34;__codelineno-30-11&#34; href=&#34;#__codelineno-30-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-12&#34; name=&#34;__codelineno-30-12&#34; href=&#34;#__codelineno-30-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;GPU acceleration supported&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-13&#34; name=&#34;__codelineno-30-13&#34; href=&#34;#__codelineno-30-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-14&#34; name=&#34;__codelineno-30-14&#34; href=&#34;#__codelineno-30-14&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-30-15&#34; name=&#34;__codelineno-30-15&#34; href=&#34;#__codelineno-30-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 获取支持的后端&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-16&#34; name=&#34;__codelineno-30-16&#34; href=&#34;#__codelineno-30-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Backends&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Cllama_GetSupportBackends&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-17&#34; name=&#34;__codelineno-30-17&#34; href=&#34;#__codelineno-30-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Backend&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Backends&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-18&#34; name=&#34;__codelineno-30-18&#34; href=&#34;#__codelineno-30-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-19&#34; name=&#34;__codelineno-30-19&#34; href=&#34;#__codelineno-30-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Backend: %s&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Backend&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-20&#34; name=&#34;__codelineno-30-20&#34; href=&#34;#__codelineno-30-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-21&#34; name=&#34;__codelineno-30-21&#34; href=&#34;#__codelineno-30-21&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-30-22&#34; name=&#34;__codelineno-30-22&#34; href=&#34;#__codelineno-30-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 准备 Pak 中的模型路径&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-23&#34; name=&#34;__codelineno-30-23&#34; href=&#34;#__codelineno-30-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ModelPath&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Models/my_model.gguf&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-24&#34; name=&#34;__codelineno-30-24&#34; href=&#34;#__codelineno-30-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ActualPath&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Cllama_PrepareModelPathFromPak&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ModelPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-25&#34; name=&#34;__codelineno-30-25&#34; href=&#34;#__codelineno-30-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 如果模型在 Pak 中，会解压到临时目录并返回新路径&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-26&#34; name=&#34;__codelineno-30-26&#34; href=&#34;#__codelineno-30-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;_20&#34;&gt;文件辅助函数&lt;/h2&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-31-1&#34; name=&#34;__codelineno-31-1&#34; href=&#34;#__codelineno-31-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::FileUtilities&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-31-2&#34; name=&#34;__codelineno-31-2&#34; href=&#34;#__codelineno-31-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-31-3&#34; name=&#34;__codelineno-31-3&#34; href=&#34;#__codelineno-31-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 获取插件基础目录&lt;/span&gt;
&lt;a id=&#34;__codelineno-31-4&#34; name=&#34;__codelineno-31-4&#34; href=&#34;#__codelineno-31-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PluginDir&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetPluginBaseDir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;AIChatPlus&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-31-5&#34; name=&#34;__codelineno-31-5&#34; href=&#34;#__codelineno-31-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Plugin dir: %s&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PluginDir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-31-6&#34; name=&#34;__codelineno-31-6&#34; href=&#34;#__codelineno-31-6&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-31-7&#34; name=&#34;__codelineno-31-7&#34; href=&#34;#__codelineno-31-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 复制目录&lt;/span&gt;
&lt;a id=&#34;__codelineno-31-8&#34; name=&#34;__codelineno-31-8&#34; href=&#34;#__codelineno-31-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SourceDir&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FPaths&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ProjectContentDir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Source&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-31-9&#34; name=&#34;__codelineno-31-9&#34; href=&#34;#__codelineno-31-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DestDir&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FPaths&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ProjectSavedDir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Backup&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-31-10&#34; name=&#34;__codelineno-31-10&#34; href=&#34;#__codelineno-31-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bCopied&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CopyDirectory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SourceDir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DestDir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// true = 覆盖&lt;/span&gt;
&lt;a id=&#34;__codelineno-31-11&#34; name=&#34;__codelineno-31-11&#34; href=&#34;#__codelineno-31-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;prompt&#34;&gt;Prompt 模板&lt;/h2&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-32-1&#34; name=&#34;__codelineno-32-1&#34; href=&#34;#__codelineno-32-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UMyClass::PromptTemplates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-32-2&#34; name=&#34;__codelineno-32-2&#34; href=&#34;#__codelineno-32-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-32-3&#34; name=&#34;__codelineno-32-3&#34; href=&#34;#__codelineno-32-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 获取 Prompt 模板 JSON 文件列表&lt;/span&gt;
&lt;a id=&#34;__codelineno-32-4&#34; name=&#34;__codelineno-32-4&#34; href=&#34;#__codelineno-32-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FDirectoryPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ExtraDirs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 额外搜索目录（可选）&lt;/span&gt;
&lt;a id=&#34;__codelineno-32-5&#34; name=&#34;__codelineno-32-5&#34; href=&#34;#__codelineno-32-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FFilePath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TemplateFiles&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetPromptTemplateJsonFiles&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ExtraDirs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-32-6&#34; name=&#34;__codelineno-32-6&#34; href=&#34;#__codelineno-32-6&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-32-7&#34; name=&#34;__codelineno-32-7&#34; href=&#34;#__codelineno-32-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 加载 Prompt 模板&lt;/span&gt;
&lt;a id=&#34;__codelineno-32-8&#34; name=&#34;__codelineno-32-8&#34; href=&#34;#__codelineno-32-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_PromptTemplate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Templates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetPromptTemplates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TemplateFiles&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-32-9&#34; name=&#34;__codelineno-32-9&#34; href=&#34;#__codelineno-32-9&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-32-10&#34; name=&#34;__codelineno-32-10&#34; href=&#34;#__codelineno-32-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_PromptTemplate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Template&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Templates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-32-11&#34; name=&#34;__codelineno-32-11&#34; href=&#34;#__codelineno-32-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-32-12&#34; name=&#34;__codelineno-32-12&#34; href=&#34;#__codelineno-32-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Template: %s&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Template&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-32-13&#34; name=&#34;__codelineno-32-13&#34; href=&#34;#__codelineno-32-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-32-14&#34; name=&#34;__codelineno-32-14&#34; href=&#34;#__codelineno-32-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-Utils/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 12 Feb 2026 08:03:39 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-Utils/</guid>
      
    </item>
    
    <item>
      <title>打包</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 插件 AIChatPlus 使用说明 - Package 篇 - Get Started&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;_1&#34;&gt;打包&lt;/h1&gt;
&lt;h2 id=&#34;_2&#34;&gt;插件打包&lt;/h2&gt;
&lt;p&gt;Unreal 打包的时候，会自动把插件需要的动态库文件都打包好，只需要启用插件即可。&lt;/p&gt;
&lt;p&gt;譬如对于 Windows，打包会自动把 llama.cpp, CUDA 相关的 dll 文件都放到打包后的目录中。对于其他平台 Android / Mac / IOS 也是同样的。&lt;/p&gt;
&lt;p&gt;可以在打包后的 Development 版本游戏里面执行指令 &#34;AIChatPlus.PrintCllamaInfo&#34;，查看当前的 Cllama 环境状态，确认是否状态是否正常，是否支持 GPU backend。&lt;/p&gt;
&lt;h2 id=&#34;_3&#34;&gt;模型打包&lt;/h2&gt;
&lt;p&gt;假设加入项目的模型文件放在了目录 Content/LLAMA 下面，那么可以设置打包的时候包含此目录：&lt;/p&gt;
&lt;p&gt;打开 &#34;Project Setting&#34;，选择 Packaging 页签，或者直接搜索 &#34;asset package&#34;，看到设置 &#34;Additional Non-Asset Directories to Package&#34;，添加目录 Content/LLAMA 即可：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/package/getstarted_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;添加目录之后，Unreal 在打包的时候就会自动把目录的所有文件都打包好。&lt;/p&gt;
&lt;h2 id=&#34;_4&#34;&gt;读取打包后的离线模型文件&lt;/h2&gt;
&lt;p&gt;一般 Uneal 会把项目文件都打包到 .Pak 文件中，此时如果把 .Pak 中的文件路径传递给 Cllam 离线模型，是会执行失败的，因为 llama.cpp 无法直接读取 .Pak 中打包后的模型文件。&lt;/p&gt;
&lt;p&gt;因此需要先把 .Pak 中的模型文件复制出来文件系统中，插件提供了一个方便的函数可以直接把 .Pak 的模型文件复制出来，并返回复制后的文件路径，让 Cllama 可以方便读取。&lt;/p&gt;
&lt;p&gt;蓝图节点是 &#34;Cllama Prepare ModelFile In Pak&#34;: 自动把 Pak 中的模型文件复制到文件系统中&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_util_4.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;C++ 代码函数是：&lt;/p&gt;
&lt;div class=&#34;language-text highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;#include &amp;lt;Cllama/AIChatPlusCllama_Util.h&amp;gt;
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34; href=&#34;#__codelineno-0-3&#34;&gt;&lt;/a&gt;auto ModelPath = FAIChatPlusCllama_Util::PrepareModelFileInPak(InContentPath);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Package-GetStarted/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Sun, 09 Mar 2025 15:29:24 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Package-GetStarted/</guid>
      
    </item>
    
    <item>
      <title>版本日志</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 插件 AIChatPlus 版本日志&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;ue-aichatplus&#34;&gt;UE 插件 AIChatPlus 版本日志&lt;/h1&gt;
&lt;h2 id=&#34;v200-20260214&#34;&gt;v2.0.0 - 2026.02.14&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tool Calling 多平台支持&lt;/strong&gt;: 新增 OpenAI、Claude、Gemini、Ollama、CllamaServer 五大平台的工具调用/函数调用功能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cllama Server 集成&lt;/strong&gt;: 完整支持本地 llama.cpp Server，包括创建、管理、Speech-to-Text，并提供编辑器可视化管理界面&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JSON 蓝图库&lt;/strong&gt;: 新增 JsonObject/JsonArray 蓝图操作类，支持 JSON 与 USTRUCT 互转&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OpenAI Audio&lt;/strong&gt;: 支持 OpenAI 音频输入输出，编辑器可预览音频响应&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;v180-20251103&#34;&gt;v1.8.0 - 2025.11.03&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;升级 llama.cpp b6792&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;v170-20250706&#34;&gt;v1.7.0 - 2025.07.06&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;升级 llama.cpp b5536&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;支持 UE5.6&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Android 发布 shipping 会 crash，禁用掉 llama.cpp&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;v162-20250317&#34;&gt;v1.6.2 - 2025.03.17&lt;/h2&gt;
&lt;h3 id=&#34;_1&#34;&gt;新功能&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Cllama 增加 KeepContext 参数，默认 false，Context 在 Chat 结束后自动销毁&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Cllama 增加 KeepAlive 参数，可以减少 model 重复读取&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;v161-20250307&#34;&gt;v1.6.1 - 2025.03.07&lt;/h2&gt;
&lt;h3 id=&#34;bug-fix&#34;&gt;Bug Fix&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;OpenAI Image Chat 蓝图支持输入图片&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Editor Tool Cllama mmproj 模型允许空&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;v160-20250302&#34;&gt;v1.6.0 - 2025.03.02&lt;/h2&gt;
&lt;h3 id=&#34;_2&#34;&gt;新功能&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;llama.cpp 升级至 b4604 版本&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Cllama 支持 GPU backends: cuda 和 metal&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;chat tool Cllama 支持使用 GPU&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;支持读取打包 Pak 中的模型文件&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;bug-fix_1&#34;&gt;Bug Fix&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;修复 Cllama 在推理的时候 reload 会崩溃的问题&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;修复 ios 编译报错&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;v151-20250130&#34;&gt;v1.5.1 - 2025.01.30&lt;/h2&gt;
&lt;h3 id=&#34;_3&#34;&gt;新功能&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;只允许 Gemini 发音频&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;优化获取 PCMData 的方法，生成 B64 的时候再解压缩音频数据&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;request 增加两个回调 OnMessageFinished OnImagesFinished&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;优化 Gemini Method，自动根据 bStream 获取 Method&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;增加一些蓝图函数，方便转换 Wrapper 到实际类型，并且获取 Response Message 和 Error&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;bug-fix_2&#34;&gt;Bug Fix&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;修复 Request Finish 多次调用问题&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;v150-20250129&#34;&gt;v1.5.0 - 2025.01.29&lt;/h2&gt;
&lt;h3 id=&#34;_4&#34;&gt;新功能&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;支持给 Gemini 发音频&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;编辑器工具支持发送音频和录音&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;bug-fix_3&#34;&gt;Bug Fix&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;修复 Session copy 失败的 bug&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;v141-20250104&#34;&gt;v1.4.1 - 2025.01.04&lt;/h2&gt;
&lt;h3 id=&#34;_5&#34;&gt;问题修复&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;聊天工具支持只发图片不发信息&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;修复 OpenAI 接口发送图片问题失败文图&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;修复 OpanAI、Azure 聊天工具设置遗漏了参数 Quality、Style、ApiVersion 问题=&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;v140-20241230&#34;&gt;v1.4.0 - 2024.12.30&lt;/h2&gt;
&lt;h3 id=&#34;_6&#34;&gt;新功能&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;（实验性功能）Cllama(llama.cpp) 支持多模态模型，可以处理图片&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;所有的蓝图类型参数都加上了详细提示&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;v134-20241205&#34;&gt;v1.3.4 - 2024.12.05&lt;/h2&gt;
&lt;h3 id=&#34;_7&#34;&gt;新功能&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;OpenAI 支持 vision api&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;_8&#34;&gt;问题修复&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;修复 OpenAI stream=false 时的错误&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;v133-20241125&#34;&gt;v1.3.3 - 2024.11.25&lt;/h2&gt;
&lt;h3 id=&#34;_9&#34;&gt;新功能&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;支持 UE-5.5&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;_10&#34;&gt;问题修复&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;修复部分蓝图不生效问题&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;v132-20241010&#34;&gt;v1.3.2 - 2024.10.10&lt;/h2&gt;
&lt;h3 id=&#34;_11&#34;&gt;问题修复&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;修复 手动停止 request 的时候 cllama 崩溃&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;修复商城下载版本 win 打包找不到 ggml.dll llama.dll 文件的问题&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;创建请求时检查是否在 GameThread 中，CreateRequest check in game thread&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;v131-2024930&#34;&gt;v1.3.1 - 2024.9.30&lt;/h2&gt;
&lt;h3 id=&#34;_12&#34;&gt;新功能&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;增加一个 SystemTemplateViewer，可以查看和使用几百个 system 设置模版&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;_13&#34;&gt;问题修复&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;修复从商城下载的插件，llama.cpp 找不到链接库&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;修复 LLAMACpp 路径过长问题&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;修复 windows 打包后的链接 llama.dll 错误&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;修复 ios/android 读取文件路径问题&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;修复 Cllame 设置名字错误&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;v130-2024923&#34;&gt;v1.3.0 - 2024.9.23&lt;/h2&gt;
&lt;h3 id=&#34;_14&#34;&gt;重大新功能&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;整合了 llama.cpp，支持本地离线执行大模型&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;v120-20240820&#34;&gt;v1.2.0 - 2024.08.20&lt;/h2&gt;
&lt;h3 id=&#34;_15&#34;&gt;新功能&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;支持 OpenAI Image Edit/Image Variation&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;支持 Ollama API，支持自动获取 Ollama 支持的模型列表&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;v110-20240807&#34;&gt;v1.1.0 - 2024.08.07&lt;/h2&gt;
&lt;h3 id=&#34;_16&#34;&gt;新功能&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;支持蓝图&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;v100-20240805&#34;&gt;v1.0.0 - 2024.08.05&lt;/h2&gt;
&lt;h3 id=&#34;_17&#34;&gt;新功能&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;基础完整功能&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;支持 OpenAI， Azure，Claude，Gemini&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;自带功能完善编辑器聊天工具&lt;/li&gt;
&lt;/ul&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-ChangeLogs/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 06 Mar 2025 17:44:59 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-ChangeLogs/</guid>
      
    </item>
    
    <item>
      <title>Azure</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 插件 AIChatPlus 使用说明 - 蓝图篇 - Azure&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;-azure&#34;&gt;蓝图篇 - Azure&lt;/h1&gt;
&lt;p&gt;&lt;img alt=&#34;blueprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/azure_all.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Azure 的用法跟 OpenAI 也很相似，所以这里简略介绍&lt;/p&gt;
&lt;h2 id=&#34;_1&#34;&gt;文本聊天&lt;/h2&gt;
&lt;p&gt;创建 &#34;Azure Chat Options&#34; 节点，设置参数 &#34;Deployment Name&#34;, &#34;Base Url&#34;, &#34;Api Key&#34;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/azure_chat_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 &#34;Messages&#34; 相关节点，并连接 &#34;Azure Chat Request&#34;，点击运行，即可看到屏幕上打印 Azure 返回的聊天信息。如图&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_azure_blueprint_chat_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_azure_blueprint_chat_2.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_2&#34;&gt;创建图片&lt;/h2&gt;
&lt;p&gt;创建 &#34;Azure Image Options&#34; 节点，设置参数 &#34;Deployment Name&#34;, &#34;Base Url&#34;, &#34;Api Key&#34;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/azure_image_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;设置好 &#34;Azure Image Request&#34; 等节点，点击运行，即可看到屏幕上打印 Azure 返回的聊天信息。如图&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_azure_blueprint_image_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;根据上面蓝图的设置，图片会保存在路径 D:\Dwnloads\butterfly.png&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-Azure/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 06 Mar 2025 17:44:59 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-Azure/</guid>
      
    </item>
    
    <item>
      <title>Claude</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 插件 AIChatPlus 使用说明 - 蓝图篇 - Claude&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;-claude&#34;&gt;蓝图篇 - Claude&lt;/h1&gt;
&lt;p&gt;&lt;img alt=&#34;blueprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/claude_all.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_1&#34;&gt;文本聊天&lt;/h2&gt;
&lt;p&gt;创建 &#34;Options&#34; 节点，设置参数 &#34;Model&#34;, &#34;Api Key&#34;, &#34;Anthropic Version&#34;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/claude_chat_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;连接 &#34;Claude Request&#34; 节点 和 &#34;Messages&#34; 相关节点，点击运行，即可看到屏幕上打印 Claude 返回的聊天信息。如图&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/claude_chat_2.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_2&#34;&gt;图片生成文字&lt;/h2&gt;
&lt;p&gt;Claude 同样支持 Vision 功能&lt;/p&gt;
&lt;p&gt;在蓝图中右键创建一个节点 &lt;code&gt;Send Claude Chat Request&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_claude_blueprint_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 Options 节点，并设置 &lt;code&gt;Stream=true, Api Key=&#34;you api key from Clude&#34;, Max Output Tokens=1024&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_claude_blueprint_2.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 Messages，从文件创建 Texture2D，并从 Texture2D 创建 AIChatPlusTexture，把 AIChatPlusTexture 添加到 Message 中&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_claude_blueprint_3.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Event 并把信息打印到游戏屏幕上&lt;/p&gt;
&lt;p&gt;完整的蓝图看起来是这样的，运行蓝图，即可看到游戏屏幕在打印大模型返回的消息&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_claude_blueprint_4.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_claude_blueprint_5.png&#34; /&gt;&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-Claude/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 06 Mar 2025 17:44:59 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-Claude/</guid>
      
    </item>
    
    <item>
      <title>Cllama (llama.cpp)(已废弃)</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 插件 AIChatPlus 使用说明 - 蓝图篇 - Cllama (llama.cpp)&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;-cllama-llamacpp&#34;&gt;蓝图篇 - Cllama (llama.cpp)(已废弃)&lt;/h1&gt;
&lt;p&gt;&lt;img alt=&#34;blueprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllama_all.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_1&#34;&gt;已废弃&lt;/h2&gt;
&lt;p&gt;Cllama 已经标记为&lt;strong&gt;废弃&lt;/strong&gt;，不再维护。&lt;/p&gt;
&lt;p&gt;Cllama 原有功能由 &lt;a href=&#34;../ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-CllamaServer/&#34;&gt;CllamaServer&lt;/a&gt; 来承载。&lt;/p&gt;
&lt;h2 id=&#34;_2&#34;&gt;离线模型&lt;/h2&gt;
&lt;p&gt;Cllama 是基于 llama.cpp 来实现的，支持离线使用 AI 推理模型。&lt;/p&gt;
&lt;p&gt;由于是离线，因为我们需要先准备好模型文件，譬如从 HuggingFace 网站下载离线模型：&lt;a href=&#34;https://huggingface.co/second-state/Qwen1.5-1.8B-Chat-GGUF/resolve/main/Qwen1.5-1.8B-Chat-Q8_0.gguf&#34;&gt;Qwen1.5-1.8B-Chat-Q8_0.gguf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;把模型放在某个文件夹下面，譬如放在游戏项目的目录 Content/LLAMA 下&lt;/p&gt;
&lt;div class=&#34;language-shell highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;E:/UE/projects/FP_Test1/Content/LLAMA&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ls
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;qwen1.5-1_8b-chat-q8_0.gguf*
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;有了离线模型文件之后，我们就可以通过 Cllama 来进行 AI 聊天&lt;/p&gt;
&lt;h2 id=&#34;_3&#34;&gt;文本聊天&lt;/h2&gt;
&lt;p&gt;使用 Cllama 进行文本聊天&lt;/p&gt;
&lt;p&gt;在蓝图中右键创建一个节点 &lt;code&gt;Send Cllama Chat Request&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_blueprint_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 Options 节点，并设置 &lt;code&gt;Stream=true, ModelPath=&#34;E:\UE\projects\FP_Test1\Content\LLAMA\qwen1.5-1_8b-chat-q8_0.gguf&#34;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_blueprint_2.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_blueprint_3.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 Messages，分别添加一条 System Message 和 User Message&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_blueprint_4.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 Delegate 接受模型输出的信息，并打印在屏幕上&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_blueprint_5.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_blueprint_6.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;完整的蓝图看起来是这样的，运行蓝图，即可看到游戏屏幕在打印大模型返回的消息&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_blueprint_7.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_blueprint_8.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;llava&#34;&gt;图片生成文字 llava&lt;/h2&gt;
&lt;p&gt;Cllama 还实验性支持了 llava 库，提供了 Vision 的能力&lt;/p&gt;
&lt;p&gt;首先准备好 Multimodal 离线模型文件，例如 Moondream （&lt;a href=&#34;https://huggingface.co/vikhyatk/moondream2/blob/main/moondream2-text-model-f16.gguf&#34;&gt;moondream2-text-model-f16.gguf&lt;/a&gt;, &lt;a href=&#34;https://huggingface.co/vikhyatk/moondream2/blob/main/moondream2-mmproj-f16.gguf&#34;&gt;moondream2-mmproj-f16.gguf&lt;/a&gt;）或者 Qwen2-VL（&lt;a href=&#34;https://huggingface.co/bartowski/Qwen2-VL-7B-Instruct-GGUF/resolve/main/Qwen2-VL-7B-Instruct-Q8_0.gguf&#34;&gt;Qwen2-VL-7B-Instruct-Q8_0.gguf&lt;/a&gt;, &lt;a href=&#34;https://huggingface.co/bartowski/Qwen2-VL-7B-Instruct-GGUF/resolve/main/mmproj-Qwen2-VL-7B-Instruct-f16.gguf&#34;&gt;mmproj-Qwen2-VL-7B-Instruct-f16.gguf&lt;/a&gt;）或者其他 llama.cpp 支持的 Multimodal 模型。&lt;/p&gt;
&lt;p&gt;创建 Options 节点，分别设置参数 &#34;Model Path&#34; 和 &#34;MMProject Model Path&#34; 为对应的 Multimodal 模型文件。&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllama_vision_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建节点读取图片文件 flower.png，并设置 Messages&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllama_vision_2.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllama_vision_3.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;最后创建节点接受返回的信息，并打印到屏幕上，完整的蓝图看起来是这样的&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllama_vision_4.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;运行蓝图可看到返回的文字&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/cllama_vision_5.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;llamacpp-gpu&#34;&gt;llama.cpp 使用 GPU&lt;/h2&gt;
&lt;p&gt;&#34;Cllama Chat Request Options&#34; 增加参数 &#34;Num Gpu Layer&#34; ，可以设置 llama.cpp 的 gpu payload，可以控制需要在 GPU 上计算的层数。如图&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_cllama_gpu_1.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;keepalive&#34;&gt;KeepAlive&lt;/h2&gt;
&lt;p&gt;&#34;Cllama Chat Request Options&#34; 增加参数 &#34;KeepAlive&#34;，可以让读取后的模型文件保留在内存中，方便下次直接使用，减少读取模型的次数。KeepAlive 是模型保留的时间，0 表示不保留，使用后立即释放；-1 表示永久保留。每次请求设置的 Options 都可以设置不同的 KeepAlive，新的 KeepAlive 会替代旧的数值，譬如前几次的请求可以设置  KeepAlive=-1，让模型保留在内存中，直到最后一次的请求设置 KeepAlive=0，释放模型文件。&lt;/p&gt;
&lt;h2 id=&#34;pak&#34;&gt;处理打包后 .Pak 中的模型文件&lt;/h2&gt;
&lt;p&gt;开启 Pak 打包后，项目的所有资源文件都会放在 .Pak 文件中，当然也包含了离线模型 gguf 文件。&lt;/p&gt;
&lt;p&gt;由于 llama.cpp 无法支持直接读取 .Pak 文件，因此需要把 .Pak 文件中的离线模型文件拷贝出来文件系统中。&lt;/p&gt;
&lt;p&gt;AIChatPlus 提供了一个功能函数可以自动把 .Pak 中的模型文件拷贝处理，并放在 Saved 文件夹中：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_cllama_gpu_3.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;又或者你可以自己处理 .Pak 中的模型文件，关键就是需要把文件复制出来，因为 llama.cpp 无法正确读取 .Pak。&lt;/p&gt;
&lt;h2 id=&#34;_4&#34;&gt;功能节点&lt;/h2&gt;
&lt;p&gt;Cllama 提供了一些功能节点方便获取当前环境下状态&lt;/p&gt;
&lt;p&gt;&#34;Cllama Is Valid&#34;：判断 Cllama llama.cpp 是否正常初始化&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_util_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&#34;Cllama Is Support Gpu&#34;：判断 llama.cpp 在当前环境下是否支持 GPU backend&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_util_2.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&#34;Cllama Get Support Backends&#34;: 获取当前 llama.cpp 支持的所有 backends&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_util_3.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&#34;Cllama Prepare ModelFile In Pak&#34;: 自动把 Pak 中的模型文件复制到文件系统中&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_util_4.png&#34; /&gt;&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-Cllama/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 06 Mar 2025 17:44:59 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-Cllama/</guid>
      
    </item>
    
    <item>
      <title>DeepSeek</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 插件 AIChatPlus 使用说明 - 蓝图篇 - DeepSeek&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;-deepseek&#34;&gt;蓝图篇 - DeepSeek&lt;/h1&gt;
&lt;p&gt;因为 DeepSeek 兼容了 OpenAI 的 API 接口格式，所以我们可以很简单的使用 OpenAI 相关的节点来访问 DeepSeek，只要把相关的 url 修改成 DeepSeek 的 url 即可&lt;/p&gt;
&lt;h1 id=&#34;_1&#34;&gt;文本聊天&lt;/h1&gt;
&lt;p&gt;创建 &#34;OpenAI Chat Options&#34; 节点，设置好 Model, Url, Api Key 参数&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/deepseek_chat_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;其他设置跟 OpenAI 相同，完整的蓝图看起来像这样：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_deepseek_blueprint_chat_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;运行即可在屏幕看看到 DeepSeek 的返回：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_deepseek_blueprint_chat_2.png&#34; /&gt;&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-DeepSeek/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 06 Mar 2025 17:44:59 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-DeepSeek/</guid>
      
    </item>
    
    <item>
      <title>Gemini</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 插件 AIChatPlus 使用说明 - 蓝图篇 - Gemini&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;-gemini&#34;&gt;蓝图篇 - Gemini&lt;/h1&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/gemini_all.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_1&#34;&gt;文本聊天&lt;/h3&gt;
&lt;p&gt;创建 &#34;Gemini Chat Options&#34; 节点，设置参数 &#34;Model&#34;, &#34;Api Key&#34;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/gemini_chat_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 &#34;Gemini Chat Request&#34; 节点，并连接 &#34;Options&#34; 和 &#34;Messages&#34; 节点，点击运行，即可看到屏幕上打印 Gemini 返回的聊天信息，如图：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_gemini_blueprint_chat_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_gemini_blueprint_chat_2.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_2&#34;&gt;图片生成文字&lt;/h3&gt;
&lt;p&gt;同样创建 &#34;Gemini Chat Options&#34; 节点，设置参数 &#34;Model&#34;, &#34;Api Key&#34;&lt;/p&gt;
&lt;p&gt;从文件读取图片 flower.png，并设置到 &#34;Messages&#34; 上&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;flower.png&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/gemini_vision_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 &#34;Gemini Chat Request&#34; 节点，点击运行，即可看到屏幕上打印 Gemini 返回的聊天信息，如图：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/gemini_vision_2.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_3&#34;&gt;音频生成文字&lt;/h3&gt;
&lt;p&gt;Gemini 支持把音频转成文字&lt;/p&gt;
&lt;p&gt;创建如下蓝图，设置加载音频，设置好 Gemini Options，点击运行，即可看到屏幕上打印 Gemini 处理音频后返回的聊天信息&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_gemini_blueprint_sound_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_gemini_blueprint_sound_2.png&#34; /&gt;&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-Gemini/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 06 Mar 2025 17:44:59 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-Gemini/</guid>
      
    </item>
    
    <item>
      <title>Get Started</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 插件 AIChatPlus 使用说明 - 蓝图篇 - Get Started&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;-get-started&#34;&gt;蓝图篇 - Get Started&lt;/h1&gt;
&lt;p&gt;&lt;img alt=&#34;blueprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/blueprint.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;get-started&#34;&gt;Get Started&lt;/h2&gt;
&lt;p&gt;下面以 OpenAI 为例，介绍蓝图的基本使用方法&lt;/p&gt;
&lt;h3 id=&#34;_1&#34;&gt;文本聊天&lt;/h3&gt;
&lt;p&gt;使用 OpenAI 进行文本聊天&lt;/p&gt;
&lt;p&gt;在蓝图中右键创建一个节点 &lt;code&gt;Send OpenAI Chat Request In World&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_blueprint_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 Options 节点，并设置 &lt;code&gt;Stream=true, Api Key=&#34;you api key from OpenAI&#34;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_blueprint_2.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 Messages，分别添加一条 System Message 和 User Message&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_blueprint_4.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 Delegate 接受模型输出的信息，并打印在屏幕上&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_blueprint_5.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_blueprint_6.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;完整的蓝图看起来是这样的，运行蓝图，即可看到游戏屏幕在打印大模型返回的消息&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_blueprint_3.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_blueprint_4.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_2&#34;&gt;本文生成图片&lt;/h3&gt;
&lt;p&gt;使用 OpenAI 创建图片&lt;/p&gt;
&lt;p&gt;在蓝图中右键创建一个节点 &lt;code&gt;Send OpenAI Image Request&lt;/code&gt;，并设置 &lt;code&gt;In Prompt=&#34;a beautiful butterfly&#34;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_image_blueprint_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 Options 节点，并设置 &lt;code&gt;Api Key=&#34;you api key from OpenAI&#34;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_image_blueprint_2.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;绑定 On Images 事件，并把图片保存到本地硬盘上&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_image_blueprint_3.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;完整的蓝图看起来是这样的，运行蓝图，即可看到图片保存在指定的位置上&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_image_blueprint_4.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_image_blueprint_5.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_3&#34;&gt;图片生成文字&lt;/h3&gt;
&lt;p&gt;使用 OpenAI Vision 分析图片&lt;/p&gt;
&lt;p&gt;在蓝图中右键创建一个节点 &lt;code&gt;Send OpenAI Image Request&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/getstarted_vision_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 Options 节点，并设置 &lt;code&gt;Api Key=&#34;you api key from OpenAI&#34;&lt;/code&gt;，设置模型为 &lt;code&gt;gpt-4o-mini&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/getstarted_vision_2.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 Messages。
* 先创建节点 &#34;Import File as Texture 2D&#34; 从文件系统读取一张图片；
* 通过节点 &#34;Create AIChatPlus Texture From Texture2D&#34; 把图片转换成插件可用的对象；
* 通过 &#34;Make Array&#34; 节点把图片连接到节点 &#34;AIChatPlus_ChatRequestMessage&#34; 的 &#34;Images&#34; 字段上；
* 设置 &#34;Content&#34; 字段内容为 &#34;describe this image&#34;。&lt;/p&gt;
&lt;p&gt;如图：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/getstarted_vision_3.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;完整的蓝图看起来是这样的，运行蓝图，即可看到结果显示在屏幕上&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/getstarted_vision_4.png&#34; /&gt;&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-GetStarted/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 06 Mar 2025 17:44:59 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-GetStarted/</guid>
      
    </item>
    
    <item>
      <title>Ollama</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 插件 AIChatPlus 使用说明 - 蓝图篇 - Ollama&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;-ollama&#34;&gt;蓝图篇 - Ollama&lt;/h1&gt;
&lt;p&gt;&lt;img alt=&#34;blueprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/ollama_all.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;ollama&#34;&gt;获取 Ollama&lt;/h2&gt;
&lt;p&gt;可以通过 Ollama 官网获取安装包本地安装：&lt;a href=&#34;https://ollama.com/&#34;&gt;ollama.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;可以通过其他人提供的 Ollama API 接口使用 Ollama。&lt;/p&gt;
&lt;p&gt;本地使用 Ollama 下载模型：&lt;/p&gt;
&lt;div class=&#34;language-shell highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ollama&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;run&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;qwen:latest
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ollama&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;run&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;moondream:latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;_1&#34;&gt;文本聊天&lt;/h2&gt;
&lt;p&gt;创建 &#34;Ollama Options&#34; 节点，设置参数 &#34;Model&#34;, &#34;Base Url&#34;，如果是本地运行的 Ollama，则 &#34;Base Url&#34; 一般是 &#34;http://localhost:11434&#34;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/ollama_chat_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;连接 &#34;Ollama Request&#34; 节点 和 &#34;Messages&#34; 相关节点，点击运行，即可看到屏幕上打印 Ollama 返回的聊天信息。如图&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_ollama_blueprint_chat_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_ollama_blueprint_chat_2.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;llava&#34;&gt;图片生成文字 llava&lt;/h2&gt;
&lt;p&gt;Ollama 同样支持了 llava 库，提供了 Vision 的能力&lt;/p&gt;
&lt;p&gt;首先获取 Multimodal 模型文件：&lt;/p&gt;
&lt;div class=&#34;language-shell highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ollama&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;run&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;moondream:latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;设置 &#34;Options&#34; 节点，&#34;Model&#34; 设置为 moondream:latest&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/ollama_vision_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;读取图片 flower.png，并设置 Message&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;flower.png&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/ollama_vision_2.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/ollama_vision_3.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;连接 &#34;Ollama Request&#34; 节点，点击运行，即可看到屏幕上打印 Ollama 返回的聊天信息。如图&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/ollama_vision_4.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/ollama_vision_5.png&#34; /&gt;&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-Ollama/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 06 Mar 2025 17:44:59 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-Ollama/</guid>
      
    </item>
    
    <item>
      <title>OpenAI</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 插件 AIChatPlus 使用说明 - 蓝图篇 - OpenAI&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;-openai&#34;&gt;蓝图篇 - OpenAI&lt;/h1&gt;
&lt;p&gt;&lt;img alt=&#34;blueprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/openai_all.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;在 &lt;a href=&#34;../ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-GetStarted/&#34;&gt;Get Started&lt;/a&gt; 章节已经介绍过 OpenAI 的基本用法，我们在这里再给出详细的用法。&lt;/p&gt;
&lt;h2 id=&#34;_1&#34;&gt;文本聊天&lt;/h2&gt;
&lt;p&gt;使用 OpenAI 进行文本聊天&lt;/p&gt;
&lt;p&gt;在蓝图中右键创建一个节点 &lt;code&gt;Send OpenAI Chat Request In World&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_blueprint_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 Options 节点，并设置 &lt;code&gt;Stream=true, Api Key=&#34;you api key from OpenAI&#34;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_blueprint_2.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 Messages，分别添加一条 System Message 和 User Message&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_blueprint_4.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 Delegate 接受模型输出的信息，并打印在屏幕上&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_blueprint_5.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_blueprint_6.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;完整的蓝图看起来是这样的，运行蓝图，即可看到游戏屏幕在打印大模型返回的消息&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_blueprint_3.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_blueprint_4.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_2&#34;&gt;本文生成图片&lt;/h2&gt;
&lt;p&gt;使用 OpenAI 创建图片&lt;/p&gt;
&lt;p&gt;在蓝图中右键创建一个节点 &lt;code&gt;Send OpenAI Image Request&lt;/code&gt;，并设置 &lt;code&gt;In Prompt=&#34;a beautiful butterfly&#34;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_image_blueprint_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 Options 节点，并设置 &lt;code&gt;Api Key=&#34;you api key from OpenAI&#34;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_image_blueprint_2.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;绑定 On Images 事件，并把图片保存到本地硬盘上&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_image_blueprint_3.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;完整的蓝图看起来是这样的，运行蓝图，即可看到图片保存在指定的位置上&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_image_blueprint_4.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_image_blueprint_5.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_3&#34;&gt;图片生成文字&lt;/h2&gt;
&lt;p&gt;使用 OpenAI Vision 分析图片&lt;/p&gt;
&lt;p&gt;在蓝图中右键创建一个节点 &lt;code&gt;Send OpenAI Image Request&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/getstarted_vision_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 Options 节点，并设置 &lt;code&gt;Api Key=&#34;you api key from OpenAI&#34;&lt;/code&gt;，设置模型为 &lt;code&gt;gpt-4o-mini&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/getstarted_vision_2.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 Messages。
* 先创建节点 &#34;Import File as Texture 2D&#34; 从文件系统读取一张图片；
* 通过节点 &#34;Create AIChatPlus Texture From Texture2D&#34; 把图片转换成插件可用的对象；
* 通过 &#34;Make Array&#34; 节点把图片连接到节点 &#34;AIChatPlus_ChatRequestMessage&#34; 的 &#34;Images&#34; 字段上；
* 设置 &#34;Content&#34; 字段内容为 &#34;describe this image&#34;。&lt;/p&gt;
&lt;p&gt;如图：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/getstarted_vision_3.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;完整的蓝图看起来是这样的，运行蓝图，即可看到结果显示在屏幕上&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/getstarted_vision_4.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_4&#34;&gt;修改图片&lt;/h2&gt;
&lt;p&gt;OpenAI 支持对图片标记的区域进行修改&lt;/p&gt;
&lt;p&gt;首先准备两张图片&lt;/p&gt;
&lt;p&gt;一张是需要修改的图片 src.png&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/openai_image_edit_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;一张是把需要修改的区域标记出来的图片 mask.png，可以通过修改源图片，把修改区域的透明度设置成 0，即 Alpha 通道数值改成 0&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/openai_image_edit_2.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;分别读取以上两张照片，组合成数组&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/openai_image_edit_3.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 &#34;OpenAI Image Options&#34; 节点，设置 ChatType = Edit，并修改 &#34;End Point Url&#34; = v1/images/edits&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/openai_image_edit_4.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 &#34;OpenAI Image Request&#34;，设置 &#34;Prompt&#34; 为 &#34;change into two butterfly&#34;，连接 &#34;Options&#34; 节点 和 图片数组，并把生成的图片保存到文件系统中。&lt;/p&gt;
&lt;p&gt;完整的蓝图看起来是这样的：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/openai_image_edit_5.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;运行蓝图，生成的图片保存在指定的位置上&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/openai_image_edit_6.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_5&#34;&gt;图片变种&lt;/h2&gt;
&lt;p&gt;OpenAI 支持根据输入的图片生成类似的变种 (Variation)&lt;/p&gt;
&lt;p&gt;首先还是准备一张图片 src.png，并在蓝图中读取进来&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/openai_image_edit_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/openai_image_variation_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 &#34;OpenAI Image Options&#34; 节点，设置 ChatType = Variation，并修改 &#34;End Point Url&#34; = v1/images/variations&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/openai_image_variation_2.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建 &#34;OpenAI Image Request&#34;，保留 &#34;Prompt&#34; 为空，连接 &#34;Options&#34; 节点 和 图片，并把生成的图片保存到文件系统中。&lt;/p&gt;
&lt;p&gt;完整的蓝图看起来是这样的：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/openai_image_variation_3.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;运行蓝图，生成的图片保存在指定的位置上&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/usage/blueprint/openai_image_variation_4.png&#34; /&gt;&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-OpenAI/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 06 Mar 2025 17:44:59 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-OpenAI/</guid>
      
    </item>
    
    <item>
      <title>功能节点</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 插件 AIChatPlus 使用说明 - 蓝图篇 - 功能节点&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;-&#34;&gt;蓝图篇 - 功能节点&lt;/h1&gt;
&lt;p&gt;插件额外提供了一些便利的蓝图功能节点&lt;/p&gt;
&lt;h2 id=&#34;cllama&#34;&gt;Cllama 相关&lt;/h2&gt;
&lt;p&gt;&#34;Cllama Is Valid&#34;：判断 Cllama llama.cpp 是否正常初始化&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_util_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&#34;Cllama Is Support Gpu&#34;：判断 llama.cpp 在当前环境下是否支持 GPU backend&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_util_2.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&#34;Cllama Get Support Backends&#34;: 获取当前 llama.cpp 支持的所有 backends&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_util_3.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&#34;Cllama Prepare ModelFile In Pak&#34;: 自动把 Pak 中的模型文件复制到文件系统中&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_util_4.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_1&#34;&gt;图像相关&lt;/h2&gt;
&lt;p&gt;&#34;Convert UTexture2D to Base64&#34;: 把 UTexture2D 的图像转成 png base64 格式&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_util_5.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&#34;Save UTexture2D to .png file&#34;: 把 UTexture2D 保存成 png 文件&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_util_6.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&#34;Load .png file to UTexture2D&#34;: 读取 png 文件为 UTexture2D&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_util_7.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&#34;Duplicate UTexture2D&#34;: 复制 UTexture2D&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_util_8.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_2&#34;&gt;音频相关&lt;/h2&gt;
&lt;p&gt;&#34;Load .wav file to USoundWave&#34;: 读取 wav 文件为 USoundWave&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_util_9.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&#34;Convert .wav data to USoundWave&#34;: 把 wav 二进制数据转成 USoundWave&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_util_10.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&#34;Save USoundWave to .wav file&#34;: 把 USoundWave 保存为 .wav 文件&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_util_11.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&#34;Get USoundWave Raw PCM Data&#34;: 把 USoundWave 转成二进制音频数据&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_util_12.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&#34;Convert USoundWave to Base64&#34;: 把 USoundWave 转成 Base64 数据&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_util_13.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&#34;Duplicate USoundWave&#34;: 复制 USoundWave&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_util_14.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&#34;Convert Audio Capture Data to USoundWave&#34;: 把 Audio Capture 录音数据转成 USoundWave&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_util_15.png&#34; /&gt;&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-Utils/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 06 Mar 2025 17:44:59 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-Utils/</guid>
      
    </item>
    
    <item>
      <title>Get Started</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 插件 AIChatPlus 使用说明 - 编辑器篇 - Get Started&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;-get-started&#34;&gt;编辑器篇 - Get Started&lt;/h1&gt;
&lt;h2 id=&#34;_1&#34;&gt;编辑器聊天工具&lt;/h2&gt;
&lt;p&gt;菜单栏 Tools -&amp;gt; AIChatPlus -&amp;gt; AIChat 可打开插件提供的编辑器聊天工具&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-aichatplus/chat_tool3.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;工具支持文本生成、文本聊天、图像生成，图像分析。&lt;/p&gt;
&lt;p&gt;工具的界面大致为：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;text chat&#34; src=&#34;../assets/img/2024-ue-aichatplus/chat_tool2.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;image chat&#34; src=&#34;../assets/img/2024-ue-aichatplus/chat_tool.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_2&#34;&gt;主要功能&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;离线大模型&lt;/strong&gt;：整合了 llama.cpp 库，支持本地离线执行大模型&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;文本聊天&lt;/strong&gt;：点击左下角的 &lt;code&gt;New Chat&lt;/code&gt; 按钮，创建新的文本聊天会话。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;图像生成&lt;/strong&gt;：点击左下角的 &lt;code&gt;New Image Chat&lt;/code&gt; 按钮，创建新的图像生成会话。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;图像分析&lt;/strong&gt;：&lt;code&gt;New Chat&lt;/code&gt; 的部分聊天服务支持发送图像，例如 Claude, Google Gemini。点击输入框上方的 🖼️ 或 🎨 按钮即可加载需要发送的图像。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;音频处理&lt;/strong&gt;：工具提供读取音频文件 (.wav) 和 录音功能，可以使用获得的音频跟 AI 聊天。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;设置当前聊天角色&lt;/strong&gt;：聊天框上方的下拉框可以设置当前发送文本的角色，可以通过模拟不同的角色来调节 AI 聊天。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;清空会话&lt;/strong&gt;：聊天框上方的 ❌ 按可以清空当前会话的历史消息。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;对话模版&lt;/strong&gt;：内置几百种对话设置模版，方便处理常用的问题。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;全局设置&lt;/strong&gt;：点击左下角的 &lt;code&gt;Setting&lt;/code&gt; 按钮，可以打开全局设置窗口。可以设置默认文本聊天，图像生成的 API 服务，并设置每种 API 服务的具体参数。设置会自动保存在项目的路径 &lt;code&gt;$(ProjectFolder)/Saved/AIChatPlusEditor&lt;/code&gt; 下。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;会话设置&lt;/strong&gt;：点击聊天框上方的设置按钮，可以打开当前会话的设置窗口。支持修改会话名字，修改会话使用的 API 服务，支持独立设置每个会话使用 API 的具体参数。会话设置自动保存在 &lt;code&gt;$(ProjectFolder)/Saved/AIChatPlusEditor/Sessions&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;聊天内容修改&lt;/strong&gt;：鼠标悬停在聊天内容上，会出现当个聊天内容的设置按钮，支持重新生成内容、修改内容、复制内容、删除内容、在下方重新生成内容（对于角色是用户的内容）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;图像浏览&lt;/strong&gt;：对于图像生成，点击图像会打开图像查看窗口 (ImageViewer) ，支持图片另存为 PNG/UE Texture，Texture 可以直接在内容浏览器 (Content Browser) 查看，方便图片在编辑器内使用。另外还支持删除图片、重新生成图片、继续生成更多图片等功能。对于 Windows 下的编辑器，还支持复制图片，可以直接把图片复制到剪贴板，方便使用。会话生成的图片也会自动保存在每个会话文件夹下面，通常路径是 &lt;code&gt;$(ProjectFolder)/Saved/AIChatPlusEditor/Sessions/${GUID}/images&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;全局设置：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;global settings&#34; src=&#34;../assets/img/2024-ue-aichatplus/global_setting.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;会话设置：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;session settings&#34; src=&#34;../assets/img/2024-ue-aichatplus/session_setting.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;修改聊天内容：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;chat edit&#34; src=&#34;../assets/img/2024-ue-aichatplus/chat_edit.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;图像查看器：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;image viewer&#34; src=&#34;../assets/img/2024-ue-aichatplus/image_viewer.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;使用离线大模型&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;offline model&#34; src=&#34;../assets/img/2024-ue-aichatplus/offline_model.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;对话模版&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;system template&#34; src=&#34;../assets/img/2024-ue-aichatplus/system_template.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;cllamallamacpp&#34;&gt;编辑器工具使用离线模型 Cllama(llama.cpp)&lt;/h2&gt;
&lt;p&gt;以下说明如何在 AIChatPlus 编辑器工具中使用离线模型 llama.cpp&lt;/p&gt;
&lt;p&gt;首先，从 HuggingFace 网站下载离线模型：&lt;a href=&#34;https://huggingface.co/second-state/Qwen1.5-1.8B-Chat-GGUF/resolve/main/Qwen1.5-1.8B-Chat-Q8_0.gguf&#34;&gt;Qwen1.5-1.8B-Chat-Q8_0.gguf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;把模型放在某个文件夹下面，譬如放在游戏项目的目录 Content/LLAMA 下&lt;/p&gt;
&lt;div class=&#34;language-shell highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;E:/UE/projects/FP_Test1/Content/LLAMA
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ls
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34; href=&#34;#__codelineno-0-3&#34;&gt;&lt;/a&gt;qwen1.5-1_8b-chat-q8_0.gguf*
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;打开 AIChatPlus 编辑器工具：Tools -&amp;gt; AIChatPlus -&amp;gt; AIChat，新建聊天会话，并打开会话设置页面&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide editor&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_editor_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;设置 Api 为 Cllama，开启 Custom Api Settings， 并添加模型搜索路径，并选择模型&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide editor&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_editor_2.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;开始聊天！！&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide editor&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_editor_3.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;cllamallamacpp_1&#34;&gt;编辑器工具使用离线模型 Cllama(llama.cpp) 处理图片&lt;/h2&gt;
&lt;p&gt;从 HuggingFace 网站下载离线模型 MobileVLM_V2-1.7B-GGUF 同样放到目录 Content/LLAMA 下：&lt;a href=&#34;https://huggingface.co/ZiangWu/MobileVLM_V2-1.7B-GGUF/resolve/main/ggml-model-q4_k.gguf&#34;&gt;ggml-model-q4_k.gguf&lt;/a&gt; 和 &lt;a href=&#34;https://huggingface.co/ZiangWu/MobileVLM_V2-1.7B-GGUF/resolve/main/mmproj-model-f16.gguf&#34;&gt;mmproj-model-f16.gguf&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;设置会话的模型：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide editor&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_cllama_vision_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;发送图片开始聊天&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide editor&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_cllama_vision_2.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;openai&#34;&gt;编辑器使用 OpenAI 聊天&lt;/h2&gt;
&lt;p&gt;打开聊天工具 Tools -&amp;gt; AIChatPlus -&amp;gt; AIChat，创建新的聊天会话 New Chat，设置会话 ChatApi 为 OpenAI, 设置接口参数&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_tool_chat_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;开始聊天：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_tool_chat_2.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;切换模型为 gpt-4o / gpt-4o-mini，可以使用 OpenAI 的视觉功能分析图片&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_tool_chat_3.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;openai_1&#34;&gt;编辑器使用 OpenAI 处理图片（创建/修改/变种）&lt;/h2&gt;
&lt;p&gt;在聊天工具中创建新的图片会话 New Image Chat，修改会话设置为 OpenAI，并设置参数&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_tool_image_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;创建图片&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_tool_image_2.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;修改图片，把会话 Image Chat Type 修改为 Edit，并上传两张图片，一张是原图片，一张是 mask 其中透明的位置（alpha 通道为 0）表示需要修改的地方&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_tool_image_3.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_tool_image_4.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;图片变种，把会话 Image Chat Type 修改为 Variation，并上传一张图片，OpenAI 会返回一张原图片的变种&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_openai_tool_image_5.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;azure&#34;&gt;编辑器使用 Azure&lt;/h2&gt;
&lt;p&gt;新建会话（New Chat），把 ChatApi 改为 Azure，并设置 Azure 的 Api 参数&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_azure_tool_chat_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;开始聊天&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_azure_tool_chat_2.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;azure_1&#34;&gt;编辑器使用 Azure 创建图片&lt;/h2&gt;
&lt;p&gt;新建图片会话（New Image Chat），把 ChatApi 改为Azure，并设置 Azure 的 Api 参数，注意，如果是 dall-e-2 模型，需要把参数 Quality 和 Stype 设置成 not_use&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_azure_tool_image_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;开始聊天，让 Azure 创建图片&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_azure_tool_image_2.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;claude&#34;&gt;编辑器使用 Claude 聊天和分析图片&lt;/h2&gt;
&lt;p&gt;新建会话（New Chat），把 ChatApi 改为 Claude，并设置 Claude 的 Api 参数&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_claude_tool_chat_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;开始聊天&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_claude_tool_chat_2.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;ollama&#34;&gt;编辑器使用 Ollama 聊天和分析图片&lt;/h2&gt;
&lt;p&gt;新建会话（New Chat），把 ChatApi 改为 Ollama，并设置 Ollama 的 Api 参数。如果是文本聊天，则设置模型为文本模型，如 llama3.1；如果需要处理图片，则设置模型为支持 vision 的模型，例如 moondream。&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_ollama_tool_chat_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;开始聊天&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_ollama_tool_chat_2.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;gemini&#34;&gt;编辑器使用 Gemini&lt;/h3&gt;
&lt;p&gt;新建会话（New Chat），把 ChatApi 改为 Gemini，并设置 Gemini 的 Api 参数。&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_gemini_tool_chat_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;开始聊天&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_gemini_tool_chat_2.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;gemini_1&#34;&gt;编辑器使用 Gemini 发送音频&lt;/h2&gt;
&lt;p&gt;选择 从文件读取音频 / 从 Asset 读取音频 / 从麦克风录取音频，生成需要发送的音频&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_gemini_tool_sound_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;开始聊天&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_gemini_tool_sound_2.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;deepseek&#34;&gt;編輯器使用 Deepseek&lt;/h2&gt;
&lt;p&gt;新建会话（New Chat），把 ChatApi 改为 OpenAi，并设置 Deepseek 的 Api 参数。新增 Candidate Models 叫做 deepseek-chat，并把 Model 设置为 deepseek-chat&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_deepseek_tool_chat_1.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;开始聊天&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;guide bludprint&#34; src=&#34;../assets/img/2024-ue-aichatplus/guide_deepseek_tool_chat_2.png&#34; /&gt;&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-EditorTool-GetStarted/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 06 Mar 2025 17:44:59 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-EditorTool-GetStarted/</guid>
      
    </item>
    
    <item>
      <title>Get Started</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 插件 AIChatPlus 使用说明 - C++ 篇 - Get Started&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;c-get-started&#34;&gt;C++ 篇 - Get Started&lt;/h1&gt;
&lt;h2 id=&#34;_1&#34;&gt;模块介绍&lt;/h2&gt;
&lt;p&gt;插件分成以下几个模块：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AIChatPlusCommon&lt;/strong&gt;: 运行时模块 (Runtime)，负责处理各种 AI API 接口发送请求和解析回复内容。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AIChatPlusEditor&lt;/strong&gt;: 编辑器模块 (Editor)，负责实现编辑器 AI 聊天工具。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AIChatPlusCllama&lt;/strong&gt;: 运行时模块 (Runtime)，负责封装 llama.cpp 的接口和参数，实现离线执行大模型。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Thirdparty/LLAMACpp&lt;/strong&gt;: 运行时第三方模块 (Runtime)，整合了 llama.cpp 的动态库和头文件。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;_2&#34;&gt;核心概念&lt;/h2&gt;
&lt;p&gt;在使用源码之前，需要了解几个核心类及其关系：&lt;/p&gt;
&lt;h3 id=&#34;request&#34;&gt;Request（请求）&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;UAIChatPlus_ChatRequestBase&lt;/code&gt; 是所有聊天请求的基类。每种 API Provider 都有对应的子类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;UAIChatPlus_OpenAIChatRequest&lt;/code&gt; - OpenAI 聊天请求&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UAIChatPlus_AzureChatRequest&lt;/code&gt; - Azure 聊天请求&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UAIChatPlus_ClaudeChatRequest&lt;/code&gt; - Claude 聊天请求&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UAIChatPlus_GeminiChatRequest&lt;/code&gt; - Gemini 聊天请求&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UAIChatPlus_OllamaChatRequest&lt;/code&gt; - Ollama 聊天请求&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UAIChatPlus_CllamaChatRequest&lt;/code&gt; - Cllama 离线模型请求&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UAIChatPlus_CllamaServerChatRequest&lt;/code&gt; - CllamaServer 本地服务器请求&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Request 对象负责配置请求参数、发送请求、接收回调。&lt;/p&gt;
&lt;h3 id=&#34;handler&#34;&gt;Handler（处理器）&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;UAIChatPlus_ChatHandlerBase&lt;/code&gt; 是一个可选的处理器类，用于统一管理请求的回调。&lt;/p&gt;
&lt;p&gt;Handler 提供了以下委托：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;OnStarted&lt;/code&gt; - 请求开始时触发&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OnMessage&lt;/code&gt; - 收到流式消息时触发（流式输出）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OnUpdated&lt;/code&gt; - 收到更新时触发&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OnFinished&lt;/code&gt; - 请求完成时触发&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OnFailed&lt;/code&gt; - 请求失败时触发&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;何时使用 Handler？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;需要将多个请求的回调逻辑统一管理时&lt;/li&gt;
&lt;li&gt;需要在蓝图和 C++ 之间共享回调逻辑时&lt;/li&gt;
&lt;li&gt;直接使用 Request 的委托（如 &lt;code&gt;OnStartedListeners&lt;/code&gt;）同样可以实现回调监听&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;options&#34;&gt;Options（选项）&lt;/h3&gt;
&lt;p&gt;每种 API Provider 都有对应的 Options 结构体，用于配置 API 参数：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;FAIChatPlus_OpenAIChatRequestOptions&lt;/code&gt; - OpenAI 选项（ApiKey、Model、Temperature 等）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FAIChatPlus_ClaudeChatRequestOptions&lt;/code&gt; - Claude 选项&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FAIChatPlus_GeminiChatRequestOptions&lt;/code&gt; - Gemini 选项&lt;/li&gt;
&lt;li&gt;等等...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Options 包含了 API 连接所需的所有配置，如 API Key、端点 URL、模型名称、生成参数等。&lt;/p&gt;
&lt;h3 id=&#34;messages&#34;&gt;Messages（消息）&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;FAIChatPlus_ChatRequestMessage&lt;/code&gt; 是发送给 AI 的消息结构体，包含：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Content&lt;/code&gt; - 文本内容&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Role&lt;/code&gt; - 消息角色（System/User/Assistant/Developer/Tool）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Images&lt;/code&gt; - 图片数组（Vision 功能）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Audios&lt;/code&gt; - 音频数组（Audio 功能）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ToolCallUses&lt;/code&gt; - 工具调用请求&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ToolCallResults&lt;/code&gt; - 工具调用结果&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;response&#34;&gt;Response（响应）&lt;/h3&gt;
&lt;p&gt;每种 API Provider 都有对应的 ResponseBody 结构体：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;FAIChatPlus_OpenAIChatResponseBody&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FAIChatPlus_ClaudeChatResponseBody&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;等等...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ResponseBody 包含了 AI 返回的全部信息，包括：消息文本、Token 用量、工具调用、音频输出等。&lt;/p&gt;
&lt;h2 id=&#34;5&#34;&gt;基础使用流程（5 步模式）&lt;/h2&gt;
&lt;p&gt;使用 AIChatPlus 发送请求的基本流程如下：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;quot;Common_OpenAI/AIChatPlus_OpenAIChatRequest.h&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34; href=&#34;#__codelineno-0-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;SendChatRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-4&#34; name=&#34;__codelineno-0-4&#34; href=&#34;#__codelineno-0-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-5&#34; name=&#34;__codelineno-0-5&#34; href=&#34;#__codelineno-0-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ===== 步骤 1: 创建 Handler（可选）=====&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-6&#34; name=&#34;__codelineno-0-6&#34; href=&#34;#__codelineno-0-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Handler 用于统一管理回调，也可以直接使用 Request 的委托&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-7&#34; name=&#34;__codelineno-0-7&#34; href=&#34;#__codelineno-0-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TWeakObjectPtr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_ChatHandlerBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Handler&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_ChatHandlerBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;New&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-8&#34; name=&#34;__codelineno-0-8&#34; href=&#34;#__codelineno-0-8&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-9&#34; name=&#34;__codelineno-0-9&#34; href=&#34;#__codelineno-0-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ===== 步骤 2: 配置 Options =====&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-10&#34; name=&#34;__codelineno-0-10&#34; href=&#34;#__codelineno-0-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_OpenAIChatRequestOptions&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-11&#34; name=&#34;__codelineno-0-11&#34; href=&#34;#__codelineno-0-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ApiKey&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;your-api-key&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-12&#34; name=&#34;__codelineno-0-12&#34; href=&#34;#__codelineno-0-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Model&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;gpt-4o-mini&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-13&#34; name=&#34;__codelineno-0-13&#34; href=&#34;#__codelineno-0-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bStream&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 启用流式输出&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-14&#34; name=&#34;__codelineno-0-14&#34; href=&#34;#__codelineno-0-14&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-15&#34; name=&#34;__codelineno-0-15&#34; href=&#34;#__codelineno-0-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ===== 步骤 3: 创建 Request =====&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-16&#34; name=&#34;__codelineno-0-16&#34; href=&#34;#__codelineno-0-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_ChatRequestMessage&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Messages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-17&#34; name=&#34;__codelineno-0-17&#34; href=&#34;#__codelineno-0-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Messages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;You are a helpful assistant.&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EAIChatPlus_ChatRole&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;System&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-18&#34; name=&#34;__codelineno-0-18&#34; href=&#34;#__codelineno-0-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Messages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Hello, who are you?&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EAIChatPlus_ChatRole&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;User&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-19&#34; name=&#34;__codelineno-0-19&#34; href=&#34;#__codelineno-0-19&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-20&#34; name=&#34;__codelineno-0-20&#34; href=&#34;#__codelineno-0-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_OpenAIChatRequest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateWithOptionsAndMessages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Messages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-21&#34; name=&#34;__codelineno-0-21&#34; href=&#34;#__codelineno-0-21&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-22&#34; name=&#34;__codelineno-0-22&#34; href=&#34;#__codelineno-0-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ===== 步骤 4: 绑定回调 =====&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-23&#34; name=&#34;__codelineno-0-23&#34; href=&#34;#__codelineno-0-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 方式 A: 使用 Handler&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-24&#34; name=&#34;__codelineno-0-24&#34; href=&#34;#__codelineno-0-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Handler&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BindChatRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-25&#34; name=&#34;__codelineno-0-25&#34; href=&#34;#__codelineno-0-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Handler&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OnMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([](&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-26&#34; name=&#34;__codelineno-0-26&#34; href=&#34;#__codelineno-0-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-27&#34; name=&#34;__codelineno-0-27&#34; href=&#34;#__codelineno-0-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Stream Message: %s&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-28&#34; name=&#34;__codelineno-0-28&#34; href=&#34;#__codelineno-0-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-29&#34; name=&#34;__codelineno-0-29&#34; href=&#34;#__codelineno-0-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Handler&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OnFinished&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([](&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_ChatResponseBodyBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-30&#34; name=&#34;__codelineno-0-30&#34; href=&#34;#__codelineno-0-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-31&#34; name=&#34;__codelineno-0-31&#34; href=&#34;#__codelineno-0-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Request Finished&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-32&#34; name=&#34;__codelineno-0-32&#34; href=&#34;#__codelineno-0-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-33&#34; name=&#34;__codelineno-0-33&#34; href=&#34;#__codelineno-0-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Handler&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OnFailed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([](&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_ResponseErrorBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-34&#34; name=&#34;__codelineno-0-34&#34; href=&#34;#__codelineno-0-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-35&#34; name=&#34;__codelineno-0-35&#34; href=&#34;#__codelineno-0-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Request Failed: %s&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetDescription&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-36&#34; name=&#34;__codelineno-0-36&#34; href=&#34;#__codelineno-0-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-37&#34; name=&#34;__codelineno-0-37&#34; href=&#34;#__codelineno-0-37&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-38&#34; name=&#34;__codelineno-0-38&#34; href=&#34;#__codelineno-0-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 方式 B: 直接使用 Request 的委托（不需要 Handler）&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-39&#34; name=&#34;__codelineno-0-39&#34; href=&#34;#__codelineno-0-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Request-&amp;gt;OnMessageListeners.AddDynamic(this, &amp;amp;UMyClass::OnMessageReceived);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-40&#34; name=&#34;__codelineno-0-40&#34; href=&#34;#__codelineno-0-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Request-&amp;gt;OnFinishedListeners.AddDynamic(this, &amp;amp;UMyClass::OnRequestFinished);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-41&#34; name=&#34;__codelineno-0-41&#34; href=&#34;#__codelineno-0-41&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-42&#34; name=&#34;__codelineno-0-42&#34; href=&#34;#__codelineno-0-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ===== 步骤 5: 发送请求 =====&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-43&#34; name=&#34;__codelineno-0-43&#34; href=&#34;#__codelineno-0-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SendRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-44&#34; name=&#34;__codelineno-0-44&#34; href=&#34;#__codelineno-0-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;_3&#34;&gt;简化写法&lt;/h2&gt;
&lt;p&gt;如果不需要精细的回调控制，可以使用更简洁的写法：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;SendSimpleChatRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-2&#34; name=&#34;__codelineno-1-2&#34; href=&#34;#__codelineno-1-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-3&#34; name=&#34;__codelineno-1-3&#34; href=&#34;#__codelineno-1-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_OpenAIChatRequestOptions&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-4&#34; name=&#34;__codelineno-1-4&#34; href=&#34;#__codelineno-1-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ApiKey&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;your-api-key&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-5&#34; name=&#34;__codelineno-1-5&#34; href=&#34;#__codelineno-1-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Model&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;gpt-4o-mini&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-6&#34; name=&#34;__codelineno-1-6&#34; href=&#34;#__codelineno-1-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bStream&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-7&#34; name=&#34;__codelineno-1-7&#34; href=&#34;#__codelineno-1-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-8&#34; name=&#34;__codelineno-1-8&#34; href=&#34;#__codelineno-1-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_OpenAIChatRequest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateWithOptionsAndMessages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-9&#34; name=&#34;__codelineno-1-9&#34; href=&#34;#__codelineno-1-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-10&#34; name=&#34;__codelineno-1-10&#34; href=&#34;#__codelineno-1-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-11&#34; name=&#34;__codelineno-1-11&#34; href=&#34;#__codelineno-1-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;You are a helpful assistant.&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EAIChatPlus_ChatRole&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;System&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-12&#34; name=&#34;__codelineno-1-12&#34; href=&#34;#__codelineno-1-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Hello!&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EAIChatPlus_ChatRole&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;User&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-13&#34; name=&#34;__codelineno-1-13&#34; href=&#34;#__codelineno-1-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-14&#34; name=&#34;__codelineno-1-14&#34; href=&#34;#__codelineno-1-14&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-15&#34; name=&#34;__codelineno-1-15&#34; href=&#34;#__codelineno-1-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 直接在 Request 上绑定 Lambda&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-16&#34; name=&#34;__codelineno-1-16&#34; href=&#34;#__codelineno-1-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OnMessageListeners&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([](&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-17&#34; name=&#34;__codelineno-1-17&#34; href=&#34;#__codelineno-1-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-18&#34; name=&#34;__codelineno-1-18&#34; href=&#34;#__codelineno-1-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Message: %s&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-19&#34; name=&#34;__codelineno-1-19&#34; href=&#34;#__codelineno-1-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-20&#34; name=&#34;__codelineno-1-20&#34; href=&#34;#__codelineno-1-20&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-21&#34; name=&#34;__codelineno-1-21&#34; href=&#34;#__codelineno-1-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OnFinishedListeners&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([](&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_PointerWrapper&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ResponseWrapper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-22&#34; name=&#34;__codelineno-1-22&#34; href=&#34;#__codelineno-1-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-23&#34; name=&#34;__codelineno-1-23&#34; href=&#34;#__codelineno-1-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Response&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_OpenAIChatRequest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CastWrapperToResponse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ResponseWrapper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-24&#34; name=&#34;__codelineno-1-24&#34; href=&#34;#__codelineno-1-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogTemp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Final Message: %s&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-25&#34; name=&#34;__codelineno-1-25&#34; href=&#34;#__codelineno-1-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-26&#34; name=&#34;__codelineno-1-26&#34; href=&#34;#__codelineno-1-26&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-27&#34; name=&#34;__codelineno-1-27&#34; href=&#34;#__codelineno-1-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SendRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-28&#34; name=&#34;__codelineno-1-28&#34; href=&#34;#__codelineno-1-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;api-provider&#34;&gt;通过 API Provider 枚举创建请求&lt;/h2&gt;
&lt;p&gt;如果需要根据配置动态选择 API Provider，可以使用工厂方法：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-2-1&#34; name=&#34;__codelineno-2-1&#34; href=&#34;#__codelineno-2-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CreateRequestByProvider&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EAIChatPlus_ChatApiProvider&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Provider&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-2&#34; name=&#34;__codelineno-2-2&#34; href=&#34;#__codelineno-2-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-3&#34; name=&#34;__codelineno-2-3&#34; href=&#34;#__codelineno-2-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 根据枚举创建对应的 Request&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-4&#34; name=&#34;__codelineno-2-4&#34; href=&#34;#__codelineno-2-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_ChatRequestBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateByApi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Provider&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-5&#34; name=&#34;__codelineno-2-5&#34; href=&#34;#__codelineno-2-5&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-6&#34; name=&#34;__codelineno-2-6&#34; href=&#34;#__codelineno-2-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 根据实际类型设置 Options&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-7&#34; name=&#34;__codelineno-2-7&#34; href=&#34;#__codelineno-2-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;switch&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Provider&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-8&#34; name=&#34;__codelineno-2-8&#34; href=&#34;#__codelineno-2-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-9&#34; name=&#34;__codelineno-2-9&#34; href=&#34;#__codelineno-2-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;EAIChatPlus_ChatApiProvider&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;OpenAI&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-10&#34; name=&#34;__codelineno-2-10&#34; href=&#34;#__codelineno-2-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-11&#34; name=&#34;__codelineno-2-11&#34; href=&#34;#__codelineno-2-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OpenAIRequest&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Cast&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_OpenAIChatRequest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-12&#34; name=&#34;__codelineno-2-12&#34; href=&#34;#__codelineno-2-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_OpenAIChatRequestOptions&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-13&#34; name=&#34;__codelineno-2-13&#34; href=&#34;#__codelineno-2-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ApiKey&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;your-api-key&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-14&#34; name=&#34;__codelineno-2-14&#34; href=&#34;#__codelineno-2-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OpenAIRequest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetOptions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-15&#34; name=&#34;__codelineno-2-15&#34; href=&#34;#__codelineno-2-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-16&#34; name=&#34;__codelineno-2-16&#34; href=&#34;#__codelineno-2-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-17&#34; name=&#34;__codelineno-2-17&#34; href=&#34;#__codelineno-2-17&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-18&#34; name=&#34;__codelineno-2-18&#34; href=&#34;#__codelineno-2-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;EAIChatPlus_ChatApiProvider&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;Claude&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-19&#34; name=&#34;__codelineno-2-19&#34; href=&#34;#__codelineno-2-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-20&#34; name=&#34;__codelineno-2-20&#34; href=&#34;#__codelineno-2-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ClaudeRequest&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Cast&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_ClaudeChatRequest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-21&#34; name=&#34;__codelineno-2-21&#34; href=&#34;#__codelineno-2-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_ClaudeChatRequestOptions&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-22&#34; name=&#34;__codelineno-2-22&#34; href=&#34;#__codelineno-2-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ApiKey&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;your-api-key&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-23&#34; name=&#34;__codelineno-2-23&#34; href=&#34;#__codelineno-2-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ClaudeRequest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetOptions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-24&#34; name=&#34;__codelineno-2-24&#34; href=&#34;#__codelineno-2-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-25&#34; name=&#34;__codelineno-2-25&#34; href=&#34;#__codelineno-2-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-26&#34; name=&#34;__codelineno-2-26&#34; href=&#34;#__codelineno-2-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ... 其他 Provider&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-27&#34; name=&#34;__codelineno-2-27&#34; href=&#34;#__codelineno-2-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-28&#34; name=&#34;__codelineno-2-28&#34; href=&#34;#__codelineno-2-28&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-29&#34; name=&#34;__codelineno-2-29&#34; href=&#34;#__codelineno-2-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 设置消息并发送&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-30&#34; name=&#34;__codelineno-2-30&#34; href=&#34;#__codelineno-2-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlus_ChatRequestMessage&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Messages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-31&#34; name=&#34;__codelineno-2-31&#34; href=&#34;#__codelineno-2-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Messages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Hello!&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EAIChatPlus_ChatRole&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;User&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-32&#34; name=&#34;__codelineno-2-32&#34; href=&#34;#__codelineno-2-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetMessages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Messages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-33&#34; name=&#34;__codelineno-2-33&#34; href=&#34;#__codelineno-2-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SendRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-34&#34; name=&#34;__codelineno-2-34&#34; href=&#34;#__codelineno-2-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;_4&#34;&gt;回调说明&lt;/h2&gt;
&lt;h3 id=&#34;_5&#34;&gt;主要回调委托&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;委托&lt;/th&gt;
&lt;th&gt;触发时机&lt;/th&gt;
&lt;th&gt;参数&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OnStarted&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;请求开始发送时&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OnMessage&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;收到流式消息时（每个 token）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;const FString&amp;amp; Message&lt;/code&gt; - 累积的消息内容&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OnUpdated&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;收到响应更新时&lt;/td&gt;
&lt;td&gt;&lt;code&gt;const FAIChatPlus_ResponseBodyBase&amp;amp; Response&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OnFinished&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;请求成功完成时&lt;/td&gt;
&lt;td&gt;&lt;code&gt;const FAIChatPlus_ResponseBodyBase&amp;amp; Response&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OnFailed&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;请求失败时&lt;/td&gt;
&lt;td&gt;&lt;code&gt;const FAIChatPlus_ResponseErrorBase&amp;amp; Error&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OnMessageFinished&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;消息接收完成时&lt;/td&gt;
&lt;td&gt;&lt;code&gt;const FAIChatPlus_MessageFinishedPayload&amp;amp; Payload&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;vs&#34;&gt;流式输出 vs 非流式输出&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;流式输出&lt;/strong&gt; (&lt;code&gt;bStream = true&lt;/code&gt;)：&lt;code&gt;OnMessage&lt;/code&gt; 会多次触发，每次返回累积的消息内容&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;非流式输出&lt;/strong&gt; (&lt;code&gt;bStream = false&lt;/code&gt;)：&lt;code&gt;OnMessage&lt;/code&gt; 只在完成时触发一次，返回完整消息&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;_6&#34;&gt;下一步&lt;/h2&gt;
&lt;p&gt;更多详细用法请参考各 API Provider 的专题文档：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-OpenAI/&#34;&gt;OpenAI / Azure 使用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-Claude/&#34;&gt;Claude 使用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-Gemini/&#34;&gt;Gemini 使用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-Ollama/&#34;&gt;Ollama 使用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-Cllama/&#34;&gt;Cllama 离线模型&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-CllamaServer/&#34;&gt;CllamaServer 本地服务器&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-Utils/&#34;&gt;工具类&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-GetStarted/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 06 Mar 2025 17:44:59 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-GetStarted/</guid>
      
    </item>
    
    <item>
      <title>UE 实现各种图片 (UTexture2D) 操作 （读取、保存、复制、剪贴板...）</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 实现读取本地系统图片&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;ue-utexture2d&#34;&gt;UE 实现各种图片 (UTexture2D) 操作 （读取、保存、复制、剪贴板...）&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;以下代码都是以 UE5.3 版本为例。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;_1&#34;&gt;源码&lt;/h2&gt;
&lt;p&gt;更多源码细节可在 UE 商城获取插件：&lt;a href=&#34;https://www.unrealengine.com/marketplace/zh-CN/product/aichatplus-ai-chat-integration-openai-azure-claude-gemini&#34;&gt;AIChatPlus&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;ue-utexture2d_1&#34;&gt;读取：UE 实现读取本地系统图片为 UTexture2D&lt;/h2&gt;
&lt;h3 id=&#34;_2&#34;&gt;通用方法&lt;/h3&gt;
&lt;p&gt;本方法在 编辑器 和 GamePlay 模式下都可行，支持的图片文件格式有 PNG, JPEG, BMP, ICO, EXR, ICNS, HDR, TIFF, DDS, TGA，基本能覆盖大部分的常用图片类型。&lt;/p&gt;
&lt;p&gt;代码也很简洁：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;lt;Engine/Texture2D.h&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;lt;ImageUtils.h&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34; href=&#34;#__codelineno-0-3&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-4&#34; name=&#34;__codelineno-0-4&#34; href=&#34;#__codelineno-0-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;LoadImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InLoadPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-5&#34; name=&#34;__codelineno-0-5&#34; href=&#34;#__codelineno-0-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-6&#34; name=&#34;__codelineno-0-6&#34; href=&#34;#__codelineno-0-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FImage&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ImageInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-7&#34; name=&#34;__codelineno-0-7&#34; href=&#34;#__codelineno-0-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FImageUtils&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LoadImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InLoadPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ImageInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-8&#34; name=&#34;__codelineno-0-8&#34; href=&#34;#__codelineno-0-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FImageUtils&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateTexture2DFromImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ImageInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-9&#34; name=&#34;__codelineno-0-9&#34; href=&#34;#__codelineno-0-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;返回的即是 UTexture2D。&lt;/p&gt;
&lt;h3 id=&#34;_3&#34;&gt;编辑器专用方法&lt;/h3&gt;
&lt;p&gt;本方法可以额外支持更多的图片类型：UDIM 纹理贴图、IES 文件、PCX 、PSD。&lt;/p&gt;
&lt;p&gt;代码实现上会更复杂一些：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;lt;Engine/Texture2D.h&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-2&#34; name=&#34;__codelineno-1-2&#34; href=&#34;#__codelineno-1-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;lt;Misc/FileHelper.h&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-3&#34; name=&#34;__codelineno-1-3&#34; href=&#34;#__codelineno-1-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;lt;Misc/Paths.h&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-4&#34; name=&#34;__codelineno-1-4&#34; href=&#34;#__codelineno-1-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;lt;UObject/UObjectGlobals.h&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-5&#34; name=&#34;__codelineno-1-5&#34; href=&#34;#__codelineno-1-5&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-6&#34; name=&#34;__codelineno-1-6&#34; href=&#34;#__codelineno-1-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#if WITH_EDITOR&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-7&#34; name=&#34;__codelineno-1-7&#34; href=&#34;#__codelineno-1-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;LoadImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InLoadPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-8&#34; name=&#34;__codelineno-1-8&#34; href=&#34;#__codelineno-1-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-9&#34; name=&#34;__codelineno-1-9&#34; href=&#34;#__codelineno-1-9&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-10&#34; name=&#34;__codelineno-1-10&#34; href=&#34;#__codelineno-1-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray64&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint8&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-11&#34; name=&#34;__codelineno-1-11&#34; href=&#34;#__codelineno-1-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FFileHelper&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LoadFileToArray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InLoadPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-12&#34; name=&#34;__codelineno-1-12&#34; href=&#34;#__codelineno-1-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-13&#34; name=&#34;__codelineno-1-13&#34; href=&#34;#__codelineno-1-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;nullptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-14&#34; name=&#34;__codelineno-1-14&#34; href=&#34;#__codelineno-1-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-15&#34; name=&#34;__codelineno-1-15&#34; href=&#34;#__codelineno-1-15&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-16&#34; name=&#34;__codelineno-1-16&#34; href=&#34;#__codelineno-1-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TextureName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-17&#34; name=&#34;__codelineno-1-17&#34; href=&#34;#__codelineno-1-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Extension&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FPaths&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetExtension&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InLoadPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ToLower&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-18&#34; name=&#34;__codelineno-1-18&#34; href=&#34;#__codelineno-1-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint8&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BufferPtr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-19&#34; name=&#34;__codelineno-1-19&#34; href=&#34;#__codelineno-1-19&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-20&#34; name=&#34;__codelineno-1-20&#34; href=&#34;#__codelineno-1-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TextureFact&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTextureFactory&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-21&#34; name=&#34;__codelineno-1-21&#34; href=&#34;#__codelineno-1-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Ret&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Cast&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TextureFact&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FactoryCreateBinary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-22&#34; name=&#34;__codelineno-1-22&#34; href=&#34;#__codelineno-1-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;StaticClass&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetTransientPackage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TextureName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RF_Transient&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-23&#34; name=&#34;__codelineno-1-23&#34; href=&#34;#__codelineno-1-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Extension&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BufferPtr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BufferPtr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Num&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GWarn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-24&#34; name=&#34;__codelineno-1-24&#34; href=&#34;#__codelineno-1-24&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-25&#34; name=&#34;__codelineno-1-25&#34; href=&#34;#__codelineno-1-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Ret&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-26&#34; name=&#34;__codelineno-1-26&#34; href=&#34;#__codelineno-1-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-27&#34; name=&#34;__codelineno-1-27&#34; href=&#34;#__codelineno-1-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#endif&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;实现是使用了 UTextureFactory 的 FactoryCreateBinary 函数，这个函数能够读取前面提到的额外文件类型。&lt;/p&gt;
&lt;h2 id=&#34;ue-utexture2d_2&#34;&gt;复制：UE 实现复制 UTexture2D&lt;/h2&gt;
&lt;p&gt;有的时候需要复制一个 UTexture2D 出来，再对这个复制出来的图片进行修改，复制图片需要使用到引擎自带的函数 &lt;code&gt;FImageCore::CopyImage&lt;/code&gt;，只要设置好两个图片的参数，调用这个接口即可&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-2-1&#34; name=&#34;__codelineno-2-1&#34; href=&#34;#__codelineno-2-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CopyTexture2D&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Outer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FName&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EObjectFlags&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Flags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-2&#34; name=&#34;__codelineno-2-2&#34; href=&#34;#__codelineno-2-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-3&#34; name=&#34;__codelineno-2-3&#34; href=&#34;#__codelineno-2-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// src texture info, src ImageView&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-4&#34; name=&#34;__codelineno-2-4&#34; href=&#34;#__codelineno-2-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FTextureMipDataLockGuard&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTextureGuard&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-5&#34; name=&#34;__codelineno-2-5&#34; href=&#34;#__codelineno-2-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint8&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SrcMipData&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTextureGuard&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Lock&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCK_READ_ONLY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Texture-&amp;gt;GetPlatformData()-&amp;gt;Mips[0].BulkData.Lock(InLockFlag)&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-6&#34; name=&#34;__codelineno-2-6&#34; href=&#34;#__codelineno-2-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetSizeX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-7&#34; name=&#34;__codelineno-2-7&#34; href=&#34;#__codelineno-2-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetSizeY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-8&#34; name=&#34;__codelineno-2-8&#34; href=&#34;#__codelineno-2-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EPixelFormat&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InFormat&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetPixelFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-9&#34; name=&#34;__codelineno-2-9&#34; href=&#34;#__codelineno-2-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FImageView&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SrcMipImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-10&#34; name=&#34;__codelineno-2-10&#34; href=&#34;#__codelineno-2-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SrcMipData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetRawImageFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetGammaSpace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-11&#34; name=&#34;__codelineno-2-11&#34; href=&#34;#__codelineno-2-11&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-12&#34; name=&#34;__codelineno-2-12&#34; href=&#34;#__codelineno-2-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// create dst texture&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-13&#34; name=&#34;__codelineno-2-13&#34; href=&#34;#__codelineno-2-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewTexture&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Outer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Flags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-14&#34; name=&#34;__codelineno-2-14&#34; href=&#34;#__codelineno-2-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetPlatformData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FTexturePlatformData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-15&#34; name=&#34;__codelineno-2-15&#34; href=&#34;#__codelineno-2-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetPlatformData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SizeX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-16&#34; name=&#34;__codelineno-2-16&#34; href=&#34;#__codelineno-2-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetPlatformData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SizeY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-17&#34; name=&#34;__codelineno-2-17&#34; href=&#34;#__codelineno-2-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetPlatformData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetNumSlices&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-18&#34; name=&#34;__codelineno-2-18&#34; href=&#34;#__codelineno-2-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetPlatformData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PixelFormat&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-19&#34; name=&#34;__codelineno-2-19&#34; href=&#34;#__codelineno-2-19&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-20&#34; name=&#34;__codelineno-2-20&#34; href=&#34;#__codelineno-2-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Allocate first mipmap.&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-21&#34; name=&#34;__codelineno-2-21&#34; href=&#34;#__codelineno-2-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NumBlocksX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GPixelFormats&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BlockSizeX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-22&#34; name=&#34;__codelineno-2-22&#34; href=&#34;#__codelineno-2-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NumBlocksY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GPixelFormats&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BlockSizeY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-23&#34; name=&#34;__codelineno-2-23&#34; href=&#34;#__codelineno-2-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FTexture2DMipMap&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Mip&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FTexture2DMipMap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-24&#34; name=&#34;__codelineno-2-24&#34; href=&#34;#__codelineno-2-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Mip&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SizeX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-25&#34; name=&#34;__codelineno-2-25&#34; href=&#34;#__codelineno-2-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Mip&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SizeY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-26&#34; name=&#34;__codelineno-2-26&#34; href=&#34;#__codelineno-2-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Mip&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SizeX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-27&#34; name=&#34;__codelineno-2-27&#34; href=&#34;#__codelineno-2-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetPlatformData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Mips&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Mip&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-28&#34; name=&#34;__codelineno-2-28&#34; href=&#34;#__codelineno-2-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Mip&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BulkData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Lock&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCK_READ_WRITE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-29&#34; name=&#34;__codelineno-2-29&#34; href=&#34;#__codelineno-2-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Mip&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BulkData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Realloc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NumBlocksX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NumBlocksY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GPixelFormats&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BlockBytes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-30&#34; name=&#34;__codelineno-2-30&#34; href=&#34;#__codelineno-2-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Mip&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BulkData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Unlock&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-31&#34; name=&#34;__codelineno-2-31&#34; href=&#34;#__codelineno-2-31&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-32&#34; name=&#34;__codelineno-2-32&#34; href=&#34;#__codelineno-2-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// dst texture ImageView&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-33&#34; name=&#34;__codelineno-2-33&#34; href=&#34;#__codelineno-2-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint8&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DstMipData&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;static_cast&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint8&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetPlatformData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Mips&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BulkData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Lock&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCK_READ_WRITE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-34&#34; name=&#34;__codelineno-2-34&#34; href=&#34;#__codelineno-2-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FImageView&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DstMipImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-35&#34; name=&#34;__codelineno-2-35&#34; href=&#34;#__codelineno-2-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DstMipData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetRawImageFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetGammaSpace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-36&#34; name=&#34;__codelineno-2-36&#34; href=&#34;#__codelineno-2-36&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-37&#34; name=&#34;__codelineno-2-37&#34; href=&#34;#__codelineno-2-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// run CopyImage&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-38&#34; name=&#34;__codelineno-2-38&#34; href=&#34;#__codelineno-2-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FImageCore&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CopyImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SrcMipImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DstMipImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-39&#34; name=&#34;__codelineno-2-39&#34; href=&#34;#__codelineno-2-39&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-40&#34; name=&#34;__codelineno-2-40&#34; href=&#34;#__codelineno-2-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#if WITH_EDITORONLY_DATA&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-41&#34; name=&#34;__codelineno-2-41&#34; href=&#34;#__codelineno-2-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Source&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-42&#34; name=&#34;__codelineno-2-42&#34; href=&#34;#__codelineno-2-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-43&#34; name=&#34;__codelineno-2-43&#34; href=&#34;#__codelineno-2-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FImageCoreUtils&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ConvertToTextureSourceFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetRawImageFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DstMipData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-44&#34; name=&#34;__codelineno-2-44&#34; href=&#34;#__codelineno-2-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#endif&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-45&#34; name=&#34;__codelineno-2-45&#34; href=&#34;#__codelineno-2-45&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-46&#34; name=&#34;__codelineno-2-46&#34; href=&#34;#__codelineno-2-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// cleanup&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-47&#34; name=&#34;__codelineno-2-47&#34; href=&#34;#__codelineno-2-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetPlatformData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Mips&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BulkData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Unlock&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-48&#34; name=&#34;__codelineno-2-48&#34; href=&#34;#__codelineno-2-48&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UpdateResource&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-49&#34; name=&#34;__codelineno-2-49&#34; href=&#34;#__codelineno-2-49&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-50&#34; name=&#34;__codelineno-2-50&#34; href=&#34;#__codelineno-2-50&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-51&#34; name=&#34;__codelineno-2-51&#34; href=&#34;#__codelineno-2-51&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;ue-utexture2d_3&#34;&gt;保存：UE 实现保存 UTexture2D 到文件&lt;/h2&gt;
&lt;p&gt;核心是使用引擎函数 &lt;code&gt;FImageUtils::SaveImageAutoFormat&lt;/code&gt;，实现起来比较简单，不过需要注意失败重试的情况&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-3-1&#34; name=&#34;__codelineno-3-1&#34; href=&#34;#__codelineno-3-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;SaveImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSavePath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-2&#34; name=&#34;__codelineno-3-2&#34; href=&#34;#__codelineno-3-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-3&#34; name=&#34;__codelineno-3-3&#34; href=&#34;#__codelineno-3-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-4&#34; name=&#34;__codelineno-3-4&#34; href=&#34;#__codelineno-3-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FImage&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ImageInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-5&#34; name=&#34;__codelineno-3-5&#34; href=&#34;#__codelineno-3-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FImageUtils&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetTexture2DSourceImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ImageInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-6&#34; name=&#34;__codelineno-3-6&#34; href=&#34;#__codelineno-3-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-7&#34; name=&#34;__codelineno-3-7&#34; href=&#34;#__codelineno-3-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FImageUtils&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SaveImageAutoFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSavePath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ImageInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-8&#34; name=&#34;__codelineno-3-8&#34; href=&#34;#__codelineno-3-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-9&#34; name=&#34;__codelineno-3-9&#34; href=&#34;#__codelineno-3-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-10&#34; name=&#34;__codelineno-3-10&#34; href=&#34;#__codelineno-3-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-11&#34; name=&#34;__codelineno-3-11&#34; href=&#34;#__codelineno-3-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// if prev save failed&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-12&#34; name=&#34;__codelineno-3-12&#34; href=&#34;#__codelineno-3-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// use ConvertTextureToStandard to change InImage to Standard format, and try again&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-13&#34; name=&#34;__codelineno-3-13&#34; href=&#34;#__codelineno-3-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// then revert InImage&amp;#39;s origin format&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-14&#34; name=&#34;__codelineno-3-14&#34; href=&#34;#__codelineno-3-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// this is what FTextureMipDataLockGuard does&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-15&#34; name=&#34;__codelineno-3-15&#34; href=&#34;#__codelineno-3-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FTextureMipDataLockGuard&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InImageGuard&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-16&#34; name=&#34;__codelineno-3-16&#34; href=&#34;#__codelineno-3-16&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-17&#34; name=&#34;__codelineno-3-17&#34; href=&#34;#__codelineno-3-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint8&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MipData&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InImageGuard&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Lock&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCK_READ_ONLY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-18&#34; name=&#34;__codelineno-3-18&#34; href=&#34;#__codelineno-3-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;check&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MipData&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;nullptr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-19&#34; name=&#34;__codelineno-3-19&#34; href=&#34;#__codelineno-3-19&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-20&#34; name=&#34;__codelineno-3-20&#34; href=&#34;#__codelineno-3-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FImageView&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MipImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-21&#34; name=&#34;__codelineno-3-21&#34; href=&#34;#__codelineno-3-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MipData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InImage&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetSizeX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InImage&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetSizeY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-22&#34; name=&#34;__codelineno-3-22&#34; href=&#34;#__codelineno-3-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetRawImageFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InImage&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetPixelFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InImage&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetGammaSpace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-23&#34; name=&#34;__codelineno-3-23&#34; href=&#34;#__codelineno-3-23&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-24&#34; name=&#34;__codelineno-3-24&#34; href=&#34;#__codelineno-3-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FImageUtils&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SaveImageAutoFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSavePath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MipImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-25&#34; name=&#34;__codelineno-3-25&#34; href=&#34;#__codelineno-3-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-26&#34; name=&#34;__codelineno-3-26&#34; href=&#34;#__codelineno-3-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;ue-utexture2d-asset&#34;&gt;保存：UE 实现保存 UTexture2D 到 Asset&lt;/h2&gt;
&lt;p&gt;保存内存中的 UTexture2D 到 Asset 中，并可以在资源浏览器 (Content Browser) 中查看。&lt;/p&gt;
&lt;p&gt;核心函数需要用到上面实现的 &lt;code&gt;CopyTexture2D&lt;/code&gt;，我们需要先复制出来一个新的图片，然后再调用 &lt;code&gt;UPackage::SavePackage&lt;/code&gt; 把图片所在的 &lt;code&gt;Package&lt;/code&gt; 保存成 Asset。&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-4-1&#34; name=&#34;__codelineno-4-1&#34; href=&#34;#__codelineno-4-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;SaveTextureToAsset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-2&#34; name=&#34;__codelineno-4-2&#34; href=&#34;#__codelineno-4-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-3&#34; name=&#34;__codelineno-4-3&#34; href=&#34;#__codelineno-4-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-4&#34; name=&#34;__codelineno-4-4&#34; href=&#34;#__codelineno-4-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-5&#34; name=&#34;__codelineno-4-5&#34; href=&#34;#__codelineno-4-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// open save asset dialog, choose where/which to save&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-6&#34; name=&#34;__codelineno-4-6&#34; href=&#34;#__codelineno-4-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FSaveAssetDialogConfig&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SaveAssetDialogConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-7&#34; name=&#34;__codelineno-4-7&#34; href=&#34;#__codelineno-4-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-8&#34; name=&#34;__codelineno-4-8&#34; href=&#34;#__codelineno-4-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SaveAssetDialogConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DefaultPath&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorDirectories&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetLastDirectory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ELastDirectory&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NEW_ASSET&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-9&#34; name=&#34;__codelineno-4-9&#34; href=&#34;#__codelineno-4-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SaveAssetDialogConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AssetClassNames&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;StaticClass&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetClassPathName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-10&#34; name=&#34;__codelineno-4-10&#34; href=&#34;#__codelineno-4-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SaveAssetDialogConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ExistingAssetPolicy&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ESaveAssetDialogExistingAssetPolicy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AllowButWarn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-11&#34; name=&#34;__codelineno-4-11&#34; href=&#34;#__codelineno-4-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SaveAssetDialogConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DialogTitleOverride&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAIChatPlusEditor_Constants&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FCText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SaveAsAsset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-12&#34; name=&#34;__codelineno-4-12&#34; href=&#34;#__codelineno-4-12&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-13&#34; name=&#34;__codelineno-4-13&#34; href=&#34;#__codelineno-4-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FContentBrowserModule&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ContentBrowserModule&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FModuleManager&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LoadModuleChecked&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FContentBrowserModule&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;ContentBrowser&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-14&#34; name=&#34;__codelineno-4-14&#34; href=&#34;#__codelineno-4-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SaveObjectPath&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ContentBrowserModule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateModalSaveAssetDialog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SaveAssetDialogConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-15&#34; name=&#34;__codelineno-4-15&#34; href=&#34;#__codelineno-4-15&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-16&#34; name=&#34;__codelineno-4-16&#34; href=&#34;#__codelineno-4-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SaveObjectPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IsEmpty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-17&#34; name=&#34;__codelineno-4-17&#34; href=&#34;#__codelineno-4-17&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-18&#34; name=&#34;__codelineno-4-18&#34; href=&#34;#__codelineno-4-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// init save info&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-19&#34; name=&#34;__codelineno-4-19&#34; href=&#34;#__codelineno-4-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PackageName&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FPackageName&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ObjectPathToPackageName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SaveObjectPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-20&#34; name=&#34;__codelineno-4-20&#34; href=&#34;#__codelineno-4-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PackageFileName&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FPackageName&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LongPackageNameToFilename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PackageName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FPackageName&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetAssetPackageExtension&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-21&#34; name=&#34;__codelineno-4-21&#34; href=&#34;#__codelineno-4-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PackagePath&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FPaths&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PackageFileName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-22&#34; name=&#34;__codelineno-4-22&#34; href=&#34;#__codelineno-4-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TextureName&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FPaths&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetBaseFilename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PackageName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-23&#34; name=&#34;__codelineno-4-23&#34; href=&#34;#__codelineno-4-23&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-24&#34; name=&#34;__codelineno-4-24&#34; href=&#34;#__codelineno-4-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// create new UPackage to put the new texture in&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-25&#34; name=&#34;__codelineno-4-25&#34; href=&#34;#__codelineno-4-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UPackage&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewPackage&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreatePackage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PackageName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-26&#34; name=&#34;__codelineno-4-26&#34; href=&#34;#__codelineno-4-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewPackage&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FullyLoad&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-27&#34; name=&#34;__codelineno-4-27&#34; href=&#34;#__codelineno-4-27&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-28&#34; name=&#34;__codelineno-4-28&#34; href=&#34;#__codelineno-4-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// copy texture&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-29&#34; name=&#34;__codelineno-4-29&#34; href=&#34;#__codelineno-4-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewTexture&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UAIChatPlus_Util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CopyTexture2D&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-30&#34; name=&#34;__codelineno-4-30&#34; href=&#34;#__codelineno-4-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewPackage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TextureName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RF_Public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RF_Standalone&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RF_Transactional&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-31&#34; name=&#34;__codelineno-4-31&#34; href=&#34;#__codelineno-4-31&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-32&#34; name=&#34;__codelineno-4-32&#34; href=&#34;#__codelineno-4-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Generate the thumbnail&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-33&#34; name=&#34;__codelineno-4-33&#34; href=&#34;#__codelineno-4-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// if not doing so, the texture will not have thumbnail in content browser&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-34&#34; name=&#34;__codelineno-4-34&#34; href=&#34;#__codelineno-4-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FObjectThumbnail&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewThumbnail&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-35&#34; name=&#34;__codelineno-4-35&#34; href=&#34;#__codelineno-4-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ThumbnailTools&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RenderThumbnail&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-36&#34; name=&#34;__codelineno-4-36&#34; href=&#34;#__codelineno-4-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetSizeX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetSizeY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-37&#34; name=&#34;__codelineno-4-37&#34; href=&#34;#__codelineno-4-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ThumbnailTools&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EThumbnailTextureFlushMode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NeverFlush&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-38&#34; name=&#34;__codelineno-4-38&#34; href=&#34;#__codelineno-4-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewThumbnail&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-39&#34; name=&#34;__codelineno-4-39&#34; href=&#34;#__codelineno-4-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ThumbnailTools&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CacheThumbnail&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetFullName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewThumbnail&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewPackage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-40&#34; name=&#34;__codelineno-4-40&#34; href=&#34;#__codelineno-4-40&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-41&#34; name=&#34;__codelineno-4-41&#34; href=&#34;#__codelineno-4-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// setting up new package and new texture&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-42&#34; name=&#34;__codelineno-4-42&#34; href=&#34;#__codelineno-4-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewPackage&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MarkPackageDirty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-43&#34; name=&#34;__codelineno-4-43&#34; href=&#34;#__codelineno-4-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FAssetRegistryModule&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AssetCreated&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-44&#34; name=&#34;__codelineno-4-44&#34; href=&#34;#__codelineno-4-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorDirectories&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetLastDirectory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ELastDirectory&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NEW_ASSET&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FPaths&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PackageName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-45&#34; name=&#34;__codelineno-4-45&#34; href=&#34;#__codelineno-4-45&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-46&#34; name=&#34;__codelineno-4-46&#34; href=&#34;#__codelineno-4-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// save args&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-47&#34; name=&#34;__codelineno-4-47&#34; href=&#34;#__codelineno-4-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FSavePackageArgs&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SaveArgs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-48&#34; name=&#34;__codelineno-4-48&#34; href=&#34;#__codelineno-4-48&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SaveArgs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TopLevelFlags&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RF_Public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RF_Standalone&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-49&#34; name=&#34;__codelineno-4-49&#34; href=&#34;#__codelineno-4-49&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SaveArgs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bForceByteSwapping&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-50&#34; name=&#34;__codelineno-4-50&#34; href=&#34;#__codelineno-4-50&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SaveArgs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bWarnOfLongFilename&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-51&#34; name=&#34;__codelineno-4-51&#34; href=&#34;#__codelineno-4-51&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-52&#34; name=&#34;__codelineno-4-52&#34; href=&#34;#__codelineno-4-52&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// save it&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-53&#34; name=&#34;__codelineno-4-53&#34; href=&#34;#__codelineno-4-53&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UPackage&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SavePackage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewPackage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PackageFileName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SaveArgs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-54&#34; name=&#34;__codelineno-4-54&#34; href=&#34;#__codelineno-4-54&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-55&#34; name=&#34;__codelineno-4-55&#34; href=&#34;#__codelineno-4-55&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AIChatPlusEditor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Failed to save Asset: [%s]&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PackageFileName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-56&#34; name=&#34;__codelineno-4-56&#34; href=&#34;#__codelineno-4-56&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-57&#34; name=&#34;__codelineno-4-57&#34; href=&#34;#__codelineno-4-57&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;ue-utexture2d-windows-clipboard&#34;&gt;剪贴板：UE 实现复制图片 (UTexture2D) 到 Windows 剪贴板 (Clipboard)&lt;/h2&gt;
&lt;h3 id=&#34;windows&#34;&gt;Windows 相关函数&lt;/h3&gt;
&lt;p&gt;我们会用到以下 Windows 操作剪贴板的相关函数：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-openclipboard&#34;&gt;OpenClipboard&lt;/a&gt;：打开剪贴板，获取剪贴板的 Handler 。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-emptyclipboard&#34;&gt;EmptyClipboard&lt;/a&gt;：清空剪贴板，并把剪贴板的所有权分配给当前的窗口。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-setclipboarddata&#34;&gt;SetClipboardData&lt;/a&gt;：设置剪贴板的数据，图片的数据是通过这个接口发送给剪贴板。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-closeclipboard&#34;&gt;CloseClipboard&lt;/a&gt;：设置好数据之后，关闭剪贴板。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;_4&#34;&gt;剪贴板的图片格式&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://learn.microsoft.com/zh-cn/windows/win32/dataxchg/standard-clipboard-formats&#34;&gt;标准剪贴板格式&lt;/a&gt; 里面介绍了可用的剪贴板格式，其中 &lt;code&gt;CF_DIBV5&lt;/code&gt; 即可以用来设置图片。&lt;/p&gt;
&lt;p&gt;CF_DIBV5 要求的格式具体定义 &lt;a href=&#34;https://learn.microsoft.com/zh-cn/windows/win32/api/wingdi/ns-wingdi-bitmapv5header&#34;&gt;BITMAPV5HEADER 结构&lt;/a&gt;，在这里我们选用以下配置&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-5-1&#34; name=&#34;__codelineno-5-1&#34; href=&#34;#__codelineno-5-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;BITMAPV5HEADER&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-2&#34; name=&#34;__codelineno-5-2&#34; href=&#34;#__codelineno-5-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5CSType&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LCS_sRGB&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-3&#34; name=&#34;__codelineno-5-3&#34; href=&#34;#__codelineno-5-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5Compression&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BI_BITFIELDS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;utexture2d&#34;&gt;UTexture2D 设置&lt;/h3&gt;
&lt;p&gt;我们在上面选择了剪贴板图片的颜色空间是 &lt;code&gt;LCS_sRGB&lt;/code&gt;，即 sRGB 颜色空间，那么 UTexture2D 也需要先设置到对应的格式：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-6-1&#34; name=&#34;__codelineno-6-1&#34; href=&#34;#__codelineno-6-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ConvertTextureToStandard&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-2&#34; name=&#34;__codelineno-6-2&#34; href=&#34;#__codelineno-6-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-3&#34; name=&#34;__codelineno-6-3&#34; href=&#34;#__codelineno-6-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CompressionSettings&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TC_VectorDisplacementmap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-4&#34; name=&#34;__codelineno-6-4&#34; href=&#34;#__codelineno-6-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-5&#34; name=&#34;__codelineno-6-5&#34; href=&#34;#__codelineno-6-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CompressionSettings&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TC_VectorDisplacementmap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-6&#34; name=&#34;__codelineno-6-6&#34; href=&#34;#__codelineno-6-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IsChanged&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-7&#34; name=&#34;__codelineno-6-7&#34; href=&#34;#__codelineno-6-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-8&#34; name=&#34;__codelineno-6-8&#34; href=&#34;#__codelineno-6-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SRGB&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-9&#34; name=&#34;__codelineno-6-9&#34; href=&#34;#__codelineno-6-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-10&#34; name=&#34;__codelineno-6-10&#34; href=&#34;#__codelineno-6-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SRGB&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-11&#34; name=&#34;__codelineno-6-11&#34; href=&#34;#__codelineno-6-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IsChanged&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-12&#34; name=&#34;__codelineno-6-12&#34; href=&#34;#__codelineno-6-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-13&#34; name=&#34;__codelineno-6-13&#34; href=&#34;#__codelineno-6-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IsChanged&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-14&#34; name=&#34;__codelineno-6-14&#34; href=&#34;#__codelineno-6-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-15&#34; name=&#34;__codelineno-6-15&#34; href=&#34;#__codelineno-6-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UpdateResource&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-16&#34; name=&#34;__codelineno-6-16&#34; href=&#34;#__codelineno-6-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-17&#34; name=&#34;__codelineno-6-17&#34; href=&#34;#__codelineno-6-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ConvertTextureToStandard 就是负责把 UTexture2D 转换成标准格式：TC_VectorDisplacementmap (RGBA8) 和 SRGB 颜色空间。对齐了 UTexture2D 和 Windows 剪贴板的图片格式之后，我们就可以把图片的数据复制到剪贴板上。&lt;/p&gt;
&lt;h3 id=&#34;_5&#34;&gt;具体代码&lt;/h3&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-7-1&#34; name=&#34;__codelineno-7-1&#34; href=&#34;#__codelineno-7-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CopyTexture2DToClipboard&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-2&#34; name=&#34;__codelineno-7-2&#34; href=&#34;#__codelineno-7-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-3&#34; name=&#34;__codelineno-7-3&#34; href=&#34;#__codelineno-7-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-4&#34; name=&#34;__codelineno-7-4&#34; href=&#34;#__codelineno-7-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-5&#34; name=&#34;__codelineno-7-5&#34; href=&#34;#__codelineno-7-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FTextureMipDataLockGuard&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTextureGuard&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-6&#34; name=&#34;__codelineno-7-6&#34; href=&#34;#__codelineno-7-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// get InTexture info&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-7&#34; name=&#34;__codelineno-7-7&#34; href=&#34;#__codelineno-7-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint8&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SrcMipData&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTextureGuard&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Lock&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCK_READ_ONLY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-8&#34; name=&#34;__codelineno-7-8&#34; href=&#34;#__codelineno-7-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetSizeX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-9&#34; name=&#34;__codelineno-7-9&#34; href=&#34;#__codelineno-7-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetSizeY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-10&#34; name=&#34;__codelineno-7-10&#34; href=&#34;#__codelineno-7-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EPixelFormat&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InFormat&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetPixelFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-11&#34; name=&#34;__codelineno-7-11&#34; href=&#34;#__codelineno-7-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FImageView&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SrcMipImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-12&#34; name=&#34;__codelineno-7-12&#34; href=&#34;#__codelineno-7-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SrcMipData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetRawImageFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetGammaSpace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-13&#34; name=&#34;__codelineno-7-13&#34; href=&#34;#__codelineno-7-13&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-14&#34; name=&#34;__codelineno-7-14&#34; href=&#34;#__codelineno-7-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// set clipboard Texture info&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-15&#34; name=&#34;__codelineno-7-15&#34; href=&#34;#__codelineno-7-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EPixelFormat&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OutFormat&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PF_B8G8R8A8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-16&#34; name=&#34;__codelineno-7-16&#34; href=&#34;#__codelineno-7-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NumBlocksX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GPixelFormats&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OutFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BlockSizeX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-17&#34; name=&#34;__codelineno-7-17&#34; href=&#34;#__codelineno-7-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NumBlocksY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GPixelFormats&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OutFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BlockSizeY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-18&#34; name=&#34;__codelineno-7-18&#34; href=&#34;#__codelineno-7-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int64&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BufSize&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;static_cast&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int64&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NumBlocksX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NumBlocksY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GPixelFormats&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BlockBytes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-19&#34; name=&#34;__codelineno-7-19&#34; href=&#34;#__codelineno-7-19&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-20&#34; name=&#34;__codelineno-7-20&#34; href=&#34;#__codelineno-7-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// set header info&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-21&#34; name=&#34;__codelineno-7-21&#34; href=&#34;#__codelineno-7-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BITMAPV5HEADER&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-22&#34; name=&#34;__codelineno-7-22&#34; href=&#34;#__codelineno-7-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5Size&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;sizeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BITMAPV5HEADER&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-23&#34; name=&#34;__codelineno-7-23&#34; href=&#34;#__codelineno-7-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5Width&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-24&#34; name=&#34;__codelineno-7-24&#34; href=&#34;#__codelineno-7-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5Height&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-25&#34; name=&#34;__codelineno-7-25&#34; href=&#34;#__codelineno-7-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5Planes&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-26&#34; name=&#34;__codelineno-7-26&#34; href=&#34;#__codelineno-7-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5BitCount&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;32&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-27&#34; name=&#34;__codelineno-7-27&#34; href=&#34;#__codelineno-7-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5Compression&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BI_BITFIELDS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-28&#34; name=&#34;__codelineno-7-28&#34; href=&#34;#__codelineno-7-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5SizeImage&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BufSize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-29&#34; name=&#34;__codelineno-7-29&#34; href=&#34;#__codelineno-7-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5XPelsPerMeter&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-30&#34; name=&#34;__codelineno-7-30&#34; href=&#34;#__codelineno-7-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5YPelsPerMeter&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-31&#34; name=&#34;__codelineno-7-31&#34; href=&#34;#__codelineno-7-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5ClrUsed&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-32&#34; name=&#34;__codelineno-7-32&#34; href=&#34;#__codelineno-7-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5ClrImportant&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-33&#34; name=&#34;__codelineno-7-33&#34; href=&#34;#__codelineno-7-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5RedMask&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;0x00FF0000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-34&#34; name=&#34;__codelineno-7-34&#34; href=&#34;#__codelineno-7-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5GreenMask&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;0x0000FF00&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-35&#34; name=&#34;__codelineno-7-35&#34; href=&#34;#__codelineno-7-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5BlueMask&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;0x000000FF&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-36&#34; name=&#34;__codelineno-7-36&#34; href=&#34;#__codelineno-7-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5AlphaMask&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;0xFF000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-37&#34; name=&#34;__codelineno-7-37&#34; href=&#34;#__codelineno-7-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5CSType&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LCS_sRGB&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-38&#34; name=&#34;__codelineno-7-38&#34; href=&#34;#__codelineno-7-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Header.bV5Endpoints;    // ignored&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-39&#34; name=&#34;__codelineno-7-39&#34; href=&#34;#__codelineno-7-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5GammaRed&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-40&#34; name=&#34;__codelineno-7-40&#34; href=&#34;#__codelineno-7-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5GammaGreen&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-41&#34; name=&#34;__codelineno-7-41&#34; href=&#34;#__codelineno-7-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5GammaBlue&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-42&#34; name=&#34;__codelineno-7-42&#34; href=&#34;#__codelineno-7-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5Intent&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-43&#34; name=&#34;__codelineno-7-43&#34; href=&#34;#__codelineno-7-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5ProfileData&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-44&#34; name=&#34;__codelineno-7-44&#34; href=&#34;#__codelineno-7-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5ProfileSize&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-45&#34; name=&#34;__codelineno-7-45&#34; href=&#34;#__codelineno-7-45&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bV5Reserved&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-46&#34; name=&#34;__codelineno-7-46&#34; href=&#34;#__codelineno-7-46&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-47&#34; name=&#34;__codelineno-7-47&#34; href=&#34;#__codelineno-7-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;HGLOBAL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WinBuf&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GlobalAlloc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GMEM_MOVEABLE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;sizeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BITMAPV5HEADER&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BufSize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-48&#34; name=&#34;__codelineno-7-48&#34; href=&#34;#__codelineno-7-48&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WinBuf&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-49&#34; name=&#34;__codelineno-7-49&#34; href=&#34;#__codelineno-7-49&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-50&#34; name=&#34;__codelineno-7-50&#34; href=&#34;#__codelineno-7-50&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-51&#34; name=&#34;__codelineno-7-51&#34; href=&#34;#__codelineno-7-51&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;HWND&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WinHandler&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetActiveWindow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-52&#34; name=&#34;__codelineno-7-52&#34; href=&#34;#__codelineno-7-52&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OpenClipboard&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WinHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-53&#34; name=&#34;__codelineno-7-53&#34; href=&#34;#__codelineno-7-53&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GlobalFree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WinBuf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-54&#34; name=&#34;__codelineno-7-54&#34; href=&#34;#__codelineno-7-54&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-55&#34; name=&#34;__codelineno-7-55&#34; href=&#34;#__codelineno-7-55&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-56&#34; name=&#34;__codelineno-7-56&#34; href=&#34;#__codelineno-7-56&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;verify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EmptyClipboard&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-57&#34; name=&#34;__codelineno-7-57&#34; href=&#34;#__codelineno-7-57&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-58&#34; name=&#34;__codelineno-7-58&#34; href=&#34;#__codelineno-7-58&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// copy InTexture into BGRA8 sRGB Standard Texture&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-59&#34; name=&#34;__codelineno-7-59&#34; href=&#34;#__codelineno-7-59&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FTexture2DMipMap&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DstMip&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FTexture2DMipMap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-60&#34; name=&#34;__codelineno-7-60&#34; href=&#34;#__codelineno-7-60&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DstMip&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SizeX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-61&#34; name=&#34;__codelineno-7-61&#34; href=&#34;#__codelineno-7-61&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DstMip&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SizeY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-62&#34; name=&#34;__codelineno-7-62&#34; href=&#34;#__codelineno-7-62&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DstMip&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SizeZ&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-63&#34; name=&#34;__codelineno-7-63&#34; href=&#34;#__codelineno-7-63&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DstMip&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BulkData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Lock&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCK_READ_WRITE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-64&#34; name=&#34;__codelineno-7-64&#34; href=&#34;#__codelineno-7-64&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint8&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DstMipData&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;static_cast&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint8&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DstMip&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BulkData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Realloc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BufSize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-65&#34; name=&#34;__codelineno-7-65&#34; href=&#34;#__codelineno-7-65&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FImageView&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DstMipImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-66&#34; name=&#34;__codelineno-7-66&#34; href=&#34;#__codelineno-7-66&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DstMipData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InSizeY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ERawImageFormat&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BGRA8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EGammaSpace&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sRGB&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-67&#34; name=&#34;__codelineno-7-67&#34; href=&#34;#__codelineno-7-67&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-68&#34; name=&#34;__codelineno-7-68&#34; href=&#34;#__codelineno-7-68&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FImageCore&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CopyImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SrcMipImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DstMipImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-69&#34; name=&#34;__codelineno-7-69&#34; href=&#34;#__codelineno-7-69&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DstMip&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BulkData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Unlock&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-70&#34; name=&#34;__codelineno-7-70&#34; href=&#34;#__codelineno-7-70&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-71&#34; name=&#34;__codelineno-7-71&#34; href=&#34;#__codelineno-7-71&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// copy Standard Texture data into Clipboard&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-72&#34; name=&#34;__codelineno-7-72&#34; href=&#34;#__codelineno-7-72&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WinLockedBuf&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GlobalLock&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WinBuf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-73&#34; name=&#34;__codelineno-7-73&#34; href=&#34;#__codelineno-7-73&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WinLockedBuf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-74&#34; name=&#34;__codelineno-7-74&#34; href=&#34;#__codelineno-7-74&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;memcpy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WinLockedBuf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;sizeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BITMAPV5HEADER&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-75&#34; name=&#34;__codelineno-7-75&#34; href=&#34;#__codelineno-7-75&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;memcpy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WinLockedBuf&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;sizeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BITMAPV5HEADER&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DstMipData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BufSize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-76&#34; name=&#34;__codelineno-7-76&#34; href=&#34;#__codelineno-7-76&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-77&#34; name=&#34;__codelineno-7-77&#34; href=&#34;#__codelineno-7-77&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GlobalUnlock&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WinLockedBuf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-78&#34; name=&#34;__codelineno-7-78&#34; href=&#34;#__codelineno-7-78&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-79&#34; name=&#34;__codelineno-7-79&#34; href=&#34;#__codelineno-7-79&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetClipboardData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CF_DIBV5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WinBuf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-80&#34; name=&#34;__codelineno-7-80&#34; href=&#34;#__codelineno-7-80&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-81&#34; name=&#34;__codelineno-7-81&#34; href=&#34;#__codelineno-7-81&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UE_LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AIChatPlus_Internal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Fatal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;SetClipboardData failed with error code %i&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint32&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetLastError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-82&#34; name=&#34;__codelineno-7-82&#34; href=&#34;#__codelineno-7-82&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-83&#34; name=&#34;__codelineno-7-83&#34; href=&#34;#__codelineno-7-83&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-84&#34; name=&#34;__codelineno-7-84&#34; href=&#34;#__codelineno-7-84&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// finish, close clipboard&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-85&#34; name=&#34;__codelineno-7-85&#34; href=&#34;#__codelineno-7-85&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;verify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CloseClipboard&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-86&#34; name=&#34;__codelineno-7-86&#34; href=&#34;#__codelineno-7-86&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-87&#34; name=&#34;__codelineno-7-87&#34; href=&#34;#__codelineno-7-87&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;delete&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DstMip&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-88&#34; name=&#34;__codelineno-7-88&#34; href=&#34;#__codelineno-7-88&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;utexture2d-base64&#34;&gt;UTexture2D 跟 Base64 之间的转换&lt;/h3&gt;
&lt;p&gt;这个实现起来比较简单，直接上代码&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-8-1&#34; name=&#34;__codelineno-8-1&#34; href=&#34;#__codelineno-8-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;lt;Misc/Base64.h&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-2&#34; name=&#34;__codelineno-8-2&#34; href=&#34;#__codelineno-8-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;lt;ImageUtils.h&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-3&#34; name=&#34;__codelineno-8-3&#34; href=&#34;#__codelineno-8-3&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-4&#34; name=&#34;__codelineno-8-4&#34; href=&#34;#__codelineno-8-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;B64ToImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;B64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-5&#34; name=&#34;__codelineno-8-5&#34; href=&#34;#__codelineno-8-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-6&#34; name=&#34;__codelineno-8-6&#34; href=&#34;#__codelineno-8-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint8&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-7&#34; name=&#34;__codelineno-8-7&#34; href=&#34;#__codelineno-8-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FBase64&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Decode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;B64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-8&#34; name=&#34;__codelineno-8-8&#34; href=&#34;#__codelineno-8-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FImageUtils&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ImportBufferAsTexture2D&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-9&#34; name=&#34;__codelineno-8-9&#34; href=&#34;#__codelineno-8-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-10&#34; name=&#34;__codelineno-8-10&#34; href=&#34;#__codelineno-8-10&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-11&#34; name=&#34;__codelineno-8-11&#34; href=&#34;#__codelineno-8-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ImageToB64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTexture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InQuality&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-12&#34; name=&#34;__codelineno-8-12&#34; href=&#34;#__codelineno-8-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-13&#34; name=&#34;__codelineno-8-13&#34; href=&#34;#__codelineno-8-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FTextureMipDataLockGuard&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTextureGuard&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-14&#34; name=&#34;__codelineno-8-14&#34; href=&#34;#__codelineno-8-14&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-15&#34; name=&#34;__codelineno-8-15&#34; href=&#34;#__codelineno-8-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint8&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MipData&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTextureGuard&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Lock&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCK_READ_ONLY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-16&#34; name=&#34;__codelineno-8-16&#34; href=&#34;#__codelineno-8-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;check&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MipData&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;nullptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-17&#34; name=&#34;__codelineno-8-17&#34; href=&#34;#__codelineno-8-17&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-18&#34; name=&#34;__codelineno-8-18&#34; href=&#34;#__codelineno-8-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FImageView&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-19&#34; name=&#34;__codelineno-8-19&#34; href=&#34;#__codelineno-8-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MipData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetSizeX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetSizeY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-20&#34; name=&#34;__codelineno-8-20&#34; href=&#34;#__codelineno-8-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetRawImageFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetPixelFormat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InTexture&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetGammaSpace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-21&#34; name=&#34;__codelineno-8-21&#34; href=&#34;#__codelineno-8-21&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-22&#34; name=&#34;__codelineno-8-22&#34; href=&#34;#__codelineno-8-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray64&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint8&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-23&#34; name=&#34;__codelineno-8-23&#34; href=&#34;#__codelineno-8-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Ret&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-24&#34; name=&#34;__codelineno-8-24&#34; href=&#34;#__codelineno-8-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FImageUtils&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CompressImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;png&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InQuality&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-25&#34; name=&#34;__codelineno-8-25&#34; href=&#34;#__codelineno-8-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-26&#34; name=&#34;__codelineno-8-26&#34; href=&#34;#__codelineno-8-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Ret&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FBase64&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Encode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Num&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-27&#34; name=&#34;__codelineno-8-27&#34; href=&#34;#__codelineno-8-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-28&#34; name=&#34;__codelineno-8-28&#34; href=&#34;#__codelineno-8-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Ret&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-29&#34; name=&#34;__codelineno-8-29&#34; href=&#34;#__codelineno-8-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E5%9B%BE%E7%89%87-%E5%90%84%E7%A7%8D%E5%9B%BE%E7%89%87%E6%93%8D%E4%BD%9C/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 08 Aug 2024 15:41:08 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E5%9B%BE%E7%89%87-%E5%90%84%E7%A7%8D%E5%9B%BE%E7%89%87%E6%93%8D%E4%BD%9C/</guid>
      
    </item>
    
    <item>
      <title>UE 编辑器插件 UE.EditorPlus 说明文档</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 编辑器插件 EditorPlus 说明文档&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;ue-ueeditorplus&#34;&gt;UE 编辑器插件 UE.EditorPlus 说明文档&lt;/h1&gt;
&lt;h2 id=&#34;_1&#34;&gt;介绍视频&lt;/h2&gt;
&lt;p&gt;&lt;img alt=&#34;type:video&#34; src=&#34;../assets/img/2024-ue-editorplus/market/video.mp4&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_2&#34;&gt;插件源码&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/disenone/UE.EditorPlus&#34;&gt;UE.EditorPlus&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;_3&#34;&gt;商城下载&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://www.unrealengine.com/marketplace/zh-CN/product/editorplus&#34;&gt;EditorPlus&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;eueditorplus&#34;&gt;项目添加源码插件 EU.EditorPlus&lt;/h2&gt;
&lt;p&gt;参考文档：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;中文：&lt;a href=&#34;https://wiki.disenone.site/ue-%E9%80%9A%E8%BF%87%E6%8F%92%E4%BB%B6%E6%BA%90%E7%A0%81%E6%B7%BB%E5%8A%A0%E6%8F%92%E4%BB%B6/&#34;&gt;UE 通过插件源码添加插件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;English: &lt;a href=&#34;https://wiki.disenone.site/en/ue-%E9%80%9A%E8%BF%87%E6%8F%92%E4%BB%B6%E6%BA%90%E7%A0%81%E6%B7%BB%E5%8A%A0%E6%8F%92%E4%BB%B6/&#34;&gt;UE adds plugins through the plugin source code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;_4&#34;&gt;插件说明&lt;/h2&gt;
&lt;p&gt;UE.EditorPlus 是一个 UE 编辑器插件，提供了一种方便的方式来扩展编辑器菜单，并支持高级方式来扩展，同时包含了一些实用的编辑器工具。本插件支持 UE5.3+。&lt;/p&gt;
&lt;h2 id=&#34;_5&#34;&gt;扩展编辑器菜单&lt;/h2&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-editorplus/menu.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-editorplus/toolbar.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_6&#34;&gt;说明&lt;/h3&gt;
&lt;p&gt;支持多种方式扩展编辑器菜单：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;路径方式：&lt;code&gt;RegisterPathAction(&#34;/&amp;lt;MenuBar&amp;gt;Bar/&amp;lt;SubMenu&amp;gt;SubMenu/&amp;lt;Command&amp;gt;Action&#34;)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;实例化方式：&lt;code&gt;EP_NEW_MENU(FEditorPlusMenuBar)(&#34;Bar&#34;)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;混合方式：&lt;code&gt;RegisterPath(&#34;/&amp;lt;MenuBar&amp;gt;Bar/&amp;lt;SubMenu&amp;gt;SubMenu/&amp;lt;Command&amp;gt;Action&#34;,EP_NEW_MENU(FEditorPlusCommand)(&#34;Action&#34;)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;_7&#34;&gt;路径方式&lt;/h3&gt;
&lt;p&gt;可以通过这样的方式来注册一个编辑器菜单指令：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegisterPathAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;/&amp;lt;MenuBar&amp;gt;Bar/&amp;lt;SubMenu&amp;gt;SubMenu/&amp;lt;Command&amp;gt;Action&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34; href=&#34;#__codelineno-0-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FExecuteAction&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([]&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-4&#34; name=&#34;__codelineno-0-4&#34; href=&#34;#__codelineno-0-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-5&#34; name=&#34;__codelineno-0-5&#34; href=&#34;#__codelineno-0-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// do action&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-6&#34; name=&#34;__codelineno-0-6&#34; href=&#34;#__codelineno-0-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-7&#34; name=&#34;__codelineno-0-7&#34; href=&#34;#__codelineno-0-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这样就可以在编辑器菜单栏 Help 后面增加一个菜单栏 Bar，Bar 里面增加一个子菜单 SubMenu， SubMenu 里面增加一个命令 Action。&lt;/p&gt;
&lt;p&gt;完整的路径格式会是这样的：&lt;code&gt;/&amp;lt;Hook&amp;gt;HookName/&amp;lt;Type1&amp;gt;Name1/&amp;lt;Type2&amp;gt;Name2&lt;/code&gt;，第一个路径必须是 &lt;code&gt;&amp;lt;Hook&amp;gt;&lt;/code&gt;，目前支持的类型和限制：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;Hook&amp;gt;&lt;/code&gt;：表示需要在哪个 Hook 的位置上生成菜单，后续路径不能有 &lt;code&gt;&amp;lt;Hook&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;MenuBar&amp;gt;&lt;/code&gt;：菜单栏，后面路径不能有 &lt;code&gt;&amp;lt;Hook&amp;gt;, &amp;lt;MenuBar&amp;gt;, &amp;lt;ToolBar&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;ToolBar&amp;gt;&lt;/code&gt;: 工具栏，后面路径不能有 &lt;code&gt;&amp;lt;Hook&amp;gt;, &amp;lt;MenuBar&amp;gt;, &amp;lt;ToolBar&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;Section&amp;gt;&lt;/code&gt;：菜单分节，后面路径不能有 &lt;code&gt;&amp;lt;Hook&amp;gt;, &amp;lt;MenuBar&amp;gt;, &amp;lt;Section&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;Separator&amp;gt;&lt;/code&gt;：菜单分隔符，后面路径不能有 &lt;code&gt;&amp;lt;Hook&amp;gt;, &amp;lt;MenuBar&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;SubMenu&amp;gt;&lt;/code&gt;：子菜单，后面路径不能有 &lt;code&gt;&amp;lt;Hook&amp;gt;, &amp;lt;MenuBar&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;Command&amp;gt;&lt;/code&gt;：菜单命令，后面不能有任何路径&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;Widget&amp;gt;&lt;/code&gt;：更多可扩展定制的 Slate UI 组件，后面不能有任何路径&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;更简易的路径形式：&lt;code&gt;/BarName/SubMenuName1/SubMenuName2/CommandName&lt;/code&gt;，如果不指定类型，默认路径的第一个是 &lt;code&gt;&amp;lt;MenuBar&amp;gt;&lt;/code&gt;，中间的是 &lt;code&gt;&amp;lt;SubMenu&amp;gt;&lt;/code&gt;，最后的是 &lt;code&gt;&amp;lt;Command&amp;gt;&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;如果没有指定 &lt;code&gt;&amp;lt;Hook&amp;gt;&lt;/code&gt; 则自动最前面加上 &lt;code&gt;&amp;lt;Hook&amp;gt;Help&lt;/code&gt;，表示在 Help 菜单后面添加菜单栏。&lt;/p&gt;
&lt;h3 id=&#34;_8&#34;&gt;实例化方式&lt;/h3&gt;
&lt;p&gt;路径方式是自动把所有节点根据类型和默认参数实例化出来，我们也可以自己控制实例化，可以更细致控制扩展的内容。&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;EP_NEW_MENU&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MyBar&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MyBar&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MyBar&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MyBar&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MyBarTips&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MyBarTips&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-2&#34; name=&#34;__codelineno-1-2&#34; href=&#34;#__codelineno-1-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegisterPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-3&#34; name=&#34;__codelineno-1-3&#34; href=&#34;#__codelineno-1-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-4&#34; name=&#34;__codelineno-1-4&#34; href=&#34;#__codelineno-1-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EP_NEW_MENU&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusSubMenu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MySubMenu&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-5&#34; name=&#34;__codelineno-1-5&#34; href=&#34;#__codelineno-1-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-6&#34; name=&#34;__codelineno-1-6&#34; href=&#34;#__codelineno-1-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EP_NEW_MENU&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusCommand&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MyAction&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-7&#34; name=&#34;__codelineno-1-7&#34; href=&#34;#__codelineno-1-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BindAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FExecuteAction&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([]&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-8&#34; name=&#34;__codelineno-1-8&#34; href=&#34;#__codelineno-1-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-9&#34; name=&#34;__codelineno-1-9&#34; href=&#34;#__codelineno-1-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// do action&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-10&#34; name=&#34;__codelineno-1-10&#34; href=&#34;#__codelineno-1-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})),&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-11&#34; name=&#34;__codelineno-1-11&#34; href=&#34;#__codelineno-1-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-12&#34; name=&#34;__codelineno-1-12&#34; href=&#34;#__codelineno-1-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;实例化 &lt;code&gt;MyBar&lt;/code&gt; 的时候可以传入 Hook 名字，本地化名字，本地化提示参数（&lt;code&gt;&#34;MyBar&#34;, LOCTEXT(&#34;MyBar&#34;, &#34;MyBar&#34;), LOCTEXT(&#34;MyBarTips&#34;, &#34;MyBarTips&#34;)&lt;/code&gt;）。上面代码就相当于路径方式 &lt;code&gt;/&amp;lt;Hook&amp;gt;Help/&amp;lt;MenuBar&amp;gt;MyBar/&amp;lt;SubMenu&amp;gt;MySubMenu/&amp;lt;Command&amp;gt;MyAction&lt;/code&gt;。&lt;/p&gt;
&lt;h3 id=&#34;_9&#34;&gt;混合方式&lt;/h3&gt;
&lt;p&gt;当然还可以两种方式混合使用：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-2-1&#34; name=&#34;__codelineno-2-1&#34; href=&#34;#__codelineno-2-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegisterPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-2&#34; name=&#34;__codelineno-2-2&#34; href=&#34;#__codelineno-2-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;/&amp;lt;MenuBar&amp;gt;Bar/&amp;lt;SubMenu&amp;gt;SubMenu/&amp;lt;Command&amp;gt;Action&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-3&#34; name=&#34;__codelineno-2-3&#34; href=&#34;#__codelineno-2-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EP_NEW_MENU&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusCommand&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Action&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-4&#34; name=&#34;__codelineno-2-4&#34; href=&#34;#__codelineno-2-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BindAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FExecuteAction&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([]&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-5&#34; name=&#34;__codelineno-2-5&#34; href=&#34;#__codelineno-2-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-6&#34; name=&#34;__codelineno-2-6&#34; href=&#34;#__codelineno-2-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// do action&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-7&#34; name=&#34;__codelineno-2-7&#34; href=&#34;#__codelineno-2-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})),&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-8&#34; name=&#34;__codelineno-2-8&#34; href=&#34;#__codelineno-2-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这种情况下，插件会自动实例化中间路径的节点，最后的路径使用用户自己实例化的节点。&lt;/p&gt;
&lt;h3 id=&#34;_10&#34;&gt;更多用例&lt;/h3&gt;
&lt;p&gt;头文件:&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-3-1&#34; name=&#34;__codelineno-3-1&#34; href=&#34;#__codelineno-3-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;lt;EditorPlusPath.h&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;路径方式指定本地化语言，&lt;code&gt;EP_FNAME_HOOK_AUTO&lt;/code&gt; 表示自动使用路径名字作为 &lt;code&gt;Hook&lt;/code&gt; 名字：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-4-1&#34; name=&#34;__codelineno-4-1&#34; href=&#34;#__codelineno-4-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegisterPathAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-2&#34; name=&#34;__codelineno-4-2&#34; href=&#34;#__codelineno-4-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;/Bar/Action&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-3&#34; name=&#34;__codelineno-4-3&#34; href=&#34;#__codelineno-4-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FExecuteAction&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([]&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-4&#34; name=&#34;__codelineno-4-4&#34; href=&#34;#__codelineno-4-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-5&#34; name=&#34;__codelineno-4-5&#34; href=&#34;#__codelineno-4-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// do action&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-6&#34; name=&#34;__codelineno-4-6&#34; href=&#34;#__codelineno-4-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}),&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-7&#34; name=&#34;__codelineno-4-7&#34; href=&#34;#__codelineno-4-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EP_FNAME_HOOK_AUTO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-8&#34; name=&#34;__codelineno-4-8&#34; href=&#34;#__codelineno-4-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Action&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Action&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-9&#34; name=&#34;__codelineno-4-9&#34; href=&#34;#__codelineno-4-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;ActionTips&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;ActionTips&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;通过路径获取节点并设置本地化文本：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-5-1&#34; name=&#34;__codelineno-5-1&#34; href=&#34;#__codelineno-5-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetNodeByPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;/MenuTest&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-2&#34; name=&#34;__codelineno-5-2&#34; href=&#34;#__codelineno-5-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetFriendlyName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTest&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTest&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-3&#34; name=&#34;__codelineno-5-3&#34; href=&#34;#__codelineno-5-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetFriendlyTips&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestTips&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestTips&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;路径末端添加一个 Slate UI 控件&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-6-1&#34; name=&#34;__codelineno-6-1&#34; href=&#34;#__codelineno-6-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegisterPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-2&#34; name=&#34;__codelineno-6-2&#34; href=&#34;#__codelineno-6-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;/&amp;lt;MenuBar&amp;gt;Bar/&amp;lt;SubMenu&amp;gt;SubMenu/&amp;lt;Widget&amp;gt;Widget&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-3&#34; name=&#34;__codelineno-6-3&#34; href=&#34;#__codelineno-6-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EP_NEW_MENU&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusWidget&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Widget&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Widget&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Widget&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-4&#34; name=&#34;__codelineno-6-4&#34; href=&#34;#__codelineno-6-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BindWidget&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SNew&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SHorizontalBox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)));&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-5&#34; name=&#34;__codelineno-6-5&#34; href=&#34;#__codelineno-6-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;在 UE 自带的 Hook 里面添加新的节点&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-7-1&#34; name=&#34;__codelineno-7-1&#34; href=&#34;#__codelineno-7-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegisterPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&amp;lt;Hook&amp;gt;EpicGamesHelp/&amp;lt;Separator&amp;gt;ExtendSeparator&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;多次声明相同的路径，都被识别成同一个路径，因此可以不断扩展相同的路径&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-8-1&#34; name=&#34;__codelineno-8-1&#34; href=&#34;#__codelineno-8-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegisterPathAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;/MenuTest/SubMenu1/SubMenu1/Path1&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Action&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EP_FNAME_HOOK_AUTO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Path1&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Path1&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Path1Tips&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Path1Tips&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-2&#34; name=&#34;__codelineno-8-2&#34; href=&#34;#__codelineno-8-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegisterPathAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;/MenuTest/SubMenu1/SubMenu1/Path2&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Action&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EP_FNAME_HOOK_AUTO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Path2&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Path2&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Path2Tips&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Path2Tips&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;为一个节点继续扩展路径&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-9-1&#34; name=&#34;__codelineno-9-1&#34; href=&#34;#__codelineno-9-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetNodeByPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;/MenuTest&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-2&#34; name=&#34;__codelineno-9-2&#34; href=&#34;#__codelineno-9-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegisterChildPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&amp;lt;SubMenu&amp;gt;Sub/&amp;lt;Separator&amp;gt;Sep&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;删除一个路径&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-10-1&#34; name=&#34;__codelineno-10-1&#34; href=&#34;#__codelineno-10-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UnregisterPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;/MenuTest/SubMenu1/SubMenu1/Path1&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;扩展工具栏
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-11-1&#34; name=&#34;__codelineno-11-1&#34; href=&#34;#__codelineno-11-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegisterPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;/&amp;lt;Hook&amp;gt;ProjectSettings/&amp;lt;ToolBar&amp;gt;MenuTestToolBar&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-2&#34; name=&#34;__codelineno-11-2&#34; href=&#34;#__codelineno-11-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-3&#34; name=&#34;__codelineno-11-3&#34; href=&#34;#__codelineno-11-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EP_NEW_MENU&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusCommand&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;ToolBarCommand1&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-4&#34; name=&#34;__codelineno-11-4&#34; href=&#34;#__codelineno-11-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BindAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(...)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-5&#34; name=&#34;__codelineno-11-5&#34; href=&#34;#__codelineno-11-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;h3 id=&#34;_11&#34;&gt;接口说明&lt;/h3&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-12-1&#34; name=&#34;__codelineno-12-1&#34; href=&#34;#__codelineno-12-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;EDITORPLUS_API&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusPath&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-2&#34; name=&#34;__codelineno-12-2&#34; href=&#34;#__codelineno-12-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-3&#34; name=&#34;__codelineno-12-3&#34; href=&#34;#__codelineno-12-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-4&#34; name=&#34;__codelineno-12-4&#34; href=&#34;#__codelineno-12-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-12-5&#34; name=&#34;__codelineno-12-5&#34; href=&#34;#__codelineno-12-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSharedPtr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegisterPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSharedPtr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Menu&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;nullptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-6&#34; name=&#34;__codelineno-12-6&#34; href=&#34;#__codelineno-12-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSharedPtr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegisterPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FriendlyName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FriendlyTips&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-7&#34; name=&#34;__codelineno-12-7&#34; href=&#34;#__codelineno-12-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSharedPtr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegisterPathAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-8&#34; name=&#34;__codelineno-12-8&#34; href=&#34;#__codelineno-12-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FExecuteAction&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ExecuteAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FName&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Hook&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EP_FNAME_HOOK_AUTO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-9&#34; name=&#34;__codelineno-12-9&#34; href=&#34;#__codelineno-12-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FriendlyName&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetEmpty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FriendlyTips&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetEmpty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-10&#34; name=&#34;__codelineno-12-10&#34; href=&#34;#__codelineno-12-10&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-12-11&#34; name=&#34;__codelineno-12-11&#34; href=&#34;#__codelineno-12-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSharedPtr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegisterChildPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-12&#34; name=&#34;__codelineno-12-12&#34; href=&#34;#__codelineno-12-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSharedRef&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InParent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSharedPtr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Menu&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;nullptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-13&#34; name=&#34;__codelineno-12-13&#34; href=&#34;#__codelineno-12-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSharedPtr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegisterChildPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-14&#34; name=&#34;__codelineno-12-14&#34; href=&#34;#__codelineno-12-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSharedRef&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InParent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FriendlyName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FriendlyTips&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-15&#34; name=&#34;__codelineno-12-15&#34; href=&#34;#__codelineno-12-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSharedPtr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegisterChildPathAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-16&#34; name=&#34;__codelineno-12-16&#34; href=&#34;#__codelineno-12-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSharedRef&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InParent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FExecuteAction&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ExecuteAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-17&#34; name=&#34;__codelineno-12-17&#34; href=&#34;#__codelineno-12-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FName&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Hook&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EP_FNAME_HOOK_AUTO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FriendlyName&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetEmpty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FriendlyTips&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetEmpty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-18&#34; name=&#34;__codelineno-12-18&#34; href=&#34;#__codelineno-12-18&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-12-19&#34; name=&#34;__codelineno-12-19&#34; href=&#34;#__codelineno-12-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;UnregisterPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-20&#34; name=&#34;__codelineno-12-20&#34; href=&#34;#__codelineno-12-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSharedPtr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Leaf&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;nullptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-21&#34; name=&#34;__codelineno-12-21&#34; href=&#34;#__codelineno-12-21&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-12-22&#34; name=&#34;__codelineno-12-22&#34; href=&#34;#__codelineno-12-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSharedPtr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetNodeByPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-23&#34; name=&#34;__codelineno-12-23&#34; href=&#34;#__codelineno-12-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;RegisterPath&lt;/code&gt;：生成路径菜单&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RegisterPathAction&lt;/code&gt;：生成路径菜单，并自动为末端 &lt;code&gt;&amp;lt;Command&amp;gt;&lt;/code&gt; 节点绑定操作&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RegisterChildPath&lt;/code&gt;：为指定节点继续生成子路径&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RegisterChildPathAction&lt;/code&gt;：为指定节点继续生成子路径，并自动绑定操作&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UnregisterPath&lt;/code&gt;：删除路径，&lt;code&gt;Leaf&lt;/code&gt; 在有多个同名的末端节点可以指定严格匹配。删除的过程中，会回溯中间节点，一旦中间节点没有任何子节点也会被删除&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GetNodeByPath&lt;/code&gt;：根据路径获取节点&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;节点类型&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-13-1&#34; name=&#34;__codelineno-13-1&#34; href=&#34;#__codelineno-13-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// base class of all node&lt;/span&gt;
&lt;a id=&#34;__codelineno-13-2&#34; name=&#34;__codelineno-13-2&#34; href=&#34;#__codelineno-13-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;EDITORPLUS_API&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSharedFromThis&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;a id=&#34;__codelineno-13-3&#34; name=&#34;__codelineno-13-3&#34; href=&#34;#__codelineno-13-3&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-4&#34; name=&#34;__codelineno-13-4&#34; href=&#34;#__codelineno-13-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;EDITORPLUS_API&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusHook&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEditorPlusMenuBaseRoot&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;a id=&#34;__codelineno-13-5&#34; name=&#34;__codelineno-13-5&#34; href=&#34;#__codelineno-13-5&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-6&#34; name=&#34;__codelineno-13-6&#34; href=&#34;#__codelineno-13-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;EDITORPLUS_API&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBar&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEditorPlusMenuBaseNode&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;a id=&#34;__codelineno-13-7&#34; name=&#34;__codelineno-13-7&#34; href=&#34;#__codelineno-13-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-8&#34; name=&#34;__codelineno-13-8&#34; href=&#34;#__codelineno-13-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;EDITORPLUS_API&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusToolBar&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEditorPlusMenuBaseNode&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;a id=&#34;__codelineno-13-9&#34; name=&#34;__codelineno-13-9&#34; href=&#34;#__codelineno-13-9&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-10&#34; name=&#34;__codelineno-13-10&#34; href=&#34;#__codelineno-13-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;EDITORPLUS_API&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusSection&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEditorPlusMenuBaseNode&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;a id=&#34;__codelineno-13-11&#34; name=&#34;__codelineno-13-11&#34; href=&#34;#__codelineno-13-11&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-12&#34; name=&#34;__codelineno-13-12&#34; href=&#34;#__codelineno-13-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;EDITORPLUS_API&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusSeparator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEditorPlusMenuBaseNode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;a id=&#34;__codelineno-13-13&#34; name=&#34;__codelineno-13-13&#34; href=&#34;#__codelineno-13-13&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-14&#34; name=&#34;__codelineno-13-14&#34; href=&#34;#__codelineno-13-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;EDITORPLUS_API&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusSubMenu&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEditorPlusMenuBaseNode&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;a id=&#34;__codelineno-13-15&#34; name=&#34;__codelineno-13-15&#34; href=&#34;#__codelineno-13-15&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-16&#34; name=&#34;__codelineno-13-16&#34; href=&#34;#__codelineno-13-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;EDITORPLUS_API&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusCommand&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEditorPlusMenuBaseLeaf&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;a id=&#34;__codelineno-13-17&#34; name=&#34;__codelineno-13-17&#34; href=&#34;#__codelineno-13-17&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-18&#34; name=&#34;__codelineno-13-18&#34; href=&#34;#__codelineno-13-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;EDITORPLUS_API&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusWidget&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEditorPlusMenuBaseLeaf&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;更多样例和接口说明请参考源码 &lt;a href=&#34;https://github.com/disenone/UE.EditorPlus&#34;&gt;UE.EditorPlus&lt;/a&gt;，测试用例 &lt;a href=&#34;https://github.com/disenone/UE.EditorPlus/blob/ue5.3/Source/EditorPlusTools/Private/MenuTest/MenuTest.cpp&#34;&gt;MenuTest.cpp&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;_12&#34;&gt;模块化管理&lt;/h3&gt;
&lt;p&gt;UE.EditorPlus 还提供了一个模块化管理扩展菜单的框架，支持插件加载和卸载的时候，自动加载和卸载扩展的菜单&lt;/p&gt;
&lt;p&gt;让菜单类继承 &lt;code&gt;IEditorPlusToolInterface&lt;/code&gt;，并覆写 &lt;code&gt;OnStartup&lt;/code&gt; 和 &lt;code&gt;OnShutdown&lt;/code&gt; 函数。&lt;code&gt;OnStartup&lt;/code&gt; 负责创建菜单，&lt;code&gt;OnShutdown&lt;/code&gt; 负责调用节点的 &lt;code&gt;Destroy&lt;/code&gt; 函数清理菜单。单节点的引用数归0，则会执行自动清理。&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-14-1&#34; name=&#34;__codelineno-14-1&#34; href=&#34;#__codelineno-14-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;FMenuTest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IEditorPlusToolInterface&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-2&#34; name=&#34;__codelineno-14-2&#34; href=&#34;#__codelineno-14-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-3&#34; name=&#34;__codelineno-14-3&#34; href=&#34;#__codelineno-14-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-4&#34; name=&#34;__codelineno-14-4&#34; href=&#34;#__codelineno-14-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;virtual&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OnStartup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;override&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-5&#34; name=&#34;__codelineno-14-5&#34; href=&#34;#__codelineno-14-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;virtual&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;OnShutdown&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;override&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-6&#34; name=&#34;__codelineno-14-6&#34; href=&#34;#__codelineno-14-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-7&#34; name=&#34;__codelineno-14-7&#34; href=&#34;#__codelineno-14-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-14-8&#34; name=&#34;__codelineno-14-8&#34; href=&#34;#__codelineno-14-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMenuTest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OnStartup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-9&#34; name=&#34;__codelineno-14-9&#34; href=&#34;#__codelineno-14-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-10&#34; name=&#34;__codelineno-14-10&#34; href=&#34;#__codelineno-14-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BuildPathMenu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-11&#34; name=&#34;__codelineno-14-11&#34; href=&#34;#__codelineno-14-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BuildCustomMenu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-12&#34; name=&#34;__codelineno-14-12&#34; href=&#34;#__codelineno-14-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BuildMixMenu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-13&#34; name=&#34;__codelineno-14-13&#34; href=&#34;#__codelineno-14-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BuildExtendMenu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-14&#34; name=&#34;__codelineno-14-14&#34; href=&#34;#__codelineno-14-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-15&#34; name=&#34;__codelineno-14-15&#34; href=&#34;#__codelineno-14-15&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-14-16&#34; name=&#34;__codelineno-14-16&#34; href=&#34;#__codelineno-14-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMenuTest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OnShutdown&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-17&#34; name=&#34;__codelineno-14-17&#34; href=&#34;#__codelineno-14-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-18&#34; name=&#34;__codelineno-14-18&#34; href=&#34;#__codelineno-14-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Menu&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Menus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-19&#34; name=&#34;__codelineno-14-19&#34; href=&#34;#__codelineno-14-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-20&#34; name=&#34;__codelineno-14-20&#34; href=&#34;#__codelineno-14-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Menu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IsValid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Menu&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Destroy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-21&#34; name=&#34;__codelineno-14-21&#34; href=&#34;#__codelineno-14-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-22&#34; name=&#34;__codelineno-14-22&#34; href=&#34;#__codelineno-14-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Menus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Empty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-23&#34; name=&#34;__codelineno-14-23&#34; href=&#34;#__codelineno-14-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;菜单管理类继承 &lt;code&gt;IEditorPlusToolManagerInterface&lt;/code&gt;，并覆写 &lt;code&gt;AddTools&lt;/code&gt; 函数，在 &lt;code&gt;AddTools&lt;/code&gt; 里面添加菜单类&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-15-1&#34; name=&#34;__codelineno-15-1&#34; href=&#34;#__codelineno-15-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;FEditorPlusToolsImpl&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IEditorPlusToolManagerInterface&lt;/span&gt;
&lt;a id=&#34;__codelineno-15-2&#34; name=&#34;__codelineno-15-2&#34; href=&#34;#__codelineno-15-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-15-3&#34; name=&#34;__codelineno-15-3&#34; href=&#34;#__codelineno-15-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-15-4&#34; name=&#34;__codelineno-15-4&#34; href=&#34;#__codelineno-15-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;virtual&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddTools&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;override&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-15-5&#34; name=&#34;__codelineno-15-5&#34; href=&#34;#__codelineno-15-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-15-6&#34; name=&#34;__codelineno-15-6&#34; href=&#34;#__codelineno-15-6&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-15-7&#34; name=&#34;__codelineno-15-7&#34; href=&#34;#__codelineno-15-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusToolsImpl&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddTools&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-15-8&#34; name=&#34;__codelineno-15-8&#34; href=&#34;#__codelineno-15-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-15-9&#34; name=&#34;__codelineno-15-9&#34; href=&#34;#__codelineno-15-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Tools&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Num&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;a id=&#34;__codelineno-15-10&#34; name=&#34;__codelineno-15-10&#34; href=&#34;#__codelineno-15-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-15-11&#34; name=&#34;__codelineno-15-11&#34; href=&#34;#__codelineno-15-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Tools&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Emplace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MakeShared&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMenuTest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-15-12&#34; name=&#34;__codelineno-15-12&#34; href=&#34;#__codelineno-15-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-15-13&#34; name=&#34;__codelineno-15-13&#34; href=&#34;#__codelineno-15-13&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-15-14&#34; name=&#34;__codelineno-15-14&#34; href=&#34;#__codelineno-15-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;插件加载和卸载的时候分别调用管理类的 &lt;code&gt;StartupTools&lt;/code&gt; 和 &lt;code&gt;ShutdownTools&lt;/code&gt; 函数&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-16-1&#34; name=&#34;__codelineno-16-1&#34; href=&#34;#__codelineno-16-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;FEditorPlusToolsModule::StartupModule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-2&#34; name=&#34;__codelineno-16-2&#34; href=&#34;#__codelineno-16-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-3&#34; name=&#34;__codelineno-16-3&#34; href=&#34;#__codelineno-16-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Impl&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusToolsImpl&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-4&#34; name=&#34;__codelineno-16-4&#34; href=&#34;#__codelineno-16-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Impl&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;StartupTools&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-5&#34; name=&#34;__codelineno-16-5&#34; href=&#34;#__codelineno-16-5&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-16-6&#34; name=&#34;__codelineno-16-6&#34; href=&#34;#__codelineno-16-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-7&#34; name=&#34;__codelineno-16-7&#34; href=&#34;#__codelineno-16-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;FEditorPlusToolsModule::ShutdownModule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-8&#34; name=&#34;__codelineno-16-8&#34; href=&#34;#__codelineno-16-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-9&#34; name=&#34;__codelineno-16-9&#34; href=&#34;#__codelineno-16-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Impl&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ShutdownTools&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-10&#34; name=&#34;__codelineno-16-10&#34; href=&#34;#__codelineno-16-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;完成以上适配，则可以自动在加载和卸载插件的时候，自动加载和卸载扩展的菜单。&lt;/p&gt;
&lt;h2 id=&#34;_13&#34;&gt;编辑器工具&lt;/h2&gt;
&lt;p&gt;UE.EditorPlus 还提供了一些实用的编辑器工具&lt;/p&gt;
&lt;h2 id=&#34;_14&#34;&gt;创建编辑器窗口&lt;/h2&gt;
&lt;p&gt;使用 EditorPlus，可以很简单的创建一个新的编辑器窗口&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-17-1&#34; name=&#34;__codelineno-17-1&#34; href=&#34;#__codelineno-17-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// register spawn tab&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-2&#34; name=&#34;__codelineno-17-2&#34; href=&#34;#__codelineno-17-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tab&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MakeShared&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusTab&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;ClassBrowser&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;ClassBrowser&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;ClassBrowserTip&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Open the ClassBrowser&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-3&#34; name=&#34;__codelineno-17-3&#34; href=&#34;#__codelineno-17-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tab&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Register&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SClassBrowserTab&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-4&#34; name=&#34;__codelineno-17-4&#34; href=&#34;#__codelineno-17-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-17-5&#34; name=&#34;__codelineno-17-5&#34; href=&#34;#__codelineno-17-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// register menu action to spawn tab&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-6&#34; name=&#34;__codelineno-17-6&#34; href=&#34;#__codelineno-17-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegisterPathAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-7&#34; name=&#34;__codelineno-17-7&#34; href=&#34;#__codelineno-17-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;/EditorPlusTools/ClassBrowser&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-8&#34; name=&#34;__codelineno-17-8&#34; href=&#34;#__codelineno-17-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FExecuteAction&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateSP&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Tab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ToSharedRef&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusTab&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TryInvokeTab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-9&#34; name=&#34;__codelineno-17-9&#34; href=&#34;#__codelineno-17-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;SClassBrowserTab&lt;/code&gt; 是一个自定义的 UI 控件&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-18-1&#34; name=&#34;__codelineno-18-1&#34; href=&#34;#__codelineno-18-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;SClassBrowserTab&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;final&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SCompoundWidget&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-2&#34; name=&#34;__codelineno-18-2&#34; href=&#34;#__codelineno-18-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-3&#34; name=&#34;__codelineno-18-3&#34; href=&#34;#__codelineno-18-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SLATE_BEGIN_ARGS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SClassBrowserTab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-4&#34; name=&#34;__codelineno-18-4&#34; href=&#34;#__codelineno-18-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-5&#34; name=&#34;__codelineno-18-5&#34; href=&#34;#__codelineno-18-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SLATE_END_ARGS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-6&#34; name=&#34;__codelineno-18-6&#34; href=&#34;#__codelineno-18-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-7&#34; name=&#34;__codelineno-18-7&#34; href=&#34;#__codelineno-18-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;classbrowser&#34;&gt;ClassBrowser&lt;/h3&gt;
&lt;p&gt;ClassBrowser 是一个 UE Class 查看器，通过菜单 EditorPlusTools -&amp;gt; ClassBrowser 来打开&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-editorplus/classbrowser_menu.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-editorplus/classbrowser.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;基于 UE 的反射来实现，可以很方便查看 UE 各种类型的成员信息，说明提示等，支持模糊搜索，并能跳转打开父类的信息。&lt;/p&gt;
&lt;h3 id=&#34;menucollections&#34;&gt;MenuCollections&lt;/h3&gt;
&lt;p&gt;MenuCollections 是一个菜单命令快速查找和收藏工具，能够帮助你快速找到需要执行的菜单命令，并可以收藏常用命令，提升效率。&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-editorplus/menucollection_find.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-editorplus/menucollection_star.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;slateresourcebrowser&#34;&gt;SlateResourceBrowser&lt;/h3&gt;
&lt;p&gt;SlateResourceBrowser 是一个可以快速查看 Slate UI 资源的工具，能够帮助你浏览和查找需要的编辑器资源，方便扩展编辑器。&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-editorplus/slateresourcebrowser_color.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-editorplus/slateresourcebrowser_icon.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-editorplus/slateresourcebrowser_font.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2024-ue-editorplus/slateresourcebrowser_widgetstyle.png&#34; /&gt;&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E7%BC%96%E8%BE%91%E5%99%A8%E6%8F%92%E4%BB%B6-EditorPlus/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Sun, 04 Aug 2024 15:51:52 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E7%BC%96%E8%BE%91%E5%99%A8%E6%8F%92%E4%BB%B6-EditorPlus/</guid>
      
    </item>
    
    <item>
      <title>说明文档</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 插件 AIChatPlus 说明文档&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;ue-aichatplus&#34;&gt;UE 插件 AIChatPlus 说明文档&lt;/h1&gt;
&lt;h2 id=&#34;_1&#34;&gt;插件商城&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://www.fab.com/zh-cn/listings/0e49d138-10e1-452e-ba07-9a4bea578ace&#34;&gt;AIChatPlus&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;_2&#34;&gt;公共仓库&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/disenone/UE.AIChatPlus.Public&#34;&gt;UE.AIChatPlus.Public&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;_3&#34;&gt;插件简介&lt;/h2&gt;
&lt;p&gt;最新版本 v2.0.0。&lt;/p&gt;
&lt;p&gt;本插件支持 UE5.2 - UE5.7。&lt;/p&gt;
&lt;p&gt;UE.AIChatPlus 是一个 UnrealEngine 插件，该插件实现了与各种 GPT AI 聊天服务进行通信，目前支持的服务有 OpenAI (ChatGPT, DALL-E)，Azure OpenAI (ChatGPT, DALL-E), Claude, Google Gemini, Ollama, llama.cpp 本地离线。未来还会继续支持更多服务提供商。它的实现基于异步 REST 请求，性能高效，方便 UE 开发人员接入这些 AI 聊天服务。&lt;/p&gt;
&lt;p&gt;同时 UE.AIChatPlus 还包含了一个编辑器工具，可以直接在编辑器中使用这些 AI 聊天服务，生成文本和图像，分析图像等。&lt;/p&gt;
&lt;h2 id=&#34;_4&#34;&gt;主要功能&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;全新！&lt;/strong&gt;所有 API 支持 ToolCall。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;全新！&lt;/strong&gt;OpenAI/Azure 支持 speech-to-text 和 text-to-speech。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;全新！&lt;/strong&gt;蓝图支持 Json。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;全新！&lt;/strong&gt;离线 AI llama.cpp 升级至版本 b6792。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;全新！&lt;/strong&gt;离线 AI llama.cpp 支持 GPU Cuda 和 Metal。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;全新！&lt;/strong&gt;支持 Gemini 语音转文字。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;API&lt;/strong&gt;：支持 OpenAI、Azure OpenAI、Claude、Gemini、Ollama、llama.cpp、DeepSeek&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;离线实时 API&lt;/strong&gt;：支持 llama.cpp 离线运行 AI，支持 GPU Cuda 和 Metal。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;文本转文本&lt;/strong&gt;：各种 API 支持文本生成。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;文本转图像&lt;/strong&gt;：OpenAI Dall-E&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;图像转文本&lt;/strong&gt;：OpenAI Vision、Claude、Gemini、Ollama、llama.cpp&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;图像转图像&lt;/strong&gt;：OpenAI Dall-E&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;语音转文本&lt;/strong&gt;：Gemini&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;蓝图&lt;/strong&gt;：所有 API 和功能都支持蓝图&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;编辑器聊天工具&lt;/strong&gt;：功能丰富、精心打造的编辑器 AI 聊天工具&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;异步调用&lt;/strong&gt;：所有的 API 都可以异步调用&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实用工具&lt;/strong&gt;：各种图像、音频工具&lt;/p&gt;
&lt;h2 id=&#34;api&#34;&gt;支持的 API：&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;离线 llama.cpp&lt;/strong&gt;：与 llama.cpp 库集成，可以离线运行 AI 模型！还支持多模态模型（实验性）。支持 Win64/Mac/Android/IOS。支持 GPU CUDA 和 METAL。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;OpenAI&lt;/strong&gt;：/chat/completions、/completions、/images/generations、/images/edits、/images/variations&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Azure OpenAI&lt;/strong&gt;：/chat/completions、/images/generations&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Claude&lt;/strong&gt;：/messages、/complete&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Gemini&lt;/strong&gt;：:generateText、:generateContent、:streamGenerateContent&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ollama&lt;/strong&gt;：/api/chat、/api/generate、/api/tags&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DeepSeek&lt;/strong&gt;：/chat/completions&lt;/p&gt;
&lt;h2 id=&#34;_5&#34;&gt;使用说明&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;../ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Blueprint-GetStarted/&#34;&gt;&lt;strong&gt;使用说明 - 蓝图篇&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;../ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Source-GetStarted/&#34;&gt;&lt;strong&gt;使用说明 - C++ 篇&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;../ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-EditorTool-GetStarted/&#34;&gt;&lt;strong&gt;使用说明 - 编辑器篇&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;../ue-%E6%8F%92%E4%BB%B6-AIChatPlus-Usage-Package-GetStarted/&#34;&gt;&lt;strong&gt;使用说明 - 打包&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;_6&#34;&gt;更改日志&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;../ue-%E6%8F%92%E4%BB%B6-AIChatPlus-ChangeLogs/&#34;&gt;&lt;strong&gt;更改日志&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;_7&#34;&gt;技术支持&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;评论&lt;/strong&gt;：有任何问题欢迎在下面评论区留言&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;邮件&lt;/strong&gt;：也可以通过邮箱给我发邮件 ( disenonec@gmail.com )&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;discord&lt;/strong&gt;: 即将上线&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Sun, 04 Aug 2024 15:49:54 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%8F%92%E4%BB%B6-AIChatPlus/</guid>
      
    </item>
    
    <item>
      <title>Python 杂谈 2 - Python3.12 热更新</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;Python 杂谈 2 - Python3.12 热更新&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;python-2-python312&#34;&gt;Python 杂谈 2 - Python3.12 热更新&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;记录如何在 Python3.12 中实现热更新&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;_1&#34;&gt;热更新&lt;/h2&gt;
&lt;p&gt;热更新（Hot Reload）可以理解在不需要重启程序的情况下对其进行更新的技术。这项技术在游戏行业有广泛的应用，开发者对游戏问题进行修复的时候，为了不对玩家造成影响，往往需要采用一些静默更新的方式，也就是热更新。&lt;/p&gt;
&lt;h2 id=&#34;python&#34;&gt;Python 热更新&lt;/h2&gt;
&lt;p&gt;Python 本身是动态语言，一切皆是对象，是有能力做到热更新的。我们可以粗略把 Python 中的需要热更的对象分成两种：数据 和 函数。&lt;/p&gt;
&lt;p&gt;数据，可以理解成游戏中的数值或者设定，譬如玩家的等级，装备等等一些数据，部分数据是不应该热更的（譬如玩家当前等级，玩家身上拥有哪些装备，这些数据的修改不应该通过热更来实现），部分数据是我们想要热更的（譬如装备的基础数值设定，技能的基础数值设定，UI 上的文字等等）。&lt;/p&gt;
&lt;p&gt;函数，可以理解成游戏逻辑，这基本都是我们想要热更的，逻辑错误基本都需要通过热更新函数来实现。&lt;/p&gt;
&lt;p&gt;下面我们来具体看看有什么方法可以对 Python3.12 执行热更新。&lt;/p&gt;
&lt;h2 id=&#34;hotfix&#34;&gt;Hotfix&lt;/h2&gt;
&lt;p&gt;第一种方法我们叫做 Hotfix，通过让程序（客户端程序 / 服务端程序都可以）执行一段特定的 Python 代码，实现对数据和函数的热更新。一段简单的 Hotfix 代码可能是这样：&lt;/p&gt;
&lt;div class=&#34;language-python highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;# hotfix code&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34; href=&#34;#__codelineno-0-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;# hotfix data&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-4&#34; name=&#34;__codelineno-0-4&#34; href=&#34;#__codelineno-0-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;weapon_data&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-5&#34; name=&#34;__codelineno-0-5&#34; href=&#34;#__codelineno-0-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;weapon_data&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gun&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;damage&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-6&#34; name=&#34;__codelineno-0-6&#34; href=&#34;#__codelineno-0-6&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-7&#34; name=&#34;__codelineno-0-7&#34; href=&#34;#__codelineno-0-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;# hotfix func&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-8&#34; name=&#34;__codelineno-0-8&#34; href=&#34;#__codelineno-0-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;player&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-9&#34; name=&#34;__codelineno-0-9&#34; href=&#34;#__codelineno-0-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;new_fire_func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;target&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-10&#34; name=&#34;__codelineno-0-10&#34; href=&#34;#__codelineno-0-10&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;n&#34;&gt;target&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;health&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;weapon_data&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gun&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;damage&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-11&#34; name=&#34;__codelineno-0-11&#34; href=&#34;#__codelineno-0-11&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;c1&#34;&gt;# ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-12&#34; name=&#34;__codelineno-0-12&#34; href=&#34;#__codelineno-0-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;player&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fire_func&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new_fire_func&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;以上代码简单展示 Hotfix 的写法，数据 / 函数修改之后，程序后续访问的时候就会读到新的数据 / 函数来执行。&lt;/p&gt;
&lt;p&gt;如果你比较细致，你可能会有一个疑问：那如果其他代码里面引用住了这些需要修改数据和函数，会发生什么事情？&lt;/p&gt;
&lt;div class=&#34;language-python highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;# attack.py module&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-2&#34; name=&#34;__codelineno-1-2&#34; href=&#34;#__codelineno-1-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-3&#34; name=&#34;__codelineno-1-3&#34; href=&#34;#__codelineno-1-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;player_fire&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fire_func&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-4&#34; name=&#34;__codelineno-1-4&#34; href=&#34;#__codelineno-1-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-5&#34; name=&#34;__codelineno-1-5&#34; href=&#34;#__codelineno-1-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;player_attack_by_gun&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;player&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;target&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-6&#34; name=&#34;__codelineno-1-6&#34; href=&#34;#__codelineno-1-6&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;n&#34;&gt;player_fire&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;player&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;target&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-7&#34; name=&#34;__codelineno-1-7&#34; href=&#34;#__codelineno-1-7&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;c1&#34;&gt;# ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;答案是，前面的 Hotfix 对这种情况是不生效的，&lt;code&gt;fire_func&lt;/code&gt; 这个函数相当于在其他模块多了一份副本，该模块中调用的是函数的副本，我们修改函数本体对副本不生效。&lt;/p&gt;
&lt;p&gt;所以需要注意，一般代码中尽量减少模块级别的数据引用和函数引用，避免出现这种 Hotfix 不生效的情况，如果代码已经是这样写的，Hotfix 需要多做一些工作：&lt;/p&gt;
&lt;div class=&#34;language-python highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-2-1&#34; name=&#34;__codelineno-2-1&#34; href=&#34;#__codelineno-2-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;# hotfix code&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-2&#34; name=&#34;__codelineno-2-2&#34; href=&#34;#__codelineno-2-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;# ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-3&#34; name=&#34;__codelineno-2-3&#34; href=&#34;#__codelineno-2-3&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-4&#34; name=&#34;__codelineno-2-4&#34; href=&#34;#__codelineno-2-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;attack&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-5&#34; name=&#34;__codelineno-2-5&#34; href=&#34;#__codelineno-2-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;attack&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;player_fire&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fire_func&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;在对数据 / 函数本体 Hotfix 修改之后，再额外对引用的地方进行修改。这些额外的修改很容易被遗漏，所以我们还是建议，从代码规范上来尽量避免多处引用的写法。&lt;/p&gt;
&lt;p&gt;综上，Hotfix 能满足热更的基本需求，同时存在以下问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果数据/函数被其他模块明确引用住，需要额外对这些模块的引用 Hotfix&lt;/li&gt;
&lt;li&gt;如果有大量的数据/函数需要 Hotfix，那么 Hotfix 的代码会变得很庞大，维护难度上升，也更容易出错&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;reload&#34;&gt;Reload&lt;/h2&gt;
&lt;p&gt;本章节源码可从这里获得：&lt;a href=&#34;https://github.com/disenone/python_reloader&#34;&gt;python_reloader&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我们更想要的是自动热更新，不需要额外写 Hotfix，只需要更新代码文件，让程序执行一个 Reload 函数则会自动替换新的函数和新的数据。我们把这个自动热更新的功能叫做 Reload。&lt;/p&gt;
&lt;p&gt;Python3.12 提供了 importlib.reload 函数，可以重新加载模块，但是却是全量加载，并且返回新的模块对象，对于其他模块中的引用，并不能自动修改，也就是其他模块如果 import 了 reload 的模块，那么访问的依然是旧的模块对象。这个功能比我们的 Hotfix 好不了多少，更何况是全量 reload 模块，不能由我们控制哪些数据应该保留。我们想要自己实现一个 Reload 功能，满足这些要求：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自动替换函数，同时旧函数的引用依然有效，并会执行新函数的内容&lt;/li&gt;
&lt;li&gt;自动替换数据，同时可控制部分替换&lt;/li&gt;
&lt;li&gt;保留旧模块的引用，通过旧模块就能访问到新的内容&lt;/li&gt;
&lt;li&gt;需要 Reload 的模块可控&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;要完成这些要求，我们需要借助 Python 里面 meta_path 的机制，详细的介绍可以看官方文档 &lt;a href=&#34;https://docs.python.org/zh-cn/3/reference/import.html?highlight=meta_path#the-meta-path&#34;&gt;the-meta-path&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;sys.meta_path 里面可以定义我们的元路径查找器对象，譬如我们把用于 Reload 的查找器叫做 reload_finder，reload_finder 需要实现一个函数 find_spec 并返回 spec 对象。Python 拿到 spec 对象后，会依次执行 spec.loader.create_module 和 spec.loader.exec_module 完成模块的导入。&lt;/p&gt;
&lt;p&gt;如果我们在这个过程中，执行新的模块代码，并把新的模块里面的函数和需要的数据复制到旧模块中，则可以达到 Reload 的目的：&lt;/p&gt;
&lt;div class=&#34;language-python highlight&#34;&gt;&lt;table class=&#34;highlighttable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;linenos&#34;&gt;&lt;div class=&#34;linenodiv&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-1&#34;&gt; 1&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-2&#34;&gt; 2&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-3&#34;&gt; 3&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-4&#34;&gt; 4&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-5&#34;&gt; 5&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-6&#34;&gt; 6&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-7&#34;&gt; 7&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-8&#34;&gt; 8&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-9&#34;&gt; 9&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-10&#34;&gt;10&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-11&#34;&gt;11&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-12&#34;&gt;12&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-13&#34;&gt;13&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-14&#34;&gt;14&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-15&#34;&gt;15&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-16&#34;&gt;16&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-17&#34;&gt;17&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-18&#34;&gt;18&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-19&#34;&gt;19&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-20&#34;&gt;20&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-21&#34;&gt;21&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-22&#34;&gt;22&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-23&#34;&gt;23&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-24&#34;&gt;24&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-25&#34;&gt;25&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-26&#34;&gt;26&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-27&#34;&gt;27&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-28&#34;&gt;28&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-29&#34;&gt;29&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-30&#34;&gt;30&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-31&#34;&gt;31&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-32&#34;&gt;32&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-33&#34;&gt;33&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-34&#34;&gt;34&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-35&#34;&gt;35&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-36&#34;&gt;36&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-37&#34;&gt;37&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-38&#34;&gt;38&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-39&#34;&gt;39&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-40&#34;&gt;40&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-3-41&#34;&gt;41&lt;/a&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-3-1&#34; name=&#34;__codelineno-3-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;MetaFinder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-2&#34; name=&#34;__codelineno-3-2&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;fm&#34;&gt;__init__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reloader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-3&#34; name=&#34;__codelineno-3-3&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_reloader&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reloader&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-4&#34; name=&#34;__codelineno-3-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-5&#34; name=&#34;__codelineno-3-5&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;find_spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fullname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;target&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-6&#34; name=&#34;__codelineno-3-6&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;c1&#34;&gt;# find source file&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-7&#34; name=&#34;__codelineno-3-7&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;n&#34;&gt;finder&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;importlib&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;machinery&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PathFinder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-8&#34; name=&#34;__codelineno-3-8&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;n&#34;&gt;spec&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;finder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;find_spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fullname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-9&#34; name=&#34;__codelineno-3-9&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-10&#34; name=&#34;__codelineno-3-10&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-11&#34; name=&#34;__codelineno-3-11&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-12&#34; name=&#34;__codelineno-3-12&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;n&#34;&gt;old_module&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_reloader&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetOldModule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fullname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-13&#34; name=&#34;__codelineno-3-13&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;old_module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-14&#34; name=&#34;__codelineno-3-14&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;c1&#34;&gt;# run new code in old module dict&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-15&#34; name=&#34;__codelineno-3-15&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;n&#34;&gt;code&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;loader&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_code&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fullname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-16&#34; name=&#34;__codelineno-3-16&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;n&#34;&gt;exec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;code&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;old_module&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;vm&#34;&gt;__dict__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-17&#34; name=&#34;__codelineno-3-17&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;n&#34;&gt;module&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;old_module&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-18&#34; name=&#34;__codelineno-3-18&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-19&#34; name=&#34;__codelineno-3-19&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;c1&#34;&gt;# if old module not exists, just create a new one&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-20&#34; name=&#34;__codelineno-3-20&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;n&#34;&gt;module&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;import_util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;module_from_spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-21&#34; name=&#34;__codelineno-3-21&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;n&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;loader&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exec_module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-22&#34; name=&#34;__codelineno-3-22&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-23&#34; name=&#34;__codelineno-3-23&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-24&#34; name=&#34;__codelineno-3-24&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_reloader&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ReloadModule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-25&#34; name=&#34;__codelineno-3-25&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-26&#34; name=&#34;__codelineno-3-26&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;excepthook&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exc_info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-27&#34; name=&#34;__codelineno-3-27&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-28&#34; name=&#34;__codelineno-3-28&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;import_util&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;spec_from_loader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fullname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;MetaLoader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-29&#34; name=&#34;__codelineno-3-29&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-30&#34; name=&#34;__codelineno-3-30&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-31&#34; name=&#34;__codelineno-3-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;MetaLoader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-32&#34; name=&#34;__codelineno-3-32&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;fm&#34;&gt;__init__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-33&#34; name=&#34;__codelineno-3-33&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_module&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-34&#34; name=&#34;__codelineno-3-34&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-35&#34; name=&#34;__codelineno-3-35&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;create_module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;spec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-36&#34; name=&#34;__codelineno-3-36&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_module&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-37&#34; name=&#34;__codelineno-3-37&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-38&#34; name=&#34;__codelineno-3-38&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;exec_module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-39&#34; name=&#34;__codelineno-3-39&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;c1&#34;&gt;# restore __spec__&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-40&#34; name=&#34;__codelineno-3-40&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;__spec__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;vm&#34;&gt;__dict__&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;__backup_spec__&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-41&#34; name=&#34;__codelineno-3-41&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;__loader__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;vm&#34;&gt;__dict__&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;__backup_loader__&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;如上，&lt;code&gt;find_spec&lt;/code&gt; 加载最新的模块源码，并在旧模块的 &lt;code&gt;__dict__&lt;/code&gt; 里面执行新模块的代码，之后我们调用 &lt;code&gt;ReloadModule&lt;/code&gt; 来处理类 / 函数 / 数据的引用和替换。&lt;code&gt;MetaLoader&lt;/code&gt; 的目的是适配 meta_path 机制，给 Python 虚拟机返回我们处理过的模块对象。&lt;/p&gt;
&lt;p&gt;处理完加载的流程，再来看 &lt;code&gt;ReloadModule&lt;/code&gt; 的大致实现&lt;/p&gt;
&lt;div class=&#34;language-python highlight&#34;&gt;&lt;table class=&#34;highlighttable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;linenos&#34;&gt;&lt;div class=&#34;linenodiv&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-1&#34;&gt; 1&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-2&#34;&gt; 2&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-3&#34;&gt; 3&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-4&#34;&gt; 4&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-5&#34;&gt; 5&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-6&#34;&gt; 6&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-7&#34;&gt; 7&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-8&#34;&gt; 8&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-9&#34;&gt; 9&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-10&#34;&gt;10&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-11&#34;&gt;11&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-12&#34;&gt;12&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-13&#34;&gt;13&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-14&#34;&gt;14&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-15&#34;&gt;15&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-16&#34;&gt;16&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-17&#34;&gt;17&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-18&#34;&gt;18&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-19&#34;&gt;19&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-20&#34;&gt;20&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-21&#34;&gt;21&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-22&#34;&gt;22&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-23&#34;&gt;23&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-24&#34;&gt;24&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-25&#34;&gt;25&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-26&#34;&gt;26&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-27&#34;&gt;27&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-28&#34;&gt;28&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-29&#34;&gt;29&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-30&#34;&gt;30&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-31&#34;&gt;31&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-32&#34;&gt;32&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-33&#34;&gt;33&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-34&#34;&gt;34&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-35&#34;&gt;35&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-36&#34;&gt;36&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-37&#34;&gt;37&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-38&#34;&gt;38&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-39&#34;&gt;39&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-40&#34;&gt;40&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-41&#34;&gt;41&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-42&#34;&gt;42&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-43&#34;&gt;43&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-44&#34;&gt;44&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-45&#34;&gt;45&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-46&#34;&gt;46&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-47&#34;&gt;47&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-48&#34;&gt;48&lt;/a&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-4-1&#34; name=&#34;__codelineno-4-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;# ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-2&#34; name=&#34;__codelineno-4-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ReloadModule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-3&#34; name=&#34;__codelineno-4-3&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;n&#34;&gt;old_module_info&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_old_module_infos&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-4&#34; name=&#34;__codelineno-4-4&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;old_module_info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-5&#34; name=&#34;__codelineno-4-5&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-6&#34; name=&#34;__codelineno-4-6&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-7&#34; name=&#34;__codelineno-4-7&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ReloadDict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;old_module_info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;vm&#34;&gt;__dict__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-8&#34; name=&#34;__codelineno-4-8&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-9&#34; name=&#34;__codelineno-4-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ReloadDict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;old_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_reload_all_data&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_del_func&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-10&#34; name=&#34;__codelineno-4-10&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;n&#34;&gt;dels&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-11&#34; name=&#34;__codelineno-4-11&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-12&#34; name=&#34;__codelineno-4-12&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;attr_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;old_attr&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;old_dict&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;items&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-13&#34; name=&#34;__codelineno-4-13&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-14&#34; name=&#34;__codelineno-4-14&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;attr_name&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IGNORE_ATTRS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-15&#34; name=&#34;__codelineno-4-15&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-16&#34; name=&#34;__codelineno-4-16&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-17&#34; name=&#34;__codelineno-4-17&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;attr_name&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-18&#34; name=&#34;__codelineno-4-18&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_del_func&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inspect&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isfunction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;old_attr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inspect&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ismethod&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;old_attr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)):&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-19&#34; name=&#34;__codelineno-4-19&#34;&gt;&lt;/a&gt;                &lt;span class=&#34;n&#34;&gt;dels&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;attr_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-20&#34; name=&#34;__codelineno-4-20&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-21&#34; name=&#34;__codelineno-4-21&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-22&#34; name=&#34;__codelineno-4-22&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;n&#34;&gt;new_attr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;attr_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-23&#34; name=&#34;__codelineno-4-23&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-24&#34; name=&#34;__codelineno-4-24&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inspect&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isclass&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;old_attr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-25&#34; name=&#34;__codelineno-4-25&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;n&#34;&gt;new_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;attr_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ReloadClass&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;old_attr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new_attr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-26&#34; name=&#34;__codelineno-4-26&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-27&#34; name=&#34;__codelineno-4-27&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;k&#34;&gt;elif&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inspect&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isfunction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;old_attr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-28&#34; name=&#34;__codelineno-4-28&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;n&#34;&gt;new_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;attr_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ReloadFunction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;old_attr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new_attr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-29&#34; name=&#34;__codelineno-4-29&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-30&#34; name=&#34;__codelineno-4-30&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;k&#34;&gt;elif&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inspect&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ismethod&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;old_attr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;old_attr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;classmethod&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;old_attr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;staticmethod&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-31&#34; name=&#34;__codelineno-4-31&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ReloadFunction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;old_attr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;vm&#34;&gt;__func__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new_attr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;vm&#34;&gt;__func__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-32&#34; name=&#34;__codelineno-4-32&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;n&#34;&gt;new_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;attr_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;old_attr&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-33&#34; name=&#34;__codelineno-4-33&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-34&#34; name=&#34;__codelineno-4-34&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;k&#34;&gt;elif&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inspect&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isbuiltin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;old_attr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; \
&lt;a id=&#34;__codelineno-4-35&#34; name=&#34;__codelineno-4-35&#34;&gt;&lt;/a&gt;                &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inspect&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ismodule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;old_attr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; \
&lt;a id=&#34;__codelineno-4-36&#34; name=&#34;__codelineno-4-36&#34;&gt;&lt;/a&gt;                &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inspect&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ismethoddescriptor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;old_attr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; \
&lt;a id=&#34;__codelineno-4-37&#34; name=&#34;__codelineno-4-37&#34;&gt;&lt;/a&gt;                &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;old_attr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;property&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-38&#34; name=&#34;__codelineno-4-38&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;c1&#34;&gt;# keep new&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-39&#34; name=&#34;__codelineno-4-39&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;k&#34;&gt;pass&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-40&#34; name=&#34;__codelineno-4-40&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-41&#34; name=&#34;__codelineno-4-41&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;k&#34;&gt;elif&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_reload_all_data&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NeedUpdateData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;attr_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-42&#34; name=&#34;__codelineno-4-42&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;c1&#34;&gt;# keep old data&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-43&#34; name=&#34;__codelineno-4-43&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;n&#34;&gt;new_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;attr_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;old_attr&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-44&#34; name=&#34;__codelineno-4-44&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-45&#34; name=&#34;__codelineno-4-45&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-46&#34; name=&#34;__codelineno-4-46&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-47&#34; name=&#34;__codelineno-4-47&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;n&#34;&gt;old_dict&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-48&#34; name=&#34;__codelineno-4-48&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;# ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;ReloadDict&lt;/code&gt; 里面会区分处理不同类型的对象&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果是 class，则调用 &lt;code&gt;ReloadClass&lt;/code&gt;，会返回旧模块的引用，并更新 class 的成员&lt;/li&gt;
&lt;li&gt;如果是 function / method ，则调用 &lt;code&gt;ReloadFunction&lt;/code&gt;，会返回旧模块的引用，并更新函数的内部数据&lt;/li&gt;
&lt;li&gt;如果是数据，并且需要保留，则会回滚 &lt;code&gt;new_dict[attr_name] = old_attr&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;其余的都保持新的引用&lt;/li&gt;
&lt;li&gt;删除新模块不存在的函数&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;ReloadClass&lt;/code&gt;，&lt;code&gt;ReloadFunction&lt;/code&gt; 的具体代码这里不再展开分析，有兴趣可以直接看&lt;a href=&#34;https://github.com/disenone/python_reloader&#34;&gt;源码&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;整个 Reload 的过程，可以概括为：旧瓶装新酒。为了保持模块/模块的函数/模块的类/模块的数据有效，我们需要保留原来的这些对象的引用（躯壳），转而去更新它们内部的具体数据，譬如对于函数，更新 &lt;code&gt;__code__&lt;/code&gt;，&lt;code&gt;__dict__&lt;/code&gt; 等数据，函数执行的时候，就会转而执行新的代码。&lt;/p&gt;
&lt;h2 id=&#34;_2&#34;&gt;总结&lt;/h2&gt;
&lt;p&gt;本文详细介绍了 Python3 的两种热更新方式，每种都有相应的应用场景，希望能对你有帮助。有任何疑问欢迎随时交流。&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/py-Python%E6%9D%82%E8%B0%882-Python312-%E7%83%AD%E6%9B%B4%E6%96%B0/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Fri, 12 Jan 2024 06:37:04 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/py-Python%E6%9D%82%E8%B0%882-Python312-%E7%83%AD%E6%9B%B4%E6%96%B0/</guid>
      
    </item>
    
    <item>
      <title>UE 设置本地化多语言</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 设置本地化多语言&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;ue&#34;&gt;UE 设置本地化多语言&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;记录如何在 UE 中实现本地化多语言&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果不熟悉 UE 扩展菜单，建议先简单看下：&lt;a href=&#34;../ue-%E6%89%A9%E5%B1%95%E7%BC%96%E8%BE%91%E5%99%A8%E8%8F%9C%E5%8D%95/&#34;&gt;UE 扩展编辑器菜单&lt;/a&gt;，&lt;a href=&#34;../ue-%E4%BD%BF%E7%94%A8%E8%B7%AF%E5%BE%84%E5%BD%A2%E5%BC%8F%E6%89%A9%E5%B1%95%E8%8F%9C%E5%8D%95/&#34;&gt;ue-使用路径形式扩展菜单&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本文代码基于插件：&lt;a href=&#34;https://github.com/disenone/UE.EditorPlus&#34;&gt;UE.EditorPlus&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;_1&#34;&gt;功能介绍&lt;/h2&gt;
&lt;p&gt;UE 自带工具可以实现本地化多语言，譬如我们可以为编辑器菜单实现本地化：&lt;/p&gt;
&lt;p&gt;中文菜单：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-localization/chinese.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;英文菜单：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-localization/english.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_2&#34;&gt;代码声明&lt;/h2&gt;
&lt;p&gt;为了实现菜单本地化，我们需要在代码中明确声明需要 UE 处理的字符串，使用 UE 定义好的宏 &lt;code&gt;LOCTEXT&lt;/code&gt; 和 &lt;code&gt;NSLOCTEXT&lt;/code&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;文件全局定义方式，先开始定义一个叫做 &lt;code&gt;LOCTEXT_NAMESPACE&lt;/code&gt; 的宏，内容是当前多语言文本所在的名字空间，之后文件中的文本就可以用 &lt;code&gt;LOCTEXT&lt;/code&gt; 来定义，文件最后取消宏 &lt;code&gt;LOCTEXT_NAMESPACE&lt;/code&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// #define LOCTEXT(InKey, InTextLiteral)&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34; href=&#34;#__codelineno-0-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define LOCTEXT_NAMESPACE &amp;quot;EditorPlusTools&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-4&#34; name=&#34;__codelineno-0-4&#34; href=&#34;#__codelineno-0-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Key&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Content&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-5&#34; name=&#34;__codelineno-0-5&#34; href=&#34;#__codelineno-0-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#undef LOCTEXT_NAMESPACE&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;局部定义方式，使用 &lt;code&gt;NSLOCTEXT&lt;/code&gt;，定义文本的时候带上名字空间参数：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// #define NSLOCTEXT(InNamespace, InKey, InTextLiteral)&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-2&#34; name=&#34;__codelineno-1-2&#34; href=&#34;#__codelineno-1-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-3&#34; name=&#34;__codelineno-1-3&#34; href=&#34;#__codelineno-1-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;NSLOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;EditorPlusTools&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Key&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Content&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;UE 工具通过查找宏 &lt;code&gt;LOCTEXT&lt;/code&gt; 和 &lt;code&gt;NSLOCTEXT&lt;/code&gt; 的出现来收集出所有需要翻译的文本。&lt;/p&gt;
&lt;h2 id=&#34;_3&#34;&gt;使用工具翻译文本&lt;/h2&gt;
&lt;p&gt;假设我们有如下代码定义文本：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-2-1&#34; name=&#34;__codelineno-2-1&#34; href=&#34;#__codelineno-2-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define LOCTEXT_NAMESPACE &amp;quot;EditorPlusTools&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-2&#34; name=&#34;__codelineno-2-2&#34; href=&#34;#__codelineno-2-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// register path node loctext&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-3&#34; name=&#34;__codelineno-2-3&#34; href=&#34;#__codelineno-2-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetNodeByPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;/MenuTest&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetFriendlyName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTest&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTest&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetFriendlyTips&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestTips&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestTips&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-4&#34; name=&#34;__codelineno-2-4&#34; href=&#34;#__codelineno-2-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetNodeByPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;/MenuTest/&amp;lt;SubMenu&amp;gt;SubMenu1&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetFriendlyName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;SubMenu1&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;SubMenu1&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetFriendlyTips&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;SubMenu1Tips&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;SubMenu1Tips&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-5&#34; name=&#34;__codelineno-2-5&#34; href=&#34;#__codelineno-2-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetNodeByPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;/MenuTest/&amp;lt;SubMenu&amp;gt;SubMenu1/&amp;lt;SubMenu&amp;gt;SubMenu1&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetFriendlyName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;SubMenu1&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;SubMenu1&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetFriendlyTips&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;SubMenu1Tips&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;SubMenu1Tips&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-6&#34; name=&#34;__codelineno-2-6&#34; href=&#34;#__codelineno-2-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetNodeByPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;/&amp;lt;Hook&amp;gt;Help/&amp;lt;MenuBar&amp;gt;MenuTest/&amp;lt;SubMenu&amp;gt;SubMenu1/&amp;lt;Section&amp;gt;Section1&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetFriendlyName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Section1&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Section1&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetFriendlyTips&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Section1Tips&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Section1Tips&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-7&#34; name=&#34;__codelineno-2-7&#34; href=&#34;#__codelineno-2-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#undef LOCTEXT_NAMESPACE&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;首先开启翻译工具，打开编辑器设置 &lt;code&gt;编辑 - 编辑器偏好设置&lt;/code&gt;，勾选 &lt;code&gt;通用 - 试验性功能 - Tools - 翻译选取器&lt;/code&gt;：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-localization/editor_enable_tool.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;然后打开翻译工具 &lt;code&gt;工具 - 本地化控制板&lt;/code&gt;：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-localization/editor_open_tool.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;新建一个目标（在默认的 Game 下面也行，新建一个是为了方便管理和移动这些翻译文本）&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-localization/tool_new_target.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;配置目标的参数，我这里名字改为 &lt;code&gt;EditorPlusTools&lt;/code&gt;，加载政策是 &lt;code&gt;编辑器&lt;/code&gt;，从文本收集，并加上插件目录，目标依赖性是 &lt;code&gt;Engine, Editor&lt;/code&gt;，其他配置保持不变：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-localization/tool_target_config.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;添加语系，保证有中文（简体）和英文两个语系，确认鼠标放在语言名字上分别显示 &lt;code&gt;zh-Hans&lt;/code&gt; 和 &lt;code&gt;en&lt;/code&gt;，并选中英语（因为我们代码里面是用英文定义的文本，我们这里需要收集这些英语文本）：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-localization/tool_target_lang.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;点击收集文本：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-localization/tool_target_collect.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;会弹出收集进度框，等待收集成功，会显示绿色对钩：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-localization/tool_target_collected.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;关掉收集进度框，回到翻译工具可以看到英文一行有显示收集到的数量，本身英文的我们不需要翻译，点开中文一行的翻译按钮：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-localization/tool_go_trans.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;打开后我们可以看到未翻译一栏有内容，在英文文本的右边一栏输入翻译后的内容，翻译内容都完成之后，保存退出窗口：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-localization/tool_trans.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;点击统计字数，结束后能看到中文一栏显示了翻译的数量：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-localization/tool_count.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;最后编译文本：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-localization/tool_build.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;翻译的数据会放在 &lt;code&gt;Content\Localization\EditorPlusTools&lt;/code&gt; 里面，每种语言一个文件夹，在 zh-Hans 里面能看到两个文件，&lt;code&gt;.archive&lt;/code&gt; 是收集和翻译的文本，&lt;code&gt;.locres&lt;/code&gt; 则是编译之后的数据：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-localization/tool_ret.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-localization/tool_ret2.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_4&#34;&gt;翻译好的文本放入插件目录中&lt;/h2&gt;
&lt;p&gt;我们上面给插件生成的翻译文本放在了项目目录下面，我们需要把这些文本移动到插件里面，方便随着插件一起发布。&lt;/p&gt;
&lt;p&gt;把 &lt;code&gt;Content\Localization\EditorPlusTools&lt;/code&gt; 目录移动到插件目录 Content 下面，我这里是 &lt;code&gt;Plugins\UE.EditorPlus\Content\Localization\EditorPlusTools&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;修改项目的配置文件 &lt;code&gt;DefaultEditor.ini&lt;/code&gt;，加上新路径：&lt;/p&gt;
&lt;div class=&#34;language-ini highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-3-1&#34; name=&#34;__codelineno-3-1&#34; href=&#34;#__codelineno-3-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;[Internationalization]&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-2&#34; name=&#34;__codelineno-3-2&#34; href=&#34;#__codelineno-3-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;na&#34;&gt;+LocalizationPaths&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;%GAMEDIR%Plugins/UE.EditorPlus/Content/Localization/EditorPlusTools&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这样，其他项目拿到插件后，只要修改 &lt;code&gt;DefaultEditor.ini&lt;/code&gt; 则可以直接使用翻译文本，不需要重新配置翻译。&lt;/p&gt;
&lt;h2 id=&#34;_5&#34;&gt;注意事项&lt;/h2&gt;
&lt;p&gt;在生成翻译数据的过程中，遇到过一些问题，以下总结出来注意的事项：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;代码里面定义文本必须要用宏 &lt;code&gt;LOCTEXT&lt;/code&gt; 和 &lt;code&gt;NSLOCTEXT&lt;/code&gt;，文本需要是字符串常量，这样 UE 才是收集出来。&lt;/li&gt;
&lt;li&gt;翻译目标名字不能带有符号 &lt;code&gt;.&lt;/code&gt;，&lt;code&gt;Content\Localiztion\&lt;/code&gt; 下的目录名字不能带有 &lt;code&gt;.&lt;/code&gt;，UE 只会截取 &lt;code&gt;.&lt;/code&gt; 前面的名字。会导致 UE 在读取翻译文本的时候，由于名字错误，读取失败。&lt;/li&gt;
&lt;li&gt;对于编辑器插件，需要判断如果是命令行模式 &lt;code&gt;IsRunningCommandlet()&lt;/code&gt; 则不生成菜单和 SlateUI ，因为命令行模式下没有 Slate 模块，会导致收集文本的时候报错 &lt;code&gt;Assertion failed: CurrentApplication.IsValid()&lt;/code&gt;。如果你也遇到类似的报错，可以尝试加上这个判断。具体报错信息：&lt;blockquote&gt;
&lt;p&gt;Assertion failed: CurrentApplication.IsValid() [File:E:\UE\ue5.3_git\Engine\Source\Runtime\Slate\Public\Framework\Application\SlateApplication.h] [Line: 255] &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-localization/tool_error.png&#34; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E8%AE%BE%E7%BD%AE%E6%9C%AC%E5%9C%B0%E5%8C%96%E5%A4%9A%E8%AF%AD%E8%A8%80/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 28 Dec 2023 18:06:38 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E8%AE%BE%E7%BD%AE%E6%9C%AC%E5%9C%B0%E5%8C%96%E5%A4%9A%E8%AF%AD%E8%A8%80/</guid>
      
    </item>
    
    <item>
      <title>UE 使用路径形式扩展菜单</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 使用路径形式扩展菜单&#34; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;记录如何在 UE 中实现路径形式扩展菜单&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果不熟悉 UE 扩展菜单，建议先简单看下：&lt;a href=&#34;../ue-%E6%89%A9%E5%B1%95%E7%BC%96%E8%BE%91%E5%99%A8%E8%8F%9C%E5%8D%95/&#34;&gt;UE 扩展编辑器菜单&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本文代码基于插件：&lt;a href=&#34;https://github.com/disenone/UE.EditorPlus&#34;&gt;UE.EditorPlus&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;_1&#34;&gt;节点管理&lt;/h2&gt;
&lt;p&gt;把菜单按照树的结构来管理，父节点可以包含孩子：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;EDITORPLUS_API&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSharedFromThis&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34; href=&#34;#__codelineno-0-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;protected&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-4&#34; name=&#34;__codelineno-0-4&#34; href=&#34;#__codelineno-0-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// sub menus&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-5&#34; name=&#34;__codelineno-0-5&#34; href=&#34;#__codelineno-0-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TArray&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSharedRef&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Children&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-6&#34; name=&#34;__codelineno-0-6&#34; href=&#34;#__codelineno-0-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;在创建父节点的同时创建子节点：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;FEditorPlusMenuBase::Register&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMenuBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-2&#34; name=&#34;__codelineno-1-2&#34; href=&#34;#__codelineno-1-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-3&#34; name=&#34;__codelineno-1-3&#34; href=&#34;#__codelineno-1-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Menu&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Children&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-4&#34; name=&#34;__codelineno-1-4&#34; href=&#34;#__codelineno-1-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-5&#34; name=&#34;__codelineno-1-5&#34; href=&#34;#__codelineno-1-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Menu&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Register&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-6&#34; name=&#34;__codelineno-1-6&#34; href=&#34;#__codelineno-1-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-7&#34; name=&#34;__codelineno-1-7&#34; href=&#34;#__codelineno-1-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;当然每个节点的具体创建行为会有点不同，覆写虚函数来实现：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-2-1&#34; name=&#34;__codelineno-2-1&#34; href=&#34;#__codelineno-2-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// Menubar&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-2&#34; name=&#34;__codelineno-2-2&#34; href=&#34;#__codelineno-2-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;FEditorPlusMenuBar::Register&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMenuBarBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBarBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-3&#34; name=&#34;__codelineno-2-3&#34; href=&#34;#__codelineno-2-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-4&#34; name=&#34;__codelineno-2-4&#34; href=&#34;#__codelineno-2-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBarBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddPullDownMenu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-5&#34; name=&#34;__codelineno-2-5&#34; href=&#34;#__codelineno-2-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetFriendlyName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-6&#34; name=&#34;__codelineno-2-6&#34; href=&#34;#__codelineno-2-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetFriendlyTips&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-7&#34; name=&#34;__codelineno-2-7&#34; href=&#34;#__codelineno-2-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Delegate to call Register&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-8&#34; name=&#34;__codelineno-2-8&#34; href=&#34;#__codelineno-2-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuManager&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetDelegate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FNewMenuDelegate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetUniqueId&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;
&lt;a id=&#34;__codelineno-2-9&#34; name=&#34;__codelineno-2-9&#34; href=&#34;#__codelineno-2-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Hook&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-10&#34; name=&#34;__codelineno-2-10&#34; href=&#34;#__codelineno-2-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-11&#34; name=&#34;__codelineno-2-11&#34; href=&#34;#__codelineno-2-11&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-12&#34; name=&#34;__codelineno-2-12&#34; href=&#34;#__codelineno-2-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// Section&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-13&#34; name=&#34;__codelineno-2-13&#34; href=&#34;#__codelineno-2-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;FEditorPlusSection::Register&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMenuBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-14&#34; name=&#34;__codelineno-2-14&#34; href=&#34;#__codelineno-2-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-15&#34; name=&#34;__codelineno-2-15&#34; href=&#34;#__codelineno-2-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BeginSection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Hook&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetFriendlyName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-16&#34; name=&#34;__codelineno-2-16&#34; href=&#34;#__codelineno-2-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Register&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-17&#34; name=&#34;__codelineno-2-17&#34; href=&#34;#__codelineno-2-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EndSection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-18&#34; name=&#34;__codelineno-2-18&#34; href=&#34;#__codelineno-2-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-19&#34; name=&#34;__codelineno-2-19&#34; href=&#34;#__codelineno-2-19&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-20&#34; name=&#34;__codelineno-2-20&#34; href=&#34;#__codelineno-2-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// Separator&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-21&#34; name=&#34;__codelineno-2-21&#34; href=&#34;#__codelineno-2-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;FEditorPlusSeparator::Register&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMenuBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-22&#34; name=&#34;__codelineno-2-22&#34; href=&#34;#__codelineno-2-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-23&#34; name=&#34;__codelineno-2-23&#34; href=&#34;#__codelineno-2-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddMenuSeparator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Hook&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-24&#34; name=&#34;__codelineno-2-24&#34; href=&#34;#__codelineno-2-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Register&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-25&#34; name=&#34;__codelineno-2-25&#34; href=&#34;#__codelineno-2-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-26&#34; name=&#34;__codelineno-2-26&#34; href=&#34;#__codelineno-2-26&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-27&#34; name=&#34;__codelineno-2-27&#34; href=&#34;#__codelineno-2-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// SubMenu&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-28&#34; name=&#34;__codelineno-2-28&#34; href=&#34;#__codelineno-2-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;FEditorPlusSubMenu::Register&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMenuBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-29&#34; name=&#34;__codelineno-2-29&#34; href=&#34;#__codelineno-2-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-30&#34; name=&#34;__codelineno-2-30&#34; href=&#34;#__codelineno-2-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddSubMenu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-31&#34; name=&#34;__codelineno-2-31&#34; href=&#34;#__codelineno-2-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetFriendlyName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-32&#34; name=&#34;__codelineno-2-32&#34; href=&#34;#__codelineno-2-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetFriendlyTips&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-33&#34; name=&#34;__codelineno-2-33&#34; href=&#34;#__codelineno-2-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FNewMenuDelegate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateSP&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusSubMenu&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MakeSubMenu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-34&#34; name=&#34;__codelineno-2-34&#34; href=&#34;#__codelineno-2-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-35&#34; name=&#34;__codelineno-2-35&#34; href=&#34;#__codelineno-2-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FSlateIcon&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-36&#34; name=&#34;__codelineno-2-36&#34; href=&#34;#__codelineno-2-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-37&#34; name=&#34;__codelineno-2-37&#34; href=&#34;#__codelineno-2-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Hook&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-38&#34; name=&#34;__codelineno-2-38&#34; href=&#34;#__codelineno-2-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-39&#34; name=&#34;__codelineno-2-39&#34; href=&#34;#__codelineno-2-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-40&#34; name=&#34;__codelineno-2-40&#34; href=&#34;#__codelineno-2-40&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-41&#34; name=&#34;__codelineno-2-41&#34; href=&#34;#__codelineno-2-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// Command&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-42&#34; name=&#34;__codelineno-2-42&#34; href=&#34;#__codelineno-2-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;FEditorPlusCommand::Register&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMenuBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-43&#34; name=&#34;__codelineno-2-43&#34; href=&#34;#__codelineno-2-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-44&#34; name=&#34;__codelineno-2-44&#34; href=&#34;#__codelineno-2-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddMenuEntry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-45&#34; name=&#34;__codelineno-2-45&#34; href=&#34;#__codelineno-2-45&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CommandInfo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Label&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CommandInfo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Tips&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CommandInfo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Icon&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-46&#34; name=&#34;__codelineno-2-46&#34; href=&#34;#__codelineno-2-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CommandInfo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ExecuteAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CommandInfo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Hook&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CommandInfo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-47&#34; name=&#34;__codelineno-2-47&#34; href=&#34;#__codelineno-2-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-48&#34; name=&#34;__codelineno-2-48&#34; href=&#34;#__codelineno-2-48&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-49&#34; name=&#34;__codelineno-2-49&#34; href=&#34;#__codelineno-2-49&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// ......&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;_2&#34;&gt;通过路径生成节点&lt;/h2&gt;
&lt;p&gt;按照树形结构组织好菜单，路径格式就可以定义一条菜单的树形结构：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-3-1&#34; name=&#34;__codelineno-3-1&#34; href=&#34;#__codelineno-3-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;/&amp;lt;Hook&amp;gt;Help/&amp;lt;MenuBar&amp;gt;BarTest/&amp;lt;SubMenu&amp;gt;SubTest/&amp;lt;Command&amp;gt;Action&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;以上路径即可以定义一系列菜单的创建：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;Hook&amp;gt;Help&lt;/code&gt;：位置在 Hook 名字为 Help 的菜单后&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;MenuBar&amp;gt;BarTest&lt;/code&gt;：创建类型 MenuBar 的菜单，名字为 BarTest&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;SubMenu&amp;gt;SubTest&lt;/code&gt;：创建子节点，类型 SubMenu, 名字 SubTest&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;Command&amp;gt;Action&lt;/code&gt;：最后创建一个命令&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;接口调用形式可以很简洁：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-4-1&#34; name=&#34;__codelineno-4-1&#34; href=&#34;#__codelineno-4-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FString&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;/&amp;lt;Hook&amp;gt;Help/&amp;lt;MenuBar&amp;gt;BarTest/&amp;lt;SubMenu&amp;gt;SubTest/&amp;lt;Command&amp;gt;Action&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-2&#34; name=&#34;__codelineno-4-2&#34; href=&#34;#__codelineno-4-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegisterPathAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-3&#34; name=&#34;__codelineno-4-3&#34; href=&#34;#__codelineno-4-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-4-4&#34; name=&#34;__codelineno-4-4&#34; href=&#34;#__codelineno-4-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FExecuteAction&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([]&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-5&#34; name=&#34;__codelineno-4-5&#34; href=&#34;#__codelineno-4-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-6&#34; name=&#34;__codelineno-4-6&#34; href=&#34;#__codelineno-4-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// do action&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-7&#34; name=&#34;__codelineno-4-7&#34; href=&#34;#__codelineno-4-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-8&#34; name=&#34;__codelineno-4-8&#34; href=&#34;#__codelineno-4-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;_3&#34;&gt;自定义形式生成节点&lt;/h2&gt;
&lt;p&gt;我们依然保留了笨重的方式来创建菜单，笨重的方式可以允许有更详细的设置，代码的组织形式跟 UE 的 SlateUI 写法有些像：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-5-1&#34; name=&#34;__codelineno-5-1&#34; href=&#34;#__codelineno-5-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;EP_NEW_MENU&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusMenuBar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;BarTest&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-2&#34; name=&#34;__codelineno-5-2&#34; href=&#34;#__codelineno-5-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegisterPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-3&#34; name=&#34;__codelineno-5-3&#34; href=&#34;#__codelineno-5-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-4&#34; name=&#34;__codelineno-5-4&#34; href=&#34;#__codelineno-5-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EP_NEW_MENU&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusSubMenu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;SubTest&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-5&#34; name=&#34;__codelineno-5-5&#34; href=&#34;#__codelineno-5-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-6&#34; name=&#34;__codelineno-5-6&#34; href=&#34;#__codelineno-5-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EP_NEW_MENU&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusCommand&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Action&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-7&#34; name=&#34;__codelineno-5-7&#34; href=&#34;#__codelineno-5-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BindAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FExecuteAction&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([]&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-8&#34; name=&#34;__codelineno-5-8&#34; href=&#34;#__codelineno-5-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-9&#34; name=&#34;__codelineno-5-9&#34; href=&#34;#__codelineno-5-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// do action&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-10&#34; name=&#34;__codelineno-5-10&#34; href=&#34;#__codelineno-5-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})),&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-11&#34; name=&#34;__codelineno-5-11&#34; href=&#34;#__codelineno-5-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-12&#34; name=&#34;__codelineno-5-12&#34; href=&#34;#__codelineno-5-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;_4&#34;&gt;混合形式&lt;/h2&gt;
&lt;p&gt;当然，本身路径形式和自定义生成的菜单，都是相同的，它们之间可以混用，有很大的灵活性：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-6-1&#34; name=&#34;__codelineno-6-1&#34; href=&#34;#__codelineno-6-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegisterPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-2&#34; name=&#34;__codelineno-6-2&#34; href=&#34;#__codelineno-6-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;/&amp;lt;MenuBar&amp;gt;BarTest/&amp;lt;SubMenu&amp;gt;SubMenu/&amp;lt;Command&amp;gt;Action1&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-6-3&#34; name=&#34;__codelineno-6-3&#34; href=&#34;#__codelineno-6-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EP_NEW_MENU&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusCommand&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Action1&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-4&#34; name=&#34;__codelineno-6-4&#34; href=&#34;#__codelineno-6-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BindAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FExecuteAction&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([]&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-5&#34; name=&#34;__codelineno-6-5&#34; href=&#34;#__codelineno-6-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-6&#34; name=&#34;__codelineno-6-6&#34; href=&#34;#__codelineno-6-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// do action&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-7&#34; name=&#34;__codelineno-6-7&#34; href=&#34;#__codelineno-6-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})),&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-8&#34; name=&#34;__codelineno-6-8&#34; href=&#34;#__codelineno-6-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-9&#34; name=&#34;__codelineno-6-9&#34; href=&#34;#__codelineno-6-9&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-10&#34; name=&#34;__codelineno-6-10&#34; href=&#34;#__codelineno-6-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegisterPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-11&#34; name=&#34;__codelineno-6-11&#34; href=&#34;#__codelineno-6-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;/&amp;lt;MenuBar&amp;gt;BarTest/&amp;lt;SubMenu&amp;gt;SubMenu/&amp;lt;Command&amp;gt;Action2&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-6-12&#34; name=&#34;__codelineno-6-12&#34; href=&#34;#__codelineno-6-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EP_NEW_MENU&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusCommand&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Action2&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-13&#34; name=&#34;__codelineno-6-13&#34; href=&#34;#__codelineno-6-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BindAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FExecuteAction&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([]&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-14&#34; name=&#34;__codelineno-6-14&#34; href=&#34;#__codelineno-6-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-15&#34; name=&#34;__codelineno-6-15&#34; href=&#34;#__codelineno-6-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// do action&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-16&#34; name=&#34;__codelineno-6-16&#34; href=&#34;#__codelineno-6-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})),&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-17&#34; name=&#34;__codelineno-6-17&#34; href=&#34;#__codelineno-6-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;多个地方定义的菜单，会合并到同一个树形结构中，名字相同的节点会认为是同一个节点。换言之，路径是唯一的，同一个路径可以唯一确定一个菜单节点。
于是我们也可以把节点找出来，重新做一些设置和修改：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-7-1&#34; name=&#34;__codelineno-7-1&#34; href=&#34;#__codelineno-7-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// set Name and Tips&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-2&#34; name=&#34;__codelineno-7-2&#34; href=&#34;#__codelineno-7-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;FEditorPlusPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetNodeByPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;/&amp;lt;MenuBar&amp;gt;BarTest&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetFriendlyName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTest&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTest&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetFriendlyTips&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOCTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestTips&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestTips&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E4%BD%BF%E7%94%A8%E8%B7%AF%E5%BE%84%E5%BD%A2%E5%BC%8F%E6%89%A9%E5%B1%95%E8%8F%9C%E5%8D%95/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 28 Dec 2023 09:35:18 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E4%BD%BF%E7%94%A8%E8%B7%AF%E5%BE%84%E5%BD%A2%E5%BC%8F%E6%89%A9%E5%B1%95%E8%8F%9C%E5%8D%95/</guid>
      
    </item>
    
    <item>
      <title>UE 扩展编辑器菜单</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 扩展编辑器菜单&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;ue&#34;&gt;UE 扩展编辑器菜单&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;记录 UE 如何扩展编辑器菜单&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;hook&#34;&gt;Hook&lt;/h2&gt;
&lt;p&gt;Hook 可以理解为扩展菜单的锚点，我们可以设置新加的菜单命令在 Hook 的前面或者后面，UE 自带的编辑器菜单命令基本都带有 Hook，UE5 下打开 &lt;code&gt;编辑 - 编辑器偏好设置 - 通用 - 其他 - 显示 UI 扩展点&lt;/code&gt; 来显示所有菜单的 Hook：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-extend_menu/show_hook.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-extend_menu/show_hook2.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_1&#34;&gt;模块依赖&lt;/h2&gt;
&lt;p&gt;需要在项目 .Build.cs 文件里面加上依赖的模块 LevelEditor, Slate, SlateCore, EditorStyle, EditorWidgets, UnrealEd, ToolMenus：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PrivateDependencyModuleNames&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddRange&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34; href=&#34;#__codelineno-0-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-4&#34; name=&#34;__codelineno-0-4&#34; href=&#34;#__codelineno-0-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Core&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-5&#34; name=&#34;__codelineno-0-5&#34; href=&#34;#__codelineno-0-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Engine&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-6&#34; name=&#34;__codelineno-0-6&#34; href=&#34;#__codelineno-0-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;CoreUObject&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-7&#34; name=&#34;__codelineno-0-7&#34; href=&#34;#__codelineno-0-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;LevelEditor&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-8&#34; name=&#34;__codelineno-0-8&#34; href=&#34;#__codelineno-0-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Slate&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-9&#34; name=&#34;__codelineno-0-9&#34; href=&#34;#__codelineno-0-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;SlateCore&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-10&#34; name=&#34;__codelineno-0-10&#34; href=&#34;#__codelineno-0-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;EditorStyle&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-11&#34; name=&#34;__codelineno-0-11&#34; href=&#34;#__codelineno-0-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;EditorWidgets&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-12&#34; name=&#34;__codelineno-0-12&#34; href=&#34;#__codelineno-0-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;UnrealEd&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-13&#34; name=&#34;__codelineno-0-13&#34; href=&#34;#__codelineno-0-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;ToolMenus&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-14&#34; name=&#34;__codelineno-0-14&#34; href=&#34;#__codelineno-0-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-15&#34; name=&#34;__codelineno-0-15&#34; href=&#34;#__codelineno-0-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;_2&#34;&gt;添加菜单栏&lt;/h2&gt;
&lt;p&gt;直接上代码&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuExtender&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MakeShared&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FExtender&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-2&#34; name=&#34;__codelineno-1-2&#34; href=&#34;#__codelineno-1-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-3&#34; name=&#34;__codelineno-1-3&#34; href=&#34;#__codelineno-1-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;MenuExtender&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddMenuBarExtension&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-4&#34; name=&#34;__codelineno-1-4&#34; href=&#34;#__codelineno-1-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Help&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EExtensionHook&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;After&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Create After Help&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-5&#34; name=&#34;__codelineno-1-5&#34; href=&#34;#__codelineno-1-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;nullptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-6&#34; name=&#34;__codelineno-1-6&#34; href=&#34;#__codelineno-1-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMenuBarExtensionDelegate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([](&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMenuBarBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBarBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-7&#34; name=&#34;__codelineno-1-7&#34; href=&#34;#__codelineno-1-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-8&#34; name=&#34;__codelineno-1-8&#34; href=&#34;#__codelineno-1-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBarBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddPullDownMenu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-9&#34; name=&#34;__codelineno-1-9&#34; href=&#34;#__codelineno-1-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTest&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Name&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-10&#34; name=&#34;__codelineno-1-10&#34; href=&#34;#__codelineno-1-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTest&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Tips&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-11&#34; name=&#34;__codelineno-1-11&#34; href=&#34;#__codelineno-1-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FNewMenuDelegate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([](&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMenuBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-12&#34; name=&#34;__codelineno-1-12&#34; href=&#34;#__codelineno-1-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-13&#34; name=&#34;__codelineno-1-13&#34; href=&#34;#__codelineno-1-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// create sub menus&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-14&#34; name=&#34;__codelineno-1-14&#34; href=&#34;#__codelineno-1-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}),&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-15&#34; name=&#34;__codelineno-1-15&#34; href=&#34;#__codelineno-1-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuText&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// New Hook&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-16&#34; name=&#34;__codelineno-1-16&#34; href=&#34;#__codelineno-1-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-17&#34; name=&#34;__codelineno-1-17&#34; href=&#34;#__codelineno-1-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-18&#34; name=&#34;__codelineno-1-18&#34; href=&#34;#__codelineno-1-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;FModuleManager&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LoadModuleChecked&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FLevelEditorModule&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;LevelEditor&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetMenuExtensibilityManager&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddExtender&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuExtender&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;执行以上代码可以看到在 帮助 后面加上了一个菜单栏 MenuTest:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-extend_menu/bar.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_3&#34;&gt;添加命令&lt;/h2&gt;
&lt;p&gt;使用接口 &lt;code&gt;MenuBuilder.AddMenuEntry&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-2-1&#34; name=&#34;__codelineno-2-1&#34; href=&#34;#__codelineno-2-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// Inside MenuTest Lambda&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-2&#34; name=&#34;__codelineno-2-2&#34; href=&#34;#__codelineno-2-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddMenuEntry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-3&#34; name=&#34;__codelineno-2-3&#34; href=&#34;#__codelineno-2-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestAction&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestAction&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-4&#34; name=&#34;__codelineno-2-4&#34; href=&#34;#__codelineno-2-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FSlateIcon&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FUIAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FExecuteAction&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([]()&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-5&#34; name=&#34;__codelineno-2-5&#34; href=&#34;#__codelineno-2-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-6&#34; name=&#34;__codelineno-2-6&#34; href=&#34;#__codelineno-2-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// do action&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-7&#34; name=&#34;__codelineno-2-7&#34; href=&#34;#__codelineno-2-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;把以上代码放到 CreateLambda 里面，即可生成菜单命令：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-extend_menu/action.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_4&#34;&gt;菜单分节&lt;/h2&gt;
&lt;p&gt;使用 &lt;code&gt;MenuBuilder.BeginSection&lt;/code&gt; 和 &lt;code&gt;MenuBuilder.EndSection&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-3-1&#34; name=&#34;__codelineno-3-1&#34; href=&#34;#__codelineno-3-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BeginSection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NAME_None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestSection&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-2&#34; name=&#34;__codelineno-3-2&#34; href=&#34;#__codelineno-3-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// code to create action&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-3&#34; name=&#34;__codelineno-3-3&#34; href=&#34;#__codelineno-3-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EndSection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;_5&#34;&gt;分隔符&lt;/h2&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-4-1&#34; name=&#34;__codelineno-4-1&#34; href=&#34;#__codelineno-4-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddMenuSeparator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-extend_menu/section%26sperator.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_6&#34;&gt;子菜单&lt;/h2&gt;
&lt;p&gt;子菜单类似菜单栏，需要在 Lambda 里面定义：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-5-1&#34; name=&#34;__codelineno-5-1&#34; href=&#34;#__codelineno-5-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddSubMenu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-2&#34; name=&#34;__codelineno-5-2&#34; href=&#34;#__codelineno-5-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestSub&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-5-3&#34; name=&#34;__codelineno-5-3&#34; href=&#34;#__codelineno-5-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestSub&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-5-4&#34; name=&#34;__codelineno-5-4&#34; href=&#34;#__codelineno-5-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FNewMenuDelegate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([](&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMenuBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-5&#34; name=&#34;__codelineno-5-5&#34; href=&#34;#__codelineno-5-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-6&#34; name=&#34;__codelineno-5-6&#34; href=&#34;#__codelineno-5-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddMenuEntry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-7&#34; name=&#34;__codelineno-5-7&#34; href=&#34;#__codelineno-5-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestSubAction&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestSubAction&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-8&#34; name=&#34;__codelineno-5-8&#34; href=&#34;#__codelineno-5-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FSlateIcon&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FUIAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FExecuteAction&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([]()&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-9&#34; name=&#34;__codelineno-5-9&#34; href=&#34;#__codelineno-5-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-10&#34; name=&#34;__codelineno-5-10&#34; href=&#34;#__codelineno-5-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// do action&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-11&#34; name=&#34;__codelineno-5-11&#34; href=&#34;#__codelineno-5-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})));&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-12&#34; name=&#34;__codelineno-5-12&#34; href=&#34;#__codelineno-5-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-extend_menu/submenu.png&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;slateui&#34;&gt;SlateUI 控件&lt;/h1&gt;
&lt;p&gt;还可以添加 UI 控件：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-6-1&#34; name=&#34;__codelineno-6-1&#34; href=&#34;#__codelineno-6-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddWidget&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-2&#34; name=&#34;__codelineno-6-2&#34; href=&#34;#__codelineno-6-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SNew&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SHorizontalBox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-3&#34; name=&#34;__codelineno-6-3&#34; href=&#34;#__codelineno-6-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SHorizontalBox&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Slot&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-4&#34; name=&#34;__codelineno-6-4&#34; href=&#34;#__codelineno-6-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AutoWidth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-5&#34; name=&#34;__codelineno-6-5&#34; href=&#34;#__codelineno-6-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-6&#34; name=&#34;__codelineno-6-6&#34; href=&#34;#__codelineno-6-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SNew&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SEditableTextBox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-7&#34; name=&#34;__codelineno-6-7&#34; href=&#34;#__codelineno-6-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MinDesiredWidth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;50&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-8&#34; name=&#34;__codelineno-6-8&#34; href=&#34;#__codelineno-6-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestWidget&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-9&#34; name=&#34;__codelineno-6-9&#34; href=&#34;#__codelineno-6-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-10&#34; name=&#34;__codelineno-6-10&#34; href=&#34;#__codelineno-6-10&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-11&#34; name=&#34;__codelineno-6-11&#34; href=&#34;#__codelineno-6-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SHorizontalBox&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Slot&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-12&#34; name=&#34;__codelineno-6-12&#34; href=&#34;#__codelineno-6-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AutoWidth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-13&#34; name=&#34;__codelineno-6-13&#34; href=&#34;#__codelineno-6-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Padding&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-14&#34; name=&#34;__codelineno-6-14&#34; href=&#34;#__codelineno-6-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-15&#34; name=&#34;__codelineno-6-15&#34; href=&#34;#__codelineno-6-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SNew&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SButton&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-16&#34; name=&#34;__codelineno-6-16&#34; href=&#34;#__codelineno-6-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;ExtendWidget&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-17&#34; name=&#34;__codelineno-6-17&#34; href=&#34;#__codelineno-6-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OnClicked&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FOnClicked&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([]()&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-18&#34; name=&#34;__codelineno-6-18&#34; href=&#34;#__codelineno-6-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-19&#34; name=&#34;__codelineno-6-19&#34; href=&#34;#__codelineno-6-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// do action&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-20&#34; name=&#34;__codelineno-6-20&#34; href=&#34;#__codelineno-6-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FReply&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Handled&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-21&#34; name=&#34;__codelineno-6-21&#34; href=&#34;#__codelineno-6-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}))&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-22&#34; name=&#34;__codelineno-6-22&#34; href=&#34;#__codelineno-6-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-23&#34; name=&#34;__codelineno-6-23&#34; href=&#34;#__codelineno-6-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetEmpty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-24&#34; name=&#34;__codelineno-6-24&#34; href=&#34;#__codelineno-6-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-extend_menu/widget.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Slate UI 相关的内容这里不详细展开，有兴趣可以去另外找文章看。&lt;/p&gt;
&lt;h1 id=&#34;hook_1&#34;&gt;Hook 增加菜单&lt;/h1&gt;
&lt;p&gt;譬如在 &lt;code&gt;工具 - 编程&lt;/code&gt; 里面增加一个命令：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-7-1&#34; name=&#34;__codelineno-7-1&#34; href=&#34;#__codelineno-7-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;MenuExtender&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddMenuExtension&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-2&#34; name=&#34;__codelineno-7-2&#34; href=&#34;#__codelineno-7-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Programming&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EExtensionHook&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;After&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-3&#34; name=&#34;__codelineno-7-3&#34; href=&#34;#__codelineno-7-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;nullptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-4&#34; name=&#34;__codelineno-7-4&#34; href=&#34;#__codelineno-7-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMenuExtensionDelegate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([](&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMenuBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-5&#34; name=&#34;__codelineno-7-5&#34; href=&#34;#__codelineno-7-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-6&#34; name=&#34;__codelineno-7-6&#34; href=&#34;#__codelineno-7-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddMenuEntry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-7&#34; name=&#34;__codelineno-7-7&#34; href=&#34;#__codelineno-7-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestAction&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestAction&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-8&#34; name=&#34;__codelineno-7-8&#34; href=&#34;#__codelineno-7-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FSlateIcon&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FUIAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FExecuteAction&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([]()&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-9&#34; name=&#34;__codelineno-7-9&#34; href=&#34;#__codelineno-7-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-10&#34; name=&#34;__codelineno-7-10&#34; href=&#34;#__codelineno-7-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// do action&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-11&#34; name=&#34;__codelineno-7-11&#34; href=&#34;#__codelineno-7-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})));&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-12&#34; name=&#34;__codelineno-7-12&#34; href=&#34;#__codelineno-7-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-13&#34; name=&#34;__codelineno-7-13&#34; href=&#34;#__codelineno-7-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-extend_menu/other_hook.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;同理可以添加其他菜单类型。&lt;/p&gt;
&lt;h1 id=&#34;_7&#34;&gt;完整代码&lt;/h1&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-8-1&#34; name=&#34;__codelineno-8-1&#34; href=&#34;#__codelineno-8-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;BuildTestMenu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-2&#34; name=&#34;__codelineno-8-2&#34; href=&#34;#__codelineno-8-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-3&#34; name=&#34;__codelineno-8-3&#34; href=&#34;#__codelineno-8-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuExtender&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MakeShared&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FExtender&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-4&#34; name=&#34;__codelineno-8-4&#34; href=&#34;#__codelineno-8-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-5&#34; name=&#34;__codelineno-8-5&#34; href=&#34;#__codelineno-8-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuExtender&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddMenuBarExtension&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-6&#34; name=&#34;__codelineno-8-6&#34; href=&#34;#__codelineno-8-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Help&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EExtensionHook&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;After&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-7&#34; name=&#34;__codelineno-8-7&#34; href=&#34;#__codelineno-8-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;nullptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-8&#34; name=&#34;__codelineno-8-8&#34; href=&#34;#__codelineno-8-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMenuBarExtensionDelegate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([](&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMenuBarBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBarBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-9&#34; name=&#34;__codelineno-8-9&#34; href=&#34;#__codelineno-8-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-10&#34; name=&#34;__codelineno-8-10&#34; href=&#34;#__codelineno-8-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBarBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddPullDownMenu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-11&#34; name=&#34;__codelineno-8-11&#34; href=&#34;#__codelineno-8-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTest&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-12&#34; name=&#34;__codelineno-8-12&#34; href=&#34;#__codelineno-8-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTest&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-13&#34; name=&#34;__codelineno-8-13&#34; href=&#34;#__codelineno-8-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FNewMenuDelegate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([](&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMenuBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-14&#34; name=&#34;__codelineno-8-14&#34; href=&#34;#__codelineno-8-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-15&#34; name=&#34;__codelineno-8-15&#34; href=&#34;#__codelineno-8-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BeginSection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NAME_None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestSection&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-16&#34; name=&#34;__codelineno-8-16&#34; href=&#34;#__codelineno-8-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddMenuSeparator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-17&#34; name=&#34;__codelineno-8-17&#34; href=&#34;#__codelineno-8-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddMenuEntry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-18&#34; name=&#34;__codelineno-8-18&#34; href=&#34;#__codelineno-8-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestAction&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestAction&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-19&#34; name=&#34;__codelineno-8-19&#34; href=&#34;#__codelineno-8-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FSlateIcon&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FUIAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FExecuteAction&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([]()&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-20&#34; name=&#34;__codelineno-8-20&#34; href=&#34;#__codelineno-8-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-21&#34; name=&#34;__codelineno-8-21&#34; href=&#34;#__codelineno-8-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// do action&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-22&#34; name=&#34;__codelineno-8-22&#34; href=&#34;#__codelineno-8-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})));&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-23&#34; name=&#34;__codelineno-8-23&#34; href=&#34;#__codelineno-8-23&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-24&#34; name=&#34;__codelineno-8-24&#34; href=&#34;#__codelineno-8-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddSubMenu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-25&#34; name=&#34;__codelineno-8-25&#34; href=&#34;#__codelineno-8-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestSubb&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-26&#34; name=&#34;__codelineno-8-26&#34; href=&#34;#__codelineno-8-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestSubb&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-27&#34; name=&#34;__codelineno-8-27&#34; href=&#34;#__codelineno-8-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FNewMenuDelegate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([](&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMenuBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-28&#34; name=&#34;__codelineno-8-28&#34; href=&#34;#__codelineno-8-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-29&#34; name=&#34;__codelineno-8-29&#34; href=&#34;#__codelineno-8-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddMenuEntry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-30&#34; name=&#34;__codelineno-8-30&#34; href=&#34;#__codelineno-8-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestSubAction&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestSubAction&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-31&#34; name=&#34;__codelineno-8-31&#34; href=&#34;#__codelineno-8-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FSlateIcon&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FUIAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FExecuteAction&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([]()&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-32&#34; name=&#34;__codelineno-8-32&#34; href=&#34;#__codelineno-8-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                                &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-33&#34; name=&#34;__codelineno-8-33&#34; href=&#34;#__codelineno-8-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                                    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// do action&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-34&#34; name=&#34;__codelineno-8-34&#34; href=&#34;#__codelineno-8-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                                &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})));&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-35&#34; name=&#34;__codelineno-8-35&#34; href=&#34;#__codelineno-8-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}));&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-36&#34; name=&#34;__codelineno-8-36&#34; href=&#34;#__codelineno-8-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EndSection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-37&#34; name=&#34;__codelineno-8-37&#34; href=&#34;#__codelineno-8-37&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-38&#34; name=&#34;__codelineno-8-38&#34; href=&#34;#__codelineno-8-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddWidget&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-39&#34; name=&#34;__codelineno-8-39&#34; href=&#34;#__codelineno-8-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SNew&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SHorizontalBox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-40&#34; name=&#34;__codelineno-8-40&#34; href=&#34;#__codelineno-8-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                         &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SHorizontalBox&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Slot&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-41&#34; name=&#34;__codelineno-8-41&#34; href=&#34;#__codelineno-8-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                         &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AutoWidth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-42&#34; name=&#34;__codelineno-8-42&#34; href=&#34;#__codelineno-8-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                         &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-43&#34; name=&#34;__codelineno-8-43&#34; href=&#34;#__codelineno-8-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                             &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SNew&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SEditableTextBox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-44&#34; name=&#34;__codelineno-8-44&#34; href=&#34;#__codelineno-8-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                             &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MinDesiredWidth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;50&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-45&#34; name=&#34;__codelineno-8-45&#34; href=&#34;#__codelineno-8-45&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                             &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestWidget&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-46&#34; name=&#34;__codelineno-8-46&#34; href=&#34;#__codelineno-8-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                         &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-47&#34; name=&#34;__codelineno-8-47&#34; href=&#34;#__codelineno-8-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                         &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SHorizontalBox&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Slot&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-48&#34; name=&#34;__codelineno-8-48&#34; href=&#34;#__codelineno-8-48&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                         &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AutoWidth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-49&#34; name=&#34;__codelineno-8-49&#34; href=&#34;#__codelineno-8-49&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                         &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Padding&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-50&#34; name=&#34;__codelineno-8-50&#34; href=&#34;#__codelineno-8-50&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                         &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-51&#34; name=&#34;__codelineno-8-51&#34; href=&#34;#__codelineno-8-51&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SNew&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SButton&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-52&#34; name=&#34;__codelineno-8-52&#34; href=&#34;#__codelineno-8-52&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;ExtendWidget&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-53&#34; name=&#34;__codelineno-8-53&#34; href=&#34;#__codelineno-8-53&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OnClicked&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FOnClicked&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([]()&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-54&#34; name=&#34;__codelineno-8-54&#34; href=&#34;#__codelineno-8-54&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-55&#34; name=&#34;__codelineno-8-55&#34; href=&#34;#__codelineno-8-55&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// do action&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-56&#34; name=&#34;__codelineno-8-56&#34; href=&#34;#__codelineno-8-56&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FReply&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Handled&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-57&#34; name=&#34;__codelineno-8-57&#34; href=&#34;#__codelineno-8-57&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}))&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-58&#34; name=&#34;__codelineno-8-58&#34; href=&#34;#__codelineno-8-58&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                         &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-59&#34; name=&#34;__codelineno-8-59&#34; href=&#34;#__codelineno-8-59&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                     &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetEmpty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-60&#34; name=&#34;__codelineno-8-60&#34; href=&#34;#__codelineno-8-60&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-61&#34; name=&#34;__codelineno-8-61&#34; href=&#34;#__codelineno-8-61&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}),&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-62&#34; name=&#34;__codelineno-8-62&#34; href=&#34;#__codelineno-8-62&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTest&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-63&#34; name=&#34;__codelineno-8-63&#34; href=&#34;#__codelineno-8-63&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-64&#34; name=&#34;__codelineno-8-64&#34; href=&#34;#__codelineno-8-64&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-65&#34; name=&#34;__codelineno-8-65&#34; href=&#34;#__codelineno-8-65&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-66&#34; name=&#34;__codelineno-8-66&#34; href=&#34;#__codelineno-8-66&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuExtender&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddMenuExtension&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-67&#34; name=&#34;__codelineno-8-67&#34; href=&#34;#__codelineno-8-67&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Programming&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EExtensionHook&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;After&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-68&#34; name=&#34;__codelineno-8-68&#34; href=&#34;#__codelineno-8-68&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;nullptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-69&#34; name=&#34;__codelineno-8-69&#34; href=&#34;#__codelineno-8-69&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMenuExtensionDelegate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([](&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FMenuBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-70&#34; name=&#34;__codelineno-8-70&#34; href=&#34;#__codelineno-8-70&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-71&#34; name=&#34;__codelineno-8-71&#34; href=&#34;#__codelineno-8-71&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddMenuEntry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-72&#34; name=&#34;__codelineno-8-72&#34; href=&#34;#__codelineno-8-72&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestAction&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FText&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;MenuTestAction&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-73&#34; name=&#34;__codelineno-8-73&#34; href=&#34;#__codelineno-8-73&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FSlateIcon&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FUIAction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FExecuteAction&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateLambda&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([]()&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-74&#34; name=&#34;__codelineno-8-74&#34; href=&#34;#__codelineno-8-74&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-75&#34; name=&#34;__codelineno-8-75&#34; href=&#34;#__codelineno-8-75&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// do action&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-76&#34; name=&#34;__codelineno-8-76&#34; href=&#34;#__codelineno-8-76&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})));&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-77&#34; name=&#34;__codelineno-8-77&#34; href=&#34;#__codelineno-8-77&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-78&#34; name=&#34;__codelineno-8-78&#34; href=&#34;#__codelineno-8-78&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-79&#34; name=&#34;__codelineno-8-79&#34; href=&#34;#__codelineno-8-79&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-80&#34; name=&#34;__codelineno-8-80&#34; href=&#34;#__codelineno-8-80&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FModuleManager&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LoadModuleChecked&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FLevelEditorModule&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;LevelEditor&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetMenuExtensibilityManager&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AddExtender&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MenuExtender&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-81&#34; name=&#34;__codelineno-8-81&#34; href=&#34;#__codelineno-8-81&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-extend_menu/overall.png&#34; /&gt;&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E6%89%A9%E5%B1%95%E7%BC%96%E8%BE%91%E5%99%A8%E8%8F%9C%E5%8D%95/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Mon, 25 Dec 2023 17:20:26 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E6%89%A9%E5%B1%95%E7%BC%96%E8%BE%91%E5%99%A8%E8%8F%9C%E5%8D%95/</guid>
      
    </item>
    
    <item>
      <title>Contact and Subscribe</title>
      
      
      
      
      <description>&lt;h1 id=&#34;contact-and-subscribe&#34;&gt;Contact and Subscribe&lt;/h1&gt;
&lt;!-- no translate --&gt;

&lt;p&gt;&lt;a href=&#34;https://github.com/disenone&#34;&gt;&lt;img alt=&#34;badge&#34; src=&#34;https://img.shields.io/badge/GitHub-282c34?&amp;amp;style=for-the-badge&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;mailto:disenonec@gmail.com&#34;&gt;&lt;img alt=&#34;badge&#34; src=&#34;https://img.shields.io/badge/Email-f48222?&amp;amp;style=for-the-badge&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://wiki.disenone.site/sitemap.xml&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/Sitemap-green?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://wiki.disenone.site/feed_rss_created.xml&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/RSS-post%20created-pcf?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://wiki.disenone.site/feed_rss_updated.xml&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/RSS-post%20updated-yellowgreen?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <link>https://wiki.disenone.site/contact-and-subscribe/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Sat, 02 Dec 2023 05:09:54 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/contact-and-subscribe/</guid>
      
    </item>
    
    <item>
      <title>Contact and Subscribe</title>
      
      
      
      
      <description>&lt;h1 id=&#34;contact-and-subscribe&#34;&gt;Contact and Subscribe&lt;/h1&gt;
&lt;!-- no translate --&gt;

&lt;p&gt;&lt;a href=&#34;https://github.com/disenone&#34;&gt;&lt;img alt=&#34;badge&#34; src=&#34;https://img.shields.io/badge/GitHub-282c34?&amp;amp;style=for-the-badge&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;mailto:disenonec@gmail.com&#34;&gt;&lt;img alt=&#34;badge&#34; src=&#34;https://img.shields.io/badge/Email-f48222?&amp;amp;style=for-the-badge&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://wiki.disenone.site/sitemap.xml&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/Sitemap-green?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://wiki.disenone.site/feed_rss_created.xml&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/RSS-post%20created-pcf?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://wiki.disenone.site/feed_rss_updated.xml&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/RSS-post%20updated-yellowgreen?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <link>https://wiki.disenone.site/zh-Hant/contact-and-subscribe/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Sat, 02 Dec 2023 05:09:54 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/zh-Hant/contact-and-subscribe/</guid>
      
    </item>
    
    <item>
      <title>Contact and Subscribe</title>
      
      
      
      
      <description>&lt;h1 id=&#34;contact-and-subscribe&#34;&gt;Contact and Subscribe&lt;/h1&gt;
&lt;!-- no translate --&gt;

&lt;p&gt;&lt;a href=&#34;https://github.com/disenone&#34;&gt;&lt;img alt=&#34;badge&#34; src=&#34;https://img.shields.io/badge/GitHub-282c34?&amp;amp;style=for-the-badge&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;mailto:disenonec@gmail.com&#34;&gt;&lt;img alt=&#34;badge&#34; src=&#34;https://img.shields.io/badge/Email-f48222?&amp;amp;style=for-the-badge&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://wiki.disenone.site/sitemap.xml&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/Sitemap-green?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://wiki.disenone.site/feed_rss_created.xml&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/RSS-post%20created-pcf?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://wiki.disenone.site/feed_rss_updated.xml&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/RSS-post%20updated-yellowgreen?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <link>https://wiki.disenone.site/ja/contact-and-subscribe/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Sat, 02 Dec 2023 05:09:54 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ja/contact-and-subscribe/</guid>
      
    </item>
    
    <item>
      <title>Contact and Subscribe</title>
      
      
      
      
      <description>&lt;h1 id=&#34;contact-and-subscribe&#34;&gt;Contact and Subscribe&lt;/h1&gt;
&lt;!-- no translate --&gt;

&lt;p&gt;&lt;a href=&#34;https://github.com/disenone&#34;&gt;&lt;img alt=&#34;badge&#34; src=&#34;https://img.shields.io/badge/GitHub-282c34?&amp;amp;style=for-the-badge&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;mailto:disenonec@gmail.com&#34;&gt;&lt;img alt=&#34;badge&#34; src=&#34;https://img.shields.io/badge/Email-f48222?&amp;amp;style=for-the-badge&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://wiki.disenone.site/sitemap.xml&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/Sitemap-green?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://wiki.disenone.site/feed_rss_created.xml&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/RSS-post%20created-pcf?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://wiki.disenone.site/feed_rss_updated.xml&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/RSS-post%20updated-yellowgreen?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <link>https://wiki.disenone.site/de/contact-and-subscribe/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Sat, 02 Dec 2023 05:09:54 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/de/contact-and-subscribe/</guid>
      
    </item>
    
    <item>
      <title>Contact and Subscribe</title>
      
      
      
      
      <description>&lt;h1 id=&#34;contact-and-subscribe&#34;&gt;Contact and Subscribe&lt;/h1&gt;
&lt;!-- no translate --&gt;

&lt;p&gt;&lt;a href=&#34;https://github.com/disenone&#34;&gt;&lt;img alt=&#34;badge&#34; src=&#34;https://img.shields.io/badge/GitHub-282c34?&amp;amp;style=for-the-badge&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;mailto:disenonec@gmail.com&#34;&gt;&lt;img alt=&#34;badge&#34; src=&#34;https://img.shields.io/badge/Email-f48222?&amp;amp;style=for-the-badge&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://wiki.disenone.site/sitemap.xml&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/Sitemap-green?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://wiki.disenone.site/feed_rss_created.xml&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/RSS-post%20created-pcf?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://wiki.disenone.site/feed_rss_updated.xml&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/RSS-post%20updated-yellowgreen?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <link>https://wiki.disenone.site/fr/contact-and-subscribe/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Sat, 02 Dec 2023 05:09:54 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/fr/contact-and-subscribe/</guid>
      
    </item>
    
    <item>
      <title>Contact and Subscribe</title>
      
      
      
      
      <description>&lt;h1 id=&#34;contact-and-subscribe&#34;&gt;Contact and Subscribe&lt;/h1&gt;
&lt;!-- no translate --&gt;

&lt;p&gt;&lt;a href=&#34;https://github.com/disenone&#34;&gt;&lt;img alt=&#34;badge&#34; src=&#34;https://img.shields.io/badge/GitHub-282c34?&amp;amp;style=for-the-badge&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;mailto:disenonec@gmail.com&#34;&gt;&lt;img alt=&#34;badge&#34; src=&#34;https://img.shields.io/badge/Email-f48222?&amp;amp;style=for-the-badge&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://wiki.disenone.site/sitemap.xml&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/Sitemap-green?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://wiki.disenone.site/feed_rss_created.xml&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/RSS-post%20created-pcf?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://wiki.disenone.site/feed_rss_updated.xml&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/RSS-post%20updated-yellowgreen?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <link>https://wiki.disenone.site/ar/contact-and-subscribe/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Sat, 02 Dec 2023 05:09:54 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ar/contact-and-subscribe/</guid>
      
    </item>
    
    <item>
      <title>Contact and Subscribe</title>
      
      
      
      
      <description>&lt;h1 id=&#34;contact-and-subscribe&#34;&gt;Contact and Subscribe&lt;/h1&gt;
&lt;!-- no translate --&gt;

&lt;p&gt;&lt;a href=&#34;https://github.com/disenone&#34;&gt;&lt;img alt=&#34;badge&#34; src=&#34;https://img.shields.io/badge/GitHub-282c34?&amp;amp;style=for-the-badge&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;mailto:disenonec@gmail.com&#34;&gt;&lt;img alt=&#34;badge&#34; src=&#34;https://img.shields.io/badge/Email-f48222?&amp;amp;style=for-the-badge&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://wiki.disenone.site/sitemap.xml&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/Sitemap-green?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://wiki.disenone.site/feed_rss_created.xml&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/RSS-post%20created-pcf?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://wiki.disenone.site/feed_rss_updated.xml&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/RSS-post%20updated-yellowgreen?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <link>https://wiki.disenone.site/ko/contact-and-subscribe/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Sat, 02 Dec 2023 05:09:54 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ko/contact-and-subscribe/</guid>
      
    </item>
    
    <item>
      <title>使用 FASTBuild 编译 UE4 和 UE5</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;使用 FASTBuild 编译 UE4 和 UE5&#34; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;本文方法经测试支持 UE4.27 - UE5.3，其他版本未测试过，可以尝试。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;_1&#34;&gt;前言&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://www.fastbuild.org/docs/home.html&#34;&gt;FASTBuild&lt;/a&gt; 是一个免费开源的分布式编译工具，UE 本身编译比较耗时，如果可以用上 FASTBuild，能够大大减少耗时。&lt;/p&gt;
&lt;p&gt;UE 从 4.x 开始能够支持 FASTBuild，官方源码自带了魔改过的 FASTBuild 工具，基于 FASTBuild 0.99 版本，位置在 &lt;code&gt;Engine\Extras\ThirdPartyNotUE\FASTBuild&lt;/code&gt;，UE5.3 同样使用的是这个版本。这个已经是比较久以前的版本了，截止本文创建时间，FASTBuild 官方最新版本是 1.11，有了更多新的功能支持和 bug 修复。本文着重记录如何使用 1.11 版本同时支持 UE4 和 UE5。&lt;/p&gt;
&lt;h2 id=&#34;_2&#34;&gt;简易配置&lt;/h2&gt;
&lt;p&gt;要达到目的，我们需要对 FASTBuild 1.11 和 UE 源码做一些修改。在这里，其实我已经都修改完了，于是我们可以直接用我修改完的版本来使用。&lt;/p&gt;
&lt;p&gt;FASTBuild 下载我提交的 &lt;a href=&#34;https://github.com/disenone/fastbuild/releases&#34;&gt;最新版本&lt;/a&gt; 里面的执行文件 FBuild.exe, FBuildCoordinator.exe, FBuildWorker.exe。为了清晰表达，下面把使用 FBuild.exe 来进行编程的机器叫做&lt;code&gt;本机&lt;/code&gt;，其他提供 CPU 参与编辑的远程机器叫做&lt;code&gt;远程机&lt;/code&gt;。&lt;/p&gt;
&lt;h3 id=&#34;_3&#34;&gt;本机配置&lt;/h3&gt;
&lt;p&gt;把 FBuild.exe 所在目录加入系统环境变量 Path 中，保证 cmd 里面能直接执行 FBuild.exe。&lt;/p&gt;
&lt;p&gt;配置 Cache 共享目录（如果不需要生成 Cache 的话，可以不配置）：把一个空目录设置成共享路径，并确认远程机可以访问。&lt;/p&gt;
&lt;p&gt;打开本机 UE4 / UE5 的源码项目，修改编译配置文件 Engine\Saved\UnrealBuildTool\BuildConfiguration.xml 如下：&lt;/p&gt;
&lt;div class=&#34;language-xml highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;Configuration&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;xmlns=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;https://www.unrealengine.com/BuildConfiguration&amp;quot;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34; href=&#34;#__codelineno-0-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;BuildConfiguration&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-4&#34; name=&#34;__codelineno-0-4&#34; href=&#34;#__codelineno-0-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;bAllowFASTBuild&amp;gt;&lt;/span&gt;true&lt;span class=&#34;nt&#34;&gt;&amp;lt;/bAllowFASTBuild&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-5&#34; name=&#34;__codelineno-0-5&#34; href=&#34;#__codelineno-0-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;/BuildConfiguration&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-6&#34; name=&#34;__codelineno-0-6&#34; href=&#34;#__codelineno-0-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;FASTBuild&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-7&#34; name=&#34;__codelineno-0-7&#34; href=&#34;#__codelineno-0-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;bEnableDistribution&amp;gt;&lt;/span&gt;true&lt;span class=&#34;nt&#34;&gt;&amp;lt;/bEnableDistribution&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-8&#34; name=&#34;__codelineno-0-8&#34; href=&#34;#__codelineno-0-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;bEnableCaching&amp;gt;&lt;/span&gt;true&lt;span class=&#34;nt&#34;&gt;&amp;lt;/bEnableCaching&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-9&#34; name=&#34;__codelineno-0-9&#34; href=&#34;#__codelineno-0-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;FBuildCachePath&amp;gt;&lt;/span&gt;\\127.0.0.1\Cache\&lt;span class=&#34;nt&#34;&gt;&amp;lt;/FBuildCachePath&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-10&#34; name=&#34;__codelineno-0-10&#34; href=&#34;#__codelineno-0-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;FBuildCoordinator&amp;gt;&lt;/span&gt;127.0.0.1&lt;span class=&#34;nt&#34;&gt;&amp;lt;/FBuildCoordinator&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-11&#34; name=&#34;__codelineno-0-11&#34; href=&#34;#__codelineno-0-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;/FASTBuild&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-12&#34; name=&#34;__codelineno-0-12&#34; href=&#34;#__codelineno-0-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;/Configuration&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;本机运行之前下载的 FBuildCoordinator.exe。&lt;/p&gt;
&lt;h3 id=&#34;_4&#34;&gt;远程机配置&lt;/h3&gt;
&lt;p&gt;同样配置 Cache，只是 ip 需要指定到本机 ip，这里假定为 192.168.1.100&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FASTBUILD_CACHE_PATH: \192.168.1.100\Cache&lt;/li&gt;
&lt;li&gt;FASTBUILD_CACHE_MODE: rw&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;同样配置 Coordinator ip&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FASTBUILD_COORDINATOR: 192.168.1.100&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;配置完如下图&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2023-ue-fastbuild/remote_vars.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;远程机上运行 FBuildWorker.exe，如果配置成功，可以看到本机的 FBuildCoordinator.exe 上会打印日志（这里 192.168.1.101 是远程机的 ip）：&lt;/p&gt;
&lt;div class=&#34;language-text highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;FBuildCoordinator - v1.11-UE
&lt;a id=&#34;__codelineno-1-2&#34; name=&#34;__codelineno-1-2&#34; href=&#34;#__codelineno-1-2&#34;&gt;&lt;/a&gt;[2023-12-01-20:06:38] Listening on port 31392
&lt;a id=&#34;__codelineno-1-3&#34; name=&#34;__codelineno-1-3&#34; href=&#34;#__codelineno-1-3&#34;&gt;&lt;/a&gt;[2023-12-01-20:06:38] current [0] workers: []
&lt;a id=&#34;__codelineno-1-4&#34; name=&#34;__codelineno-1-4&#34; href=&#34;#__codelineno-1-4&#34;&gt;&lt;/a&gt;[2023-12-01-20:06:42] New worker available: 192.168.1.101
&lt;a id=&#34;__codelineno-1-5&#34; name=&#34;__codelineno-1-5&#34; href=&#34;#__codelineno-1-5&#34;&gt;&lt;/a&gt;[2023-12-01-20:06:42] current [1] workers: [192.168.1.101]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;ue&#34;&gt;测试 UE 编译&lt;/h3&gt;
&lt;p&gt;用 VisualStudio 打开 UE 源码工程 sln，选一个 C++ 的项目，点击 Rebuild。如果配置正常，可以看到类似如下的日志&lt;/p&gt;
&lt;div class=&#34;language-text highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-2-1&#34; name=&#34;__codelineno-2-1&#34; href=&#34;#__codelineno-2-1&#34;&gt;&lt;/a&gt;11&amp;gt;FBuild Command Line Arguments: &amp;#39;-monitor -summary -dist -cache -ide -j12 -clean -config &amp;quot;E:\UE\ue5.3_git\Engine\Intermediate\Build\fbuild.bff&amp;quot; -nostoponerror
&lt;a id=&#34;__codelineno-2-2&#34; name=&#34;__codelineno-2-2&#34; href=&#34;#__codelineno-2-2&#34;&gt;&lt;/a&gt;11&amp;gt;FBuild Executable: &amp;#39;d:\libs\FASTBuild\bin\FBuild.exe
&lt;a id=&#34;__codelineno-2-3&#34; name=&#34;__codelineno-2-3&#34; href=&#34;#__codelineno-2-3&#34;&gt;&lt;/a&gt;11&amp;gt;FBuild Coordinator: &amp;#39;127.0.0.1
&lt;a id=&#34;__codelineno-2-4&#34; name=&#34;__codelineno-2-4&#34; href=&#34;#__codelineno-2-4&#34;&gt;&lt;/a&gt;11&amp;gt;FBuild BrokeragePath: &amp;#39;\\127.0.0.1\Brokerage\
&lt;a id=&#34;__codelineno-2-5&#34; name=&#34;__codelineno-2-5&#34; href=&#34;#__codelineno-2-5&#34;&gt;&lt;/a&gt;11&amp;gt;FBuild CachePath: &amp;#39;\\127.0.0.1\Cache\
&lt;a id=&#34;__codelineno-2-6&#34; name=&#34;__codelineno-2-6&#34; href=&#34;#__codelineno-2-6&#34;&gt;&lt;/a&gt;11&amp;gt;BFF file &amp;#39;E:\UE\ue5.3_git\Engine\Intermediate\Build\fbuild.bff&amp;#39; has changed (reparsing will occur).
&lt;a id=&#34;__codelineno-2-7&#34; name=&#34;__codelineno-2-7&#34; href=&#34;#__codelineno-2-7&#34;&gt;&lt;/a&gt;11&amp;gt;Using Coordinator: 127.0.0.1
&lt;a id=&#34;__codelineno-2-8&#34; name=&#34;__codelineno-2-8&#34; href=&#34;#__codelineno-2-8&#34;&gt;&lt;/a&gt;11&amp;gt;Requesting worker list from Corrdinator
&lt;a id=&#34;__codelineno-2-9&#34; name=&#34;__codelineno-2-9&#34; href=&#34;#__codelineno-2-9&#34;&gt;&lt;/a&gt;11&amp;gt;Get Worker List from Coordinator.
&lt;a id=&#34;__codelineno-2-10&#34; name=&#34;__codelineno-2-10&#34; href=&#34;#__codelineno-2-10&#34;&gt;&lt;/a&gt;11&amp;gt;2 workers in payload: [192.168.1.101]
&lt;a id=&#34;__codelineno-2-11&#34; name=&#34;__codelineno-2-11&#34; href=&#34;#__codelineno-2-11&#34;&gt;&lt;/a&gt;11&amp;gt;Worker list received: 1 workers
&lt;a id=&#34;__codelineno-2-12&#34; name=&#34;__codelineno-2-12&#34; href=&#34;#__codelineno-2-12&#34;&gt;&lt;/a&gt;11&amp;gt;Distributed Compilation : 1 Workers in pool &amp;#39;127.0.0.1&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;FASTBuild 能找到远程机的 ip，并开始给远程机发送编译。在远程机的 FBuildWorker 上也能看到当前有编译任务在执行。&lt;/p&gt;
&lt;h2 id=&#34;_5&#34;&gt;进阶配置&lt;/h2&gt;
&lt;h3 id=&#34;ue_1&#34;&gt;支持更久版本的 UE&lt;/h3&gt;
&lt;p&gt;如果你发现自己的 UE 没有 FASTBuild 工具（Engine\Extras\ThirdPartyNotUE\FASTBuild），并且项目 UnrealBuildTool 里面没有 FASTBuild.cs 文件，那么很大概率是你的 UE 版本还不支持 FASTBuild。&lt;/p&gt;
&lt;p&gt;那么你需要参考 UE4.27 的源码，也创建一个类似的 FASTBuild.cs，并补上其他相关代码的修改，这里不详述。&lt;/p&gt;
&lt;h3 id=&#34;fastbuild&#34;&gt;编译自己的 FASTBuild&lt;/h3&gt;
&lt;p&gt;如果你对 FASTBuild 本身也感兴趣，或者想要做一些修改，可以尝试用 FASTBuild 来编译 FASTBuild。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;下载我的 &lt;a href=&#34;https://github.com/disenone/fastbuild/releases&#34;&gt;最新源码&lt;/a&gt;，并解压&lt;/li&gt;
&lt;li&gt;修改 External\SDK\VisualStudio\VS2019.bff，把 .VS2019_BasePath 和 .VS2019_Version 修改成你本机对应的内容，Version 可以在 .VS2019_BasePath\Tools\MSVC 目录下面看，例如
    &lt;div class=&#34;language-text highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-3-1&#34; name=&#34;__codelineno-3-1&#34; href=&#34;#__codelineno-3-1&#34;&gt;&lt;/a&gt;.VS2019_BasePath        = &amp;#39;C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC&amp;#39;    // &amp;lt;-- Set path here
&lt;a id=&#34;__codelineno-3-2&#34; name=&#34;__codelineno-3-2&#34; href=&#34;#__codelineno-3-2&#34;&gt;&lt;/a&gt;.VS2019_Version         = &amp;#39;14.29.30133&amp;#39; // &amp;lt;-- Set version here
&lt;a id=&#34;__codelineno-3-3&#34; name=&#34;__codelineno-3-3&#34; href=&#34;#__codelineno-3-3&#34;&gt;&lt;/a&gt;.VS2019_MSC_VER         = &amp;#39;1929&amp;#39; // &amp;lt;-- Set MSC_VER here
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;修改 External\SDK\Windows\Windows10SDK.bff 的 .Windows10_SDKBasePath 和 .Windows10_SDKVersion，版本可以在 .Windows10_SDKBasePath/bin 里面看：
    &lt;div class=&#34;language-text highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-4-1&#34; name=&#34;__codelineno-4-1&#34; href=&#34;#__codelineno-4-1&#34;&gt;&lt;/a&gt;.Windows10_SDKBasePath        = &amp;#39;C:\Program Files (x86)\Windows Kits/10&amp;#39;    // &amp;lt;-- Set path here
&lt;a id=&#34;__codelineno-4-2&#34; name=&#34;__codelineno-4-2&#34; href=&#34;#__codelineno-4-2&#34;&gt;&lt;/a&gt;.Windows10_SDKVersion         = &amp;#39;10.0.19041.0&amp;#39; // &amp;lt;-- Set version here
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;修改 External\SDK\Clang\Windows\Clang11.bff 的 .Clang11_BasePath 和 .Clang11_Version，路径在 .VS2019_BasePath\Tools\Tools/LLVM/x64
    &lt;div class=&#34;language-text highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-5-1&#34; name=&#34;__codelineno-5-1&#34; href=&#34;#__codelineno-5-1&#34;&gt;&lt;/a&gt;.Clang11_BasePath = &amp;#39;C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC/Tools/LLVM/x64&amp;#39;    // &amp;lt;-- Set path here
&lt;a id=&#34;__codelineno-5-2&#34; name=&#34;__codelineno-5-2&#34; href=&#34;#__codelineno-5-2&#34;&gt;&lt;/a&gt;.Clang11_Version  = &amp;#39;12.x.x&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;进入 Code 目录，在 cmd 执行 &lt;code&gt;FBuild.exe All-x64-Release&lt;/code&gt;，如果配置正常，可以看到编译成功，在 tmp\x64-Release\Tools\FBuild\FBuild 能看到 FBuild.exe。&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;FBuild.exe All-x64-Release -dist -coordinator=127.0.0.1&lt;/code&gt; 可以开启分布式编译。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;fbuild&#34;&gt;FBuild 更多选项&lt;/h3&gt;
&lt;p&gt;我提供的 FBuild 本身支持以下常用的选项：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;coordinator: 指定 Coordinator ip 地址（可以覆盖系统环境变量的值）&lt;/li&gt;
&lt;li&gt;brokerage: 指定 Brokerage 地址（可以覆盖系统环境变量的值）&lt;/li&gt;
&lt;li&gt;nocache：强制不使用 cache&lt;/li&gt;
&lt;li&gt;dist：开启分布式编译&lt;/li&gt;
&lt;li&gt;forceremote：强制在远程机编译&lt;/li&gt;
&lt;li&gt;summary: 编辑结束后输出统计报告&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;等等，更多选项可以运行 &lt;code&gt;FBuild.exe -help&lt;/code&gt; 来看。&lt;/p&gt;
&lt;p&gt;FBuildWorker 常用的选项有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;coordinator: 指定 Coordinator ip 地址（可以覆盖系统环境变量的值）&lt;/li&gt;
&lt;li&gt;brokerage: 指定 Brokerage 地址（可以覆盖系统环境变量的值）&lt;/li&gt;
&lt;li&gt;nocache：强制不使用 cache&lt;/li&gt;
&lt;li&gt;cpus: 指定分配多少个核参与编译&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;更多选项可以运行 &lt;code&gt;FBuildWorder.exe -help&lt;/code&gt; 来看。&lt;/p&gt;
&lt;h3 id=&#34;ue-fastbuildcs&#34;&gt;修改 UE 自带的 FASTBuild.cs&lt;/h3&gt;
&lt;p&gt;UE 自带的 FASTBuild.cs 并没有很好的处理系统环境变量，跟 BuildConfiguration.xml 指定的参数的关系，很多参数是优先读取了系统环境变量，这显然跟 BuildConfiguration.xml 的使用逻辑是相反的。&lt;/p&gt;
&lt;p&gt;为此，可以把相关的代码改成这样，这里以 UE5.3 为例：&lt;/p&gt;
&lt;div class=&#34;language-csharp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-6-1&#34; name=&#34;__codelineno-6-1&#34; href=&#34;#__codelineno-6-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;private&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ExecuteBffFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BffFilePath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ILogger&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-2&#34; name=&#34;__codelineno-6-2&#34; href=&#34;#__codelineno-6-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-3&#34; name=&#34;__codelineno-6-3&#34; href=&#34;#__codelineno-6-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CacheArgument&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-4&#34; name=&#34;__codelineno-6-4&#34; href=&#34;#__codelineno-6-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-5&#34; name=&#34;__codelineno-6-5&#34; href=&#34;#__codelineno-6-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bEnableCaching&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-6&#34; name=&#34;__codelineno-6-6&#34; href=&#34;#__codelineno-6-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-7&#34; name=&#34;__codelineno-6-7&#34; href=&#34;#__codelineno-6-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;switch&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CacheMode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-8&#34; name=&#34;__codelineno-6-8&#34; href=&#34;#__codelineno-6-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-9&#34; name=&#34;__codelineno-6-9&#34; href=&#34;#__codelineno-6-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FASTBuildCacheMode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ReadOnly&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-10&#34; name=&#34;__codelineno-6-10&#34; href=&#34;#__codelineno-6-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CacheArgument&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;-cacheread&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-11&#34; name=&#34;__codelineno-6-11&#34; href=&#34;#__codelineno-6-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-12&#34; name=&#34;__codelineno-6-12&#34; href=&#34;#__codelineno-6-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FASTBuildCacheMode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WriteOnly&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-13&#34; name=&#34;__codelineno-6-13&#34; href=&#34;#__codelineno-6-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CacheArgument&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;-cachewrite&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-14&#34; name=&#34;__codelineno-6-14&#34; href=&#34;#__codelineno-6-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-15&#34; name=&#34;__codelineno-6-15&#34; href=&#34;#__codelineno-6-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FASTBuildCacheMode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ReadWrite&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-16&#34; name=&#34;__codelineno-6-16&#34; href=&#34;#__codelineno-6-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CacheArgument&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;-cache&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-17&#34; name=&#34;__codelineno-6-17&#34; href=&#34;#__codelineno-6-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-18&#34; name=&#34;__codelineno-6-18&#34; href=&#34;#__codelineno-6-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-19&#34; name=&#34;__codelineno-6-19&#34; href=&#34;#__codelineno-6-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-20&#34; name=&#34;__codelineno-6-20&#34; href=&#34;#__codelineno-6-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-21&#34; name=&#34;__codelineno-6-21&#34; href=&#34;#__codelineno-6-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-22&#34; name=&#34;__codelineno-6-22&#34; href=&#34;#__codelineno-6-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CacheArgument&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;-nocache&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-23&#34; name=&#34;__codelineno-6-23&#34; href=&#34;#__codelineno-6-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-24&#34; name=&#34;__codelineno-6-24&#34; href=&#34;#__codelineno-6-24&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-25&#34; name=&#34;__codelineno-6-25&#34; href=&#34;#__codelineno-6-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DistArgument&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bEnableDistribution&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;-dist&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-26&#34; name=&#34;__codelineno-6-26&#34; href=&#34;#__codelineno-6-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ForceRemoteArgument&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bForceRemote&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;-forceremote&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-27&#34; name=&#34;__codelineno-6-27&#34; href=&#34;#__codelineno-6-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NoStopOnErrorArgument&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bStopOnError&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;-nostoponerror&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-28&#34; name=&#34;__codelineno-6-28&#34; href=&#34;#__codelineno-6-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IDEArgument&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IsApple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;-ide&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-29&#34; name=&#34;__codelineno-6-29&#34; href=&#34;#__codelineno-6-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MaxProcesses&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;-j&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ParallelExecutor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LocalExecutor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NumParallelProcesses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-30&#34; name=&#34;__codelineno-6-30&#34; href=&#34;#__codelineno-6-30&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-31&#34; name=&#34;__codelineno-6-31&#34; href=&#34;#__codelineno-6-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Interesting flags for FASTBuild:&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-32&#34; name=&#34;__codelineno-6-32&#34; href=&#34;#__codelineno-6-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -nostoponerror, -verbose, -monitor (if FASTBuild Monitor Visual Studio Extension is installed!)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-33&#34; name=&#34;__codelineno-6-33&#34; href=&#34;#__codelineno-6-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Yassine: The -clean is to bypass the FASTBuild internal&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-34&#34; name=&#34;__codelineno-6-34&#34; href=&#34;#__codelineno-6-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// dependencies checks (cached in the fdb) as it could create some conflicts with UBT.&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-35&#34; name=&#34;__codelineno-6-35&#34; href=&#34;#__codelineno-6-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Basically we want FB to stupidly compile what UBT tells it to.&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-36&#34; name=&#34;__codelineno-6-36&#34; href=&#34;#__codelineno-6-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FBCommandLine&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$&amp;quot;-monitor -summary {DistArgument} {CacheArgument} {IDEArgument} {MaxProcesses} -clean -config \&amp;quot;{BffFilePath}\&amp;quot; {NoStopOnErrorArgument} {ForceRemoteArgument}&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-37&#34; name=&#34;__codelineno-6-37&#34; href=&#34;#__codelineno-6-37&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-38&#34; name=&#34;__codelineno-6-38&#34; href=&#34;#__codelineno-6-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogInformation&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;FBuild Command Line Arguments: &amp;#39;{FBCommandLine}&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FBCommandLine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-39&#34; name=&#34;__codelineno-6-39&#34; href=&#34;#__codelineno-6-39&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-40&#34; name=&#34;__codelineno-6-40&#34; href=&#34;#__codelineno-6-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FBExecutable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetExecutablePath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-41&#34; name=&#34;__codelineno-6-41&#34; href=&#34;#__codelineno-6-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogInformation&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;FBuild Executable: &amp;#39;{FBExecutable}&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FBExecutable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-42&#34; name=&#34;__codelineno-6-42&#34; href=&#34;#__codelineno-6-42&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-43&#34; name=&#34;__codelineno-6-43&#34; href=&#34;#__codelineno-6-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WorkingDirectory&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetFullPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Combine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Unreal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EngineDirectory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MakeRelativeTo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DirectoryReference&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetCurrentDirectory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Source&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-44&#34; name=&#34;__codelineno-6-44&#34; href=&#34;#__codelineno-6-44&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-45&#34; name=&#34;__codelineno-6-45&#34; href=&#34;#__codelineno-6-45&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ProcessStartInfo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FBStartInfo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ProcessStartInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FBExecutable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FBCommandLine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-46&#34; name=&#34;__codelineno-6-46&#34; href=&#34;#__codelineno-6-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FBStartInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UseShellExecute&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-47&#34; name=&#34;__codelineno-6-47&#34; href=&#34;#__codelineno-6-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FBStartInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WorkingDirectory&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WorkingDirectory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-48&#34; name=&#34;__codelineno-6-48&#34; href=&#34;#__codelineno-6-48&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FBStartInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RedirectStandardError&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-49&#34; name=&#34;__codelineno-6-49&#34; href=&#34;#__codelineno-6-49&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FBStartInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RedirectStandardOutput&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-50&#34; name=&#34;__codelineno-6-50&#34; href=&#34;#__codelineno-6-50&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-51&#34; name=&#34;__codelineno-6-51&#34; href=&#34;#__codelineno-6-51&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string?&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Coordinator&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetCoordinator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-52&#34; name=&#34;__codelineno-6-52&#34; href=&#34;#__codelineno-6-52&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IsNullOrEmpty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Coordinator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-53&#34; name=&#34;__codelineno-6-53&#34; href=&#34;#__codelineno-6-53&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-54&#34; name=&#34;__codelineno-6-54&#34; href=&#34;#__codelineno-6-54&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogInformation&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;FBuild Coordinator: &amp;#39;{Coordinator}&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Coordinator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-55&#34; name=&#34;__codelineno-6-55&#34; href=&#34;#__codelineno-6-55&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FBStartInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EnvironmentVariables&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;FASTBUILD_COORDINATOR&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Coordinator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-56&#34; name=&#34;__codelineno-6-56&#34; href=&#34;#__codelineno-6-56&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-57&#34; name=&#34;__codelineno-6-57&#34; href=&#34;#__codelineno-6-57&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-58&#34; name=&#34;__codelineno-6-58&#34; href=&#34;#__codelineno-6-58&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string?&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BrokeragePath&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetBrokeragePath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-59&#34; name=&#34;__codelineno-6-59&#34; href=&#34;#__codelineno-6-59&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IsNullOrEmpty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BrokeragePath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-60&#34; name=&#34;__codelineno-6-60&#34; href=&#34;#__codelineno-6-60&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-61&#34; name=&#34;__codelineno-6-61&#34; href=&#34;#__codelineno-6-61&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogInformation&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;FBuild BrokeragePath: &amp;#39;{BrokeragePath}&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BrokeragePath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-62&#34; name=&#34;__codelineno-6-62&#34; href=&#34;#__codelineno-6-62&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FBStartInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EnvironmentVariables&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;FASTBUILD_BROKERAGE_PATH&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BrokeragePath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-63&#34; name=&#34;__codelineno-6-63&#34; href=&#34;#__codelineno-6-63&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-64&#34; name=&#34;__codelineno-6-64&#34; href=&#34;#__codelineno-6-64&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-65&#34; name=&#34;__codelineno-6-65&#34; href=&#34;#__codelineno-6-65&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string?&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CachePath&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetCachePath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-66&#34; name=&#34;__codelineno-6-66&#34; href=&#34;#__codelineno-6-66&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IsNullOrEmpty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CachePath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-67&#34; name=&#34;__codelineno-6-67&#34; href=&#34;#__codelineno-6-67&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-68&#34; name=&#34;__codelineno-6-68&#34; href=&#34;#__codelineno-6-68&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogInformation&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;FBuild CachePath: &amp;#39;{CachePath}&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CachePath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-69&#34; name=&#34;__codelineno-6-69&#34; href=&#34;#__codelineno-6-69&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FBStartInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EnvironmentVariables&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;FASTBUILD_CACHE_PATH&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CachePath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-70&#34; name=&#34;__codelineno-6-70&#34; href=&#34;#__codelineno-6-70&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-71&#34; name=&#34;__codelineno-6-71&#34; href=&#34;#__codelineno-6-71&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;buildconfigurationxml&#34;&gt;BuildConfiguration.xml 进阶配置&lt;/h3&gt;
&lt;div class=&#34;language-xml highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-7-1&#34; name=&#34;__codelineno-7-1&#34; href=&#34;#__codelineno-7-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-2&#34; name=&#34;__codelineno-7-2&#34; href=&#34;#__codelineno-7-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;Configuration&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;xmlns=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;https://www.unrealengine.com/BuildConfiguration&amp;quot;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-3&#34; name=&#34;__codelineno-7-3&#34; href=&#34;#__codelineno-7-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;ProjectFileGenerator&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-4&#34; name=&#34;__codelineno-7-4&#34; href=&#34;#__codelineno-7-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;&amp;lt;!-- 指定vs版本 --&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-5&#34; name=&#34;__codelineno-7-5&#34; href=&#34;#__codelineno-7-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;Format&amp;gt;&lt;/span&gt;VisualStudio2022&lt;span class=&#34;nt&#34;&gt;&amp;lt;/Format&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-6&#34; name=&#34;__codelineno-7-6&#34; href=&#34;#__codelineno-7-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;/ProjectFileGenerator&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-7&#34; name=&#34;__codelineno-7-7&#34; href=&#34;#__codelineno-7-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;BuildConfiguration&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-8&#34; name=&#34;__codelineno-7-8&#34; href=&#34;#__codelineno-7-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;&amp;lt;!-- 开启 FASTBuild --&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-9&#34; name=&#34;__codelineno-7-9&#34; href=&#34;#__codelineno-7-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;bAllowFASTBuild&amp;gt;&lt;/span&gt;true&lt;span class=&#34;nt&#34;&gt;&amp;lt;/bAllowFASTBuild&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-10&#34; name=&#34;__codelineno-7-10&#34; href=&#34;#__codelineno-7-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;&amp;lt;!-- 指定本机参与编译的 cpu 核数 --&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-11&#34; name=&#34;__codelineno-7-11&#34; href=&#34;#__codelineno-7-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;MaxParallelActions&amp;gt;&lt;/span&gt;12&lt;span class=&#34;nt&#34;&gt;&amp;lt;/MaxParallelActions&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-12&#34; name=&#34;__codelineno-7-12&#34; href=&#34;#__codelineno-7-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;&amp;lt;!-- 关闭 Incredibuild --&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-13&#34; name=&#34;__codelineno-7-13&#34; href=&#34;#__codelineno-7-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;bAllowXGE&amp;gt;&lt;/span&gt;false&lt;span class=&#34;nt&#34;&gt;&amp;lt;/bAllowXGE&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-14&#34; name=&#34;__codelineno-7-14&#34; href=&#34;#__codelineno-7-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;/BuildConfiguration&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-15&#34; name=&#34;__codelineno-7-15&#34; href=&#34;#__codelineno-7-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;FASTBuild&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-16&#34; name=&#34;__codelineno-7-16&#34; href=&#34;#__codelineno-7-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;&amp;lt;!-- 指定 FBuild 路径 --&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-17&#34; name=&#34;__codelineno-7-17&#34; href=&#34;#__codelineno-7-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;FBuildExecutablePath&amp;gt;&lt;/span&gt;d:\libs\FASTBuild\bin\FBuild.exe&lt;span class=&#34;nt&#34;&gt;&amp;lt;/FBuildExecutablePath&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-18&#34; name=&#34;__codelineno-7-18&#34; href=&#34;#__codelineno-7-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;&amp;lt;!-- 开启分布式编译 --&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-19&#34; name=&#34;__codelineno-7-19&#34; href=&#34;#__codelineno-7-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;bEnableDistribution&amp;gt;&lt;/span&gt;true&lt;span class=&#34;nt&#34;&gt;&amp;lt;/bEnableDistribution&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-20&#34; name=&#34;__codelineno-7-20&#34; href=&#34;#__codelineno-7-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;&amp;lt;!-- 指定 brokerage 路径 --&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-21&#34; name=&#34;__codelineno-7-21&#34; href=&#34;#__codelineno-7-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;FBuildBrokeragePath&amp;gt;&lt;/span&gt;\\127.0.0.1\Brokerage\&lt;span class=&#34;nt&#34;&gt;&amp;lt;/FBuildBrokeragePath&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-22&#34; name=&#34;__codelineno-7-22&#34; href=&#34;#__codelineno-7-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;&amp;lt;!-- 指定 cache 路径 --&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-23&#34; name=&#34;__codelineno-7-23&#34; href=&#34;#__codelineno-7-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;FBuildCachePath&amp;gt;&lt;/span&gt;\\127.0.0.1\Cache\&lt;span class=&#34;nt&#34;&gt;&amp;lt;/FBuildCachePath&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-24&#34; name=&#34;__codelineno-7-24&#34; href=&#34;#__codelineno-7-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;&amp;lt;!-- 开启 cache --&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-25&#34; name=&#34;__codelineno-7-25&#34; href=&#34;#__codelineno-7-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;bEnableCaching&amp;gt;&lt;/span&gt;true&lt;span class=&#34;nt&#34;&gt;&amp;lt;/bEnableCaching&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-26&#34; name=&#34;__codelineno-7-26&#34; href=&#34;#__codelineno-7-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;&amp;lt;!-- cache 的读写权限 Read/Write/ReadWrite --&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-27&#34; name=&#34;__codelineno-7-27&#34; href=&#34;#__codelineno-7-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;CacheMode&amp;gt;&lt;/span&gt;ReadWrite&lt;span class=&#34;nt&#34;&gt;&amp;lt;/CacheMode&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-28&#34; name=&#34;__codelineno-7-28&#34; href=&#34;#__codelineno-7-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;&amp;lt;!-- 指定 coordinator ip --&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-29&#34; name=&#34;__codelineno-7-29&#34; href=&#34;#__codelineno-7-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;FBuildCoordinator&amp;gt;&lt;/span&gt;127.0.0.1&lt;span class=&#34;nt&#34;&gt;&amp;lt;/FBuildCoordinator&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-30&#34; name=&#34;__codelineno-7-30&#34; href=&#34;#__codelineno-7-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;&amp;lt;!-- 强制远程编译 --&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-31&#34; name=&#34;__codelineno-7-31&#34; href=&#34;#__codelineno-7-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;&amp;lt;!-- &amp;lt;bForceRemote&amp;gt;true&amp;lt;/bForceRemote&amp;gt; --&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-32&#34; name=&#34;__codelineno-7-32&#34; href=&#34;#__codelineno-7-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;/FASTBuild&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-33&#34; name=&#34;__codelineno-7-33&#34; href=&#34;#__codelineno-7-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;/Configuration&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E4%BD%BF%E7%94%A8FASTBuild%E7%BC%96%E8%AF%91UE4%E5%92%8CUE5/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Fri, 01 Dec 2023 00:00:00 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E4%BD%BF%E7%94%A8FASTBuild%E7%BC%96%E8%AF%91UE4%E5%92%8CUE5/</guid>
      
    </item>
    
    <item>
      <title>UE 通过插件源码添加插件</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;UE 通过插件源码添加插件&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;ue&#34;&gt;UE 通过插件源码添加插件&lt;/h1&gt;
&lt;h1 id=&#34;_1&#34;&gt;添加插件&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;简单记录一下如何在拥有插件源码的情况下添加插件.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;以插件 &lt;a href=&#34;https://github.com/disenone/UE.EditorPlus&#34;&gt;UE.EditorPlus&lt;/a&gt; 为例&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;把源码放到 Plugins 目录下&lt;/li&gt;
&lt;li&gt;（这一步可以不执行）修改项目 .uproject 文件，Plugins 字段下增加：
    &lt;div class=&#34;language-json highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;quot;Plugins&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34; href=&#34;#__codelineno-0-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;EditorPlus&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-4&#34; name=&#34;__codelineno-0-4&#34; href=&#34;#__codelineno-0-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;quot;Enabled&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-5&#34; name=&#34;__codelineno-0-5&#34; href=&#34;#__codelineno-0-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;quot;TargetAllowList&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-6&#34; name=&#34;__codelineno-0-6&#34; href=&#34;#__codelineno-0-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;Editor&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-7&#34; name=&#34;__codelineno-0-7&#34; href=&#34;#__codelineno-0-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-8&#34; name=&#34;__codelineno-0-8&#34; href=&#34;#__codelineno-0-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;右键 uproject 文件，执行 &#34;Generate Visual Studio Project Files&#34;，更新 sln 项目文件&lt;/li&gt;
&lt;li&gt;打开 sln 文件，编译项目&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;_2&#34;&gt;设置多语言&lt;/h1&gt;
&lt;p&gt;修改项目的配置文件 &lt;code&gt;DefaultEditor.ini&lt;/code&gt;，加上新路径：&lt;/p&gt;
&lt;div class=&#34;language-ini highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;[Internationalization]&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-2&#34; name=&#34;__codelineno-1-2&#34; href=&#34;#__codelineno-1-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;na&#34;&gt;+LocalizationPaths&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;%GAMEDIR%Plugins/UE.EditorPlus/Content/Localization/EditorPlusTools&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/ue-%E9%80%9A%E8%BF%87%E6%8F%92%E4%BB%B6%E6%BA%90%E7%A0%81%E6%B7%BB%E5%8A%A0%E6%8F%92%E4%BB%B6/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Fri, 01 Dec 2023 00:00:00 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ue-%E9%80%9A%E8%BF%87%E6%8F%92%E4%BB%B6%E6%BA%90%E7%A0%81%E6%B7%BB%E5%8A%A0%E6%8F%92%E4%BB%B6/</guid>
      
    </item>
    
    <item>
      <title>Home</title>
      
      
      
      
      <description>&lt;!-- no translate --&gt;

&lt;h1 id=&#34;disenones-wiki&#34;&gt;Disenone&#39;s Wiki&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/disenone/wiki_blog/actions&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://github.com/disenone/wiki_blog/actions/workflows/Build.yml/badge.svg?label=Build&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://github.com/disenone/wiki_blog/commits/main&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/github/last-commit/disenone/wiki_blog?color=FCD734&amp;amp;label=Last%20commit&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;contact-and-subscribe&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/Contact%20%26%20Subscribe-me-34ABE0?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;无止境&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Hi there~ 欢迎来到我的知识库。&lt;/p&gt;
&lt;p&gt;为了避免遗忘、便于分享，我在这里收录知识。
请随意浏览～&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;md-button&#34; href=&#34;cpp-C%E5%92%8CCpp%E7%9A%84%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0%E5%A4%84%E7%90%86%E6%80%BB%E7%BB%93/&#34;&gt;编程技术&lt;/a&gt;
&lt;a class=&#34;md-button&#34; href=&#34;game-%E6%B8%B8%E6%88%8FAOI%E7%AE%97%E6%B3%95%E8%A7%A3%E6%9E%90%E5%92%8C%E6%80%A7%E8%83%BD%E5%AE%9E%E6%B5%8B/&#34;&gt;游戏开发&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;md-button&#34; href=&#34;ue-%E6%8F%92%E4%BB%B6-AIChatPlus/&#34;&gt;UE.AIChatPlus&lt;/a&gt;&lt;/p&gt;</description>
      <link>https://wiki.disenone.site/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 30 Nov 2023 20:09:36 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/</guid>
      
    </item>
    
    <item>
      <title>C/C++ 宏编程解析</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;C/C++ 宏编程解析&#34; /&gt;&lt;/p&gt;
&lt;p&gt;本文的目的是要讲清楚 C/C++ 的宏编程的规则和实现方法，让你不再惧怕看到代码里面的宏。我会首先说说 C++ 标准 14 里面提到的关于宏展开的规则，然后通过修改 Clang 的源码来观察宏展开，最后基于这些知识来聊聊宏编程的实现。&lt;/p&gt;
&lt;p&gt;本文的代码全部都在这里：&lt;a href=&#34;../assets/img/2021-3-31-cpp-preprocess/macros.cpp&#34;&gt;下载&lt;/a&gt;，&lt;a href=&#34;https://godbolt.org/z/coWvc5Pse&#34;&gt;在线演示&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&#34;_1&#34;&gt;引子&lt;/h2&gt;
&lt;p&gt;我们可以通过执行命令 &lt;code&gt;gcc -P -E a.cpp -o a.cpp.i&lt;/code&gt; 来让编译器对文件 &lt;code&gt;a.cpp&lt;/code&gt; 只执行预处理并保存结果到 &lt;code&gt;a.cpp.i&lt;/code&gt; 中。&lt;/p&gt;
&lt;p&gt;首先我们先来看一些例子:&lt;/p&gt;
&lt;h4 id=&#34;reentrancy&#34;&gt;递归重入（Reentrancy）&lt;/h4&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define ITER(arg0, arg1) ITER(arg1, arg0)&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34; href=&#34;#__codelineno-0-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;ITER&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; ITER(2, 1)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;宏 &lt;code&gt;ITER&lt;/code&gt; 交换了 &lt;code&gt;arg0&lt;/code&gt;, &lt;code&gt;arg1&lt;/code&gt; 的位置。宏展开之后，得到的是 &lt;code&gt;ITER(2, 1)&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;可以看到，&lt;code&gt;arg0&lt;/code&gt; &lt;code&gt;arg1&lt;/code&gt; 的位置成功交换，在这里宏成功展开了一次，但也只展开了一次，不再递归重入。换言之，宏的展开过程中，是不可自身递归重入的，如果在递归的过程中发现相同的宏在之前的递归中已经展开过，则不再展开，这是宏展开的其中一条重要的规则。禁止递归重入的原因也很简单，就是为了避免无限递归。&lt;/p&gt;
&lt;h4 id=&#34;_2&#34;&gt;字符串拼接&lt;/h4&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define CONCAT(arg0, arg1) arg0 ## arg1&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-2&#34; name=&#34;__codelineno-1-2&#34; href=&#34;#__codelineno-1-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-3&#34; name=&#34;__codelineno-1-3&#34; href=&#34;#__codelineno-1-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;CONCAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Hello&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;World&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; HelloWorld&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-4&#34; name=&#34;__codelineno-1-4&#34; href=&#34;#__codelineno-1-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;CONCAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Hello&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CONCAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;World&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt;　HelloCONCAT(World, !)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;宏 &lt;code&gt;CONCAT&lt;/code&gt; 目的是拼接 &lt;code&gt;arg0&lt;/code&gt; &lt;code&gt;arg1&lt;/code&gt;。宏展开之后，&lt;code&gt;CONCAT(Hello, World)&lt;/code&gt; 能够得到正确的结果 &lt;code&gt;HelloWorld&lt;/code&gt;。但是 &lt;code&gt;CONCAT(Hello, CONCAT(World, !))&lt;/code&gt; 却只展开了外层的宏，内层的 &lt;code&gt;CONCAT(World, !)&lt;/code&gt; 并没有展开而是直接跟 &lt;code&gt;Hello&lt;/code&gt; 拼接在一起了，这跟我们预想的不一样，我们真正想要的结果是 &lt;code&gt;HelloWorld!&lt;/code&gt;。这就是宏展开的另外一条重要的规则：跟在 &lt;code&gt;##&lt;/code&gt; 操作符后面的宏参数，不会执行展开，而是会直接跟前面的内容先拼接在一起。&lt;/p&gt;
&lt;p&gt;通过上面两个例子可以看出来，宏展开的规则有一些是反直觉的，如果不清楚具体的规则，有可能写出来的宏跟我们想要的效果不一致。&lt;/p&gt;
&lt;h2 id=&#34;_3&#34;&gt;宏展开规则&lt;/h2&gt;
&lt;p&gt;通过引子的两个例子，我们了解到了宏展开是有一套标准的规则的，这套规则定义在 C/C++ 标准里面，内容不多，建议先仔细读几遍，我这里顺带给下标准 n4296 版本的链接，宏展开在 16.3 节：&lt;a href=&#34;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf&#34;&gt;传送门&lt;/a&gt;。下面我挑出 n4296 版本中几条重要的规则，这些规则会决定如何正确编写宏（还是建议抽时间把标准里面的宏展开细读下）。&lt;/p&gt;
&lt;h4 id=&#34;_4&#34;&gt;参数分隔&lt;/h4&gt;
&lt;p&gt;宏的参数要求是用逗号分隔，而且参数的个数需要跟宏定义的个数一致，传递给宏的参数中，额外用括号包住的内容视为一个参数，参数允许为空：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-2-1&#34; name=&#34;__codelineno-2-1&#34; href=&#34;#__codelineno-2-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define ADD_COMMA(arg1, arg2) arg1, arg2&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-2&#34; name=&#34;__codelineno-2-2&#34; href=&#34;#__codelineno-2-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-3&#34; name=&#34;__codelineno-2-3&#34; href=&#34;#__codelineno-2-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;ADD_COMMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; a, b&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-4&#34; name=&#34;__codelineno-2-4&#34; href=&#34;#__codelineno-2-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;ADD_COMMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 报错 &amp;quot;macro &amp;quot;MACRO&amp;quot; requires 2 arguments, but only 1 given&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-5&#34; name=&#34;__codelineno-2-5&#34; href=&#34;#__codelineno-2-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;ADD_COMMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; (a, b), c&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-6&#34; name=&#34;__codelineno-2-6&#34; href=&#34;#__codelineno-2-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;ADD_COMMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; , b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;ADD_COMMA((a, b), c)&lt;/code&gt; 中 &lt;code&gt;(a, b)&lt;/code&gt; 视为第一个参数。&lt;code&gt;ADD_COMMA(, b)&lt;/code&gt; 中，第一个参数为空，于是展开为 &lt;code&gt;, b&lt;/code&gt;。&lt;/p&gt;
&lt;h4 id=&#34;_5&#34;&gt;宏参数展开&lt;/h4&gt;
&lt;p&gt;在对宏进行展开的时候，如果宏的参数也是可以展开的宏，会先把参数完全展开，再展开宏，例如&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-3-1&#34; name=&#34;__codelineno-3-1&#34; href=&#34;#__codelineno-3-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;ADD_COMMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ADD_COMMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ADD_COMMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 1, 2, 3, 4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;一般情况下的宏展开，都可以认为是先对参数求值，再对宏求值，除非遇到了 &lt;code&gt;#&lt;/code&gt; 和 &lt;code&gt;##&lt;/code&gt; 操作符。&lt;/p&gt;
&lt;h4 id=&#34;_6&#34;&gt;&lt;code&gt;#&lt;/code&gt; 操作符&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;#&lt;/code&gt; 操作符后面跟的宏参数，不会进行展开，会直接字符串化，例如：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-4-1&#34; name=&#34;__codelineno-4-1&#34; href=&#34;#__codelineno-4-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define STRINGIZE(arg0) # arg0&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-2&#34; name=&#34;__codelineno-4-2&#34; href=&#34;#__codelineno-4-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-3&#34; name=&#34;__codelineno-4-3&#34; href=&#34;#__codelineno-4-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;STRINGIZE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; &amp;quot;a&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-4&#34; name=&#34;__codelineno-4-4&#34; href=&#34;#__codelineno-4-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;STRINGIZE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STRINGIZE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; &amp;quot;STRINGIZE(a)&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;根据这条规则 &lt;code&gt;STRINGIZE(STRINGIZE(a))&lt;/code&gt; 只能展开为 &lt;code&gt;&#34;STRINGIZE(a)&#34;&lt;/code&gt;。&lt;/p&gt;
&lt;h4 id=&#34;_7&#34;&gt;&lt;code&gt;##&lt;/code&gt; 操作符&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;##&lt;/code&gt; 操作符前后的宏参数，都不会进行展开，会先直接拼接起来，例如：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-5-1&#34; name=&#34;__codelineno-5-1&#34; href=&#34;#__codelineno-5-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define CONCAT(arg0, arg1) arg0 ## arg1&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-2&#34; name=&#34;__codelineno-5-2&#34; href=&#34;#__codelineno-5-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-3&#34; name=&#34;__codelineno-5-3&#34; href=&#34;#__codelineno-5-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;CONCAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Hello&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;World&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; HelloWorld&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-4&#34; name=&#34;__codelineno-5-4&#34; href=&#34;#__codelineno-5-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;CONCAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Hello&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CONCAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;World&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; HelloCONCAT(World, !)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-5&#34; name=&#34;__codelineno-5-5&#34; href=&#34;#__codelineno-5-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;CONCAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CONCAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Hello&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;World&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;C&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ONCAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; CONCAT(Hello, World) CONCAT(!)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;CONCAT(CONCAT(Hello, World) C, ONCAT(!))&lt;/code&gt; 只能是先拼接在一起，得到 &lt;code&gt;CONCAT(Hello, World) CONCAT(!)&lt;/code&gt;。&lt;/p&gt;
&lt;h4 id=&#34;_8&#34;&gt;重复扫描&lt;/h4&gt;
&lt;p&gt;预处理器执行完一次宏展开之后，会重新扫描得到的内容，继续展开，直到没有可以展开的内容为止。&lt;/p&gt;
&lt;p&gt;一次宏展开，可以理解为先把参数完全展开（除非遇到 &lt;code&gt;#&lt;/code&gt; 和 &lt;code&gt;##&lt;/code&gt;），再根据宏的定义，把宏和完全展开后的参数按照定义进行替换，再处理定义中的所有 &lt;code&gt;#&lt;/code&gt; 和 &lt;code&gt;##&lt;/code&gt; 操作符。&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-6-1&#34; name=&#34;__codelineno-6-1&#34; href=&#34;#__codelineno-6-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define CONCAT(arg0, arg1) arg0 ## arg1&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-2&#34; name=&#34;__codelineno-6-2&#34; href=&#34;#__codelineno-6-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define STRINGIZE(arg0) # arg0&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-3&#34; name=&#34;__codelineno-6-3&#34; href=&#34;#__codelineno-6-3&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-4&#34; name=&#34;__codelineno-6-4&#34; href=&#34;#__codelineno-6-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;CONCAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STRING&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IZE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Hello&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; STRINGIZE(Hello) -&amp;gt; &amp;quot;Hello&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;CONCAT(STRING, IZE(Hello))&lt;/code&gt; 第一次扫描展开得到 &lt;code&gt;STRINGIZE(Hello)&lt;/code&gt;，然后执行第二次扫描，发现 &lt;code&gt;STRINGIZE&lt;/code&gt; 可以继续展开，最后得到 &lt;code&gt;&#34;Hello&#34;&lt;/code&gt;。&lt;/p&gt;
&lt;h4 id=&#34;_9&#34;&gt;禁止递归重入&lt;/h4&gt;
&lt;p&gt;在重复扫描的过程中，禁止递归展开相同的宏。可以把宏展开理解为树形的结构，根节点就是一开始要展开的宏，每个宏展开之后的内容作为该宏的子节点连接到树上，那么禁止递归就是在展开子节点的宏时，如果该宏跟任意祖先节点的宏相同，则禁止展开。来看一些例子：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-7-1&#34; name=&#34;__codelineno-7-1&#34; href=&#34;#__codelineno-7-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define CONCAT(arg0, arg1) arg0 ## arg1&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-2&#34; name=&#34;__codelineno-7-2&#34; href=&#34;#__codelineno-7-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define CONCAT_SPACE(arg0, arg1) arg0 arg1&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-3&#34; name=&#34;__codelineno-7-3&#34; href=&#34;#__codelineno-7-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define IDENTITY(arg0) IDENTITY_IMPL(arg0)&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-4&#34; name=&#34;__codelineno-7-4&#34; href=&#34;#__codelineno-7-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define IDENTITY_IMPL(arg0) arg0&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-5&#34; name=&#34;__codelineno-7-5&#34; href=&#34;#__codelineno-7-5&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-6&#34; name=&#34;__codelineno-7-6&#34; href=&#34;#__codelineno-7-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;CONCAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CON&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; CONCAT(a, b)&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-7&#34; name=&#34;__codelineno-7-7&#34; href=&#34;#__codelineno-7-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;IDENTITY_IMPL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CONCAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CON&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; CONCAT(a, b)&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-8&#34; name=&#34;__codelineno-7-8&#34; href=&#34;#__codelineno-7-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;IDENTITY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CONCAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CON&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; IDENTITY_IMPL(CONCAT(a, b)) -&amp;gt; CONCAT(a, b)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;CONCAT(CON, CAT(a, b))&lt;/code&gt;：由于 &lt;code&gt;CONCAT&lt;/code&gt; 是用 &lt;code&gt;##&lt;/code&gt; 拼接两个参数，根据 &lt;code&gt;##&lt;/code&gt; 的规则，不会展开参数，直接拼接。所以第一次展开得到了 &lt;code&gt;CONCAT(a, b)&lt;/code&gt;，由于 &lt;code&gt;CONCAT&lt;/code&gt; 已经展开过了不会再递归展开，所以停止。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;IDENTITY_IMPL(CONCAT(CON, CAT(a, b)))&lt;/code&gt;：&lt;code&gt;IDENTITY_IMPL&lt;/code&gt; 可以理解为对参数 &lt;code&gt;arg0&lt;/code&gt; 求值，这里的参数 &lt;code&gt;arg0&lt;/code&gt; 求值得到了 &lt;code&gt;CONCAT(a, b)&lt;/code&gt;，并由于递归被标记为了禁止重入，之后 &lt;code&gt;IDENTITY_IMPL&lt;/code&gt; 展开完成，进行第二次扫描的时候，发现是禁止重入的 &lt;code&gt;CONCAT(a, b)&lt;/code&gt;，于是停止展开。在这里 &lt;code&gt;CONCAT(a, b)&lt;/code&gt; 是由参数 &lt;code&gt;arg0&lt;/code&gt; 展开而得到的，但在后续展开的时候，也会保持禁止重入的标记，可以理解为父节点是参数 &lt;code&gt;arg0&lt;/code&gt;，一直保持着禁止重入的标记。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;IDENTITY(CONCAT(CON, CAT(a, b)))&lt;/code&gt;：这个例子主要是为了加强对父子节点的理解，参数自己展开的时候，是自身作为父节点，展开的内容作为子节点去判断递归，展开后的参数传到宏定义之后，禁止重入的标记会继续保留（如果传到宏定义之后没有改变参数展开后的宏）。可以把参数的展开过程看成是另外一棵树，参数的展开结果就是树的最底层子节点，这个子节点传给宏来执行展开的同时，依然是保留着禁止重入的特性。&lt;/p&gt;
&lt;p&gt;例如这里，在第一次完全展开之后得到 &lt;code&gt;IDENTITY_IMPL(CONCAT(a, b))&lt;/code&gt;，&lt;code&gt;CONCAT(a, b)&lt;/code&gt; 被标记为禁止重入， 即使 &lt;code&gt;IDENTITY_IMPL&lt;/code&gt; 是对参数求值的，但参数已经禁止展开，所以参数就原封不动的传到定义里，最后我们还是得到 &lt;code&gt;CONCAT(a, b)&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;以上我只是列出了一些我认为比较重要的，或者觉得不太好理解的规则，详细的宏展开规则，还是建议花点时间直接去看标准文档。&lt;/p&gt;
&lt;h2 id=&#34;clang&#34;&gt;通过 Clang 观察展开过程&lt;/h2&gt;
&lt;p&gt;我们可以给 Clang 源码加上一些打印信息来观察宏展开的过程，我无意深入解释 Clang 的源码，在这里给一份修改过的文件 diff，有兴趣的可以自己编译 Clang 来研究。这里我是用的 llvm 版本 11.1.0 （&lt;a href=&#34;https://github.com/llvm/llvm-project/archive/refs/tags/llvmorg-11.1.0.tar.gz&#34;&gt;传送门&lt;/a&gt;），修改过的文件（&lt;a href=&#34;../assets/img/2021-3-31-cpp-preprocess/clang-modify.zip&#34;&gt;传送门&lt;/a&gt;）。下面简单通过例子来验证我们之前介绍的宏展开规则：&lt;/p&gt;
&lt;h4 id=&#34;1&#34;&gt;例子1&lt;/h4&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-8-1&#34; name=&#34;__codelineno-8-1&#34; href=&#34;#__codelineno-8-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define CONCAT(arg0, arg1) arg0 ## arg1&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-2&#34; name=&#34;__codelineno-8-2&#34; href=&#34;#__codelineno-8-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-3&#34; name=&#34;__codelineno-8-3&#34; href=&#34;#__codelineno-8-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;CONCAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;C&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ONCAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// CONCAT(a, b)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;使用修改过的 Clang 来预处理以上代码： &lt;code&gt;clang -P -E a.cpp -o a.cpp.i&lt;/code&gt;，得到下面的打印信息：&lt;/p&gt;
&lt;div class=&#34;language-text highlight&#34;&gt;&lt;table class=&#34;highlighttable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;linenos&#34;&gt;&lt;div class=&#34;linenodiv&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-1&#34;&gt; 1&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-2&#34;&gt; 2&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-3&#34;&gt; 3&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-4&#34;&gt; 4&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-5&#34;&gt; 5&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-6&#34;&gt; 6&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-7&#34;&gt; 7&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-8&#34;&gt; 8&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-9&#34;&gt; 9&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-10&#34;&gt;10&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-11&#34;&gt;11&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-12&#34;&gt;12&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-13&#34;&gt;13&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-14&#34;&gt;14&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-15&#34;&gt;15&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-16&#34;&gt;16&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-17&#34;&gt;17&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-18&#34;&gt;18&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-19&#34;&gt;19&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-20&#34;&gt;20&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-21&#34;&gt;21&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-22&#34;&gt;22&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-23&#34;&gt;23&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-24&#34;&gt;24&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-25&#34;&gt;25&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-9-26&#34;&gt;26&lt;/a&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-9-1&#34; name=&#34;__codelineno-9-1&#34;&gt;&lt;/a&gt;HandleIdentifier:
&lt;a id=&#34;__codelineno-9-2&#34; name=&#34;__codelineno-9-2&#34;&gt;&lt;/a&gt;MacroInfo 0x559e57496900
&lt;a id=&#34;__codelineno-9-3&#34; name=&#34;__codelineno-9-3&#34;&gt;&lt;/a&gt;    #define &amp;lt;macro&amp;gt;[2813:CONCAT](arg0, arg1) arg0 ## arg1
&lt;a id=&#34;__codelineno-9-4&#34; name=&#34;__codelineno-9-4&#34;&gt;&lt;/a&gt;Macro is ok to expand
&lt;a id=&#34;__codelineno-9-5&#34; name=&#34;__codelineno-9-5&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-6&#34; name=&#34;__codelineno-9-6&#34;&gt;&lt;/a&gt;EnterMacro: 0
&lt;a id=&#34;__codelineno-9-7&#34; name=&#34;__codelineno-9-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-8&#34; name=&#34;__codelineno-9-8&#34;&gt;&lt;/a&gt;Enter ExpandFunctionArguments:
&lt;a id=&#34;__codelineno-9-9&#34; name=&#34;__codelineno-9-9&#34;&gt;&lt;/a&gt;MacroInfo 0x559e57496900 used
&lt;a id=&#34;__codelineno-9-10&#34; name=&#34;__codelineno-9-10&#34;&gt;&lt;/a&gt;    #define &amp;lt;macro&amp;gt;[2813:CONCAT](arg0, arg1) arg0 ## arg1
&lt;a id=&#34;__codelineno-9-11&#34; name=&#34;__codelineno-9-11&#34;&gt;&lt;/a&gt;Token: 0
&lt;a id=&#34;__codelineno-9-12&#34; name=&#34;__codelineno-9-12&#34;&gt;&lt;/a&gt;identifier: arg0
&lt;a id=&#34;__codelineno-9-13&#34; name=&#34;__codelineno-9-13&#34;&gt;&lt;/a&gt;Args: [identifier: C]
&lt;a id=&#34;__codelineno-9-14&#34; name=&#34;__codelineno-9-14&#34;&gt;&lt;/a&gt;Token: 1
&lt;a id=&#34;__codelineno-9-15&#34; name=&#34;__codelineno-9-15&#34;&gt;&lt;/a&gt;hashhash:
&lt;a id=&#34;__codelineno-9-16&#34; name=&#34;__codelineno-9-16&#34;&gt;&lt;/a&gt;Token: 2
&lt;a id=&#34;__codelineno-9-17&#34; name=&#34;__codelineno-9-17&#34;&gt;&lt;/a&gt;identifier: arg1
&lt;a id=&#34;__codelineno-9-18&#34; name=&#34;__codelineno-9-18&#34;&gt;&lt;/a&gt;Args: [identifier: ONCAT][l_paren: ][identifier: a][comma: ][identifier: b][r_paren: ]
&lt;a id=&#34;__codelineno-9-19&#34; name=&#34;__codelineno-9-19&#34;&gt;&lt;/a&gt;Leave ExpandFunctionArguments: [identifier: C][hashhash: ][identifier: ONCAT][l_paren: ][identifier: a][comma: ][identifier: b][r_paren: ]
&lt;a id=&#34;__codelineno-9-20&#34; name=&#34;__codelineno-9-20&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-21&#34; name=&#34;__codelineno-9-21&#34;&gt;&lt;/a&gt;LeaveMacro: 0
&lt;a id=&#34;__codelineno-9-22&#34; name=&#34;__codelineno-9-22&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-23&#34; name=&#34;__codelineno-9-23&#34;&gt;&lt;/a&gt;HandleIdentifier:
&lt;a id=&#34;__codelineno-9-24&#34; name=&#34;__codelineno-9-24&#34;&gt;&lt;/a&gt;MacroInfo 0x559e57496900 disabled used
&lt;a id=&#34;__codelineno-9-25&#34; name=&#34;__codelineno-9-25&#34;&gt;&lt;/a&gt;    #define &amp;lt;macro&amp;gt;[2813:CONCAT](arg0, arg1) arg0 ## arg1
&lt;a id=&#34;__codelineno-9-26&#34; name=&#34;__codelineno-9-26&#34;&gt;&lt;/a&gt;Macro is not ok to expand
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;第 &lt;a href=&#34;#__codelineno-9-1&#34;&gt;1&lt;/a&gt; 行 &lt;code&gt;HandleIdentifier&lt;/code&gt; 遇到宏的时候会打印，接着打印宏的信息（第 &lt;a href=&#34;#__codelineno-9-2&#34;&gt;2-4&lt;/a&gt; 行），宏没有禁用，所以可以按照定义来展开 &lt;code&gt;Macro is ok to expand&lt;/code&gt;，之后进入宏 &lt;code&gt;EnterMacro&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;真正执行宏展开的函数是 &lt;code&gt;ExpandFunctionArguments&lt;/code&gt;，之后再次打印待展开的宏信息，注意到此时宏已经被标记为 &lt;code&gt;used&lt;/code&gt; （第 &lt;a href=&#34;#__codelineno-9-9&#34;&gt;9&lt;/a&gt; 行）。之后根据宏的定义，进行逐个 &lt;code&gt;Token&lt;/code&gt; 的展开 （&lt;code&gt;Token&lt;/code&gt; 是 &lt;code&gt;Clang&lt;/code&gt; 预处理里面的概念，这里不深入说明）。&lt;/p&gt;
&lt;p&gt;第 0 个 &lt;code&gt;Token&lt;/code&gt; 是形参 &lt;code&gt;arg0&lt;/code&gt;, 对应的实参是 &lt;code&gt;C&lt;/code&gt;，判断不需要展开，于是直接复制到结果上（第 &lt;a href=&#34;#__codelineno-9-11&#34;&gt;11-13&lt;/a&gt; 行）。&lt;/p&gt;
&lt;p&gt;第 1 个 &lt;code&gt;Token&lt;/code&gt; 是 &lt;code&gt;hashhash&lt;/code&gt;，也就是 &lt;code&gt;##&lt;/code&gt; 操作符，继续复制到结果上（第 &lt;a href=&#34;#__codelineno-9-14&#34;&gt;14-15&lt;/a&gt; 行）。&lt;/p&gt;
&lt;p&gt;第 2 个 &lt;code&gt;Token&lt;/code&gt; 是形参 &lt;code&gt;arg1&lt;/code&gt;，对应的实参是 &lt;code&gt;ONCAT(a, b)&lt;/code&gt;，预处理器也会把实参处理成一个个的 &lt;code&gt;Token&lt;/code&gt;，所以可以看到打印的结果用中括号包住了实参的每个 &lt;code&gt;Token&lt;/code&gt;（第 18 行），由于 &lt;code&gt;##&lt;/code&gt; 的原因这个实参依然不需要展开，所以还是直接复制到结果上（第 &lt;a href=&#34;#__codelineno-9-16&#34;&gt;16-18&lt;/a&gt; 行）。&lt;/p&gt;
&lt;p&gt;最后 &lt;code&gt;Leave ExpandFunctionArguments&lt;/code&gt; 打印本次扫描展开得到的结果（第 &lt;a href=&#34;#__codelineno-9-19&#34;&gt;19&lt;/a&gt; 行），把结果的 &lt;code&gt;Token&lt;/code&gt; 都翻译过来就是 &lt;code&gt;C ## ONCAT(a, b)&lt;/code&gt;，之后预处理器就执行 &lt;code&gt;##&lt;/code&gt; 操作符来生成新的内容。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;##&lt;/code&gt; 执行之后得到 &lt;code&gt;CONCAT(a, b)&lt;/code&gt;，遇到宏 &lt;code&gt;CONCAT&lt;/code&gt;，预处理还是先进入 &lt;code&gt;HandleIdentifier&lt;/code&gt;，打印宏的信息，发现该宏状态是 &lt;code&gt;disable used&lt;/code&gt;，是已经展开过的，禁止再重入了，显示 &lt;code&gt;Macro is not ok to expand&lt;/code&gt;，预处理器不再展开，最终得到的结果就是 &lt;code&gt;CONCAT(a, b)&lt;/code&gt;。&lt;/p&gt;
&lt;h4 id=&#34;2&#34;&gt;例子2&lt;/h4&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-10-1&#34; name=&#34;__codelineno-10-1&#34; href=&#34;#__codelineno-10-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define CONCAT(arg0, arg1) arg0 ## arg1&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-2&#34; name=&#34;__codelineno-10-2&#34; href=&#34;#__codelineno-10-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define IDENTITY(arg0) arg0&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-3&#34; name=&#34;__codelineno-10-3&#34; href=&#34;#__codelineno-10-3&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-10-4&#34; name=&#34;__codelineno-10-4&#34; href=&#34;#__codelineno-10-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;IDENTITY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CONCAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;C&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ONCAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;details&gt;
&lt;summary&gt; &lt;font&gt; Clang 打印信息（点击展开）：&lt;/font&gt; &lt;/summary&gt;
&lt;div class=&#34;language-text highlight&#34;&gt;&lt;table class=&#34;highlighttable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;linenos&#34;&gt;&lt;div class=&#34;linenodiv&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-1&#34;&gt; 1&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-2&#34;&gt; 2&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-3&#34;&gt; 3&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-4&#34;&gt; 4&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-5&#34;&gt; 5&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-6&#34;&gt; 6&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-7&#34;&gt; 7&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-8&#34;&gt; 8&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-9&#34;&gt; 9&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-10&#34;&gt;10&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-11&#34;&gt;11&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-12&#34;&gt;12&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-13&#34;&gt;13&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-14&#34;&gt;14&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-15&#34;&gt;15&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-16&#34;&gt;16&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-17&#34;&gt;17&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-18&#34;&gt;18&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-19&#34;&gt;19&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-20&#34;&gt;20&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-21&#34;&gt;21&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-22&#34;&gt;22&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-23&#34;&gt;23&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-24&#34;&gt;24&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-25&#34;&gt;25&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-26&#34;&gt;26&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-27&#34;&gt;27&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-28&#34;&gt;28&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-29&#34;&gt;29&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-30&#34;&gt;30&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-31&#34;&gt;31&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-32&#34;&gt;32&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-33&#34;&gt;33&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-34&#34;&gt;34&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-35&#34;&gt;35&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-36&#34;&gt;36&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-37&#34;&gt;37&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-38&#34;&gt;38&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-39&#34;&gt;39&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-40&#34;&gt;40&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-41&#34;&gt;41&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-42&#34;&gt;42&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-43&#34;&gt;43&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-44&#34;&gt;44&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-45&#34;&gt;45&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-46&#34;&gt;46&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-47&#34;&gt;47&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-48&#34;&gt;48&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-49&#34;&gt;49&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-50&#34;&gt;50&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-51&#34;&gt;51&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-52&#34;&gt;52&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-53&#34;&gt;53&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-54&#34;&gt;54&lt;/a&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-11-1&#34; name=&#34;__codelineno-11-1&#34;&gt;&lt;/a&gt;HandleIdentifier:
&lt;a id=&#34;__codelineno-11-2&#34; name=&#34;__codelineno-11-2&#34;&gt;&lt;/a&gt;MacroInfo 0x562a148f5a60
&lt;a id=&#34;__codelineno-11-3&#34; name=&#34;__codelineno-11-3&#34;&gt;&lt;/a&gt;    #define &amp;lt;macro&amp;gt;[2853:IDENTITY](arg0) arg0
&lt;a id=&#34;__codelineno-11-4&#34; name=&#34;__codelineno-11-4&#34;&gt;&lt;/a&gt;Macro is ok to expand
&lt;a id=&#34;__codelineno-11-5&#34; name=&#34;__codelineno-11-5&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-6&#34; name=&#34;__codelineno-11-6&#34;&gt;&lt;/a&gt;HandleIdentifier:
&lt;a id=&#34;__codelineno-11-7&#34; name=&#34;__codelineno-11-7&#34;&gt;&lt;/a&gt;MacroInfo 0x562a148f5930
&lt;a id=&#34;__codelineno-11-8&#34; name=&#34;__codelineno-11-8&#34;&gt;&lt;/a&gt;    #define &amp;lt;macro&amp;gt;[2813:CONCAT](arg0, arg1) arg0 ## arg1
&lt;a id=&#34;__codelineno-11-9&#34; name=&#34;__codelineno-11-9&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-10&#34; name=&#34;__codelineno-11-10&#34;&gt;&lt;/a&gt;EnterMacro: 0
&lt;a id=&#34;__codelineno-11-11&#34; name=&#34;__codelineno-11-11&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-12&#34; name=&#34;__codelineno-11-12&#34;&gt;&lt;/a&gt;Enter ExpandFunctionArguments:
&lt;a id=&#34;__codelineno-11-13&#34; name=&#34;__codelineno-11-13&#34;&gt;&lt;/a&gt;MacroInfo 0x562a148f5a60 used
&lt;a id=&#34;__codelineno-11-14&#34; name=&#34;__codelineno-11-14&#34;&gt;&lt;/a&gt;    #define &amp;lt;macro&amp;gt;[2853:IDENTITY](arg0) arg0
&lt;a id=&#34;__codelineno-11-15&#34; name=&#34;__codelineno-11-15&#34;&gt;&lt;/a&gt;Token: 0
&lt;a id=&#34;__codelineno-11-16&#34; name=&#34;__codelineno-11-16&#34;&gt;&lt;/a&gt;identifier: arg0
&lt;a id=&#34;__codelineno-11-17&#34; name=&#34;__codelineno-11-17&#34;&gt;&lt;/a&gt;Args: [identifier: CONCAT][l_paren: ][identifier: C][comma: ][identifier: ONCAT][l_paren: ][identifier: a][comma: ][identifier: b][r_paren: ][r_paren: ]
&lt;a id=&#34;__codelineno-11-18&#34; name=&#34;__codelineno-11-18&#34;&gt;&lt;/a&gt;getPreExpArgument: [identifier: CONCAT][l_paren: ][identifier: C][comma: ][identifier: ONCAT][l_paren: ][identifier: a][comma: ][identifier: b][r_paren: ][r_paren: ][eof: ]
&lt;a id=&#34;__codelineno-11-19&#34; name=&#34;__codelineno-11-19&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-20&#34; name=&#34;__codelineno-11-20&#34;&gt;&lt;/a&gt;HandleIdentifier:
&lt;a id=&#34;__codelineno-11-21&#34; name=&#34;__codelineno-11-21&#34;&gt;&lt;/a&gt;MacroInfo 0x562a148f5930
&lt;a id=&#34;__codelineno-11-22&#34; name=&#34;__codelineno-11-22&#34;&gt;&lt;/a&gt;    #define &amp;lt;macro&amp;gt;[2813:CONCAT](arg0, arg1) arg0 ## arg1
&lt;a id=&#34;__codelineno-11-23&#34; name=&#34;__codelineno-11-23&#34;&gt;&lt;/a&gt;Macro is ok to expand
&lt;a id=&#34;__codelineno-11-24&#34; name=&#34;__codelineno-11-24&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-25&#34; name=&#34;__codelineno-11-25&#34;&gt;&lt;/a&gt;EnterMacro: 1
&lt;a id=&#34;__codelineno-11-26&#34; name=&#34;__codelineno-11-26&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-27&#34; name=&#34;__codelineno-11-27&#34;&gt;&lt;/a&gt;Enter ExpandFunctionArguments:
&lt;a id=&#34;__codelineno-11-28&#34; name=&#34;__codelineno-11-28&#34;&gt;&lt;/a&gt;MacroInfo 0x562a148f5930 used
&lt;a id=&#34;__codelineno-11-29&#34; name=&#34;__codelineno-11-29&#34;&gt;&lt;/a&gt;    #define &amp;lt;macro&amp;gt;[2813:CONCAT](arg0, arg1) arg0 ## arg1
&lt;a id=&#34;__codelineno-11-30&#34; name=&#34;__codelineno-11-30&#34;&gt;&lt;/a&gt;Token: 0
&lt;a id=&#34;__codelineno-11-31&#34; name=&#34;__codelineno-11-31&#34;&gt;&lt;/a&gt;identifier: arg0
&lt;a id=&#34;__codelineno-11-32&#34; name=&#34;__codelineno-11-32&#34;&gt;&lt;/a&gt;Args: [identifier: C]
&lt;a id=&#34;__codelineno-11-33&#34; name=&#34;__codelineno-11-33&#34;&gt;&lt;/a&gt;Token: 1
&lt;a id=&#34;__codelineno-11-34&#34; name=&#34;__codelineno-11-34&#34;&gt;&lt;/a&gt;hashhash:
&lt;a id=&#34;__codelineno-11-35&#34; name=&#34;__codelineno-11-35&#34;&gt;&lt;/a&gt;Token: 2
&lt;a id=&#34;__codelineno-11-36&#34; name=&#34;__codelineno-11-36&#34;&gt;&lt;/a&gt;identifier: arg1
&lt;a id=&#34;__codelineno-11-37&#34; name=&#34;__codelineno-11-37&#34;&gt;&lt;/a&gt;Args: [identifier: ONCAT][l_paren: ][identifier: a][comma: ][identifier: b][r_paren: ]
&lt;a id=&#34;__codelineno-11-38&#34; name=&#34;__codelineno-11-38&#34;&gt;&lt;/a&gt;Leave ExpandFunctionArguments: [identifier: C][hashhash: ][identifier: ONCAT][l_paren: ][identifier: a][comma: ][identifier: b][r_paren: ]
&lt;a id=&#34;__codelineno-11-39&#34; name=&#34;__codelineno-11-39&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-40&#34; name=&#34;__codelineno-11-40&#34;&gt;&lt;/a&gt;LeaveMacro: 1
&lt;a id=&#34;__codelineno-11-41&#34; name=&#34;__codelineno-11-41&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-42&#34; name=&#34;__codelineno-11-42&#34;&gt;&lt;/a&gt;HandleIdentifier:
&lt;a id=&#34;__codelineno-11-43&#34; name=&#34;__codelineno-11-43&#34;&gt;&lt;/a&gt;MacroInfo 0x562a148f5930 disabled used
&lt;a id=&#34;__codelineno-11-44&#34; name=&#34;__codelineno-11-44&#34;&gt;&lt;/a&gt;    #define &amp;lt;macro&amp;gt;[2813:CONCAT](arg0, arg1) arg0 ## arg1
&lt;a id=&#34;__codelineno-11-45&#34; name=&#34;__codelineno-11-45&#34;&gt;&lt;/a&gt;Macro is not ok to expand
&lt;a id=&#34;__codelineno-11-46&#34; name=&#34;__codelineno-11-46&#34;&gt;&lt;/a&gt;ResultArgToks: [identifier: CONCAT][l_paren: ][identifier: a][comma: ][identifier: b][r_paren: ]
&lt;a id=&#34;__codelineno-11-47&#34; name=&#34;__codelineno-11-47&#34;&gt;&lt;/a&gt;Leave ExpandFunctionArguments: [identifier: CONCAT][l_paren: ][identifier: a][comma: ][identifier: b][r_paren: ]
&lt;a id=&#34;__codelineno-11-48&#34; name=&#34;__codelineno-11-48&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-49&#34; name=&#34;__codelineno-11-49&#34;&gt;&lt;/a&gt;LeaveMacro: 0
&lt;a id=&#34;__codelineno-11-50&#34; name=&#34;__codelineno-11-50&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-51&#34; name=&#34;__codelineno-11-51&#34;&gt;&lt;/a&gt;HandleIdentifier:
&lt;a id=&#34;__codelineno-11-52&#34; name=&#34;__codelineno-11-52&#34;&gt;&lt;/a&gt;MacroInfo 0x562a148f5930 used
&lt;a id=&#34;__codelineno-11-53&#34; name=&#34;__codelineno-11-53&#34;&gt;&lt;/a&gt;    #define &amp;lt;macro&amp;gt;[2813:CONCAT](arg0, arg1) arg0 ## arg1
&lt;a id=&#34;__codelineno-11-54&#34; name=&#34;__codelineno-11-54&#34;&gt;&lt;/a&gt;Macro is not ok to expand
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/details&gt;

&lt;p&gt;第 &lt;a href=&#34;#__codelineno-11-12&#34;&gt;12&lt;/a&gt; 行开始展开 &lt;code&gt;IDENTITY&lt;/code&gt;，发现参数 &lt;code&gt;Token 0&lt;/code&gt; 是 &lt;code&gt;CONCAT(...)&lt;/code&gt;，也是一个宏，于是先对该参数进行求值。&lt;/p&gt;
&lt;p&gt;第 &lt;a href=&#34;#__codelineno-11-27&#34;&gt;27&lt;/a&gt; 行开始展开参数宏 &lt;code&gt;CONCAT(...)&lt;/code&gt;，跟例子 1 一样，多次扫描展开完成后得到 &lt;code&gt;CONCAT(a, b)&lt;/code&gt; （第 &lt;a href=&#34;#__codelineno-11-46&#34;&gt;46&lt;/a&gt; 行）。&lt;/p&gt;
&lt;p&gt;第 &lt;a href=&#34;#__codelineno-11-47&#34;&gt;47&lt;/a&gt; 结束对 &lt;code&gt;IDENTITY&lt;/code&gt; 的展开，得到的结果是 &lt;code&gt;CONCAT(a, b)&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;第 &lt;a href=&#34;#__codelineno-11-51&#34;&gt;51&lt;/a&gt; 行重新扫描 &lt;code&gt;CONCAT(a, b)&lt;/code&gt;，发现虽然是宏，但在之前的参数展开过程中已经被设置成了 &lt;code&gt;used&lt;/code&gt;，不再递归展开，直接作为最终结果。&lt;/p&gt;
&lt;h4 id=&#34;3&#34;&gt;例子 3&lt;/h4&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-12-1&#34; name=&#34;__codelineno-12-1&#34; href=&#34;#__codelineno-12-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define CONCAT(arg0, arg1) arg0 ## arg1&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-2&#34; name=&#34;__codelineno-12-2&#34; href=&#34;#__codelineno-12-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define IDENTITY_IMPL(arg0) arg0&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-3&#34; name=&#34;__codelineno-12-3&#34; href=&#34;#__codelineno-12-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define IDENTITY(arg0) IDENTITY_IMPL(arg0)&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-4&#34; name=&#34;__codelineno-12-4&#34; href=&#34;#__codelineno-12-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-12-5&#34; name=&#34;__codelineno-12-5&#34; href=&#34;#__codelineno-12-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;IDENTITY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CONCAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;C&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ONCAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;details&gt;
&lt;summary&gt; &lt;font&gt;Clang 打印信息（点击展开）：&lt;/font&gt; &lt;/summary&gt;
&lt;div class=&#34;language-text highlight&#34;&gt;&lt;table class=&#34;highlighttable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;linenos&#34;&gt;&lt;div class=&#34;linenodiv&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-1&#34;&gt; 1&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-2&#34;&gt; 2&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-3&#34;&gt; 3&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-4&#34;&gt; 4&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-5&#34;&gt; 5&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-6&#34;&gt; 6&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-7&#34;&gt; 7&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-8&#34;&gt; 8&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-9&#34;&gt; 9&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-10&#34;&gt;10&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-11&#34;&gt;11&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-12&#34;&gt;12&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-13&#34;&gt;13&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-14&#34;&gt;14&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-15&#34;&gt;15&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-16&#34;&gt;16&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-17&#34;&gt;17&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-18&#34;&gt;18&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-19&#34;&gt;19&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-20&#34;&gt;20&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-21&#34;&gt;21&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-22&#34;&gt;22&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-23&#34;&gt;23&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-24&#34;&gt;24&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-25&#34;&gt;25&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-26&#34;&gt;26&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-27&#34;&gt;27&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-28&#34;&gt;28&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-29&#34;&gt;29&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-30&#34;&gt;30&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-31&#34;&gt;31&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-32&#34;&gt;32&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-33&#34;&gt;33&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-34&#34;&gt;34&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-35&#34;&gt;35&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-36&#34;&gt;36&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-37&#34;&gt;37&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-38&#34;&gt;38&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-39&#34;&gt;39&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-40&#34;&gt;40&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-41&#34;&gt;41&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-42&#34;&gt;42&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-43&#34;&gt;43&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-44&#34;&gt;44&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-45&#34;&gt;45&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-46&#34;&gt;46&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-47&#34;&gt;47&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-48&#34;&gt;48&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-49&#34;&gt;49&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-50&#34;&gt;50&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-51&#34;&gt;51&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-52&#34;&gt;52&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-53&#34;&gt;53&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-54&#34;&gt;54&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-55&#34;&gt;55&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-56&#34;&gt;56&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-57&#34;&gt;57&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-58&#34;&gt;58&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-59&#34;&gt;59&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-60&#34;&gt;60&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-61&#34;&gt;61&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-62&#34;&gt;62&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-63&#34;&gt;63&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-64&#34;&gt;64&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-65&#34;&gt;65&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-66&#34;&gt;66&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-67&#34;&gt;67&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-68&#34;&gt;68&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-69&#34;&gt;69&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-70&#34;&gt;70&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-71&#34;&gt;71&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-72&#34;&gt;72&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-73&#34;&gt;73&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-74&#34;&gt;74&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-75&#34;&gt;75&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-76&#34;&gt;76&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-77&#34;&gt;77&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-78&#34;&gt;78&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-79&#34;&gt;79&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-80&#34;&gt;80&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-81&#34;&gt;81&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-82&#34;&gt;82&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-83&#34;&gt;83&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-84&#34;&gt;84&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-85&#34;&gt;85&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-86&#34;&gt;86&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-87&#34;&gt;87&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-88&#34;&gt;88&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-89&#34;&gt;89&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-90&#34;&gt;90&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-91&#34;&gt;91&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-13-92&#34;&gt;92&lt;/a&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-13-1&#34; name=&#34;__codelineno-13-1&#34;&gt;&lt;/a&gt;HandleIdentifier:
&lt;a id=&#34;__codelineno-13-2&#34; name=&#34;__codelineno-13-2&#34;&gt;&lt;/a&gt;MacroInfo 0x55e824457a80
&lt;a id=&#34;__codelineno-13-3&#34; name=&#34;__codelineno-13-3&#34;&gt;&lt;/a&gt;    #define &amp;lt;macro&amp;gt;[2853:IDENTITY_IMPL](arg0) arg0
&lt;a id=&#34;__codelineno-13-4&#34; name=&#34;__codelineno-13-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-5&#34; name=&#34;__codelineno-13-5&#34;&gt;&lt;/a&gt;HandleIdentifier:
&lt;a id=&#34;__codelineno-13-6&#34; name=&#34;__codelineno-13-6&#34;&gt;&lt;/a&gt;MacroInfo 0x55e824457ba0
&lt;a id=&#34;__codelineno-13-7&#34; name=&#34;__codelineno-13-7&#34;&gt;&lt;/a&gt;    #define &amp;lt;macro&amp;gt;[2886:IDENTITY](arg0) IDENTITY_IMPL(arg0)
&lt;a id=&#34;__codelineno-13-8&#34; name=&#34;__codelineno-13-8&#34;&gt;&lt;/a&gt;Macro is ok to expand
&lt;a id=&#34;__codelineno-13-9&#34; name=&#34;__codelineno-13-9&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-10&#34; name=&#34;__codelineno-13-10&#34;&gt;&lt;/a&gt;HandleIdentifier:
&lt;a id=&#34;__codelineno-13-11&#34; name=&#34;__codelineno-13-11&#34;&gt;&lt;/a&gt;MacroInfo 0x55e824457950
&lt;a id=&#34;__codelineno-13-12&#34; name=&#34;__codelineno-13-12&#34;&gt;&lt;/a&gt;    #define &amp;lt;macro&amp;gt;[2813:CONCAT](arg0, arg1) arg0 ## arg1
&lt;a id=&#34;__codelineno-13-13&#34; name=&#34;__codelineno-13-13&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-14&#34; name=&#34;__codelineno-13-14&#34;&gt;&lt;/a&gt;EnterMacro: 0
&lt;a id=&#34;__codelineno-13-15&#34; name=&#34;__codelineno-13-15&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-16&#34; name=&#34;__codelineno-13-16&#34;&gt;&lt;/a&gt;Enter ExpandFunctionArguments:
&lt;a id=&#34;__codelineno-13-17&#34; name=&#34;__codelineno-13-17&#34;&gt;&lt;/a&gt;MacroInfo 0x55e824457ba0 used
&lt;a id=&#34;__codelineno-13-18&#34; name=&#34;__codelineno-13-18&#34;&gt;&lt;/a&gt;    #define &amp;lt;macro&amp;gt;[2886:IDENTITY](arg0) IDENTITY_IMPL(arg0)
&lt;a id=&#34;__codelineno-13-19&#34; name=&#34;__codelineno-13-19&#34;&gt;&lt;/a&gt;Token: 0
&lt;a id=&#34;__codelineno-13-20&#34; name=&#34;__codelineno-13-20&#34;&gt;&lt;/a&gt;identifier: IDENTITY_IMPL
&lt;a id=&#34;__codelineno-13-21&#34; name=&#34;__codelineno-13-21&#34;&gt;&lt;/a&gt;Token: 1
&lt;a id=&#34;__codelineno-13-22&#34; name=&#34;__codelineno-13-22&#34;&gt;&lt;/a&gt;l_paren:
&lt;a id=&#34;__codelineno-13-23&#34; name=&#34;__codelineno-13-23&#34;&gt;&lt;/a&gt;Token: 2
&lt;a id=&#34;__codelineno-13-24&#34; name=&#34;__codelineno-13-24&#34;&gt;&lt;/a&gt;identifier: arg0
&lt;a id=&#34;__codelineno-13-25&#34; name=&#34;__codelineno-13-25&#34;&gt;&lt;/a&gt;Args: [identifier: CONCAT][l_paren: ][identifier: C][comma: ][identifier: ONCAT][l_paren: ][identifier: a][comma: ][identifier: b][r_paren: ][r_paren: ]
&lt;a id=&#34;__codelineno-13-26&#34; name=&#34;__codelineno-13-26&#34;&gt;&lt;/a&gt;getPreExpArgument: [identifier: CONCAT][l_paren: ][identifier: C][comma: ][identifier: ONCAT][l_paren: ][identifier: a][comma: ][identifier: b][r_paren: ][r_paren: ][eof: ]
&lt;a id=&#34;__codelineno-13-27&#34; name=&#34;__codelineno-13-27&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-28&#34; name=&#34;__codelineno-13-28&#34;&gt;&lt;/a&gt;HandleIdentifier:
&lt;a id=&#34;__codelineno-13-29&#34; name=&#34;__codelineno-13-29&#34;&gt;&lt;/a&gt;MacroInfo 0x55e824457950
&lt;a id=&#34;__codelineno-13-30&#34; name=&#34;__codelineno-13-30&#34;&gt;&lt;/a&gt;    #define &amp;lt;macro&amp;gt;[2813:CONCAT](arg0, arg1) arg0 ## arg1
&lt;a id=&#34;__codelineno-13-31&#34; name=&#34;__codelineno-13-31&#34;&gt;&lt;/a&gt;Macro is ok to expand
&lt;a id=&#34;__codelineno-13-32&#34; name=&#34;__codelineno-13-32&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-33&#34; name=&#34;__codelineno-13-33&#34;&gt;&lt;/a&gt;EnterMacro: 1
&lt;a id=&#34;__codelineno-13-34&#34; name=&#34;__codelineno-13-34&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-35&#34; name=&#34;__codelineno-13-35&#34;&gt;&lt;/a&gt;Enter ExpandFunctionArguments:
&lt;a id=&#34;__codelineno-13-36&#34; name=&#34;__codelineno-13-36&#34;&gt;&lt;/a&gt;MacroInfo 0x55e824457950 used
&lt;a id=&#34;__codelineno-13-37&#34; name=&#34;__codelineno-13-37&#34;&gt;&lt;/a&gt;    #define &amp;lt;macro&amp;gt;[2813:CONCAT](arg0, arg1) arg0 ## arg1
&lt;a id=&#34;__codelineno-13-38&#34; name=&#34;__codelineno-13-38&#34;&gt;&lt;/a&gt;Token: 0
&lt;a id=&#34;__codelineno-13-39&#34; name=&#34;__codelineno-13-39&#34;&gt;&lt;/a&gt;identifier: arg0
&lt;a id=&#34;__codelineno-13-40&#34; name=&#34;__codelineno-13-40&#34;&gt;&lt;/a&gt;Args: [identifier: C]
&lt;a id=&#34;__codelineno-13-41&#34; name=&#34;__codelineno-13-41&#34;&gt;&lt;/a&gt;Token: 1
&lt;a id=&#34;__codelineno-13-42&#34; name=&#34;__codelineno-13-42&#34;&gt;&lt;/a&gt;hashhash:
&lt;a id=&#34;__codelineno-13-43&#34; name=&#34;__codelineno-13-43&#34;&gt;&lt;/a&gt;Token: 2
&lt;a id=&#34;__codelineno-13-44&#34; name=&#34;__codelineno-13-44&#34;&gt;&lt;/a&gt;identifier: arg1
&lt;a id=&#34;__codelineno-13-45&#34; name=&#34;__codelineno-13-45&#34;&gt;&lt;/a&gt;Args: [identifier: ONCAT][l_paren: ][identifier: a][comma: ][identifier: b][r_paren: ]
&lt;a id=&#34;__codelineno-13-46&#34; name=&#34;__codelineno-13-46&#34;&gt;&lt;/a&gt;Leave ExpandFunctionArguments: [identifier: C][hashhash: ][identifier: ONCAT][l_paren: ][identifier: a][comma: ][identifier: b][r_paren: ]
&lt;a id=&#34;__codelineno-13-47&#34; name=&#34;__codelineno-13-47&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-48&#34; name=&#34;__codelineno-13-48&#34;&gt;&lt;/a&gt;LeaveMacro: 1
&lt;a id=&#34;__codelineno-13-49&#34; name=&#34;__codelineno-13-49&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-50&#34; name=&#34;__codelineno-13-50&#34;&gt;&lt;/a&gt;HandleIdentifier:
&lt;a id=&#34;__codelineno-13-51&#34; name=&#34;__codelineno-13-51&#34;&gt;&lt;/a&gt;MacroInfo 0x55e824457950 disabled used
&lt;a id=&#34;__codelineno-13-52&#34; name=&#34;__codelineno-13-52&#34;&gt;&lt;/a&gt;    #define &amp;lt;macro&amp;gt;[2813:CONCAT](arg0, arg1) arg0 ## arg1
&lt;a id=&#34;__codelineno-13-53&#34; name=&#34;__codelineno-13-53&#34;&gt;&lt;/a&gt;Macro is not ok to expand
&lt;a id=&#34;__codelineno-13-54&#34; name=&#34;__codelineno-13-54&#34;&gt;&lt;/a&gt;ResultArgToks: [identifier: CONCAT][l_paren: ][identifier: a][comma: ][identifier: b][r_paren: ]
&lt;a id=&#34;__codelineno-13-55&#34; name=&#34;__codelineno-13-55&#34;&gt;&lt;/a&gt;Token: 3
&lt;a id=&#34;__codelineno-13-56&#34; name=&#34;__codelineno-13-56&#34;&gt;&lt;/a&gt;r_paren:
&lt;a id=&#34;__codelineno-13-57&#34; name=&#34;__codelineno-13-57&#34;&gt;&lt;/a&gt;Leave ExpandFunctionArguments: [identifier: IDENTITY_IMPL][l_paren: ][identifier: CONCAT][l_paren: ][identifier: a][comma: ][identifier: b][r_paren: ][r_paren: ]
&lt;a id=&#34;__codelineno-13-58&#34; name=&#34;__codelineno-13-58&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-59&#34; name=&#34;__codelineno-13-59&#34;&gt;&lt;/a&gt;LeaveMacro: 0
&lt;a id=&#34;__codelineno-13-60&#34; name=&#34;__codelineno-13-60&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-61&#34; name=&#34;__codelineno-13-61&#34;&gt;&lt;/a&gt;HandleIdentifier:
&lt;a id=&#34;__codelineno-13-62&#34; name=&#34;__codelineno-13-62&#34;&gt;&lt;/a&gt;MacroInfo 0x55e824457a80
&lt;a id=&#34;__codelineno-13-63&#34; name=&#34;__codelineno-13-63&#34;&gt;&lt;/a&gt;    #define &amp;lt;macro&amp;gt;[2853:IDENTITY_IMPL](arg0) arg0
&lt;a id=&#34;__codelineno-13-64&#34; name=&#34;__codelineno-13-64&#34;&gt;&lt;/a&gt;Macro is ok to expand
&lt;a id=&#34;__codelineno-13-65&#34; name=&#34;__codelineno-13-65&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-66&#34; name=&#34;__codelineno-13-66&#34;&gt;&lt;/a&gt;HandleIdentifier:
&lt;a id=&#34;__codelineno-13-67&#34; name=&#34;__codelineno-13-67&#34;&gt;&lt;/a&gt;MacroInfo 0x55e824457950 used
&lt;a id=&#34;__codelineno-13-68&#34; name=&#34;__codelineno-13-68&#34;&gt;&lt;/a&gt;    #define &amp;lt;macro&amp;gt;[2813:CONCAT](arg0, arg1) arg0 ## arg1
&lt;a id=&#34;__codelineno-13-69&#34; name=&#34;__codelineno-13-69&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-70&#34; name=&#34;__codelineno-13-70&#34;&gt;&lt;/a&gt;EnterMacro: 2
&lt;a id=&#34;__codelineno-13-71&#34; name=&#34;__codelineno-13-71&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-72&#34; name=&#34;__codelineno-13-72&#34;&gt;&lt;/a&gt;Enter ExpandFunctionArguments:
&lt;a id=&#34;__codelineno-13-73&#34; name=&#34;__codelineno-13-73&#34;&gt;&lt;/a&gt;MacroInfo 0x55e824457a80 used
&lt;a id=&#34;__codelineno-13-74&#34; name=&#34;__codelineno-13-74&#34;&gt;&lt;/a&gt;    #define &amp;lt;macro&amp;gt;[2853:IDENTITY_IMPL](arg0) arg0
&lt;a id=&#34;__codelineno-13-75&#34; name=&#34;__codelineno-13-75&#34;&gt;&lt;/a&gt;Token: 0
&lt;a id=&#34;__codelineno-13-76&#34; name=&#34;__codelineno-13-76&#34;&gt;&lt;/a&gt;identifier: arg0
&lt;a id=&#34;__codelineno-13-77&#34; name=&#34;__codelineno-13-77&#34;&gt;&lt;/a&gt;Args: [identifier: CONCAT][l_paren: ][identifier: a][comma: ][identifier: b][r_paren: ]
&lt;a id=&#34;__codelineno-13-78&#34; name=&#34;__codelineno-13-78&#34;&gt;&lt;/a&gt;getPreExpArgument: [identifier: CONCAT][l_paren: ][identifier: a][comma: ][identifier: b][r_paren: ][eof: ]
&lt;a id=&#34;__codelineno-13-79&#34; name=&#34;__codelineno-13-79&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-80&#34; name=&#34;__codelineno-13-80&#34;&gt;&lt;/a&gt;HandleIdentifier:
&lt;a id=&#34;__codelineno-13-81&#34; name=&#34;__codelineno-13-81&#34;&gt;&lt;/a&gt;MacroInfo 0x55e824457950 used
&lt;a id=&#34;__codelineno-13-82&#34; name=&#34;__codelineno-13-82&#34;&gt;&lt;/a&gt;    #define &amp;lt;macro&amp;gt;[2813:CONCAT](arg0, arg1) arg0 ## arg1
&lt;a id=&#34;__codelineno-13-83&#34; name=&#34;__codelineno-13-83&#34;&gt;&lt;/a&gt;Macro is not ok to expand
&lt;a id=&#34;__codelineno-13-84&#34; name=&#34;__codelineno-13-84&#34;&gt;&lt;/a&gt;ResultArgToks: [identifier: CONCAT][l_paren: ][identifier: a][comma: ][identifier: b][r_paren: ]
&lt;a id=&#34;__codelineno-13-85&#34; name=&#34;__codelineno-13-85&#34;&gt;&lt;/a&gt;Leave ExpandFunctionArguments: [identifier: CONCAT][l_paren: ][identifier: a][comma: ][identifier: b][r_paren: ]
&lt;a id=&#34;__codelineno-13-86&#34; name=&#34;__codelineno-13-86&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-87&#34; name=&#34;__codelineno-13-87&#34;&gt;&lt;/a&gt;LeaveMacro: 2
&lt;a id=&#34;__codelineno-13-88&#34; name=&#34;__codelineno-13-88&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-13-89&#34; name=&#34;__codelineno-13-89&#34;&gt;&lt;/a&gt;HandleIdentifier:
&lt;a id=&#34;__codelineno-13-90&#34; name=&#34;__codelineno-13-90&#34;&gt;&lt;/a&gt;MacroInfo 0x55e824457950 used
&lt;a id=&#34;__codelineno-13-91&#34; name=&#34;__codelineno-13-91&#34;&gt;&lt;/a&gt;    #define &amp;lt;macro&amp;gt;[2813:CONCAT](arg0, arg1) arg0 ## arg1
&lt;a id=&#34;__codelineno-13-92&#34; name=&#34;__codelineno-13-92&#34;&gt;&lt;/a&gt;Macro is not ok to expand
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;/details&gt;

&lt;ul&gt;
&lt;li&gt;第 &lt;a href=&#34;#__codelineno-13-16&#34;&gt;16&lt;/a&gt; 行开始展开 &lt;code&gt;IDENTITY&lt;/code&gt;，同理预处理器看到 &lt;code&gt;Token 2&lt;/code&gt; （也即是 &lt;code&gt;arg0&lt;/code&gt;）是宏，于是先展开 &lt;code&gt;CONCAT(C, ONCAT(a, b))&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;展开 &lt;code&gt;arg0&lt;/code&gt; 后得到 &lt;code&gt;CONCAT(a, b)&lt;/code&gt; （第 &lt;a href=&#34;#__codelineno-13-23&#34;&gt;23-54&lt;/a&gt; 行）&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;IDENTITY&lt;/code&gt; 最终展开为 &lt;code&gt;IDENTITY_IMPL(CONCAT(a, b))&lt;/code&gt;（第 &lt;a href=&#34;#__codelineno-13-57&#34;&gt;57&lt;/a&gt; 行）&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;重新扫描，继续展开 &lt;code&gt;IDENTITY_IMPL&lt;/code&gt;（第 &lt;a href=&#34;#__codelineno-13-61&#34;&gt;61-72&lt;/a&gt; 行），发现此时的 &lt;code&gt;Token 0&lt;/code&gt; 是宏 &lt;code&gt;CONCAT(a, b)&lt;/code&gt;，但处于 &lt;code&gt;used&lt;/code&gt; 状态，中止展开并返回（第 75-84行），最终得到的结果还是 &lt;code&gt;CONCAT(a, b)&lt;/code&gt;（第 &lt;a href=&#34;#__codelineno-13-85&#34;&gt;85&lt;/a&gt; 行）。&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;重新扫描结果，发现宏 &lt;code&gt;CONCAT(a, b)&lt;/code&gt; 的状态是 &lt;code&gt;used&lt;/code&gt;，停止展开并得到最终的结果。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;通过以上三个简单的例子，我们可以大致的理解预处理器展开宏的过程，这里不再对预处理器进行更深入的探讨，有兴趣可以对照我提供的修改文件来研究。&lt;/p&gt;
&lt;h2 id=&#34;_10&#34;&gt;宏编程实现&lt;/h2&gt;
&lt;p&gt;下面我们开始进入到了主题（前面那一大段目的是为了更好的理解宏展开规则），宏编程实现。&lt;/p&gt;
&lt;h4 id=&#34;_11&#34;&gt;基本符号&lt;/h4&gt;
&lt;p&gt;首先可以先定义宏的特殊符号，做求值和拼接的时候会用到&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-14-1&#34; name=&#34;__codelineno-14-1&#34; href=&#34;#__codelineno-14-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_LPAREN() (&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-2&#34; name=&#34;__codelineno-14-2&#34; href=&#34;#__codelineno-14-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_RPAREN() )&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-3&#34; name=&#34;__codelineno-14-3&#34; href=&#34;#__codelineno-14-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_COMMA() ,&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-4&#34; name=&#34;__codelineno-14-4&#34; href=&#34;#__codelineno-14-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_EMPTY()&lt;/span&gt;
&lt;a id=&#34;__codelineno-14-5&#34; name=&#34;__codelineno-14-5&#34; href=&#34;#__codelineno-14-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_HASHHASH # ## #      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 表示 ## 字符串，但只是作为字符串，不会当作 ## 操作符来处理&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&#34;_12&#34;&gt;求值&lt;/h4&gt;
&lt;p&gt;利用参数优先展开的规则，可以写出一个求值宏：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-15-1&#34; name=&#34;__codelineno-15-1&#34; href=&#34;#__codelineno-15-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_IDENTITY(arg0) arg0&lt;/span&gt;
&lt;a id=&#34;__codelineno-15-2&#34; name=&#34;__codelineno-15-2&#34; href=&#34;#__codelineno-15-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-15-3&#34; name=&#34;__codelineno-15-3&#34; href=&#34;#__codelineno-15-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_COMMA&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PP_LPAREN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PP_RPAREN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; PP_COMMA ( )&lt;/span&gt;
&lt;a id=&#34;__codelineno-15-4&#34; name=&#34;__codelineno-15-4&#34; href=&#34;#__codelineno-15-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IDENTITY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PP_COMMA&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PP_LPAREN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PP_RPAREN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; PP_COMMA() -&amp;gt; ,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如果只是写 &lt;code&gt;PP_COMMA PP_LPAREN() PP_RPAREN()&lt;/code&gt;，预处理器只会分别处理每个宏，对展开的结果不会再合并处理。加上 &lt;code&gt;PP_IDENTITY&lt;/code&gt; 之后，预处理器可以对展开得到的 &lt;code&gt;PP_COMMA()&lt;/code&gt; 再进行求值，得到 &lt;code&gt;,&lt;/code&gt;。&lt;/p&gt;
&lt;h4 id=&#34;_13&#34;&gt;拼接&lt;/h4&gt;
&lt;p&gt;由于 &lt;code&gt;##&lt;/code&gt; 拼接的时候，是不会展开左右两边的参数，为了让参数可以先求值再拼接，可以这样写：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-16-1&#34; name=&#34;__codelineno-16-1&#34; href=&#34;#__codelineno-16-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_CONCAT(arg0, arg1) PP_CONCAT_IMPL(arg0, arg1)&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-2&#34; name=&#34;__codelineno-16-2&#34; href=&#34;#__codelineno-16-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_CONCAT_IMPL(arg0, arg1) arg0 ## arg1&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-3&#34; name=&#34;__codelineno-16-3&#34; href=&#34;#__codelineno-16-3&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-16-4&#34; name=&#34;__codelineno-16-4&#34; href=&#34;#__codelineno-16-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_CONCAT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PP_IDENTITY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PP_IDENTITY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 12&lt;/span&gt;
&lt;a id=&#34;__codelineno-16-5&#34; name=&#34;__codelineno-16-5&#34; href=&#34;#__codelineno-16-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_CONCAT_IMPL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PP_IDENTITY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PP_IDENTITY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; PP_IDENTITY(1)PP_IDENTITY(2) -&amp;gt; 报错&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这里 &lt;code&gt;PP_CONCAT&lt;/code&gt; 用到的方法叫做延迟拼接，在展开为 &lt;code&gt;PP_CONCAT_IMPL&lt;/code&gt; 的时候，&lt;code&gt;arg0&lt;/code&gt; 和 &lt;code&gt;arg1&lt;/code&gt; 都会先展开求值，之后再由 &lt;code&gt;PP_CONCAT_IMPL&lt;/code&gt; 执行真正的拼接操作。&lt;/p&gt;
&lt;h4 id=&#34;_14&#34;&gt;逻辑运算&lt;/h4&gt;
&lt;p&gt;借助 &lt;code&gt;PP_CONCAT&lt;/code&gt; 可以实现逻辑运算。首先定义 &lt;code&gt;BOOL&lt;/code&gt; 值：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-17-1&#34; name=&#34;__codelineno-17-1&#34; href=&#34;#__codelineno-17-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_BOOL(arg0) PP_CONCAT(PP_BOOL_, arg0)&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-2&#34; name=&#34;__codelineno-17-2&#34; href=&#34;#__codelineno-17-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_BOOL_0 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-3&#34; name=&#34;__codelineno-17-3&#34; href=&#34;#__codelineno-17-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_BOOL_1 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-4&#34; name=&#34;__codelineno-17-4&#34; href=&#34;#__codelineno-17-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_BOOL_2 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-5&#34; name=&#34;__codelineno-17-5&#34; href=&#34;#__codelineno-17-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_BOOL_3 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-6&#34; name=&#34;__codelineno-17-6&#34; href=&#34;#__codelineno-17-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-7&#34; name=&#34;__codelineno-17-7&#34; href=&#34;#__codelineno-17-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_BOOL_256 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-17-8&#34; name=&#34;__codelineno-17-8&#34; href=&#34;#__codelineno-17-8&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-17-9&#34; name=&#34;__codelineno-17-9&#34; href=&#34;#__codelineno-17-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_BOOL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; PP_BOOL_3 -&amp;gt; 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;用&lt;code&gt;PP_CONCAT&lt;/code&gt; 先把 &lt;code&gt;PP_BOOL_&lt;/code&gt; 和 &lt;code&gt;arg0&lt;/code&gt; 拼接在一起，再对拼接结果进行求值。这里的 &lt;code&gt;arg0&lt;/code&gt; 要求是求值之后得到 &lt;code&gt;[0, 256]&lt;/code&gt; 范围的数字，拼接在 &lt;code&gt;PP_BOOL_&lt;/code&gt; 后面求值，就能得到布尔值。与或非运算：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-18-1&#34; name=&#34;__codelineno-18-1&#34; href=&#34;#__codelineno-18-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_NOT(arg0) PP_CONCAT(PP_NOT_, PP_BOOL(arg0))&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-2&#34; name=&#34;__codelineno-18-2&#34; href=&#34;#__codelineno-18-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_NOT_0 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-3&#34; name=&#34;__codelineno-18-3&#34; href=&#34;#__codelineno-18-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_NOT_1 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-4&#34; name=&#34;__codelineno-18-4&#34; href=&#34;#__codelineno-18-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-18-5&#34; name=&#34;__codelineno-18-5&#34; href=&#34;#__codelineno-18-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_AND(arg0, arg1) PP_CONCAT(PP_AND_, PP_CONCAT(PP_BOOL(arg0), PP_BOOL(arg1)))&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-6&#34; name=&#34;__codelineno-18-6&#34; href=&#34;#__codelineno-18-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_AND_00 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-7&#34; name=&#34;__codelineno-18-7&#34; href=&#34;#__codelineno-18-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_AND_01 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-8&#34; name=&#34;__codelineno-18-8&#34; href=&#34;#__codelineno-18-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_AND_10 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-9&#34; name=&#34;__codelineno-18-9&#34; href=&#34;#__codelineno-18-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_AND_11 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-10&#34; name=&#34;__codelineno-18-10&#34; href=&#34;#__codelineno-18-10&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-18-11&#34; name=&#34;__codelineno-18-11&#34; href=&#34;#__codelineno-18-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_OR(arg0, arg1) PP_CONCAT(PP_OR_, PP_CONCAT(PP_BOOL(arg0), PP_BOOL(arg1)))&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-12&#34; name=&#34;__codelineno-18-12&#34; href=&#34;#__codelineno-18-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_OR_00 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-13&#34; name=&#34;__codelineno-18-13&#34; href=&#34;#__codelineno-18-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_OR_01 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-14&#34; name=&#34;__codelineno-18-14&#34; href=&#34;#__codelineno-18-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_OR_10 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-15&#34; name=&#34;__codelineno-18-15&#34; href=&#34;#__codelineno-18-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_OR_11 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-16&#34; name=&#34;__codelineno-18-16&#34; href=&#34;#__codelineno-18-16&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-18-17&#34; name=&#34;__codelineno-18-17&#34; href=&#34;#__codelineno-18-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_NOT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PP_BOOL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; PP_CONCAT(PP_NOT_, 1) -&amp;gt; PP_NOT_1 -&amp;gt; 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-18&#34; name=&#34;__codelineno-18-18&#34; href=&#34;#__codelineno-18-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_AND&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; PP_CONCAT(PP_AND_, 11) -&amp;gt; PP_AND_11 -&amp;gt; 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-19&#34; name=&#34;__codelineno-18-19&#34; href=&#34;#__codelineno-18-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_AND&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; PP_CONCAT(PP_AND_, 10) -&amp;gt; PP_AND_10 -&amp;gt; 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-18-20&#34; name=&#34;__codelineno-18-20&#34; href=&#34;#__codelineno-18-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_OR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; PP_CONCAT(PP_OR_, 10) -&amp;gt; PP_OR_10, -&amp;gt; 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;先用 &lt;code&gt;PP_BOOL&lt;/code&gt; 对参数求值，之后再根据 &lt;code&gt;0 1&lt;/code&gt; 的组合来拼接逻辑运算的结果。如果不用 &lt;code&gt;PP_BOOL&lt;/code&gt; 来求值，那么参数就只能支持 &lt;code&gt;0 1&lt;/code&gt; 两种数值，适用性大大降低。同理也可以写出异或，或非等操作，有兴趣可以自己尝试。&lt;/p&gt;
&lt;h4 id=&#34;_15&#34;&gt;条件选择&lt;/h4&gt;
&lt;p&gt;利用 &lt;code&gt;PP_BOOL&lt;/code&gt; 和 &lt;code&gt;PP_CONCAT&lt;/code&gt;，还可以写出条件选择语句：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-19-1&#34; name=&#34;__codelineno-19-1&#34; href=&#34;#__codelineno-19-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_IF(if, then, else) PP_CONCAT(PP_IF_, PP_BOOL(if))(then, else)&lt;/span&gt;
&lt;a id=&#34;__codelineno-19-2&#34; name=&#34;__codelineno-19-2&#34; href=&#34;#__codelineno-19-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_IF_1(then, else) then&lt;/span&gt;
&lt;a id=&#34;__codelineno-19-3&#34; name=&#34;__codelineno-19-3&#34; href=&#34;#__codelineno-19-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_IF_0(then, else) else&lt;/span&gt;
&lt;a id=&#34;__codelineno-19-4&#34; name=&#34;__codelineno-19-4&#34; href=&#34;#__codelineno-19-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-19-5&#34; name=&#34;__codelineno-19-5&#34; href=&#34;#__codelineno-19-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IF&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; PP_IF_1(2, 3) -&amp;gt; 2&lt;/span&gt;
&lt;a id=&#34;__codelineno-19-6&#34; name=&#34;__codelineno-19-6&#34; href=&#34;#__codelineno-19-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IF&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; PP_IF_0(2, 3) -&amp;gt; 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;if&lt;/code&gt; 求值如果是 &lt;code&gt;1&lt;/code&gt;，用 &lt;code&gt;PP_CONCAT&lt;/code&gt; 拼接成 &lt;code&gt;PP_IF_1&lt;/code&gt;，最后展开为 &lt;code&gt;then&lt;/code&gt; 的值；同理若 &lt;code&gt;if&lt;/code&gt; 求值为 &lt;code&gt;0&lt;/code&gt;，得到 &lt;code&gt;PP_IF_0&lt;/code&gt;。&lt;/p&gt;
&lt;h4 id=&#34;_16&#34;&gt;递增递减&lt;/h4&gt;
&lt;p&gt;整数递增递减：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-20-1&#34; name=&#34;__codelineno-20-1&#34; href=&#34;#__codelineno-20-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_INC(arg0) PP_CONCAT(PP_INC_, arg0)&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-2&#34; name=&#34;__codelineno-20-2&#34; href=&#34;#__codelineno-20-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_INC_0 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-3&#34; name=&#34;__codelineno-20-3&#34; href=&#34;#__codelineno-20-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_INC_1 2&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-4&#34; name=&#34;__codelineno-20-4&#34; href=&#34;#__codelineno-20-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_INC_2 3&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-5&#34; name=&#34;__codelineno-20-5&#34; href=&#34;#__codelineno-20-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_INC_3 4&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-6&#34; name=&#34;__codelineno-20-6&#34; href=&#34;#__codelineno-20-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-7&#34; name=&#34;__codelineno-20-7&#34; href=&#34;#__codelineno-20-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_INC_255 256&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-8&#34; name=&#34;__codelineno-20-8&#34; href=&#34;#__codelineno-20-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_INC_256 256&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-9&#34; name=&#34;__codelineno-20-9&#34; href=&#34;#__codelineno-20-9&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-20-10&#34; name=&#34;__codelineno-20-10&#34; href=&#34;#__codelineno-20-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_DEC(arg0) PP_CONCAT(PP_DEC_, arg0)&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-11&#34; name=&#34;__codelineno-20-11&#34; href=&#34;#__codelineno-20-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_DEC_0 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-12&#34; name=&#34;__codelineno-20-12&#34; href=&#34;#__codelineno-20-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_DEC_1 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-13&#34; name=&#34;__codelineno-20-13&#34; href=&#34;#__codelineno-20-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_DEC_2 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-14&#34; name=&#34;__codelineno-20-14&#34; href=&#34;#__codelineno-20-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_DEC_3 2&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-15&#34; name=&#34;__codelineno-20-15&#34; href=&#34;#__codelineno-20-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-16&#34; name=&#34;__codelineno-20-16&#34; href=&#34;#__codelineno-20-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_DEC_255 254&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-17&#34; name=&#34;__codelineno-20-17&#34; href=&#34;#__codelineno-20-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_DEC_256 255&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-18&#34; name=&#34;__codelineno-20-18&#34; href=&#34;#__codelineno-20-18&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-20-19&#34; name=&#34;__codelineno-20-19&#34; href=&#34;#__codelineno-20-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_INC&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                   &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; PP_INC_2 -&amp;gt; 3&lt;/span&gt;
&lt;a id=&#34;__codelineno-20-20&#34; name=&#34;__codelineno-20-20&#34; href=&#34;#__codelineno-20-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_DEC&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                   &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; PP_DEC_3 -&amp;gt; 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;跟 &lt;code&gt;PP_BOOL&lt;/code&gt; 类似，整数的递增递减也是有范围限制的，这里范围设置为 &lt;code&gt;[0, 256]&lt;/code&gt;，递增到 &lt;code&gt;256&lt;/code&gt; 之后，安全起见，&lt;code&gt;PP_INC_256&lt;/code&gt; 会返回自身 &lt;code&gt;256&lt;/code&gt; 作为边界，同理 &lt;code&gt;PP_DEC_0&lt;/code&gt; 也是返回 &lt;code&gt;0&lt;/code&gt;。&lt;/p&gt;
&lt;h4 id=&#34;_17&#34;&gt;变长参数&lt;/h4&gt;
&lt;p&gt;宏可以接受变长参数，格式是：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-21-1&#34; name=&#34;__codelineno-21-1&#34; href=&#34;#__codelineno-21-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define LOG(format, ...) printf(&amp;quot;log: &amp;quot; format, __VA_ARGS__)&lt;/span&gt;
&lt;a id=&#34;__codelineno-21-2&#34; name=&#34;__codelineno-21-2&#34; href=&#34;#__codelineno-21-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-21-3&#34; name=&#34;__codelineno-21-3&#34; href=&#34;#__codelineno-21-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Hello %s&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;World&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; printf(&amp;quot;log: &amp;quot; &amp;quot;Hello %s\n&amp;quot;, &amp;quot;World&amp;quot;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-21-4&#34; name=&#34;__codelineno-21-4&#34; href=&#34;#__codelineno-21-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;LOG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Hello World&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; printf(&amp;quot;log: &amp;quot; &amp;quot;Hello World&amp;quot;, ); 多了个逗号，编译报错&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;由于变长参数有可能为空，空的情况下会导致编译失败，因此 C++ 20 引入了 &lt;code&gt;__VA_OPT__&lt;/code&gt;，如果变长参数是空，则返回空，否则返回原参数：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-22-1&#34; name=&#34;__codelineno-22-1&#34; href=&#34;#__codelineno-22-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define LOG2(format, ...) printf(&amp;quot;log: &amp;quot; format __VA_OPT__(,) __VA_ARGS__)&lt;/span&gt;
&lt;a id=&#34;__codelineno-22-2&#34; name=&#34;__codelineno-22-2&#34; href=&#34;#__codelineno-22-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-22-3&#34; name=&#34;__codelineno-22-3&#34; href=&#34;#__codelineno-22-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;LOG2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Hello %s&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;World&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; printf(&amp;quot;log: &amp;quot; &amp;quot;Hello %s\n&amp;quot;, &amp;quot;World&amp;quot;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-22-4&#34; name=&#34;__codelineno-22-4&#34; href=&#34;#__codelineno-22-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;LOG2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Hello World&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; printf(&amp;quot;log: &amp;quot; &amp;quot;Hello World&amp;quot; ); 没有逗号，正常编译&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;但可惜只有 C++ 20 以上标准才有这个宏，下文中我们将会给出 &lt;code&gt;__VA_OPT__&lt;/code&gt; 的实现方法。&lt;/p&gt;
&lt;h4 id=&#34;_18&#34;&gt;惰性求值&lt;/h4&gt;
&lt;p&gt;考虑这种情况：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-23-1&#34; name=&#34;__codelineno-23-1&#34; href=&#34;#__codelineno-23-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IF&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PP_COMMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PP_LPAREN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; PP_IF_1(,,)) -&amp;gt; 报错 unterminated argument list invoking macro &amp;quot;PP_IF_1&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;我们知道，宏展开的时候会对先参数进行求值。&lt;code&gt;PP_COMMA()&lt;/code&gt; 和 &lt;code&gt;PP_LPAREN()&lt;/code&gt; 求值之后再传给 &lt;code&gt;PP_IF_1&lt;/code&gt;，得到 &lt;code&gt;PP_IF_1(,,))&lt;/code&gt;，导致预处理出错。此时，可以采用一种叫做惰性求值方法：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-24-1&#34; name=&#34;__codelineno-24-1&#34; href=&#34;#__codelineno-24-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IF&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PP_COMMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PP_LPAREN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; PP_IF_1(PP_COMMA, PP_LPAREN)() -&amp;gt; PP_COMMA() -&amp;gt; ,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;改成这种写法，只传宏的名字，让 &lt;code&gt;PP_IF&lt;/code&gt; 选出需要的宏名字之后，再跟括号 &lt;code&gt;()&lt;/code&gt; 拼接在一起组成完成的宏，最后再展开。惰性求值在宏编程里面也是很常见的。&lt;/p&gt;
&lt;h4 id=&#34;_19&#34;&gt;以括号开始&lt;/h4&gt;
&lt;p&gt;判断变长参数是否以括号开始：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-25-1&#34; name=&#34;__codelineno-25-1&#34; href=&#34;#__codelineno-25-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_IS_BEGIN_PARENS(...) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-2&#34; name=&#34;__codelineno-25-2&#34; href=&#34;#__codelineno-25-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_IS_BEGIN_PARENS_PROCESS( \&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-3&#34; name=&#34;__codelineno-25-3&#34; href=&#34;#__codelineno-25-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        PP_IS_BEGIN_PARENS_CONCAT( \&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-4&#34; name=&#34;__codelineno-25-4&#34; href=&#34;#__codelineno-25-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;            PP_IS_BEGIN_PARENS_PRE_, PP_IS_BEGIN_PARENS_EAT __VA_ARGS__ \&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-5&#34; name=&#34;__codelineno-25-5&#34; href=&#34;#__codelineno-25-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        ) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-6&#34; name=&#34;__codelineno-25-6&#34; href=&#34;#__codelineno-25-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    )&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-7&#34; name=&#34;__codelineno-25-7&#34; href=&#34;#__codelineno-25-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-25-8&#34; name=&#34;__codelineno-25-8&#34; href=&#34;#__codelineno-25-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_IS_BEGIN_PARENS_PROCESS(...) PP_IS_BEGIN_PARENS_PROCESS_0(__VA_ARGS__)&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-9&#34; name=&#34;__codelineno-25-9&#34; href=&#34;#__codelineno-25-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_IS_BEGIN_PARENS_PROCESS_0(arg0, ...) arg0&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-10&#34; name=&#34;__codelineno-25-10&#34; href=&#34;#__codelineno-25-10&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-25-11&#34; name=&#34;__codelineno-25-11&#34; href=&#34;#__codelineno-25-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_IS_BEGIN_PARENS_CONCAT(arg0, ...) PP_IS_BEGIN_PARENS_CONCAT_IMPL(arg0, __VA_ARGS__)&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-12&#34; name=&#34;__codelineno-25-12&#34; href=&#34;#__codelineno-25-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_IS_BEGIN_PARENS_CONCAT_IMPL(arg0, ...) arg0 ## __VA_ARGS__&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-13&#34; name=&#34;__codelineno-25-13&#34; href=&#34;#__codelineno-25-13&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-25-14&#34; name=&#34;__codelineno-25-14&#34; href=&#34;#__codelineno-25-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_IS_BEGIN_PARENS_PRE_1 1,&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-15&#34; name=&#34;__codelineno-25-15&#34; href=&#34;#__codelineno-25-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_IS_BEGIN_PARENS_PRE_PP_IS_BEGIN_PARENS_EAT 0,&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-16&#34; name=&#34;__codelineno-25-16&#34; href=&#34;#__codelineno-25-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_IS_BEGIN_PARENS_EAT(...) 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-17&#34; name=&#34;__codelineno-25-17&#34; href=&#34;#__codelineno-25-17&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-25-18&#34; name=&#34;__codelineno-25-18&#34; href=&#34;#__codelineno-25-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IS_BEGIN_PARENS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(())&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-19&#34; name=&#34;__codelineno-25-19&#34; href=&#34;#__codelineno-25-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IS_BEGIN_PARENS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((()))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-20&#34; name=&#34;__codelineno-25-20&#34; href=&#34;#__codelineno-25-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IS_BEGIN_PARENS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-21&#34; name=&#34;__codelineno-25-21&#34; href=&#34;#__codelineno-25-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IS_BEGIN_PARENS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-22&#34; name=&#34;__codelineno-25-22&#34; href=&#34;#__codelineno-25-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IS_BEGIN_PARENS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-23&#34; name=&#34;__codelineno-25-23&#34; href=&#34;#__codelineno-25-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IS_BEGIN_PARENS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(()&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;aa&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-25-24&#34; name=&#34;__codelineno-25-24&#34; href=&#34;#__codelineno-25-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IS_BEGIN_PARENS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;aa&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;PP_IS_BEGIN_PARENS&lt;/code&gt; 可以用来判断传入的参数是否以括号开始，在需要处理括号参数的时候会需要用到（譬如后面说到的 &lt;code&gt;__VA_OPT__&lt;/code&gt; 实现）。看上去有点复杂，核心思想就是构建出一个宏，若变长参数以括号开始，则可以跟括号连在一起求值得到一种结果，否则就另外求值得到另一种结果。我们来慢慢看：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;PP_IS_BEGIN_PARENS_PROCESS&lt;/code&gt; 和 &lt;code&gt;PP_IS_BEGIN_PARENS_PROCESS_0&lt;/code&gt; 组成的宏功能是先对传入的不定参数求值，然后取第 0 个参数。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;PP_IS_BEGIN_PARENS_CONCAT(PP_IS_BEGIN_PARENS_PRE_, PP_IS_BEGIN_PARENS_EAT __VA_ARGS__)&lt;/code&gt; 是先对 &lt;code&gt;PP_IS_BEGIN_PARENS_EAT __VA_ARGS__&lt;/code&gt; 求值，在把求值结果跟 &lt;code&gt;PP_IS_BEGIN_PARENS_PRE_&lt;/code&gt; 拼接在一起。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;PP_IS_BEGIN_PARENS_EAT(...)&lt;/code&gt; 宏会吞掉所有参数，返回1，如果上一步 &lt;code&gt;PP_IS_BEGIN_PARENS_EAT __VA_ARGS__&lt;/code&gt; 中，&lt;code&gt;__VA_ARGS__&lt;/code&gt; 是以括号开始的，那么就会匹配到对 &lt;code&gt;PP_IS_BEGIN_PARENS_EAT(...)&lt;/code&gt; 的求值，然后返回 &lt;code&gt;1&lt;/code&gt;；相反，如果不是以括号开始，则没有匹配上，&lt;code&gt;PP_IS_BEGIN_PARENS_EAT __VA_ARGS__&lt;/code&gt; 会保留不变。&lt;/p&gt;
&lt;p&gt;若 &lt;code&gt;PP_IS_BEGIN_PARENS_EAT __VA_ARGS__&lt;/code&gt; 求值得到 &lt;code&gt;1&lt;/code&gt;，&lt;code&gt;PP_IS_BEGIN_PARENS_CONCAT(PP_IS_BEGIN_PARENS_PRE_, 1) -&amp;gt; PP_IS_BEGIN_PARENS_PRE_1 -&amp;gt; 1,&lt;/code&gt;，注意 &lt;code&gt;1&lt;/code&gt; 后面是有个逗号的，把 &lt;code&gt;1,&lt;/code&gt; 传给 &lt;code&gt;PP_IS_BEGIN_PARENS_PROCESS_0&lt;/code&gt;，取第 0 个参数，最后得到 &lt;code&gt;1&lt;/code&gt;，表示参数是以括号开始。&lt;/p&gt;
&lt;p&gt;若 &lt;code&gt;PP_IS_BEGIN_PARENS_EAT __VA_ARGS__&lt;/code&gt; 求值得到不是 &lt;code&gt;1&lt;/code&gt;，而是保持不变，则 &lt;code&gt;PP_IS_BEGIN_PARENS_CONCAT(PP_IS_BEGIN_PARENS_PRE_, PP_IS_BEGIN_PARENS_EAT __VA_ARGS__) -&amp;gt; PP_IS_BEGIN_PARENS_PRE_PP_IS_BEGIN_PARENS_EAT __VA_ARGS__ -&amp;gt; 0, __VA_ARGS__&lt;/code&gt;，传给 &lt;code&gt;PP_IS_BEGIN_PARENS_PROCESS_0&lt;/code&gt; 得到的是 &lt;code&gt;0&lt;/code&gt;，表示参数不是以括号开始。&lt;/p&gt;
&lt;h4 id=&#34;_20&#34;&gt;变长参数空&lt;/h4&gt;
&lt;p&gt;判断变长参数是否为空也是一个常用的宏，在实现 &lt;code&gt;__VA_OPT__&lt;/code&gt; 的时候需要用到，我们在这里利用 &lt;code&gt;PP_IS_BEGIN_PARENS&lt;/code&gt;，可以先写出不完整的版本：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-26-1&#34; name=&#34;__codelineno-26-1&#34; href=&#34;#__codelineno-26-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_IS_EMPTY_PROCESS(...) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-26-2&#34; name=&#34;__codelineno-26-2&#34; href=&#34;#__codelineno-26-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_IS_BEGIN_PARENS(PP_IS_EMPTY_PROCESS_EAT __VA_ARGS__ ())&lt;/span&gt;
&lt;a id=&#34;__codelineno-26-3&#34; name=&#34;__codelineno-26-3&#34; href=&#34;#__codelineno-26-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_IS_EMPTY_PROCESS_EAT(...) ()&lt;/span&gt;
&lt;a id=&#34;__codelineno-26-4&#34; name=&#34;__codelineno-26-4&#34; href=&#34;#__codelineno-26-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-26-5&#34; name=&#34;__codelineno-26-5&#34; href=&#34;#__codelineno-26-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IS_EMPTY_PROCESS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-26-6&#34; name=&#34;__codelineno-26-6&#34; href=&#34;#__codelineno-26-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IS_EMPTY_PROCESS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-26-7&#34; name=&#34;__codelineno-26-7&#34; href=&#34;#__codelineno-26-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IS_EMPTY_PROCESS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-26-8&#34; name=&#34;__codelineno-26-8&#34; href=&#34;#__codelineno-26-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IS_EMPTY_PROCESS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(())&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;PP_IS_EMPTY_PROCESS&lt;/code&gt; 的作用是判断 &lt;code&gt;PP_IS_EMPTY_PROCESS_EAT __VA_ARGS__ ()&lt;/code&gt; 是否以括号开始。&lt;/p&gt;
&lt;p&gt;如果 &lt;code&gt;__VA_ARGS__&lt;/code&gt; 是空，&lt;code&gt;PP_IS_EMPTY_PROCESS_EAT __VA_ARGS__ () -&amp;gt; PP_IS_EMPTY_PROCESS_EAT() -&amp;gt; ()&lt;/code&gt;，得到的是一对括号 &lt;code&gt;()&lt;/code&gt;，再传给 &lt;code&gt;PP_IS_BEGIN_PARENS&lt;/code&gt; 返回 &lt;code&gt;1&lt;/code&gt;，表示参数是空。&lt;/p&gt;
&lt;p&gt;否则，&lt;code&gt;PP_IS_EMPTY_PROCESS_EAT __VA_ARGS__ ()&lt;/code&gt; 保持不变地传给 &lt;code&gt;PP_IS_BEGIN_PARENS&lt;/code&gt;，返回 0，表示非空。&lt;/p&gt;
&lt;p&gt;留意第 4 个例子 &lt;code&gt;PP_IS_EMPTY_PROCESS(()) -&amp;gt; 1&lt;/code&gt;，&lt;code&gt;PP_IS_EMPTY_PROCESS&lt;/code&gt; 不能正确处理以括号开始的变长参数，因为这时变长参数带来的括号会匹配 &lt;code&gt;PP_IS_EMPTY_PROCESS_EAT&lt;/code&gt; 导致求值得到 &lt;code&gt;()&lt;/code&gt;。为了解决这个问题，我们需要区别对待参数是否以括号开始的情况：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-27-1&#34; name=&#34;__codelineno-27-1&#34; href=&#34;#__codelineno-27-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_IS_EMPTY(...) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-2&#34; name=&#34;__codelineno-27-2&#34; href=&#34;#__codelineno-27-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_IS_EMPTY_IF(PP_IS_BEGIN_PARENS(__VA_ARGS__)) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-3&#34; name=&#34;__codelineno-27-3&#34; href=&#34;#__codelineno-27-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        (PP_IS_EMPTY_ZERO, PP_IS_EMPTY_PROCESS)(__VA_ARGS__)&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-4&#34; name=&#34;__codelineno-27-4&#34; href=&#34;#__codelineno-27-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-27-5&#34; name=&#34;__codelineno-27-5&#34; href=&#34;#__codelineno-27-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_IS_EMPTY_IF(if) PP_CONCAT(PP_IS_EMPTY_IF_, if)&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-6&#34; name=&#34;__codelineno-27-6&#34; href=&#34;#__codelineno-27-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_IS_EMPTY_IF_1(then, else) then&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-7&#34; name=&#34;__codelineno-27-7&#34; href=&#34;#__codelineno-27-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_IS_EMPTY_IF_0(then, else) else&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-8&#34; name=&#34;__codelineno-27-8&#34; href=&#34;#__codelineno-27-8&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-27-9&#34; name=&#34;__codelineno-27-9&#34; href=&#34;#__codelineno-27-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_IS_EMPTY_ZERO(...) 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-10&#34; name=&#34;__codelineno-27-10&#34; href=&#34;#__codelineno-27-10&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-27-11&#34; name=&#34;__codelineno-27-11&#34; href=&#34;#__codelineno-27-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IS_EMPTY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-12&#34; name=&#34;__codelineno-27-12&#34; href=&#34;#__codelineno-27-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IS_EMPTY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-13&#34; name=&#34;__codelineno-27-13&#34; href=&#34;#__codelineno-27-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IS_EMPTY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-27-14&#34; name=&#34;__codelineno-27-14&#34; href=&#34;#__codelineno-27-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IS_EMPTY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(())&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;PP_IS_EMPTY_IF&lt;/code&gt; 根据 &lt;code&gt;if&lt;/code&gt; 条件来返回第 0 或者 第 1 个参数。&lt;/p&gt;
&lt;p&gt;如果传入的变长参数以括号开始，&lt;code&gt;PP_IS_EMPTY_IF&lt;/code&gt; 返回 &lt;code&gt;PP_IS_EMPTY_ZERO&lt;/code&gt;，最后返回 &lt;code&gt;0&lt;/code&gt;，表示变长参数非空。&lt;/p&gt;
&lt;p&gt;反之 &lt;code&gt;PP_IS_EMPTY_IF&lt;/code&gt; 返回 &lt;code&gt;PP_IS_EMPTY_PROCESS&lt;/code&gt;，最后由 &lt;code&gt;PP_IS_EMPTY_PROCESS&lt;/code&gt; 来判断变长参数是否非空。&lt;/p&gt;
&lt;h4 id=&#34;_21&#34;&gt;下标访问&lt;/h4&gt;
&lt;p&gt;获取变长参数指定位置的元素：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-28-1&#34; name=&#34;__codelineno-28-1&#34; href=&#34;#__codelineno-28-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_ARGS_ELEM(I, ...) PP_CONCAT(PP_ARGS_ELEM_, I)(__VA_ARGS__)&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-2&#34; name=&#34;__codelineno-28-2&#34; href=&#34;#__codelineno-28-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_ARGS_ELEM_0(a0, ...) a0&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-3&#34; name=&#34;__codelineno-28-3&#34; href=&#34;#__codelineno-28-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_ARGS_ELEM_1(a0, a1, ...) a1&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-4&#34; name=&#34;__codelineno-28-4&#34; href=&#34;#__codelineno-28-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_ARGS_ELEM_2(a0, a1, a2, ...) a2&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-5&#34; name=&#34;__codelineno-28-5&#34; href=&#34;#__codelineno-28-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_ARGS_ELEM_3(a0, a1, a2, a3, ...) a3&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-6&#34; name=&#34;__codelineno-28-6&#34; href=&#34;#__codelineno-28-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-7&#34; name=&#34;__codelineno-28-7&#34; href=&#34;#__codelineno-28-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_ARGS_ELEM_7(a0, a1, a2, a3, a4, a5, a6, a7, ...) a7&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-8&#34; name=&#34;__codelineno-28-8&#34; href=&#34;#__codelineno-28-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_ARGS_ELEM_8(a0, a1, a2, a3, a4, a5, a6, a7, a8, ...) a8&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-9&#34; name=&#34;__codelineno-28-9&#34; href=&#34;#__codelineno-28-9&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-28-10&#34; name=&#34;__codelineno-28-10&#34; href=&#34;#__codelineno-28-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_ARGS_ELEM&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Hello&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;World&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; PP_ARGS_ELEM_0(&amp;quot;Hello&amp;quot;, &amp;quot;World&amp;quot;) -&amp;gt; &amp;quot;Hello&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-28-11&#34; name=&#34;__codelineno-28-11&#34; href=&#34;#__codelineno-28-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_ARGS_ELEM&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Hello&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;World&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; PP_ARGS_ELEM_1(&amp;quot;Hello&amp;quot;, &amp;quot;World&amp;quot;) -&amp;gt; &amp;quot;World&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;PP_ARGS_ELEM&lt;/code&gt; 的第一个参数是元素下标 &lt;code&gt;I&lt;/code&gt;，后面是变长参数。利用 &lt;code&gt;PP_CONCAT&lt;/code&gt; 拼接 &lt;code&gt;PP_ARGS_ELEM_&lt;/code&gt; 和 &lt;code&gt;I&lt;/code&gt;，即可以得到返回相应位置元素的宏 &lt;code&gt;PP_ARGS_ELEM_0..8&lt;/code&gt;，再把变长参数传给该宏，展开返回下标对应位置的元素。&lt;/p&gt;
&lt;h4 id=&#34;pp_is_empty2&#34;&gt;PP_IS_EMPTY2&lt;/h4&gt;
&lt;p&gt;利用 &lt;code&gt;PP_ARGS_ELEM&lt;/code&gt; 也可以实现另一版本的 &lt;code&gt;PP_IS_EMPTY&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-29-1&#34; name=&#34;__codelineno-29-1&#34; href=&#34;#__codelineno-29-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_IS_EMPTY2(...) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-2&#34; name=&#34;__codelineno-29-2&#34; href=&#34;#__codelineno-29-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_AND( \&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-3&#34; name=&#34;__codelineno-29-3&#34; href=&#34;#__codelineno-29-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        PP_AND( \&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-4&#34; name=&#34;__codelineno-29-4&#34; href=&#34;#__codelineno-29-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;            PP_NOT(PP_HAS_COMMA(__VA_ARGS__)), \&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-5&#34; name=&#34;__codelineno-29-5&#34; href=&#34;#__codelineno-29-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;            PP_NOT(PP_HAS_COMMA(__VA_ARGS__())) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-6&#34; name=&#34;__codelineno-29-6&#34; href=&#34;#__codelineno-29-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        ), \&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-7&#34; name=&#34;__codelineno-29-7&#34; href=&#34;#__codelineno-29-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        PP_AND( \&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-8&#34; name=&#34;__codelineno-29-8&#34; href=&#34;#__codelineno-29-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;            PP_NOT(PP_HAS_COMMA(PP_COMMA_ARGS __VA_ARGS__)), \&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-9&#34; name=&#34;__codelineno-29-9&#34; href=&#34;#__codelineno-29-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;            PP_HAS_COMMA(PP_COMMA_ARGS __VA_ARGS__ ()) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-10&#34; name=&#34;__codelineno-29-10&#34; href=&#34;#__codelineno-29-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        ) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-11&#34; name=&#34;__codelineno-29-11&#34; href=&#34;#__codelineno-29-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    )&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-12&#34; name=&#34;__codelineno-29-12&#34; href=&#34;#__codelineno-29-12&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-29-13&#34; name=&#34;__codelineno-29-13&#34; href=&#34;#__codelineno-29-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_HAS_COMMA(...) PP_ARGS_ELEM(8, __VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 0)&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-14&#34; name=&#34;__codelineno-29-14&#34; href=&#34;#__codelineno-29-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_COMMA_ARGS(...) ,&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-15&#34; name=&#34;__codelineno-29-15&#34; href=&#34;#__codelineno-29-15&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-29-16&#34; name=&#34;__codelineno-29-16&#34; href=&#34;#__codelineno-29-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IS_EMPTY2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-17&#34; name=&#34;__codelineno-29-17&#34; href=&#34;#__codelineno-29-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IS_EMPTY2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-18&#34; name=&#34;__codelineno-29-18&#34; href=&#34;#__codelineno-29-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IS_EMPTY2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-19&#34; name=&#34;__codelineno-29-19&#34; href=&#34;#__codelineno-29-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IS_EMPTY2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(())&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-29-20&#34; name=&#34;__codelineno-29-20&#34; href=&#34;#__codelineno-29-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_IS_EMPTY2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PP_COMMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;借用 &lt;code&gt;PP_ARGS_ELEM&lt;/code&gt; 实现判断参数是否含有逗号 &lt;code&gt;PP_HAS_COMMA&lt;/code&gt;。&lt;code&gt;PP_COMMA_ARGS&lt;/code&gt; 会吞掉传入的任意参数，返回一个逗号。&lt;/p&gt;
&lt;p&gt;判断变长参数是否为空的基础逻辑是 &lt;code&gt;PP_COMMA_ARGS __VA_ARGS__ ()&lt;/code&gt; 返回一个逗号，也就是 &lt;code&gt;__VA_ARGS__&lt;/code&gt; 为空，&lt;code&gt;PP_COMMA_ARGS&lt;/code&gt; 和 &lt;code&gt;()&lt;/code&gt; 拼接在一起求值，具体的写法就是 &lt;code&gt;PP_HAS_COMMA(PP_COMMA_ARGS __VA_ARGS__ ())&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;但是会有例外的情况：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;__VA_ARGS__&lt;/code&gt; 本身有可能会带来逗号；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;__VA_ARGS__ ()&lt;/code&gt; 拼接在一起发生求值带来逗号；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PP_COMMA_ARGS __VA_ARGS__&lt;/code&gt; 拼接在一起发生求值带来逗号；&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;针对上面说到的三种例外情况，需要做排除，所以最后的写法等价于对以下 4 个条件执行与逻辑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;PP_NOT(PP_HAS_COMMA(__VA_ARGS__))&lt;/code&gt; &amp;amp;&amp;amp;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PP_NOT(PP_HAS_COMMA(__VA_ARGS__()))&lt;/code&gt; &amp;amp;&amp;amp;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PP_NOT(PP_HAS_COMMA(PP_COMMA_ARGS __VA_ARGS__))&lt;/code&gt; &amp;amp;&amp;amp;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PP_HAS_COMMA(PP_COMMA_ARGS __VA_ARGS__ ())&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;__va_opt__&#34;&gt;&lt;code&gt;__VA_OPT__&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;利用 &lt;code&gt;PP_IS_EMPTY&lt;/code&gt; 终于可以来实现类似 &lt;code&gt;__VA_OPT__&lt;/code&gt; 的宏：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-30-1&#34; name=&#34;__codelineno-30-1&#34; href=&#34;#__codelineno-30-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_REMOVE_PARENS(tuple) PP_REMOVE_PARENS_IMPL tuple&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-2&#34; name=&#34;__codelineno-30-2&#34; href=&#34;#__codelineno-30-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_REMOVE_PARENS_IMPL(...) __VA_ARGS__&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-3&#34; name=&#34;__codelineno-30-3&#34; href=&#34;#__codelineno-30-3&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-30-4&#34; name=&#34;__codelineno-30-4&#34; href=&#34;#__codelineno-30-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_ARGS_OPT(data_tuple, empty_tuple, ...) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-5&#34; name=&#34;__codelineno-30-5&#34; href=&#34;#__codelineno-30-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_ARGS_OPT_IMPL(PP_IF(PP_IS_EMPTY(__VA_ARGS__), empty_tuple, data_tuple))&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-6&#34; name=&#34;__codelineno-30-6&#34; href=&#34;#__codelineno-30-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_ARGS_OPT_IMPL(tuple) PP_REMOVE_PARENS(tuple)&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-7&#34; name=&#34;__codelineno-30-7&#34; href=&#34;#__codelineno-30-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-30-8&#34; name=&#34;__codelineno-30-8&#34; href=&#34;#__codelineno-30-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_ARGS_OPT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;empty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; empty&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-9&#34; name=&#34;__codelineno-30-9&#34; href=&#34;#__codelineno-30-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_ARGS_OPT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;empty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; data&lt;/span&gt;
&lt;a id=&#34;__codelineno-30-10&#34; name=&#34;__codelineno-30-10&#34; href=&#34;#__codelineno-30-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_ARGS_OPT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((,),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; ,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;PP_ARGS_OPT&lt;/code&gt; 接受两个固定参数和变长参数，变长参数非空时返回 &lt;code&gt;data&lt;/code&gt;，否则返回 &lt;code&gt;empty&lt;/code&gt;。为了让 &lt;code&gt;data&lt;/code&gt; 和 &lt;code&gt;empty&lt;/code&gt; 支持逗号，要求两者都要用括号包住实际的参数，最后用 &lt;code&gt;PP_REMOVE_PARENS&lt;/code&gt; 来移除外层的括号。&lt;/p&gt;
&lt;p&gt;有了 &lt;code&gt;PP_ARGS_OPT&lt;/code&gt; 可以实现 &lt;code&gt;LOG3&lt;/code&gt; 来模拟 &lt;code&gt;LOG2&lt;/code&gt; 实现的功能：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-31-1&#34; name=&#34;__codelineno-31-1&#34; href=&#34;#__codelineno-31-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define LOG3(format, ...) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-31-2&#34; name=&#34;__codelineno-31-2&#34; href=&#34;#__codelineno-31-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    printf(&amp;quot;log: &amp;quot; format PP_ARGS_OPT((,), (), __VA_ARGS__) __VA_ARGS__)&lt;/span&gt;
&lt;a id=&#34;__codelineno-31-3&#34; name=&#34;__codelineno-31-3&#34; href=&#34;#__codelineno-31-3&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-31-4&#34; name=&#34;__codelineno-31-4&#34; href=&#34;#__codelineno-31-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;LOG3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Hello&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; printf(&amp;quot;log: &amp;quot; &amp;quot;Hello&amp;quot; );&lt;/span&gt;
&lt;a id=&#34;__codelineno-31-5&#34; name=&#34;__codelineno-31-5&#34; href=&#34;#__codelineno-31-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;LOG3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Hello %s&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;World&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; printf(&amp;quot;log: &amp;quot; &amp;quot;Hello %s&amp;quot; , &amp;quot;World&amp;quot;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;data_tuple&lt;/code&gt; 是 &lt;code&gt;(,)&lt;/code&gt;，如果变长参数非空，则会返回 &lt;code&gt;data_tuple&lt;/code&gt; 里面的所有元素，在这里就是逗号 &lt;code&gt;,&lt;/code&gt;。&lt;/p&gt;
&lt;h4 id=&#34;_22&#34;&gt;求参数个数&lt;/h4&gt;
&lt;p&gt;获取变长参数的个数：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-32-1&#34; name=&#34;__codelineno-32-1&#34; href=&#34;#__codelineno-32-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_ARGS_SIZE_IMCOMPLETE(...) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-32-2&#34; name=&#34;__codelineno-32-2&#34; href=&#34;#__codelineno-32-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_ARGS_ELEM(8, __VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0)&lt;/span&gt;
&lt;a id=&#34;__codelineno-32-3&#34; name=&#34;__codelineno-32-3&#34; href=&#34;#__codelineno-32-3&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-32-4&#34; name=&#34;__codelineno-32-4&#34; href=&#34;#__codelineno-32-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_ARGS_SIZE_IMCOMPLETE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-32-5&#34; name=&#34;__codelineno-32-5&#34; href=&#34;#__codelineno-32-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_ARGS_SIZE_IMCOMPLETE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 2&lt;/span&gt;
&lt;a id=&#34;__codelineno-32-6&#34; name=&#34;__codelineno-32-6&#34; href=&#34;#__codelineno-32-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_ARGS_SIZE_IMCOMPLETE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PP_COMMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 2&lt;/span&gt;
&lt;a id=&#34;__codelineno-32-7&#34; name=&#34;__codelineno-32-7&#34; href=&#34;#__codelineno-32-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_ARGS_SIZE_IMCOMPLETE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;计算变长参数的个数，是通过数参数的位置来获得的。&lt;code&gt;__VA_ARGS__&lt;/code&gt; 会导致后续的参数全体往右移动，用宏 &lt;code&gt;PP_ARGS_ELEM&lt;/code&gt; 来获取第 8 个位置的参数，如果 &lt;code&gt;__VA_ARGS__&lt;/code&gt; 只有一个参数，则第 8 个参数等于 &lt;code&gt;1&lt;/code&gt;；同理如果 &lt;code&gt;__VA_ARGS__&lt;/code&gt; 有两个参数，则第 8 个参数就变为 &lt;code&gt;2&lt;/code&gt;，刚好等于变长参数的个数。&lt;/p&gt;
&lt;p&gt;这里给的例子只最高支持个数 8 的变长参数，这是依赖于 &lt;code&gt;PP_ARGS_ELEM&lt;/code&gt; 所能支持的最大长度。&lt;/p&gt;
&lt;p&gt;但是这个宏还不完整，在变长参数为空的情况下，这个宏会错误返回 &lt;code&gt;1&lt;/code&gt;。如果需要处理空的变长参数，则需要用到我们前面说到的 &lt;code&gt;PP_ARGS_OPT&lt;/code&gt; 宏：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-33-1&#34; name=&#34;__codelineno-33-1&#34; href=&#34;#__codelineno-33-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_COMMA_IF_ARGS(...) PP_ARGS_OPT((,), (), __VA_ARGS__)&lt;/span&gt;
&lt;a id=&#34;__codelineno-33-2&#34; name=&#34;__codelineno-33-2&#34; href=&#34;#__codelineno-33-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_ARGS_SIZE(...) PP_ARGS_ELEM(8, __VA_ARGS__ PP_COMMA_IF_ARGS(__VA_ARGS__) 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0)&lt;/span&gt;
&lt;a id=&#34;__codelineno-33-3&#34; name=&#34;__codelineno-33-3&#34; href=&#34;#__codelineno-33-3&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-33-4&#34; name=&#34;__codelineno-33-4&#34; href=&#34;#__codelineno-33-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_ARGS_SIZE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-33-5&#34; name=&#34;__codelineno-33-5&#34; href=&#34;#__codelineno-33-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_ARGS_SIZE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 2&lt;/span&gt;
&lt;a id=&#34;__codelineno-33-6&#34; name=&#34;__codelineno-33-6&#34; href=&#34;#__codelineno-33-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_ARGS_SIZE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PP_COMMA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 2&lt;/span&gt;
&lt;a id=&#34;__codelineno-33-7&#34; name=&#34;__codelineno-33-7&#34; href=&#34;#__codelineno-33-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_ARGS_SIZE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-33-8&#34; name=&#34;__codelineno-33-8&#34; href=&#34;#__codelineno-33-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_ARGS_SIZE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(,,,)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;问题的关键就是逗号 &lt;code&gt;,&lt;/code&gt;，在 &lt;code&gt;__VA_ARGS__&lt;/code&gt; 为空的时候，把逗号隐去就能正确返回 &lt;code&gt;0&lt;/code&gt;。&lt;/p&gt;
&lt;h4 id=&#34;_23&#34;&gt;遍历访问&lt;/h4&gt;
&lt;p&gt;类似 C++ 的 &lt;code&gt;for_each&lt;/code&gt;，我们可以实现宏的 &lt;code&gt;PP_FOR_EACH&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-34-1&#34; name=&#34;__codelineno-34-1&#34; href=&#34;#__codelineno-34-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_FOR_EACH(macro, contex, ...) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-34-2&#34; name=&#34;__codelineno-34-2&#34; href=&#34;#__codelineno-34-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_CONCAT(PP_FOR_EACH_, PP_ARGS_SIZE(__VA_ARGS__))(0, macro, contex, __VA_ARGS__)&lt;/span&gt;
&lt;a id=&#34;__codelineno-34-3&#34; name=&#34;__codelineno-34-3&#34; href=&#34;#__codelineno-34-3&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-34-4&#34; name=&#34;__codelineno-34-4&#34; href=&#34;#__codelineno-34-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_FOR_EACH_0(index, macro, contex, ...)&lt;/span&gt;
&lt;a id=&#34;__codelineno-34-5&#34; name=&#34;__codelineno-34-5&#34; href=&#34;#__codelineno-34-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_FOR_EACH_1(index, macro, contex, arg, ...) macro(index, contex, arg)&lt;/span&gt;
&lt;a id=&#34;__codelineno-34-6&#34; name=&#34;__codelineno-34-6&#34; href=&#34;#__codelineno-34-6&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-34-7&#34; name=&#34;__codelineno-34-7&#34; href=&#34;#__codelineno-34-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_FOR_EACH_2(index, macro, contex, arg, ...) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-34-8&#34; name=&#34;__codelineno-34-8&#34; href=&#34;#__codelineno-34-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    macro(index, contex, arg) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-34-9&#34; name=&#34;__codelineno-34-9&#34; href=&#34;#__codelineno-34-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_FOR_EACH_1(PP_INC(index), macro, contex, __VA_ARGS__)&lt;/span&gt;
&lt;a id=&#34;__codelineno-34-10&#34; name=&#34;__codelineno-34-10&#34; href=&#34;#__codelineno-34-10&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-34-11&#34; name=&#34;__codelineno-34-11&#34; href=&#34;#__codelineno-34-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_FOR_EACH_3(index, macro, contex, arg, ...) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-34-12&#34; name=&#34;__codelineno-34-12&#34; href=&#34;#__codelineno-34-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    macro(index, contex, arg) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-34-13&#34; name=&#34;__codelineno-34-13&#34; href=&#34;#__codelineno-34-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_FOR_EACH_2(PP_INC(index), macro, contex, __VA_ARGS__)&lt;/span&gt;
&lt;a id=&#34;__codelineno-34-14&#34; name=&#34;__codelineno-34-14&#34; href=&#34;#__codelineno-34-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-34-15&#34; name=&#34;__codelineno-34-15&#34; href=&#34;#__codelineno-34-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_FOR_EACH_8(index, macro, contex, arg, ...) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-34-16&#34; name=&#34;__codelineno-34-16&#34; href=&#34;#__codelineno-34-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    macro(index, contex, arg) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-34-17&#34; name=&#34;__codelineno-34-17&#34; href=&#34;#__codelineno-34-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_FOR_EACH_7(PP_INC(index), macro, contex, __VA_ARGS__)&lt;/span&gt;
&lt;a id=&#34;__codelineno-34-18&#34; name=&#34;__codelineno-34-18&#34; href=&#34;#__codelineno-34-18&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-34-19&#34; name=&#34;__codelineno-34-19&#34; href=&#34;#__codelineno-34-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define DECLARE_EACH(index, contex, arg)    PP_IF(index, PP_COMMA, PP_EMPTY)() contex arg&lt;/span&gt;
&lt;a id=&#34;__codelineno-34-20&#34; name=&#34;__codelineno-34-20&#34; href=&#34;#__codelineno-34-20&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-34-21&#34; name=&#34;__codelineno-34-21&#34; href=&#34;#__codelineno-34-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_FOR_EACH&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DECLARE_EACH&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; int x, y, z;&lt;/span&gt;
&lt;a id=&#34;__codelineno-34-22&#34; name=&#34;__codelineno-34-22&#34; href=&#34;#__codelineno-34-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_FOR_EACH&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DECLARE_EACH&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; bool a, b;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;PP_FOR_EACH&lt;/code&gt; 接收两个固定参数： &lt;code&gt;macro&lt;/code&gt; 可以理解为遍历的时候调用的宏，&lt;code&gt;contex&lt;/code&gt; 可以作为固定值参数传给 &lt;code&gt;macro&lt;/code&gt;。&lt;code&gt;PP_FOR_EACH&lt;/code&gt; 先通过 &lt;code&gt;PP_ARGS_SIZE&lt;/code&gt; 获取变长参数的长度 &lt;code&gt;N&lt;/code&gt;，再用 &lt;code&gt;PP_CONCAT&lt;/code&gt; 拼接得到 &lt;code&gt;PP_FOR_EACH_N&lt;/code&gt;，之后 &lt;code&gt;PP_FOR_EACH_N&lt;/code&gt; 会迭代调用 &lt;code&gt;PP_FOR_EACH_N-1&lt;/code&gt; 来实现跟变长参数个数相同的遍历次数。&lt;/p&gt;
&lt;p&gt;例子里我们声明了 &lt;code&gt;DECLARE_EACH&lt;/code&gt; 作为参数 &lt;code&gt;macro&lt;/code&gt;，&lt;code&gt;DECLARE_EACH&lt;/code&gt; 的作用就是返回 &lt;code&gt;contex arg&lt;/code&gt;，如果 &lt;code&gt;contex&lt;/code&gt; 是类型名字，&lt;code&gt;arg&lt;/code&gt; 是变量名字，&lt;code&gt;DECLARE_EACH&lt;/code&gt; 就可以用来声明变量。&lt;/p&gt;
&lt;h4 id=&#34;_24&#34;&gt;条件循环&lt;/h4&gt;
&lt;p&gt;有了 &lt;code&gt;FOR_EACH&lt;/code&gt; 之后，我们还可以用类似的写法写出 &lt;code&gt;PP_WHILE&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-35-1&#34; name=&#34;__codelineno-35-1&#34; href=&#34;#__codelineno-35-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_WHILE PP_WHILE_1&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-2&#34; name=&#34;__codelineno-35-2&#34; href=&#34;#__codelineno-35-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-35-3&#34; name=&#34;__codelineno-35-3&#34; href=&#34;#__codelineno-35-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_WHILE_1(pred, op, val) PP_WHILE_1_IMPL(PP_BOOL(pred(val)), pred, op, val)&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-4&#34; name=&#34;__codelineno-35-4&#34; href=&#34;#__codelineno-35-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_WHILE_1_IMPL(cond, pred, op, val) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-5&#34; name=&#34;__codelineno-35-5&#34; href=&#34;#__codelineno-35-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_IF(cond, PP_WHILE_2, val PP_EMPTY_EAT)(pred, op, PP_IF(cond, op, PP_EMPTY_EAT)(val))&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-6&#34; name=&#34;__codelineno-35-6&#34; href=&#34;#__codelineno-35-6&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-35-7&#34; name=&#34;__codelineno-35-7&#34; href=&#34;#__codelineno-35-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_WHILE_2(pred, op, val) PP_WHILE_2_IMPL(PP_BOOL(pred(val)), pred, op, val)&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-8&#34; name=&#34;__codelineno-35-8&#34; href=&#34;#__codelineno-35-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_WHILE_2_IMPL(cond, pred, op, val) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-9&#34; name=&#34;__codelineno-35-9&#34; href=&#34;#__codelineno-35-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_IF(cond, PP_WHILE_3, val PP_EMPTY_EAT)(pred, op, PP_IF(cond, op, PP_EMPTY_EAT)(val))&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-10&#34; name=&#34;__codelineno-35-10&#34; href=&#34;#__codelineno-35-10&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-35-11&#34; name=&#34;__codelineno-35-11&#34; href=&#34;#__codelineno-35-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_WHILE_3(pred, op, val) PP_WHILE_3_IMPL(PP_BOOL(pred(val)), pred, op, val)&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-12&#34; name=&#34;__codelineno-35-12&#34; href=&#34;#__codelineno-35-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_WHILE_3_IMPL(cond, pred, op, val) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-13&#34; name=&#34;__codelineno-35-13&#34; href=&#34;#__codelineno-35-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_IF(cond, PP_WHILE_4, val PP_EMPTY_EAT)(pred, op, PP_IF(cond, op, PP_EMPTY_EAT)(val))&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-14&#34; name=&#34;__codelineno-35-14&#34; href=&#34;#__codelineno-35-14&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-35-15&#34; name=&#34;__codelineno-35-15&#34; href=&#34;#__codelineno-35-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_WHILE_4(pred, op, val) PP_WHILE_4_IMPL(PP_BOOL(pred(val)), pred, op, val)&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-16&#34; name=&#34;__codelineno-35-16&#34; href=&#34;#__codelineno-35-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_WHILE_4_IMPL(cond, pred, op, val) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-17&#34; name=&#34;__codelineno-35-17&#34; href=&#34;#__codelineno-35-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_IF(cond, PP_WHILE_5, val PP_EMPTY_EAT)(pred, op, PP_IF(cond, op, PP_EMPTY_EAT)(val))&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-18&#34; name=&#34;__codelineno-35-18&#34; href=&#34;#__codelineno-35-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-19&#34; name=&#34;__codelineno-35-19&#34; href=&#34;#__codelineno-35-19&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-35-20&#34; name=&#34;__codelineno-35-20&#34; href=&#34;#__codelineno-35-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_WHILE_8(pred, op, val) PP_WHILE_8_IMPL(PP_BOOL(pred(val)), pred, op, val)&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-21&#34; name=&#34;__codelineno-35-21&#34; href=&#34;#__codelineno-35-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_WHILE_8_IMPL(cond, pred, op, val) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-22&#34; name=&#34;__codelineno-35-22&#34; href=&#34;#__codelineno-35-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_IF(cond, PP_WHILE_8, val PP_EMPTY_EAT)(pred, op, PP_IF(cond, op, PP_EMPTY_EAT)(val))&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-23&#34; name=&#34;__codelineno-35-23&#34; href=&#34;#__codelineno-35-23&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-35-24&#34; name=&#34;__codelineno-35-24&#34; href=&#34;#__codelineno-35-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_EMPTY_EAT(...)&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-25&#34; name=&#34;__codelineno-35-25&#34; href=&#34;#__codelineno-35-25&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-35-26&#34; name=&#34;__codelineno-35-26&#34; href=&#34;#__codelineno-35-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define SUM_OP(xy_tuple) SUM_OP_OP_IMPL xy_tuple&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-27&#34; name=&#34;__codelineno-35-27&#34; href=&#34;#__codelineno-35-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define SUM_OP_OP_IMPL(x, y) (PP_DEC(x), y + x)&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-28&#34; name=&#34;__codelineno-35-28&#34; href=&#34;#__codelineno-35-28&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-35-29&#34; name=&#34;__codelineno-35-29&#34; href=&#34;#__codelineno-35-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define SUM_PRED(xy_tuple) SUM_PRED_IMPL xy_tuple&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-30&#34; name=&#34;__codelineno-35-30&#34; href=&#34;#__codelineno-35-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define SUM_PRED_IMPL(x, y) x&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-31&#34; name=&#34;__codelineno-35-31&#34; href=&#34;#__codelineno-35-31&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-35-32&#34; name=&#34;__codelineno-35-32&#34; href=&#34;#__codelineno-35-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define SUM(max_num, origin_num) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-33&#34; name=&#34;__codelineno-35-33&#34; href=&#34;#__codelineno-35-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_IDENTITY(SUM_IMPL PP_WHILE(SUM_PRED, SUM_OP, (max_num, origin_num)))&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-34&#34; name=&#34;__codelineno-35-34&#34; href=&#34;#__codelineno-35-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define SUM_IMPL(ignore, ret) ret&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-35&#34; name=&#34;__codelineno-35-35&#34; href=&#34;#__codelineno-35-35&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-35-36&#34; name=&#34;__codelineno-35-36&#34; href=&#34;#__codelineno-35-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_WHILE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SUM_PRED&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SUM_OP&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; (0, a + 2 + 1)&lt;/span&gt;
&lt;a id=&#34;__codelineno-35-37&#34; name=&#34;__codelineno-35-37&#34; href=&#34;#__codelineno-35-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;SUM&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                               &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; a + 2 + 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;PP_WHILE&lt;/code&gt; 接受三个参数： &lt;code&gt;pred&lt;/code&gt; 条件判断函数，&lt;code&gt;op&lt;/code&gt; 操作函数，&lt;code&gt;val&lt;/code&gt; 初始值；循环的过程中不断用 &lt;code&gt;pred(val)&lt;/code&gt; 来做循环终止判断，把 &lt;code&gt;op(val)&lt;/code&gt; 得到的值传给后续的宏，可以理解为执行以下代码：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-36-1&#34; name=&#34;__codelineno-36-1&#34; href=&#34;#__codelineno-36-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pred&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-36-2&#34; name=&#34;__codelineno-36-2&#34; href=&#34;#__codelineno-36-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;op&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-36-3&#34; name=&#34;__codelineno-36-3&#34; href=&#34;#__codelineno-36-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;PP_WHILE_N&lt;/code&gt; 首先用 &lt;code&gt;pred(val)&lt;/code&gt; 得到条件判断结果，把条件结果 &lt;code&gt;cond&lt;/code&gt; 和其余参数再传给 &lt;code&gt;PP_WHILE_N_IMPL&lt;/code&gt;。
&lt;code&gt;PP_WHILE_N_IMPL&lt;/code&gt; 可以分两部分看：后半部分 &lt;code&gt;(pred, op, PP_IF(cond, op, PP_EMPTY_EAT)(val))&lt;/code&gt; 是作为前半部分的参数，&lt;code&gt;PP_IF(cond, op, PP_EMPTY_EAT)(val)&lt;/code&gt; 是如果 &lt;code&gt;cond&lt;/code&gt; 为真，则求值 &lt;code&gt;op(val)&lt;/code&gt;， 否则求值 &lt;code&gt;PP_EMPTY_EAT(val)&lt;/code&gt; 得到空。前半部分 &lt;code&gt;PP_IF(cond, PP_WHILE_N+1, val PP_EMPTY_EAT)&lt;/code&gt;，如果 &lt;code&gt;cond&lt;/code&gt; 为真，则返回 &lt;code&gt;PP_WHILE_N+1&lt;/code&gt;，结合后半部分的参数继续执行循环；否则返回 &lt;code&gt;val PP_EMPTY_EAT&lt;/code&gt;，此时 &lt;code&gt;val&lt;/code&gt; 就是最终的计算结果，而 &lt;code&gt;PP_EMPTY_EAT&lt;/code&gt; 会吞掉后半部分的结果。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;SUM&lt;/code&gt; 实现 &lt;code&gt;N + N-1 + ... + 1&lt;/code&gt;。初始值 &lt;code&gt;(max_num, origin_num)&lt;/code&gt;；&lt;code&gt;SUM_PRED&lt;/code&gt; 取值的第一个元素 &lt;code&gt;x&lt;/code&gt;，判断是否大于 0；&lt;code&gt;SUM_OP&lt;/code&gt; 对 &lt;code&gt;x&lt;/code&gt; 执行递减操作 &lt;code&gt;x = x - 1&lt;/code&gt;，对 &lt;code&gt;y&lt;/code&gt; 执行 &lt;code&gt;+ x&lt;/code&gt; 操作 &lt;code&gt;y = y + x&lt;/code&gt;。直接用 &lt;code&gt;SUM_PRED&lt;/code&gt; 和 &lt;code&gt;SUM_OP&lt;/code&gt; 传给 &lt;code&gt;PP_WHILE&lt;/code&gt;，返回的结果是一个元组，我们真正想要的结果是元组的第 2 个元素，于是再用 &lt;code&gt;SUM&lt;/code&gt; 取第 2 个元素的值。&lt;/p&gt;
&lt;h4 id=&#34;_25&#34;&gt;递归重入&lt;/h4&gt;
&lt;p&gt;到目前为止，我们的遍历访问和条件循环都运作的很好，结果符合预期。还记得我们在讲宏展开规则的时候提到的禁止递归重入么，当我们想要执行两重循环的时候就不幸遇到到了禁止递归重入：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-37-1&#34; name=&#34;__codelineno-37-1&#34; href=&#34;#__codelineno-37-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define SUM_OP2(xy_tuple) SUM_OP_OP_IMPL2 xy_tuple&lt;/span&gt;
&lt;a id=&#34;__codelineno-37-2&#34; name=&#34;__codelineno-37-2&#34; href=&#34;#__codelineno-37-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define SUM_OP_OP_IMPL2(x, y) (PP_DEC(x), y + SUM(x, 0))&lt;/span&gt;
&lt;a id=&#34;__codelineno-37-3&#34; name=&#34;__codelineno-37-3&#34; href=&#34;#__codelineno-37-3&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-37-4&#34; name=&#34;__codelineno-37-4&#34; href=&#34;#__codelineno-37-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define SUM2(max_num, origin_num) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-37-5&#34; name=&#34;__codelineno-37-5&#34; href=&#34;#__codelineno-37-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_IDENTITY(SUM_IMPL PP_WHILE(SUM_PRED, SUM_OP2, (max_num, origin_num)))&lt;/span&gt;
&lt;a id=&#34;__codelineno-37-6&#34; name=&#34;__codelineno-37-6&#34; href=&#34;#__codelineno-37-6&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-37-7&#34; name=&#34;__codelineno-37-7&#34; href=&#34;#__codelineno-37-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;SUM2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; a + SUM_IMPL PP_WHILE_1(SUM_PRED, SUM_OP, (1, a))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;SUM2&lt;/code&gt; 把参数 &lt;code&gt;op&lt;/code&gt; 改用 &lt;code&gt;SUM_OP2&lt;/code&gt;，&lt;code&gt;SUM_OP2&lt;/code&gt; 里面会调用到 &lt;code&gt;SUM&lt;/code&gt;，而 &lt;code&gt;SUM&lt;/code&gt; 展开还会是 &lt;code&gt;PP_WHILE_1&lt;/code&gt;，相当于 &lt;code&gt;PP_WHILE_1&lt;/code&gt; 递归调用到了自身，预处理器停止展开。&lt;/p&gt;
&lt;p&gt;为了解决这个问题，我们可以用一种自动推导递归的方法（Automatic Recursion）：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-38-1&#34; name=&#34;__codelineno-38-1&#34; href=&#34;#__codelineno-38-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_AUTO_WHILE PP_CONCAT(PP_WHILE_, PP_AUTO_REC(PP_WHILE_PRED))&lt;/span&gt;
&lt;a id=&#34;__codelineno-38-2&#34; name=&#34;__codelineno-38-2&#34; href=&#34;#__codelineno-38-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-38-3&#34; name=&#34;__codelineno-38-3&#34; href=&#34;#__codelineno-38-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_AUTO_REC(check) PP_IF(check(2), PP_AUTO_REC_12, PP_AUTO_REC_34)(check)&lt;/span&gt;
&lt;a id=&#34;__codelineno-38-4&#34; name=&#34;__codelineno-38-4&#34; href=&#34;#__codelineno-38-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_AUTO_REC_12(check) PP_IF(check(1), 1, 2)&lt;/span&gt;
&lt;a id=&#34;__codelineno-38-5&#34; name=&#34;__codelineno-38-5&#34; href=&#34;#__codelineno-38-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_AUTO_REC_34(check) PP_IF(check(3), 3, 4)&lt;/span&gt;
&lt;a id=&#34;__codelineno-38-6&#34; name=&#34;__codelineno-38-6&#34; href=&#34;#__codelineno-38-6&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-38-7&#34; name=&#34;__codelineno-38-7&#34; href=&#34;#__codelineno-38-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_WHILE_PRED(n) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-38-8&#34; name=&#34;__codelineno-38-8&#34; href=&#34;#__codelineno-38-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_CONCAT(PP_WHILE_CHECK_, PP_WHILE_ ## n(PP_WHILE_FALSE, PP_WHILE_FALSE, PP_WHILE_FALSE))&lt;/span&gt;
&lt;a id=&#34;__codelineno-38-9&#34; name=&#34;__codelineno-38-9&#34; href=&#34;#__codelineno-38-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_WHILE_FALSE(...) 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-38-10&#34; name=&#34;__codelineno-38-10&#34; href=&#34;#__codelineno-38-10&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-38-11&#34; name=&#34;__codelineno-38-11&#34; href=&#34;#__codelineno-38-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_WHILE_CHECK_PP_WHILE_FALSE 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-38-12&#34; name=&#34;__codelineno-38-12&#34; href=&#34;#__codelineno-38-12&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-38-13&#34; name=&#34;__codelineno-38-13&#34; href=&#34;#__codelineno-38-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_WHILE_CHECK_PP_WHILE_1(...) 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-38-14&#34; name=&#34;__codelineno-38-14&#34; href=&#34;#__codelineno-38-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_WHILE_CHECK_PP_WHILE_2(...) 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-38-15&#34; name=&#34;__codelineno-38-15&#34; href=&#34;#__codelineno-38-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_WHILE_CHECK_PP_WHILE_3(...) 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-38-16&#34; name=&#34;__codelineno-38-16&#34; href=&#34;#__codelineno-38-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_WHILE_CHECK_PP_WHILE_4(...) 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-38-17&#34; name=&#34;__codelineno-38-17&#34; href=&#34;#__codelineno-38-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-38-18&#34; name=&#34;__codelineno-38-18&#34; href=&#34;#__codelineno-38-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_WHILE_CHECK_PP_WHILE_8(...) 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-38-19&#34; name=&#34;__codelineno-38-19&#34; href=&#34;#__codelineno-38-19&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-38-20&#34; name=&#34;__codelineno-38-20&#34; href=&#34;#__codelineno-38-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_AUTO_WHILE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; PP_WHILE_1&lt;/span&gt;
&lt;a id=&#34;__codelineno-38-21&#34; name=&#34;__codelineno-38-21&#34; href=&#34;#__codelineno-38-21&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-38-22&#34; name=&#34;__codelineno-38-22&#34; href=&#34;#__codelineno-38-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define SUM3(max_num, origin_num) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-38-23&#34; name=&#34;__codelineno-38-23&#34; href=&#34;#__codelineno-38-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_IDENTITY(SUM_IMPL PP_AUTO_WHILE(SUM_PRED, SUM_OP, (max_num, origin_num)))&lt;/span&gt;
&lt;a id=&#34;__codelineno-38-24&#34; name=&#34;__codelineno-38-24&#34; href=&#34;#__codelineno-38-24&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-38-25&#34; name=&#34;__codelineno-38-25&#34; href=&#34;#__codelineno-38-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define SUM_OP4(xy_tuple) SUM_OP_OP_IMPL4 xy_tuple&lt;/span&gt;
&lt;a id=&#34;__codelineno-38-26&#34; name=&#34;__codelineno-38-26&#34; href=&#34;#__codelineno-38-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define SUM_OP_OP_IMPL4(x, y) (PP_DEC(x), y + SUM3(x, 0))&lt;/span&gt;
&lt;a id=&#34;__codelineno-38-27&#34; name=&#34;__codelineno-38-27&#34; href=&#34;#__codelineno-38-27&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-38-28&#34; name=&#34;__codelineno-38-28&#34; href=&#34;#__codelineno-38-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define SUM4(max_num, origin_num) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-38-29&#34; name=&#34;__codelineno-38-29&#34; href=&#34;#__codelineno-38-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_IDENTITY(SUM_IMPL PP_AUTO_WHILE(SUM_PRED, SUM_OP4, (max_num, origin_num)))&lt;/span&gt;
&lt;a id=&#34;__codelineno-38-30&#34; name=&#34;__codelineno-38-30&#34; href=&#34;#__codelineno-38-30&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-38-31&#34; name=&#34;__codelineno-38-31&#34; href=&#34;#__codelineno-38-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;SUM4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; a + 0 + 2 + 1 + 0 + 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;PP_AUTO_WHILE&lt;/code&gt; 就是 &lt;code&gt;PP_WHILE&lt;/code&gt; 的自动推导递归版本，核心的宏是 &lt;code&gt;PP_AUTO_REC(PP_WHILE_PRED)&lt;/code&gt;，这个宏可以找出当前可用的 &lt;code&gt;PP_WHILE_N&lt;/code&gt; 版本的数字 &lt;code&gt;N&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;推导的原理很简单，就是搜索所有版本，找出能够正确展开的版本，返回该版本的数字，为了提升搜索的速度，一般的做法是使用二分查找，这就是 &lt;code&gt;PP_AUTO_REC&lt;/code&gt; 在做的事情。&lt;code&gt;PP_AUTO_REC&lt;/code&gt; 接受一个参数 &lt;code&gt;check&lt;/code&gt;，&lt;code&gt;check&lt;/code&gt; 负责检查版本可用性，这里给出的是支持搜索版本范围 &lt;code&gt;[1, 4]&lt;/code&gt;。&lt;code&gt;PP_AUTO_REC&lt;/code&gt; 会首先检查 &lt;code&gt;check(2)&lt;/code&gt;，如果 &lt;code&gt;check(2)&lt;/code&gt; 为真，则调用 &lt;code&gt;PP_AUTO_REC_12&lt;/code&gt; 搜索范围 &lt;code&gt;[1, 2]&lt;/code&gt;，否则用 &lt;code&gt;PP_AUTO_REC_34&lt;/code&gt; 搜索 &lt;code&gt;[3, 4]&lt;/code&gt;。&lt;code&gt;PP_AUTO_REC_12&lt;/code&gt; 检查 &lt;code&gt;check(1)&lt;/code&gt; 如果为真，说明版本 &lt;code&gt;1&lt;/code&gt; 可用，否则用版本 &lt;code&gt;2&lt;/code&gt;，&lt;code&gt;PP_AUTO_REC_34&lt;/code&gt; 同理。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;check&lt;/code&gt; 宏要怎么写才能知道版本是否可用呢？在这里，&lt;code&gt;PP_WHILE_PRED&lt;/code&gt; 会展开成两部分的拼接，我们来看后部分 &lt;code&gt;PP_WHILE_ ## n(PP_WHILE_FALSE, PP_WHILE_FALSE, PP_WHILE_FALSE)&lt;/code&gt;：如果 &lt;code&gt;PP_WHILE_ ## n&lt;/code&gt; 可用，由于 &lt;code&gt;PP_WHILE_FALSE&lt;/code&gt; 固定返回 &lt;code&gt;0&lt;/code&gt;，这部分会展开得到 &lt;code&gt;val&lt;/code&gt; 参数的值，也就是 &lt;code&gt;PP_WHILE_FALSE&lt;/code&gt;；否则这部分宏会保持不变，依然是 &lt;code&gt;PP_WHILE_n(PP_WHILE_FALSE, PP_WHILE_FALSE, PP_WHILE_FALSE)&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;把后部分的结果跟前部分 &lt;code&gt;PP_WHILE_CHECK_&lt;/code&gt; 拼接起来，得到两种结果：&lt;code&gt;PP_WHILE_CHECK_PP_WHILE_FALSE&lt;/code&gt; 或者 &lt;code&gt;PP_WHILE_CHECK_PP_WHILE_n(PP_WHILE_FALSE, PP_WHILE_FALSE, PP_WHILE_FALSE)&lt;/code&gt;，于是我们让 &lt;code&gt;PP_WHILE_CHECK_PP_WHILE_FALSE&lt;/code&gt; 返回 &lt;code&gt;1&lt;/code&gt; 表明可用，&lt;code&gt;PP_WHILE_CHECK_PP_WHILE_n&lt;/code&gt; 返回 &lt;code&gt;0&lt;/code&gt; 表示不可用。至此，我们完成了自动推导递归的功能。&lt;/p&gt;
&lt;h4 id=&#34;_26&#34;&gt;算术比较&lt;/h4&gt;
&lt;p&gt;不相等：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-39-1&#34; name=&#34;__codelineno-39-1&#34; href=&#34;#__codelineno-39-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_NOT_EQUAL(x, y) PP_NOT_EQUAL_IMPL(x, y)&lt;/span&gt;
&lt;a id=&#34;__codelineno-39-2&#34; name=&#34;__codelineno-39-2&#34; href=&#34;#__codelineno-39-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_NOT_EQUAL_IMPL(x, y) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-39-3&#34; name=&#34;__codelineno-39-3&#34; href=&#34;#__codelineno-39-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_CONCAT(PP_NOT_EQUAL_CHECK_, PP_NOT_EQUAL_ ## x(0, PP_NOT_EQUAL_ ## y))&lt;/span&gt;
&lt;a id=&#34;__codelineno-39-4&#34; name=&#34;__codelineno-39-4&#34; href=&#34;#__codelineno-39-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-39-5&#34; name=&#34;__codelineno-39-5&#34; href=&#34;#__codelineno-39-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_NOT_EQUAL_CHECK_PP_EQUAL_NIL 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-39-6&#34; name=&#34;__codelineno-39-6&#34; href=&#34;#__codelineno-39-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_NOT_EQUAL_CHECK_PP_NOT_EQUAL_0(...) 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-39-7&#34; name=&#34;__codelineno-39-7&#34; href=&#34;#__codelineno-39-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_NOT_EQUAL_CHECK_PP_NOT_EQUAL_1(...) 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-39-8&#34; name=&#34;__codelineno-39-8&#34; href=&#34;#__codelineno-39-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_NOT_EQUAL_CHECK_PP_NOT_EQUAL_2(...) 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-39-9&#34; name=&#34;__codelineno-39-9&#34; href=&#34;#__codelineno-39-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_NOT_EQUAL_CHECK_PP_NOT_EQUAL_3(...) 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-39-10&#34; name=&#34;__codelineno-39-10&#34; href=&#34;#__codelineno-39-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_NOT_EQUAL_CHECK_PP_NOT_EQUAL_4(...) 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-39-11&#34; name=&#34;__codelineno-39-11&#34; href=&#34;#__codelineno-39-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-39-12&#34; name=&#34;__codelineno-39-12&#34; href=&#34;#__codelineno-39-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_NOT_EQUAL_CHECK_PP_NOT_EQUAL_8(...) 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-39-13&#34; name=&#34;__codelineno-39-13&#34; href=&#34;#__codelineno-39-13&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-39-14&#34; name=&#34;__codelineno-39-14&#34; href=&#34;#__codelineno-39-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_NOT_EQUAL_0(cond, y) PP_IF(cond, PP_EQUAL_NIL, y(1, PP_EQUAL_NIL))&lt;/span&gt;
&lt;a id=&#34;__codelineno-39-15&#34; name=&#34;__codelineno-39-15&#34; href=&#34;#__codelineno-39-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_NOT_EQUAL_1(cond, y) PP_IF(cond, PP_EQUAL_NIL, y(1, PP_EQUAL_NIL))&lt;/span&gt;
&lt;a id=&#34;__codelineno-39-16&#34; name=&#34;__codelineno-39-16&#34; href=&#34;#__codelineno-39-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_NOT_EQUAL_2(cond, y) PP_IF(cond, PP_EQUAL_NIL, y(1, PP_EQUAL_NIL))&lt;/span&gt;
&lt;a id=&#34;__codelineno-39-17&#34; name=&#34;__codelineno-39-17&#34; href=&#34;#__codelineno-39-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_NOT_EQUAL_3(cond, y) PP_IF(cond, PP_EQUAL_NIL, y(1, PP_EQUAL_NIL))&lt;/span&gt;
&lt;a id=&#34;__codelineno-39-18&#34; name=&#34;__codelineno-39-18&#34; href=&#34;#__codelineno-39-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_NOT_EQUAL_4(cond, y) PP_IF(cond, PP_EQUAL_NIL, y(1, PP_EQUAL_NIL))&lt;/span&gt;
&lt;a id=&#34;__codelineno-39-19&#34; name=&#34;__codelineno-39-19&#34; href=&#34;#__codelineno-39-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-39-20&#34; name=&#34;__codelineno-39-20&#34; href=&#34;#__codelineno-39-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_NOT_EQUAL_8(cond, y) PP_IF(cond, PP_EQUAL_NIL, y(1, PP_EQUAL_NIL))&lt;/span&gt;
&lt;a id=&#34;__codelineno-39-21&#34; name=&#34;__codelineno-39-21&#34; href=&#34;#__codelineno-39-21&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-39-22&#34; name=&#34;__codelineno-39-22&#34; href=&#34;#__codelineno-39-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_NOT_EQUAL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-39-23&#34; name=&#34;__codelineno-39-23&#34; href=&#34;#__codelineno-39-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_NOT_EQUAL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;判断数值是否相等，用到了禁止递归重入的特性，把 &lt;code&gt;x&lt;/code&gt; 和 &lt;code&gt;y&lt;/code&gt; 递归拼接成 &lt;code&gt;PP_NOT_EQUAL_x PP_NOT_EQUAL_y&lt;/code&gt; 宏，如果 &lt;code&gt;x == y&lt;/code&gt;，则不会展开 &lt;code&gt;PP_NOT_EQUAL_y&lt;/code&gt; 宏，跟 &lt;code&gt;PP_NOT_EQUAL_CHECK_&lt;/code&gt; 拼接成 &lt;code&gt;PP_NOT_EQUAL_CHECK_PP_NOT_EQUAL_y&lt;/code&gt; 返回 &lt;code&gt;0&lt;/code&gt;；反之，两次都成功展开最后得到 &lt;code&gt;PP_EQUAL_NIL&lt;/code&gt;，拼接得到 &lt;code&gt;PP_NOT_EQUAL_CHECK_PP_EQUAL_NIL&lt;/code&gt; 返回 &lt;code&gt;1&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;相等：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-40-1&#34; name=&#34;__codelineno-40-1&#34; href=&#34;#__codelineno-40-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_EQUAL(x, y) PP_NOT(PP_NOT_EQUAL(x, y))&lt;/span&gt;
&lt;a id=&#34;__codelineno-40-2&#34; name=&#34;__codelineno-40-2&#34; href=&#34;#__codelineno-40-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-40-3&#34; name=&#34;__codelineno-40-3&#34; href=&#34;#__codelineno-40-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_EQUAL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-40-4&#34; name=&#34;__codelineno-40-4&#34; href=&#34;#__codelineno-40-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_EQUAL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;小于等于：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-41-1&#34; name=&#34;__codelineno-41-1&#34; href=&#34;#__codelineno-41-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_LESS_EQUAL(x, y) PP_NOT(PP_SUB(x, y))&lt;/span&gt;
&lt;a id=&#34;__codelineno-41-2&#34; name=&#34;__codelineno-41-2&#34; href=&#34;#__codelineno-41-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-41-3&#34; name=&#34;__codelineno-41-3&#34; href=&#34;#__codelineno-41-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_LESS_EQUAL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-41-4&#34; name=&#34;__codelineno-41-4&#34; href=&#34;#__codelineno-41-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_LESS_EQUAL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-41-5&#34; name=&#34;__codelineno-41-5&#34; href=&#34;#__codelineno-41-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_LESS_EQUAL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;小于：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-42-1&#34; name=&#34;__codelineno-42-1&#34; href=&#34;#__codelineno-42-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_LESS(x, y) PP_AND(PP_LESS_EQUAL(x, y), PP_NOT_EQUAL(x, y))&lt;/span&gt;
&lt;a id=&#34;__codelineno-42-2&#34; name=&#34;__codelineno-42-2&#34; href=&#34;#__codelineno-42-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-42-3&#34; name=&#34;__codelineno-42-3&#34; href=&#34;#__codelineno-42-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_LESS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;               &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-42-4&#34; name=&#34;__codelineno-42-4&#34; href=&#34;#__codelineno-42-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_LESS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;               &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-42-5&#34; name=&#34;__codelineno-42-5&#34; href=&#34;#__codelineno-42-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_LESS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;               &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;另外还有大于，大于等于等等算术比较，这里不再赘述。&lt;/p&gt;
&lt;h4 id=&#34;_27&#34;&gt;算术运算&lt;/h4&gt;
&lt;p&gt;利用 &lt;code&gt;PP_AUTO_WHILE&lt;/code&gt; 我们可以实现基础的算术运算了，而且支持嵌套运算。&lt;/p&gt;
&lt;p&gt;加法：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-43-1&#34; name=&#34;__codelineno-43-1&#34; href=&#34;#__codelineno-43-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_ADD(x, y) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-43-2&#34; name=&#34;__codelineno-43-2&#34; href=&#34;#__codelineno-43-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_IDENTITY(PP_ADD_IMPL PP_AUTO_WHILE(PP_ADD_PRED, PP_ADD_OP, (x, y)))&lt;/span&gt;
&lt;a id=&#34;__codelineno-43-3&#34; name=&#34;__codelineno-43-3&#34; href=&#34;#__codelineno-43-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_ADD_IMPL(x, y) x&lt;/span&gt;
&lt;a id=&#34;__codelineno-43-4&#34; name=&#34;__codelineno-43-4&#34; href=&#34;#__codelineno-43-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-43-5&#34; name=&#34;__codelineno-43-5&#34; href=&#34;#__codelineno-43-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_ADD_PRED(xy_tuple) PP_ADD_PRED_IMPL xy_tuple&lt;/span&gt;
&lt;a id=&#34;__codelineno-43-6&#34; name=&#34;__codelineno-43-6&#34; href=&#34;#__codelineno-43-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_ADD_PRED_IMPL(x, y) y&lt;/span&gt;
&lt;a id=&#34;__codelineno-43-7&#34; name=&#34;__codelineno-43-7&#34; href=&#34;#__codelineno-43-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-43-8&#34; name=&#34;__codelineno-43-8&#34; href=&#34;#__codelineno-43-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_ADD_OP(xy_tuple) PP_ADD_OP_IMPL xy_tuple&lt;/span&gt;
&lt;a id=&#34;__codelineno-43-9&#34; name=&#34;__codelineno-43-9&#34; href=&#34;#__codelineno-43-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_ADD_OP_IMPL(x, y) (PP_INC(x), PP_DEC(y))&lt;/span&gt;
&lt;a id=&#34;__codelineno-43-10&#34; name=&#34;__codelineno-43-10&#34; href=&#34;#__codelineno-43-10&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-43-11&#34; name=&#34;__codelineno-43-11&#34; href=&#34;#__codelineno-43-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_ADD&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 3&lt;/span&gt;
&lt;a id=&#34;__codelineno-43-12&#34; name=&#34;__codelineno-43-12&#34; href=&#34;#__codelineno-43-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_ADD&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PP_ADD&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;减法：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-44-1&#34; name=&#34;__codelineno-44-1&#34; href=&#34;#__codelineno-44-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_SUB(x, y) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-44-2&#34; name=&#34;__codelineno-44-2&#34; href=&#34;#__codelineno-44-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_IDENTITY(PP_SUB_IMPL PP_AUTO_WHILE(PP_SUB_PRED, PP_SUB_OP, (x, y)))&lt;/span&gt;
&lt;a id=&#34;__codelineno-44-3&#34; name=&#34;__codelineno-44-3&#34; href=&#34;#__codelineno-44-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_SUB_IMPL(x, y) x&lt;/span&gt;
&lt;a id=&#34;__codelineno-44-4&#34; name=&#34;__codelineno-44-4&#34; href=&#34;#__codelineno-44-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-44-5&#34; name=&#34;__codelineno-44-5&#34; href=&#34;#__codelineno-44-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_SUB_PRED(xy_tuple) PP_SUB_PRED_IMPL xy_tuple&lt;/span&gt;
&lt;a id=&#34;__codelineno-44-6&#34; name=&#34;__codelineno-44-6&#34; href=&#34;#__codelineno-44-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_SUB_PRED_IMPL(x, y) y&lt;/span&gt;
&lt;a id=&#34;__codelineno-44-7&#34; name=&#34;__codelineno-44-7&#34; href=&#34;#__codelineno-44-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-44-8&#34; name=&#34;__codelineno-44-8&#34; href=&#34;#__codelineno-44-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_SUB_OP(xy_tuple) PP_SUB_OP_IMPL xy_tuple&lt;/span&gt;
&lt;a id=&#34;__codelineno-44-9&#34; name=&#34;__codelineno-44-9&#34; href=&#34;#__codelineno-44-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_SUB_OP_IMPL(x, y) (PP_DEC(x), PP_DEC(y))&lt;/span&gt;
&lt;a id=&#34;__codelineno-44-10&#34; name=&#34;__codelineno-44-10&#34; href=&#34;#__codelineno-44-10&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-44-11&#34; name=&#34;__codelineno-44-11&#34; href=&#34;#__codelineno-44-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_SUB&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-44-12&#34; name=&#34;__codelineno-44-12&#34; href=&#34;#__codelineno-44-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_SUB&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PP_ADD&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;乘法：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-45-1&#34; name=&#34;__codelineno-45-1&#34; href=&#34;#__codelineno-45-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_MUL(x, y) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-45-2&#34; name=&#34;__codelineno-45-2&#34; href=&#34;#__codelineno-45-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    IDENTITY(PP_MUL_IMPL PP_AUTO_WHILE(PP_MUL_PRED, PP_MUL_OP, (0, x, y)))&lt;/span&gt;
&lt;a id=&#34;__codelineno-45-3&#34; name=&#34;__codelineno-45-3&#34; href=&#34;#__codelineno-45-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_MUL_IMPL(ret, x, y) ret&lt;/span&gt;
&lt;a id=&#34;__codelineno-45-4&#34; name=&#34;__codelineno-45-4&#34; href=&#34;#__codelineno-45-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-45-5&#34; name=&#34;__codelineno-45-5&#34; href=&#34;#__codelineno-45-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_MUL_PRED(rxy_tuple) PP_MUL_PRED_IMPL rxy_tuple&lt;/span&gt;
&lt;a id=&#34;__codelineno-45-6&#34; name=&#34;__codelineno-45-6&#34; href=&#34;#__codelineno-45-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_MUL_PRED_IMPL(ret, x, y) y&lt;/span&gt;
&lt;a id=&#34;__codelineno-45-7&#34; name=&#34;__codelineno-45-7&#34; href=&#34;#__codelineno-45-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-45-8&#34; name=&#34;__codelineno-45-8&#34; href=&#34;#__codelineno-45-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_MUL_OP(rxy_tuple) PP_MUL_OP_IMPL rxy_tuple&lt;/span&gt;
&lt;a id=&#34;__codelineno-45-9&#34; name=&#34;__codelineno-45-9&#34; href=&#34;#__codelineno-45-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_MUL_OP_IMPL(ret, x, y) (PP_ADD(ret, x), x, PP_DEC(y))&lt;/span&gt;
&lt;a id=&#34;__codelineno-45-10&#34; name=&#34;__codelineno-45-10&#34; href=&#34;#__codelineno-45-10&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-45-11&#34; name=&#34;__codelineno-45-11&#34; href=&#34;#__codelineno-45-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_MUL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-45-12&#34; name=&#34;__codelineno-45-12&#34; href=&#34;#__codelineno-45-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_MUL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PP_ADD&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;乘法实现这里增加了一个参数 &lt;code&gt;ret&lt;/code&gt;，初始值为 &lt;code&gt;0&lt;/code&gt;，每次迭代会执行 &lt;code&gt;ret = ret + x&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;除法：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-46-1&#34; name=&#34;__codelineno-46-1&#34; href=&#34;#__codelineno-46-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_DIV(x, y) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-46-2&#34; name=&#34;__codelineno-46-2&#34; href=&#34;#__codelineno-46-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    IDENTITY(PP_DIV_IMPL PP_AUTO_WHILE(PP_DIV_PRED, PP_DIV_OP, (0, x, y)))&lt;/span&gt;
&lt;a id=&#34;__codelineno-46-3&#34; name=&#34;__codelineno-46-3&#34; href=&#34;#__codelineno-46-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_DIV_IMPL(ret, x, y) ret&lt;/span&gt;
&lt;a id=&#34;__codelineno-46-4&#34; name=&#34;__codelineno-46-4&#34; href=&#34;#__codelineno-46-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-46-5&#34; name=&#34;__codelineno-46-5&#34; href=&#34;#__codelineno-46-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_DIV_PRED(rxy_tuple) PP_DIV_PRED_IMPL rxy_tuple&lt;/span&gt;
&lt;a id=&#34;__codelineno-46-6&#34; name=&#34;__codelineno-46-6&#34; href=&#34;#__codelineno-46-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_DIV_PRED_IMPL(ret, x, y) PP_LESS_EQUAL(y, x)&lt;/span&gt;
&lt;a id=&#34;__codelineno-46-7&#34; name=&#34;__codelineno-46-7&#34; href=&#34;#__codelineno-46-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-46-8&#34; name=&#34;__codelineno-46-8&#34; href=&#34;#__codelineno-46-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_DIV_OP(rxy_tuple) PP_DIV_OP_IMPL rxy_tuple&lt;/span&gt;
&lt;a id=&#34;__codelineno-46-9&#34; name=&#34;__codelineno-46-9&#34; href=&#34;#__codelineno-46-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_DIV_OP_IMPL(ret, x, y) (PP_INC(ret), PP_SUB(x, y), y)&lt;/span&gt;
&lt;a id=&#34;__codelineno-46-10&#34; name=&#34;__codelineno-46-10&#34; href=&#34;#__codelineno-46-10&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-46-11&#34; name=&#34;__codelineno-46-11&#34; href=&#34;#__codelineno-46-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_DIV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-46-12&#34; name=&#34;__codelineno-46-12&#34; href=&#34;#__codelineno-46-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_DIV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 2&lt;/span&gt;
&lt;a id=&#34;__codelineno-46-13&#34; name=&#34;__codelineno-46-13&#34; href=&#34;#__codelineno-46-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_DIV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PP_ADD&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;除法利用了 &lt;code&gt;PP_LESS_EQUAL&lt;/code&gt;，只有 &lt;code&gt;y &amp;lt;= x&lt;/code&gt; 的情况下才继续循环。&lt;/p&gt;
&lt;h4 id=&#34;_28&#34;&gt;数据结构&lt;/h4&gt;
&lt;p&gt;宏也可以有数据结构，其实我们在前面的也稍微用到了一种数据结构 &lt;code&gt;tuple&lt;/code&gt;，&lt;code&gt;PP_REMOVE_PARENS&lt;/code&gt; 就是可以去掉 &lt;code&gt;tuple&lt;/code&gt; 的外层括号，返回里面的元素。我们这里就以 &lt;code&gt;tuple&lt;/code&gt; 为例子讨论相关的实现，其他的数据结构 &lt;code&gt;list, array&lt;/code&gt; 等有兴趣可以去看 &lt;code&gt;Boost&lt;/code&gt; 的实现。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;tuple&lt;/code&gt; 定义为用括号包住的逗号分开的元素集合：&lt;code&gt;(a, b, c)&lt;/code&gt;。&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-47-1&#34; name=&#34;__codelineno-47-1&#34; href=&#34;#__codelineno-47-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_TUPLE_REMOVE_PARENS(tuple) PP_REMOVE_PARENS(tuple)&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-2&#34; name=&#34;__codelineno-47-2&#34; href=&#34;#__codelineno-47-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-47-3&#34; name=&#34;__codelineno-47-3&#34; href=&#34;#__codelineno-47-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// 获取指定下标的元素&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-4&#34; name=&#34;__codelineno-47-4&#34; href=&#34;#__codelineno-47-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_TUPLE_ELEM(i, tuple) PP_ARGS_ELEM(i, PP_TUPLE_REMOVE_PARENS(tuple))&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-5&#34; name=&#34;__codelineno-47-5&#34; href=&#34;#__codelineno-47-5&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-47-6&#34; name=&#34;__codelineno-47-6&#34; href=&#34;#__codelineno-47-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// 吞掉整个 tuple 返回空&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-7&#34; name=&#34;__codelineno-47-7&#34; href=&#34;#__codelineno-47-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_TUPLE_EAT() PP_EMPTY_EAT&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-8&#34; name=&#34;__codelineno-47-8&#34; href=&#34;#__codelineno-47-8&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-47-9&#34; name=&#34;__codelineno-47-9&#34; href=&#34;#__codelineno-47-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// 获取大小&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-10&#34; name=&#34;__codelineno-47-10&#34; href=&#34;#__codelineno-47-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_TUPLE_SIZE(tuple) PP_ARGS_SIZE(PP_TUPLE_REMOVE_PARENS(tuple))&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-11&#34; name=&#34;__codelineno-47-11&#34; href=&#34;#__codelineno-47-11&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-47-12&#34; name=&#34;__codelineno-47-12&#34; href=&#34;#__codelineno-47-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// 添加元素&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-13&#34; name=&#34;__codelineno-47-13&#34; href=&#34;#__codelineno-47-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_TUPLE_PUSH_BACK(elem, tuple) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-14&#34; name=&#34;__codelineno-47-14&#34; href=&#34;#__codelineno-47-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_TUPLE_PUSH_BACK_IMPL(PP_TUPLE_SIZE(tuple), elem, tuple)&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-15&#34; name=&#34;__codelineno-47-15&#34; href=&#34;#__codelineno-47-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_TUPLE_PUSH_BACK_IMPL(size, elem, tuple) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-16&#34; name=&#34;__codelineno-47-16&#34; href=&#34;#__codelineno-47-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    (PP_TUPLE_REMOVE_PARENS(tuple) PP_IF(size, PP_COMMA, PP_EMPTY)() elem)&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-17&#34; name=&#34;__codelineno-47-17&#34; href=&#34;#__codelineno-47-17&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-47-18&#34; name=&#34;__codelineno-47-18&#34; href=&#34;#__codelineno-47-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// 插入元素&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-19&#34; name=&#34;__codelineno-47-19&#34; href=&#34;#__codelineno-47-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_TUPLE_INSERT(i, elem, tuple) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-20&#34; name=&#34;__codelineno-47-20&#34; href=&#34;#__codelineno-47-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_TUPLE_ELEM( \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-21&#34; name=&#34;__codelineno-47-21&#34; href=&#34;#__codelineno-47-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        3, \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-22&#34; name=&#34;__codelineno-47-22&#34; href=&#34;#__codelineno-47-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        PP_AUTO_WHILE( \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-23&#34; name=&#34;__codelineno-47-23&#34; href=&#34;#__codelineno-47-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;            PP_TUPLE_INSERT_PRED, \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-24&#34; name=&#34;__codelineno-47-24&#34; href=&#34;#__codelineno-47-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;            PP_TUPLE_INSERT_OP, \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-25&#34; name=&#34;__codelineno-47-25&#34; href=&#34;#__codelineno-47-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;            (0, i, elem, (), tuple) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-26&#34; name=&#34;__codelineno-47-26&#34; href=&#34;#__codelineno-47-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        ) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-27&#34; name=&#34;__codelineno-47-27&#34; href=&#34;#__codelineno-47-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    )&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-28&#34; name=&#34;__codelineno-47-28&#34; href=&#34;#__codelineno-47-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_TUPLE_INSERT_PRED(args) PP_TUPLE_INSERT_PERD_IMPL args&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-29&#34; name=&#34;__codelineno-47-29&#34; href=&#34;#__codelineno-47-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_TUPLE_INSERT_PERD_IMPL(curi, i, elem, ret, tuple) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-30&#34; name=&#34;__codelineno-47-30&#34; href=&#34;#__codelineno-47-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_NOT_EQUAL(PP_TUPLE_SIZE(ret), PP_INC(PP_TUPLE_SIZE(tuple)))&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-31&#34; name=&#34;__codelineno-47-31&#34; href=&#34;#__codelineno-47-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_TUPLE_INSERT_OP(args) PP_TUPLE_INSERT_OP_IMPL args&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-32&#34; name=&#34;__codelineno-47-32&#34; href=&#34;#__codelineno-47-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_TUPLE_INSERT_OP_IMPL(curi, i, elem, ret, tuple) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-33&#34; name=&#34;__codelineno-47-33&#34; href=&#34;#__codelineno-47-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    ( \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-34&#34; name=&#34;__codelineno-47-34&#34; href=&#34;#__codelineno-47-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_IF(PP_NOT_EQUAL(PP_TUPLE_SIZE(ret), i), PP_INC(curi), curi), \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-35&#34; name=&#34;__codelineno-47-35&#34; href=&#34;#__codelineno-47-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    i, elem, \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-36&#34; name=&#34;__codelineno-47-36&#34; href=&#34;#__codelineno-47-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_TUPLE_PUSH_BACK(\&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-37&#34; name=&#34;__codelineno-47-37&#34; href=&#34;#__codelineno-47-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        PP_IF( \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-38&#34; name=&#34;__codelineno-47-38&#34; href=&#34;#__codelineno-47-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;            PP_NOT_EQUAL(PP_TUPLE_SIZE(ret), i), \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-39&#34; name=&#34;__codelineno-47-39&#34; href=&#34;#__codelineno-47-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;            PP_TUPLE_ELEM(curi, tuple), elem \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-40&#34; name=&#34;__codelineno-47-40&#34; href=&#34;#__codelineno-47-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        ), \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-41&#34; name=&#34;__codelineno-47-41&#34; href=&#34;#__codelineno-47-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        ret \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-42&#34; name=&#34;__codelineno-47-42&#34; href=&#34;#__codelineno-47-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    ), \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-43&#34; name=&#34;__codelineno-47-43&#34; href=&#34;#__codelineno-47-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    tuple \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-44&#34; name=&#34;__codelineno-47-44&#34; href=&#34;#__codelineno-47-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    )&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-45&#34; name=&#34;__codelineno-47-45&#34; href=&#34;#__codelineno-47-45&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-47-46&#34; name=&#34;__codelineno-47-46&#34; href=&#34;#__codelineno-47-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// 删除末尾元素&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-47&#34; name=&#34;__codelineno-47-47&#34; href=&#34;#__codelineno-47-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_TUPLE_POP_BACK(tuple) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-48&#34; name=&#34;__codelineno-47-48&#34; href=&#34;#__codelineno-47-48&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_TUPLE_ELEM( \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-49&#34; name=&#34;__codelineno-47-49&#34; href=&#34;#__codelineno-47-49&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        1, \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-50&#34; name=&#34;__codelineno-47-50&#34; href=&#34;#__codelineno-47-50&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        PP_AUTO_WHILE( \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-51&#34; name=&#34;__codelineno-47-51&#34; href=&#34;#__codelineno-47-51&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;            PP_TUPLE_POP_BACK_PRED, \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-52&#34; name=&#34;__codelineno-47-52&#34; href=&#34;#__codelineno-47-52&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;            PP_TUPLE_POP_BACK_OP, \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-53&#34; name=&#34;__codelineno-47-53&#34; href=&#34;#__codelineno-47-53&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;            (0, (), tuple) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-54&#34; name=&#34;__codelineno-47-54&#34; href=&#34;#__codelineno-47-54&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        ) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-55&#34; name=&#34;__codelineno-47-55&#34; href=&#34;#__codelineno-47-55&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    )&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-56&#34; name=&#34;__codelineno-47-56&#34; href=&#34;#__codelineno-47-56&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_TUPLE_POP_BACK_PRED(args) PP_TUPLE_POP_BACK_PRED_IMPL args&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-57&#34; name=&#34;__codelineno-47-57&#34; href=&#34;#__codelineno-47-57&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_TUPLE_POP_BACK_PRED_IMPL(curi, ret, tuple) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-58&#34; name=&#34;__codelineno-47-58&#34; href=&#34;#__codelineno-47-58&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_IF( \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-59&#34; name=&#34;__codelineno-47-59&#34; href=&#34;#__codelineno-47-59&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        PP_TUPLE_SIZE(tuple), \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-60&#34; name=&#34;__codelineno-47-60&#34; href=&#34;#__codelineno-47-60&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        PP_NOT_EQUAL(PP_TUPLE_SIZE(ret), PP_DEC(PP_TUPLE_SIZE(tuple))), \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-61&#34; name=&#34;__codelineno-47-61&#34; href=&#34;#__codelineno-47-61&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        0 \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-62&#34; name=&#34;__codelineno-47-62&#34; href=&#34;#__codelineno-47-62&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    )&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-63&#34; name=&#34;__codelineno-47-63&#34; href=&#34;#__codelineno-47-63&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_TUPLE_POP_BACK_OP(args) PP_TUPLE_POP_BACK_OP_IMPL args&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-64&#34; name=&#34;__codelineno-47-64&#34; href=&#34;#__codelineno-47-64&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_TUPLE_POP_BACK_OP_IMPL(curi, ret, tuple) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-65&#34; name=&#34;__codelineno-47-65&#34; href=&#34;#__codelineno-47-65&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    (PP_INC(curi), PP_TUPLE_PUSH_BACK(PP_TUPLE_ELEM(curi, tuple), ret), tuple)&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-66&#34; name=&#34;__codelineno-47-66&#34; href=&#34;#__codelineno-47-66&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-47-67&#34; name=&#34;__codelineno-47-67&#34; href=&#34;#__codelineno-47-67&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// 删除元素&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-68&#34; name=&#34;__codelineno-47-68&#34; href=&#34;#__codelineno-47-68&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_TUPLE_REMOVE(i, tuple) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-69&#34; name=&#34;__codelineno-47-69&#34; href=&#34;#__codelineno-47-69&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_TUPLE_ELEM( \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-70&#34; name=&#34;__codelineno-47-70&#34; href=&#34;#__codelineno-47-70&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        2, \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-71&#34; name=&#34;__codelineno-47-71&#34; href=&#34;#__codelineno-47-71&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        PP_AUTO_WHILE( \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-72&#34; name=&#34;__codelineno-47-72&#34; href=&#34;#__codelineno-47-72&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;            PP_TUPLE_REMOVE_PRED, \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-73&#34; name=&#34;__codelineno-47-73&#34; href=&#34;#__codelineno-47-73&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;            PP_TUPLE_REMOVE_OP, \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-74&#34; name=&#34;__codelineno-47-74&#34; href=&#34;#__codelineno-47-74&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;            (0, i, (), tuple) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-75&#34; name=&#34;__codelineno-47-75&#34; href=&#34;#__codelineno-47-75&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        ) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-76&#34; name=&#34;__codelineno-47-76&#34; href=&#34;#__codelineno-47-76&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    )&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-77&#34; name=&#34;__codelineno-47-77&#34; href=&#34;#__codelineno-47-77&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_TUPLE_REMOVE_PRED(args) PP_TUPLE_REMOVE_PRED_IMPL args&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-78&#34; name=&#34;__codelineno-47-78&#34; href=&#34;#__codelineno-47-78&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_TUPLE_REMOVE_PRED_IMPL(curi, i, ret, tuple) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-79&#34; name=&#34;__codelineno-47-79&#34; href=&#34;#__codelineno-47-79&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_IF( \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-80&#34; name=&#34;__codelineno-47-80&#34; href=&#34;#__codelineno-47-80&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        PP_TUPLE_SIZE(tuple), \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-81&#34; name=&#34;__codelineno-47-81&#34; href=&#34;#__codelineno-47-81&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        PP_NOT_EQUAL(PP_TUPLE_SIZE(ret), PP_DEC(PP_TUPLE_SIZE(tuple))), \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-82&#34; name=&#34;__codelineno-47-82&#34; href=&#34;#__codelineno-47-82&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        0 \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-83&#34; name=&#34;__codelineno-47-83&#34; href=&#34;#__codelineno-47-83&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    )&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-84&#34; name=&#34;__codelineno-47-84&#34; href=&#34;#__codelineno-47-84&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_TUPLE_REMOVE_OP(args) PP_TUPLE_REMOVE_OP_IMPL args&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-85&#34; name=&#34;__codelineno-47-85&#34; href=&#34;#__codelineno-47-85&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define PP_TUPLE_REMOVE_OP_IMPL(curi, i, ret, tuple) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-86&#34; name=&#34;__codelineno-47-86&#34; href=&#34;#__codelineno-47-86&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    ( \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-87&#34; name=&#34;__codelineno-47-87&#34; href=&#34;#__codelineno-47-87&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_INC(curi), \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-88&#34; name=&#34;__codelineno-47-88&#34; href=&#34;#__codelineno-47-88&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    i, \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-89&#34; name=&#34;__codelineno-47-89&#34; href=&#34;#__codelineno-47-89&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    PP_IF( \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-90&#34; name=&#34;__codelineno-47-90&#34; href=&#34;#__codelineno-47-90&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        PP_NOT_EQUAL(curi, i), \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-91&#34; name=&#34;__codelineno-47-91&#34; href=&#34;#__codelineno-47-91&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        PP_TUPLE_PUSH_BACK(PP_TUPLE_ELEM(curi, tuple), ret), \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-92&#34; name=&#34;__codelineno-47-92&#34; href=&#34;#__codelineno-47-92&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        ret \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-93&#34; name=&#34;__codelineno-47-93&#34; href=&#34;#__codelineno-47-93&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    ), \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-94&#34; name=&#34;__codelineno-47-94&#34; href=&#34;#__codelineno-47-94&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    tuple \&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-95&#34; name=&#34;__codelineno-47-95&#34; href=&#34;#__codelineno-47-95&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    )&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-96&#34; name=&#34;__codelineno-47-96&#34; href=&#34;#__codelineno-47-96&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-47-97&#34; name=&#34;__codelineno-47-97&#34; href=&#34;#__codelineno-47-97&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_TUPLE_SIZE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(())&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;               &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-98&#34; name=&#34;__codelineno-47-98&#34; href=&#34;#__codelineno-47-98&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-47-99&#34; name=&#34;__codelineno-47-99&#34; href=&#34;#__codelineno-47-99&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_TUPLE_PUSH_BACK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; (1, 2)&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-100&#34; name=&#34;__codelineno-47-100&#34; href=&#34;#__codelineno-47-100&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_TUPLE_PUSH_BACK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; (2)&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-101&#34; name=&#34;__codelineno-47-101&#34; href=&#34;#__codelineno-47-101&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-47-102&#34; name=&#34;__codelineno-47-102&#34; href=&#34;#__codelineno-47-102&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_TUPLE_INSERT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; (1, 2, 3)&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-103&#34; name=&#34;__codelineno-47-103&#34; href=&#34;#__codelineno-47-103&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-47-104&#34; name=&#34;__codelineno-47-104&#34; href=&#34;#__codelineno-47-104&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_TUPLE_POP_BACK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(())&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; ()&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-105&#34; name=&#34;__codelineno-47-105&#34; href=&#34;#__codelineno-47-105&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_TUPLE_POP_BACK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; ()&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-106&#34; name=&#34;__codelineno-47-106&#34; href=&#34;#__codelineno-47-106&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_TUPLE_POP_BACK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; (1, 2)&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-107&#34; name=&#34;__codelineno-47-107&#34; href=&#34;#__codelineno-47-107&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-47-108&#34; name=&#34;__codelineno-47-108&#34; href=&#34;#__codelineno-47-108&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_TUPLE_REMOVE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; (1, 3)&lt;/span&gt;
&lt;a id=&#34;__codelineno-47-109&#34; name=&#34;__codelineno-47-109&#34; href=&#34;#__codelineno-47-109&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PP_TUPLE_REMOVE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// -&amp;gt; (2, 3)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这里稍微解释一下插入元素的实现，其他删除元素等操作也是通过类似的原理来实现的。&lt;code&gt;PP_TUPLE_INSERT(i, elem, tuple)&lt;/code&gt; 可以在 &lt;code&gt;tuple&lt;/code&gt; 的位置 &lt;code&gt;i&lt;/code&gt; 插入元素 &lt;code&gt;elem&lt;/code&gt;，为了完成这个操作，先把位置小于 &lt;code&gt;i&lt;/code&gt; 的元素都先用 &lt;code&gt;PP_TUPLE_PUSH_BACK&lt;/code&gt; 放到一个新的 &lt;code&gt;tuple&lt;/code&gt; 上（&lt;code&gt;ret&lt;/code&gt;），然后在位置 &lt;code&gt;i&lt;/code&gt; 放入元素 &lt;code&gt;elem&lt;/code&gt;，之后再把原 &lt;code&gt;tuple&lt;/code&gt; 位置大于等于 &lt;code&gt;i&lt;/code&gt; 的元素放到 &lt;code&gt;ret&lt;/code&gt; 后面，最后 &lt;code&gt;ret&lt;/code&gt; 就得到我们想要的结果。&lt;/p&gt;
&lt;h2 id=&#34;_29&#34;&gt;小结&lt;/h2&gt;
&lt;p&gt;本文的目的是想要阐述清楚 C/C++ 宏编程的原理和基本实现，在记录我本人的一些理解和认识的同时，希望能够对其他人能带来一些解惑和启发。需要注意的是，尽管本文篇幅有点长，但还是有一些关于宏编程的技巧和用法是没有涉及到的，譬如 CHAOS_PP 提出的&lt;a href=&#34;https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms#deferred-expression&#34;&gt;基于延迟展开的递归调用方法&lt;/a&gt;，BOOST_PP 里面的 &lt;code&gt;REPEAT&lt;/code&gt; 相关宏等等，有兴趣的可以自行查阅资料。&lt;/p&gt;
&lt;p&gt;宏编程的调试是一个痛苦的过程，我们可以：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用 &lt;code&gt;-P -E&lt;/code&gt; 选项输出预处理结果；&lt;/li&gt;
&lt;li&gt;用前面提到的我自己修改的 &lt;code&gt;clang&lt;/code&gt; 版本仔细研究展开过程；&lt;/li&gt;
&lt;li&gt;把复杂的宏拆解，查看中间宏的展开结果；&lt;/li&gt;
&lt;li&gt;屏蔽无关的头文件和宏；&lt;/li&gt;
&lt;li&gt;最后就是要脑补宏展开的过程了，熟悉宏展开之后调试的效率也会提升。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;本文中的宏是我自己在理解了原理之后重新实现出来的，有部分宏借鉴了 &lt;code&gt;Boost&lt;/code&gt; 的实现和引用里面的文章，有任何错误之处，欢迎随时指正，也欢迎找我来讨论相关的问题。&lt;/p&gt;
&lt;p&gt;本文的代码全部都在这里：&lt;a href=&#34;../assets/img/2021-3-31-cpp-preprocess/macros.cpp&#34;&gt;下载&lt;/a&gt;，&lt;a href=&#34;https://godbolt.org/z/coWvc5Pse&#34;&gt;在线演示&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&#34;_30&#34;&gt;引用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.boost.org/doc/libs/1_75_0/libs/preprocessor/doc/&#34;&gt;Boost.Preprocessor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://bot-man-jl.github.io/articles/?post=2020/Macro-Programming-Art&#34;&gt;C/C++ 宏编程的艺术&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/cpp-C%E5%92%8CCpp%E5%AE%8F%E7%BC%96%E7%A8%8B%E8%A7%A3%E6%9E%90/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 30 Nov 2023 20:09:36 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/cpp-C%E5%92%8CCpp%E5%AE%8F%E7%BC%96%E7%A8%8B%E8%A7%A3%E6%9E%90/</guid>
      
    </item>
    
    <item>
      <title>C/C++ 的命令行参数处理总结</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;C/C++ 的命令行参数处理总结&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;https://img.shields.io/badge/vs-2015-68217A.svg&#34; style=&#34;display: inline-block&#34; /&gt;
&lt;img alt=&#34;&#34; src=&#34;https://img.shields.io/badge/gcc-4.9-blue.svg&#34; style=&#34;display: inline-block&#34; /&gt;
&lt;img alt=&#34;&#34; src=&#34;https://img.shields.io/badge/clang-3.7-birghtgreen.svg&#34; style=&#34;display: inline-block&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2016-11-19-aparsing/aparsing.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;前一阵子翻 Linux 内核代码的时候看到了内核对模块参数 (moduleparam) 的处理，觉得挺精妙，让我不禁想研究下 C 下的命令行参数要怎样更好地处理。本文所用代码都在这里 &lt;a href=&#34;https://github.com/disenone/aparsing&#34;&gt;aparsing&lt;/a&gt; 。代码支持在 Windows 、 Linux 、 Mac OS X 下编译运行，详细的编译指南在 README.md 里面。 &lt;/p&gt;
&lt;h2 id=&#34;getenv&#34;&gt;getenv&lt;/h2&gt;
&lt;p&gt;标准库为我们提供了一个函数 &lt;code&gt;getenv&lt;/code&gt; ，按照字面意思，这个函数是用来获取环境变量的，那么只要我们预先设置好需要的环境变量，在程序里面拿出来，就间接地把参数传到程序里面啦。我们来看下面这段&lt;a href=&#34;https://github.com/disenone/aparsing/blob/master/getenv/getenv_test.c&#34;&gt;代码&lt;/a&gt;：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;table class=&#34;highlighttable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;linenos&#34;&gt;&lt;div class=&#34;linenodiv&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-1&#34;&gt; 1&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-2&#34;&gt; 2&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-3&#34;&gt; 3&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-4&#34;&gt; 4&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-5&#34;&gt; 5&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-6&#34;&gt; 6&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-7&#34;&gt; 7&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-8&#34;&gt; 8&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-9&#34;&gt; 9&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-10&#34;&gt;10&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-11&#34;&gt;11&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-12&#34;&gt;12&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-13&#34;&gt;13&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-14&#34;&gt;14&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-15&#34;&gt;15&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-16&#34;&gt;16&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-17&#34;&gt;17&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-18&#34;&gt;18&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-19&#34;&gt;19&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-20&#34;&gt;20&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-21&#34;&gt;21&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-22&#34;&gt;22&lt;/a&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-4&#34; name=&#34;__codelineno-0-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;//char *getenv( const char *name );&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-5&#34; name=&#34;__codelineno-0-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;//GETENV_ADD=abc GETENV_NUM=2 ./getenv_test &lt;/span&gt;
&lt;a id=&#34;__codelineno-0-6&#34; name=&#34;__codelineno-0-6&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-7&#34; name=&#34;__codelineno-0-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-8&#34; name=&#34;__codelineno-0-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-9&#34; name=&#34;__codelineno-0-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;num&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-10&#34; name=&#34;__codelineno-0-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getenv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;GETENV_ADD&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-11&#34; name=&#34;__codelineno-0-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;GETENV_ADD = %s&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-12&#34; name=&#34;__codelineno-0-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-13&#34; name=&#34;__codelineno-0-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;GETENV_ADD not found&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-14&#34; name=&#34;__codelineno-0-14&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-15&#34; name=&#34;__codelineno-0-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;num&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getenv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;GETENV_NUM&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-16&#34; name=&#34;__codelineno-0-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-17&#34; name=&#34;__codelineno-0-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;numi&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;atoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;num&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-18&#34; name=&#34;__codelineno-0-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;GETENV_NUM = %d&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;numi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-19&#34; name=&#34;__codelineno-0-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-20&#34; name=&#34;__codelineno-0-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-21&#34; name=&#34;__codelineno-0-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;GETENV_NUM not found&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-22&#34; name=&#34;__codelineno-0-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;getenv&lt;/code&gt; 函数声明如第 &lt;a href=&#34;#__codelineno-0-5&#34;&gt;4&lt;/a&gt; 行，传入想要获取的变量名字，返回该变量的值，如果找不到变量，则返回0。&lt;a href=&#34;#__codelineno-0-10&#34;&gt;10&lt;/a&gt; 和 &lt;a href=&#34;#__codelineno-0-15&#34;&gt;15&lt;/a&gt; 行就是分别获取两个环境变量的值，如果变量有效则打印变量值。需要注意的是 &lt;code&gt;getenv&lt;/code&gt; 返回的都是字符串，需要使用者手动转换数值类型的，所以使用起来不够方便。编译运行:&lt;/p&gt;
&lt;p&gt;Windows 下：&lt;/p&gt;
&lt;div class=&#34;language-bat highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;set&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;GETENV_ADD&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;abc &lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;GETENV_NUM&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;1 &lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt; .\getenv_test.exe
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Linux 下：&lt;/p&gt;
&lt;div class=&#34;language-shell highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-2-1&#34; name=&#34;__codelineno-2-1&#34; href=&#34;#__codelineno-2-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;nv&#34;&gt;GETENV_ADD&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;abc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;GETENV_NUM&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;./getenv_test&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;输出：&lt;/p&gt;
&lt;div class=&#34;language-text highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-3-1&#34; name=&#34;__codelineno-3-1&#34; href=&#34;#__codelineno-3-1&#34;&gt;&lt;/a&gt;GETENV_ADD = abc
&lt;a id=&#34;__codelineno-3-2&#34; name=&#34;__codelineno-3-2&#34; href=&#34;#__codelineno-3-2&#34;&gt;&lt;/a&gt;GETENV_NUM = 2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;getopt&#34;&gt;getopt&lt;/h2&gt;
&lt;p&gt;Linux 给我们提供了一组函数 &lt;code&gt;getopt, getopt_long, getopt_long_only&lt;/code&gt; 来处理命令行传递进来的函数，这三个函数的声明分别是：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;table class=&#34;highlighttable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;linenos&#34;&gt;&lt;div class=&#34;linenodiv&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-1&#34;&gt; 1&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-2&#34;&gt; 2&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-3&#34;&gt; 3&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-4&#34;&gt; 4&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-5&#34;&gt; 5&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-6&#34;&gt; 6&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-7&#34;&gt; 7&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-8&#34;&gt; 8&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-9&#34;&gt; 9&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-10&#34;&gt;10&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-11&#34;&gt;11&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-12&#34;&gt;12&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-4-13&#34;&gt;13&lt;/a&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-4-1&#34; name=&#34;__codelineno-4-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;extern&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optarg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-2&#34; name=&#34;__codelineno-4-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;extern&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;opterr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optopt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-3&#34; name=&#34;__codelineno-4-3&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-4&#34; name=&#34;__codelineno-4-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;getopt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[],&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-5&#34; name=&#34;__codelineno-4-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optstring&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-6&#34; name=&#34;__codelineno-4-6&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-7&#34; name=&#34;__codelineno-4-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;getopt_long&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[],&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-8&#34; name=&#34;__codelineno-4-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optstring&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-9&#34; name=&#34;__codelineno-4-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;option&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;longopts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;longindex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-10&#34; name=&#34;__codelineno-4-10&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-11&#34; name=&#34;__codelineno-4-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;getopt_long_only&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[],&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-12&#34; name=&#34;__codelineno-4-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optstring&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-13&#34; name=&#34;__codelineno-4-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;option&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;longopts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;longindex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;getopt&lt;/code&gt; 只能处理短参数（即单字符参数），&lt;code&gt;getopt_long, getopt_long_only&lt;/code&gt; 则可以处理长参数。详细的函数解释可以去翻 Linux 下的手册，下面我们通过例子来说明 &lt;code&gt;getopt&lt;/code&gt; 和 &lt;code&gt;getopt_long&lt;/code&gt; 的用法。&lt;/p&gt;
&lt;p&gt;需要注意的是， Windows 下是没有提供这一组函数的，所以我找了一份可以在 Windows 下编译的源码，做了小小的改动，代码都在&lt;a href=&#34;https://github.com/disenone/aparsing/tree/master/getopt&#34;&gt;这里&lt;/a&gt;。&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;table class=&#34;highlighttable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;linenos&#34;&gt;&lt;div class=&#34;linenodiv&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-1&#34;&gt; 1&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-2&#34;&gt; 2&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-3&#34;&gt; 3&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-4&#34;&gt; 4&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-5&#34;&gt; 5&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-6&#34;&gt; 6&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-7&#34;&gt; 7&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-8&#34;&gt; 8&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-9&#34;&gt; 9&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-10&#34;&gt;10&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-11&#34;&gt;11&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-12&#34;&gt;12&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-13&#34;&gt;13&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-14&#34;&gt;14&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-15&#34;&gt;15&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-16&#34;&gt;16&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-17&#34;&gt;17&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-18&#34;&gt;18&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-19&#34;&gt;19&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-20&#34;&gt;20&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-21&#34;&gt;21&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-22&#34;&gt;22&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-23&#34;&gt;23&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-24&#34;&gt;24&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-25&#34;&gt;25&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-26&#34;&gt;26&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-27&#34;&gt;27&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-28&#34;&gt;28&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-29&#34;&gt;29&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-30&#34;&gt;30&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-31&#34;&gt;31&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-32&#34;&gt;32&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-33&#34;&gt;33&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-34&#34;&gt;34&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-35&#34;&gt;35&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-36&#34;&gt;36&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-37&#34;&gt;37&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-38&#34;&gt;38&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-39&#34;&gt;39&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-40&#34;&gt;40&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-41&#34;&gt;41&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-42&#34;&gt;42&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-43&#34;&gt;43&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-44&#34;&gt;44&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-45&#34;&gt;45&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-46&#34;&gt;46&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-47&#34;&gt;47&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-48&#34;&gt;48&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-49&#34;&gt;49&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-50&#34;&gt;50&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-51&#34;&gt;51&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-52&#34;&gt;52&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-53&#34;&gt;53&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-54&#34;&gt;54&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-55&#34;&gt;55&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-56&#34;&gt;56&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-57&#34;&gt;57&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-58&#34;&gt;58&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-59&#34;&gt;59&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-60&#34;&gt;60&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-61&#34;&gt;61&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-62&#34;&gt;62&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-63&#34;&gt;63&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-64&#34;&gt;64&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-65&#34;&gt;65&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-66&#34;&gt;66&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-67&#34;&gt;67&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-68&#34;&gt;68&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-69&#34;&gt;69&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-70&#34;&gt;70&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-71&#34;&gt;71&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-72&#34;&gt;72&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-73&#34;&gt;73&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-74&#34;&gt;74&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-75&#34;&gt;75&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-76&#34;&gt;76&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-77&#34;&gt;77&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-78&#34;&gt;78&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-79&#34;&gt;79&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-80&#34;&gt;80&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-81&#34;&gt;81&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-82&#34;&gt;82&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-83&#34;&gt;83&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-84&#34;&gt;84&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-85&#34;&gt;85&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-86&#34;&gt;86&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-87&#34;&gt;87&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-88&#34;&gt;88&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-89&#34;&gt;89&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-90&#34;&gt;90&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-91&#34;&gt;91&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-92&#34;&gt;92&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-93&#34;&gt;93&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-94&#34;&gt;94&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-95&#34;&gt;95&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-96&#34;&gt;96&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-5-97&#34;&gt;97&lt;/a&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-5-1&#34; name=&#34;__codelineno-5-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// test getopt&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-2&#34; name=&#34;__codelineno-5-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-3&#34; name=&#34;__codelineno-5-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;lt;getopt.h&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-4&#34; name=&#34;__codelineno-5-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-5&#34; name=&#34;__codelineno-5-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;lt;string.h&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-6&#34; name=&#34;__codelineno-5-6&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-7&#34; name=&#34;__codelineno-5-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;option&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;long_options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-8&#34; name=&#34;__codelineno-5-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-9&#34; name=&#34;__codelineno-5-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;add&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;required_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;sc&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-10&#34; name=&#34;__codelineno-5-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;append&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;no_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-11&#34; name=&#34;__codelineno-5-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;delete&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;required_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-12&#34; name=&#34;__codelineno-5-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;verbose&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optional_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-13&#34; name=&#34;__codelineno-5-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;create&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;no_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-14&#34; name=&#34;__codelineno-5-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;file&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;required_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-15&#34; name=&#34;__codelineno-5-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;help&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;no_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-16&#34; name=&#34;__codelineno-5-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-17&#34; name=&#34;__codelineno-5-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-18&#34; name=&#34;__codelineno-5-18&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-19&#34; name=&#34;__codelineno-5-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;simple_options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;a:bc::d:0123456789&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-20&#34; name=&#34;__codelineno-5-20&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-21&#34; name=&#34;__codelineno-5-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-22&#34; name=&#34;__codelineno-5-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-23&#34; name=&#34;__codelineno-5-23&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-24&#34; name=&#34;__codelineno-5-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-25&#34; name=&#34;__codelineno-5-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;digit_optind&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-26&#34; name=&#34;__codelineno-5-26&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-27&#34; name=&#34;__codelineno-5-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-28&#34; name=&#34;__codelineno-5-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-29&#34; name=&#34;__codelineno-5-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;this_option_optind&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optind&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optind&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-30&#34; name=&#34;__codelineno-5-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;longindex&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-31&#34; name=&#34;__codelineno-5-31&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-32&#34; name=&#34;__codelineno-5-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getopt_long&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;simple_options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;long_options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;longindex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-33&#34; name=&#34;__codelineno-5-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-34&#34; name=&#34;__codelineno-5-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-35&#34; name=&#34;__codelineno-5-35&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-36&#34; name=&#34;__codelineno-5-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;switch&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-37&#34; name=&#34;__codelineno-5-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-38&#34; name=&#34;__codelineno-5-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// long option&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-39&#34; name=&#34;__codelineno-5-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-40&#34; name=&#34;__codelineno-5-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                   &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;option %s&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;long_options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;longindex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-41&#34; name=&#34;__codelineno-5-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                   &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optarg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-42&#34; name=&#34;__codelineno-5-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                       &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot; with arg %s&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optarg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-43&#34; name=&#34;__codelineno-5-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                   &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-44&#34; name=&#34;__codelineno-5-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                   &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-45&#34; name=&#34;__codelineno-5-45&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-46&#34; name=&#34;__codelineno-5-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-47&#34; name=&#34;__codelineno-5-47&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-48&#34; name=&#34;__codelineno-5-48&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;sc&#34;&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-49&#34; name=&#34;__codelineno-5-49&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;sc&#34;&gt;&amp;#39;1&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-50&#34; name=&#34;__codelineno-5-50&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;sc&#34;&gt;&amp;#39;2&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-51&#34; name=&#34;__codelineno-5-51&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;sc&#34;&gt;&amp;#39;3&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-52&#34; name=&#34;__codelineno-5-52&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;sc&#34;&gt;&amp;#39;4&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-53&#34; name=&#34;__codelineno-5-53&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;sc&#34;&gt;&amp;#39;5&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-54&#34; name=&#34;__codelineno-5-54&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;sc&#34;&gt;&amp;#39;6&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-55&#34; name=&#34;__codelineno-5-55&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;sc&#34;&gt;&amp;#39;7&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-56&#34; name=&#34;__codelineno-5-56&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;sc&#34;&gt;&amp;#39;8&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-57&#34; name=&#34;__codelineno-5-57&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;sc&#34;&gt;&amp;#39;9&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-58&#34; name=&#34;__codelineno-5-58&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;digit_optind&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;digit_optind&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;this_option_optind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-59&#34; name=&#34;__codelineno-5-59&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;digits occur in two different argv-elements.&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-60&#34; name=&#34;__codelineno-5-60&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-61&#34; name=&#34;__codelineno-5-61&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;digit_optind&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;this_option_optind&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-62&#34; name=&#34;__codelineno-5-62&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;option %c&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-63&#34; name=&#34;__codelineno-5-63&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-64&#34; name=&#34;__codelineno-5-64&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-65&#34; name=&#34;__codelineno-5-65&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;sc&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-66&#34; name=&#34;__codelineno-5-66&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;option a with value &amp;#39;%s&amp;#39;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optarg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-67&#34; name=&#34;__codelineno-5-67&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-68&#34; name=&#34;__codelineno-5-68&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-69&#34; name=&#34;__codelineno-5-69&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;sc&#34;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-70&#34; name=&#34;__codelineno-5-70&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;option b&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-71&#34; name=&#34;__codelineno-5-71&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-72&#34; name=&#34;__codelineno-5-72&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-73&#34; name=&#34;__codelineno-5-73&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;sc&#34;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-74&#34; name=&#34;__codelineno-5-74&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optarg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-75&#34; name=&#34;__codelineno-5-75&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;option c with value &amp;#39;%s&amp;#39;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optarg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-76&#34; name=&#34;__codelineno-5-76&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-77&#34; name=&#34;__codelineno-5-77&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;option c&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-78&#34; name=&#34;__codelineno-5-78&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-79&#34; name=&#34;__codelineno-5-79&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-80&#34; name=&#34;__codelineno-5-80&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;case&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;sc&#34;&gt;&amp;#39;?&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-81&#34; name=&#34;__codelineno-5-81&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-82&#34; name=&#34;__codelineno-5-82&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-83&#34; name=&#34;__codelineno-5-83&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-84&#34; name=&#34;__codelineno-5-84&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;?? getopt returned character code 0%o ??&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-85&#34; name=&#34;__codelineno-5-85&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// switch&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-86&#34; name=&#34;__codelineno-5-86&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// while&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-87&#34; name=&#34;__codelineno-5-87&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-88&#34; name=&#34;__codelineno-5-88&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optind&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-89&#34; name=&#34;__codelineno-5-89&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-90&#34; name=&#34;__codelineno-5-90&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;non-option ARGV-elements: &amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-91&#34; name=&#34;__codelineno-5-91&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optind&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-92&#34; name=&#34;__codelineno-5-92&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;%s &amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optind&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-93&#34; name=&#34;__codelineno-5-93&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-94&#34; name=&#34;__codelineno-5-94&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-95&#34; name=&#34;__codelineno-5-95&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-96&#34; name=&#34;__codelineno-5-96&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-97&#34; name=&#34;__codelineno-5-97&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;我们来着重分析 &lt;code&gt;getopt_long&lt;/code&gt; 的用法，&lt;code&gt;getopt_long&lt;/code&gt; 的前三个参数跟 &lt;code&gt;getopt&lt;/code&gt; 是一样的，分别是：命令行参数个数 &lt;code&gt;argc&lt;/code&gt; ，命令行参数数组 &lt;code&gt;argv&lt;/code&gt;，短参数具体形式 &lt;code&gt;optstring&lt;/code&gt;。&lt;code&gt;otpstring&lt;/code&gt; 的格式就是一个个的短参数字符，后面加冒号 &lt;code&gt;:&lt;/code&gt; 表示带参数，两个冒号 &lt;code&gt;::&lt;/code&gt; 表示可选参数，譬如第 19 行，就是声明短参数的形式，&lt;code&gt;b&lt;/code&gt; 参数不带额外参数， &lt;code&gt;a&lt;/code&gt; 参数带额外参数，&lt;code&gt;c&lt;/code&gt; 带可选参数。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;getopt_long&lt;/code&gt; 后两个参数是用来处理长参数的，其中 &lt;code&gt;option&lt;/code&gt; 的结构是：&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;language-c highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-6-1&#34; name=&#34;__codelineno-6-1&#34; href=&#34;#__codelineno-6-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;option&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-2&#34; name=&#34;__codelineno-6-2&#34; href=&#34;#__codelineno-6-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 长参数名字&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-3&#34; name=&#34;__codelineno-6-3&#34; href=&#34;#__codelineno-6-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;has_arg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 是否带额外参数&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-4&#34; name=&#34;__codelineno-6-4&#34; href=&#34;#__codelineno-6-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;flag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 设置如何返回函数调用结果&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-5&#34; name=&#34;__codelineno-6-5&#34; href=&#34;#__codelineno-6-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 返回的数值&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-6&#34; name=&#34;__codelineno-6-6&#34; href=&#34;#__codelineno-6-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
虽然说是长参数，但 &lt;code&gt;name&lt;/code&gt; 还是可以设置为单字符长度的。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;has_arg&lt;/code&gt; 可以设置为 &lt;code&gt;no_argument, required_argument, optional_argument&lt;/code&gt;，分别表示不带参数，带参数，带可选参数。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;flag&lt;/code&gt; 和 &lt;code&gt;val&lt;/code&gt; 是配合使用的，如果 &lt;code&gt;flag = NULL&lt;/code&gt;，&lt;code&gt;getopt_long&lt;/code&gt; 会直接返回 &lt;code&gt;val&lt;/code&gt; ，否则如果 &lt;code&gt;flag&lt;/code&gt; 为有效指针，&lt;code&gt;getopt_long&lt;/code&gt; 会执行类似 &lt;code&gt;*flag = val&lt;/code&gt; 的操作，把 &lt;code&gt;flag&lt;/code&gt; 指向的变量设置为 &lt;code&gt;val&lt;/code&gt; 的数值。&lt;/p&gt;
&lt;p&gt;如果 &lt;code&gt;getopt_long&lt;/code&gt; 找到匹配的短参数，会返回该短参数的字符值，如果找到匹配的长参数，会返回 &lt;code&gt;val&lt;/code&gt;（ &lt;code&gt;flag = NULL&lt;/code&gt; ）或者返回 &lt;code&gt;0&lt;/code&gt; （ &lt;code&gt;flag != NULL; *flag = val;&lt;/code&gt; ）；如果遇到非参数的字符，会返回 &lt;code&gt;?&lt;/code&gt;；如果所有参数都处理完毕，则返回 &lt;code&gt;-1&lt;/code&gt; 。&lt;/p&gt;
&lt;p&gt;利用返回值的特性，我们可以做出用长参跟短参含义相同的效果，譬如 &lt;code&gt;long_options&lt;/code&gt; 的第一个参数 &lt;code&gt;add&lt;/code&gt;，其 &lt;code&gt;val&lt;/code&gt; 值设置为短参数的字符 &lt;code&gt;&#39;a&#39;&lt;/code&gt;，那么判断返回时，&lt;code&gt;--add&lt;/code&gt; 和 &lt;code&gt;-a&lt;/code&gt; 会进入相同的处理分支，被当作相同的含义来处理了。&lt;/p&gt;
&lt;p&gt;拼图的最后一块就是 &lt;code&gt;optind&lt;/code&gt; 和 &lt;code&gt;optarg&lt;/code&gt; 的用法，&lt;code&gt;optind&lt;/code&gt; 是下一个待处理参数在 &lt;code&gt;argv&lt;/code&gt; 中的位置， &lt;code&gt;optarg&lt;/code&gt; 则指向额外参数字符串。&lt;/p&gt;
&lt;p&gt;编译运行代码：&lt;/p&gt;
&lt;div class=&#34;language-text highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-7-1&#34; name=&#34;__codelineno-7-1&#34; href=&#34;#__codelineno-7-1&#34;&gt;&lt;/a&gt;$ .\getopt_test -a 1 -b -c4 --add 2 --verbose --verbose=3 -123 -e --e
&lt;a id=&#34;__codelineno-7-2&#34; name=&#34;__codelineno-7-2&#34; href=&#34;#__codelineno-7-2&#34;&gt;&lt;/a&gt;option a with value &amp;#39;1&amp;#39;
&lt;a id=&#34;__codelineno-7-3&#34; name=&#34;__codelineno-7-3&#34; href=&#34;#__codelineno-7-3&#34;&gt;&lt;/a&gt;option b
&lt;a id=&#34;__codelineno-7-4&#34; name=&#34;__codelineno-7-4&#34; href=&#34;#__codelineno-7-4&#34;&gt;&lt;/a&gt;option c with value &amp;#39;4&amp;#39;
&lt;a id=&#34;__codelineno-7-5&#34; name=&#34;__codelineno-7-5&#34; href=&#34;#__codelineno-7-5&#34;&gt;&lt;/a&gt;option a with value &amp;#39;2&amp;#39;
&lt;a id=&#34;__codelineno-7-6&#34; name=&#34;__codelineno-7-6&#34; href=&#34;#__codelineno-7-6&#34;&gt;&lt;/a&gt;option verbose
&lt;a id=&#34;__codelineno-7-7&#34; name=&#34;__codelineno-7-7&#34; href=&#34;#__codelineno-7-7&#34;&gt;&lt;/a&gt;option verbose with arg 3
&lt;a id=&#34;__codelineno-7-8&#34; name=&#34;__codelineno-7-8&#34; href=&#34;#__codelineno-7-8&#34;&gt;&lt;/a&gt;option 1
&lt;a id=&#34;__codelineno-7-9&#34; name=&#34;__codelineno-7-9&#34; href=&#34;#__codelineno-7-9&#34;&gt;&lt;/a&gt;option 2
&lt;a id=&#34;__codelineno-7-10&#34; name=&#34;__codelineno-7-10&#34; href=&#34;#__codelineno-7-10&#34;&gt;&lt;/a&gt;option 3
&lt;a id=&#34;__codelineno-7-11&#34; name=&#34;__codelineno-7-11&#34; href=&#34;#__codelineno-7-11&#34;&gt;&lt;/a&gt;.\getopt_test: invalid option -- e
&lt;a id=&#34;__codelineno-7-12&#34; name=&#34;__codelineno-7-12&#34; href=&#34;#__codelineno-7-12&#34;&gt;&lt;/a&gt;.\getopt_test: unrecognized option `--e&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;-a&lt;/code&gt; 和 &lt;code&gt;--add&lt;/code&gt; 的含义相同，短参数的可选参数直接跟在后面，譬如 &lt;code&gt;-c4&lt;/code&gt;，而长参数的可选参数需要有等号，譬如 &lt;code&gt;--verbose=3&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;mobuleparam&#34;&gt;mobuleparam&lt;/h2&gt;
&lt;p&gt;ok，终于来到最初引发这篇文章的方法，Linux 内核用了一种很取巧的方法来给内核模块传递参数，这个方法就是 &lt;code&gt;moduleparam&lt;/code&gt; 。我在这里先简单解释 Linux 内核的 &lt;code&gt;moduleparam&lt;/code&gt; 的做法，更详细的解释可以去看代码。虽然我借鉴了一些 &lt;code&gt;moduleparam&lt;/code&gt; 的处理方法，但和 Linux 内核的 &lt;code&gt;moduleparam&lt;/code&gt; 有一些不同，为了区分，我会把我的方法叫做 &lt;code&gt;small moduleparam&lt;/code&gt; ， Linux 内核的依然叫做 &lt;code&gt;moduleparam&lt;/code&gt; 。&lt;/p&gt;
&lt;p&gt;先来看看 &lt;code&gt;moduleparam&lt;/code&gt; 的用法，在模块里面声明：&lt;/p&gt;
&lt;div class=&#34;language-c highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-8-1&#34; name=&#34;__codelineno-8-1&#34; href=&#34;#__codelineno-8-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;enable_debug&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-2&#34; name=&#34;__codelineno-8-2&#34; href=&#34;#__codelineno-8-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;module_param&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;enable_debug&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;然后加载模块时输入参数：&lt;/p&gt;
&lt;div class=&#34;language-shell highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-9-1&#34; name=&#34;__codelineno-9-1&#34; href=&#34;#__codelineno-9-1&#34;&gt;&lt;/a&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;insmod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;enable_debug&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;变量 &lt;code&gt;enable_debug&lt;/code&gt; 就被正确地设置为 &lt;code&gt;1&lt;/code&gt;，使用起来很方便，需要增加的代码也很少，代码可以写得很简短优雅，不用像 &lt;code&gt;getenv&lt;/code&gt; 和 &lt;code&gt;getopt&lt;/code&gt; 那样写很多循环判断，而且还自带类型转换，所以我看到就想，要是能把这个方法拿来处理命令行参数，那就更好了。&lt;/p&gt;
&lt;p&gt;接着来看看 &lt;code&gt;moduleparam&lt;/code&gt; 的核心实现：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;table class=&#34;highlighttable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;linenos&#34;&gt;&lt;div class=&#34;linenodiv&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-1&#34;&gt; 1&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-2&#34;&gt; 2&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-3&#34;&gt; 3&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-4&#34;&gt; 4&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-5&#34;&gt; 5&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-6&#34;&gt; 6&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-7&#34;&gt; 7&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-8&#34;&gt; 8&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-9&#34;&gt; 9&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-10&#34;&gt;10&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-11&#34;&gt;11&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-12&#34;&gt;12&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-13&#34;&gt;13&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-14&#34;&gt;14&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-15&#34;&gt;15&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-16&#34;&gt;16&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-17&#34;&gt;17&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-18&#34;&gt;18&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-19&#34;&gt;19&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-20&#34;&gt;20&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-21&#34;&gt;21&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-22&#34;&gt;22&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-23&#34;&gt;23&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-24&#34;&gt;24&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-25&#34;&gt;25&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-26&#34;&gt;26&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-27&#34;&gt;27&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-28&#34;&gt;28&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-29&#34;&gt;29&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-30&#34;&gt;30&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-31&#34;&gt;31&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-32&#34;&gt;32&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-33&#34;&gt;33&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-34&#34;&gt;34&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-35&#34;&gt;35&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-36&#34;&gt;36&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-10-37&#34;&gt;37&lt;/a&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-10-1&#34; name=&#34;__codelineno-10-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;kernel_param&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-2&#34; name=&#34;__codelineno-10-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 变量名字&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-3&#34; name=&#34;__codelineno-10-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;u16&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;perm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                   &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 变量访问权限&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-4&#34; name=&#34;__codelineno-10-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;u16&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;flags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 变量是否 bool 类型&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-5&#34; name=&#34;__codelineno-10-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;param_set_fn&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// str -&amp;gt; 变量值&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-6&#34; name=&#34;__codelineno-10-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;param_get_fn&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 变量值 -&amp;gt; str&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-7&#34; name=&#34;__codelineno-10-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;union&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-8&#34; name=&#34;__codelineno-10-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;arg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 变量指针&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-9&#34; name=&#34;__codelineno-10-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;kparam_string&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-10&#34; name=&#34;__codelineno-10-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;kparam_array&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;arr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-11&#34; name=&#34;__codelineno-10-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-12&#34; name=&#34;__codelineno-10-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-13&#34; name=&#34;__codelineno-10-13&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-10-14&#34; name=&#34;__codelineno-10-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define __module_param_call(prefix, name, set, get, arg, isbool, perm)  \&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-15&#34; name=&#34;__codelineno-10-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;/* Default value instead of permissions? */&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;         \&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-16&#34; name=&#34;__codelineno-10-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    static int __param_perm_check_##name __attribute__((unused)) =  \&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-17&#34; name=&#34;__codelineno-10-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    BUILD_BUG_ON_ZERO((perm) &amp;lt; 0 || (perm) &amp;gt; 0777 || ((perm) &amp;amp; 2))  \&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-18&#34; name=&#34;__codelineno-10-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    + BUILD_BUG_ON_ZERO(sizeof(&amp;quot;&amp;quot;prefix) &amp;gt; MAX_PARAM_PREFIX_LEN);   \&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-19&#34; name=&#34;__codelineno-10-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    static const char __param_str_##name[] = prefix #name;      \&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-20&#34; name=&#34;__codelineno-10-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    static struct kernel_param __moduleparam_const __param_##name   \&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-21&#34; name=&#34;__codelineno-10-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    __used                              \&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-22&#34; name=&#34;__codelineno-10-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        __attribute__ ((unused,__section__ (&amp;quot;__param&amp;quot;),aligned(sizeof(void *)))) \&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-23&#34; name=&#34;__codelineno-10-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    = { __param_str_##name, perm, isbool ? KPARAM_ISBOOL : 0,   \&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-24&#34; name=&#34;__codelineno-10-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;        set, get, { arg } }&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-25&#34; name=&#34;__codelineno-10-25&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-10-26&#34; name=&#34;__codelineno-10-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define module_param_call(name, set, get, arg, perm)                  \&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-27&#34; name=&#34;__codelineno-10-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    __module_param_call(MODULE_PARAM_PREFIX,                  \&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-28&#34; name=&#34;__codelineno-10-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;                name, set, get, arg,                  \&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-29&#34; name=&#34;__codelineno-10-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;                __same_type(*(arg), bool), perm)&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-30&#34; name=&#34;__codelineno-10-30&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-10-31&#34; name=&#34;__codelineno-10-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define module_param_named(name, value, type, perm)            \&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-32&#34; name=&#34;__codelineno-10-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    param_check_##type(name, &amp;amp;(value));                \&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-33&#34; name=&#34;__codelineno-10-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    module_param_call(name, param_set_##type, param_get_##type, &amp;amp;value, perm); \&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-34&#34; name=&#34;__codelineno-10-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    __MODULE_PARM_TYPE(name, #type)&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-35&#34; name=&#34;__codelineno-10-35&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-10-36&#34; name=&#34;__codelineno-10-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define module_param(name, type, perm)              \&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-37&#34; name=&#34;__codelineno-10-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    module_param_named(name, name, type, perm)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;module_param&lt;/code&gt; 是一个宏，它实际做的事情是建立了一个可以反射到传入变量的结构 &lt;code&gt;kernel_param&lt;/code&gt; ，该结构保存了足够访问和设置变量的信息，即第 20-24 行，并且把结构放在叫做 &lt;code&gt;__param&lt;/code&gt; 的 &lt;code&gt;section&lt;/code&gt; 中（ &lt;code&gt;__section__ (&#34;__param&#34;)&lt;/code&gt; ）。结构保存好之后，内核会在加载模块时，找出 elf 文件的 &lt;code&gt;section __param&lt;/code&gt; 的位置和结构数量，在根据名字和 &lt;code&gt;param_set_fn&lt;/code&gt; 分别设置每个参数的数值。找出特定名字 &lt;code&gt;section&lt;/code&gt; 的方法是平台相关的，Linux 内核实现的是对 elf 文件的处理，Linux 提供了指令 &lt;code&gt;readelf&lt;/code&gt; 来查看 elf 文件的信息，有兴趣的可以查看 &lt;code&gt;readelf&lt;/code&gt; 的帮助信息。&lt;/p&gt;
&lt;p&gt;上面说道 Linux 内核的做法是平台相关的，而我想要的平台无关的处理参数的方法，所以我们就要改一改原始的 &lt;code&gt;moduleparam&lt;/code&gt; 的做法，把 &lt;code&gt;__section__ (&#34;__param&#34;)&lt;/code&gt; 声明去掉，毕竟我们并不像去很麻烦地读取 elf 文件的 &lt;code&gt;section&lt;/code&gt; 。先来看看修改后的用法：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;table class=&#34;highlighttable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;linenos&#34;&gt;&lt;div class=&#34;linenodiv&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-1&#34;&gt; 1&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-2&#34;&gt; 2&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-3&#34;&gt; 3&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-4&#34;&gt; 4&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-5&#34;&gt; 5&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-6&#34;&gt; 6&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-7&#34;&gt; 7&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-8&#34;&gt; 8&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-9&#34;&gt; 9&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-10&#34;&gt;10&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-11&#34;&gt;11&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-12&#34;&gt;12&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-13&#34;&gt;13&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-14&#34;&gt;14&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-15&#34;&gt;15&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-16&#34;&gt;16&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-17&#34;&gt;17&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-18&#34;&gt;18&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-19&#34;&gt;19&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-20&#34;&gt;20&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-21&#34;&gt;21&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-22&#34;&gt;22&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-23&#34;&gt;23&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-24&#34;&gt;24&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-25&#34;&gt;25&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-26&#34;&gt;26&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-27&#34;&gt;27&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-28&#34;&gt;28&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-29&#34;&gt;29&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-30&#34;&gt;30&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-31&#34;&gt;31&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-32&#34;&gt;32&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-33&#34;&gt;33&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-34&#34;&gt;34&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-35&#34;&gt;35&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-36&#34;&gt;36&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-37&#34;&gt;37&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-38&#34;&gt;38&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-39&#34;&gt;39&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-40&#34;&gt;40&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-41&#34;&gt;41&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-42&#34;&gt;42&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-43&#34;&gt;43&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-44&#34;&gt;44&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-11-45&#34;&gt;45&lt;/a&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-11-1&#34; name=&#34;__codelineno-11-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;quot;moduleparam.h&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-2&#34; name=&#34;__codelineno-11-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-3&#34; name=&#34;__codelineno-11-3&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-4&#34; name=&#34;__codelineno-11-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-5&#34; name=&#34;__codelineno-11-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;btest&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-6&#34; name=&#34;__codelineno-11-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;unsigned&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;latest_num&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-7&#34; name=&#34;__codelineno-11-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;long&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;latest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-8&#34; name=&#34;__codelineno-11-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;strtest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\0&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-9&#34; name=&#34;__codelineno-11-9&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-10&#34; name=&#34;__codelineno-11-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;usage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-11&#34; name=&#34;__codelineno-11-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-12&#34; name=&#34;__codelineno-11-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;usage: moduleparam_test [test=int] [btest[=bool]] [latest=int array] [strtest=string]&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-13&#34; name=&#34;__codelineno-11-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-14&#34; name=&#34;__codelineno-11-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-15&#34; name=&#34;__codelineno-11-15&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-16&#34; name=&#34;__codelineno-11-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;unknown_handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;param&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-17&#34; name=&#34;__codelineno-11-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-18&#34; name=&#34;__codelineno-11-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;find unknown param: %s&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;param&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-19&#34; name=&#34;__codelineno-11-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-20&#34; name=&#34;__codelineno-11-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-21&#34; name=&#34;__codelineno-11-21&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-22&#34; name=&#34;__codelineno-11-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-23&#34; name=&#34;__codelineno-11-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-24&#34; name=&#34;__codelineno-11-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;init_module_param&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-25&#34; name=&#34;__codelineno-11-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;module_param&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-26&#34; name=&#34;__codelineno-11-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;module_param_bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;btest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-27&#34; name=&#34;__codelineno-11-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;module_param_array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;latest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;long&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;latest_num&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-28&#34; name=&#34;__codelineno-11-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;module_param_string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;strtest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;strtest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;sizeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;strtest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-29&#34; name=&#34;__codelineno-11-29&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-30&#34; name=&#34;__codelineno-11-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ret&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parse_params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;unknown_handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-31&#34; name=&#34;__codelineno-11-31&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-32&#34; name=&#34;__codelineno-11-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ret&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-33&#34; name=&#34;__codelineno-11-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-34&#34; name=&#34;__codelineno-11-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;usage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-35&#34; name=&#34;__codelineno-11-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-36&#34; name=&#34;__codelineno-11-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-37&#34; name=&#34;__codelineno-11-37&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-38&#34; name=&#34;__codelineno-11-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1024&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-39&#34; name=&#34;__codelineno-11-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MODULE_INIT_VARIABLE_NUM&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-40&#34; name=&#34;__codelineno-11-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-41&#34; name=&#34;__codelineno-11-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MODULE_INIT_VARIABLE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MODULE_INIT_VARIABLE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-42&#34; name=&#34;__codelineno-11-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;%s = %s&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MODULE_INIT_VARIABLE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;].&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-43&#34; name=&#34;__codelineno-11-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-44&#34; name=&#34;__codelineno-11-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-45&#34; name=&#34;__codelineno-11-45&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;那么为了保存每一个反射的结构，我就增加了一个宏 &lt;code&gt;init_module_param(num)&lt;/code&gt; ，来声明保存结构的空间， &lt;code&gt;num&lt;/code&gt; 是参数的个数，如果实际声明的参数个数超出 &lt;code&gt;num&lt;/code&gt; ，程序会触发断言错误。&lt;code&gt;module_param&lt;/code&gt; 的声明跟原始的稍有不同，去掉了最后一个表示访问权限的参数，不做权限的控制。另外新增了宏 &lt;code&gt;module_param_bool&lt;/code&gt; 来处理表示 &lt;code&gt;bool&lt;/code&gt; 的变量，这在 Linux 的版本是不需要的，因为它用到了 gcc 内建函数 &lt;code&gt;__builtin_types_compatible_p&lt;/code&gt; 来判断变量的类型，很遗憾，MSVC 是没有这个函数的，所以我只能把这个功能去掉，增加一个宏。 &lt;code&gt;module_param_array&lt;/code&gt; 和 &lt;code&gt;module_param_string&lt;/code&gt; 就是对数组和字符串的处理，这两个功能在原始的版本也是有的。&lt;/p&gt;
&lt;p&gt;声明参数完毕，就是处理传入的参数了，使用宏 &lt;code&gt;parse_params&lt;/code&gt; ，传入 &lt;code&gt;argc, argv&lt;/code&gt;，第 3 个参数是对未知参数的处理回调函数指针，可以传 &lt;code&gt;NULL&lt;/code&gt; ，则入到位置参数会中断处理参数，返回错误码。&lt;/p&gt;
&lt;p&gt;编译运行代码：&lt;/p&gt;
&lt;div class=&#34;language-text highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-12-1&#34; name=&#34;__codelineno-12-1&#34; href=&#34;#__codelineno-12-1&#34;&gt;&lt;/a&gt;.\moduleparam_test.exe error=0 test=101 btest=1 latest=1,2,3 strtest=\&amp;quot;Hello World!\&amp;quot;
&lt;a id=&#34;__codelineno-12-2&#34; name=&#34;__codelineno-12-2&#34; href=&#34;#__codelineno-12-2&#34;&gt;&lt;/a&gt;Parsing ARGS: error=0 test=101 btest=1 latest=1,2,3 strtest=&amp;quot;Hello World!&amp;quot;
&lt;a id=&#34;__codelineno-12-3&#34; name=&#34;__codelineno-12-3&#34; href=&#34;#__codelineno-12-3&#34;&gt;&lt;/a&gt;find unknown param: error
&lt;a id=&#34;__codelineno-12-4&#34; name=&#34;__codelineno-12-4&#34; href=&#34;#__codelineno-12-4&#34;&gt;&lt;/a&gt;test = 101
&lt;a id=&#34;__codelineno-12-5&#34; name=&#34;__codelineno-12-5&#34; href=&#34;#__codelineno-12-5&#34;&gt;&lt;/a&gt;btest = Y
&lt;a id=&#34;__codelineno-12-6&#34; name=&#34;__codelineno-12-6&#34; href=&#34;#__codelineno-12-6&#34;&gt;&lt;/a&gt;latest = 1,2,3
&lt;a id=&#34;__codelineno-12-7&#34; name=&#34;__codelineno-12-7&#34; href=&#34;#__codelineno-12-7&#34;&gt;&lt;/a&gt;strtest = Hello World!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看到数值，数组和字符串都能正确读入并转换格式，如果遇到不能转换格式的参数，会返回错误码并打印相关信息。我们可以很简单地添加几行代码，就完成参数的读入和转换处理，用起来很优雅。更详细实现可以直接看代码，&lt;a href=&#34;https://github.com/disenone/aparsing&#34;&gt;在这里&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&#34;_1&#34;&gt;总结&lt;/h2&gt;
&lt;p&gt;这次我们总结了一下 C/C++ 下三种处理命令行参数的方法，分别是 &lt;code&gt;getenv&lt;/code&gt; ，&lt;code&gt;getopt&lt;/code&gt; 和 &lt;code&gt;moduleparam&lt;/code&gt;。三种方法有各自的特点，以后有需要可以根据实际的需求来选择合适的方法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getenv&lt;/code&gt; 是原生多平台就支持的，可以直接使用，但也过于原始，并使用的是环境变量，对环境有一定的污染，每次使用前最好清除不必要的环境变量防止上次的设置存留污染&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getopt&lt;/code&gt; 是 Linux 平台原生支持的，Windows 不支持，所以需要包含实现的代码才能跨平台使用。参数的传递符合 Linux 的命令传参标准，支持可选参数，但使用起来略微麻烦，通常需要循环和条件判断来处理不同的参数，并对数值类型的参数不友好。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;moduleparam&lt;/code&gt; 是参考 Linux 内核的 &lt;code&gt;moduleparam&lt;/code&gt; 实现的命令行参数处理工具，支持跨平台使用，使用简单，能对不同类型的参数进行类型转换，缺点就是每个参数都需要一个相应的变量存储。&lt;/li&gt;
&lt;/ul&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/cpp-C%E5%92%8CCpp%E7%9A%84%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0%E5%A4%84%E7%90%86%E6%80%BB%E7%BB%93/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 30 Nov 2023 20:09:36 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/cpp-C%E5%92%8CCpp%E7%9A%84%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0%E5%A4%84%E7%90%86%E6%80%BB%E7%BB%93/</guid>
      
    </item>
    
    <item>
      <title>KCP 源码剖析</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;KCP 源码剖析&#34; /&gt;&lt;/p&gt;
&lt;p&gt;阅读本文之前，如果没听说过 KCP ，或者一点都不了解 KCP，麻烦抽一点时间先看看 KCP 项目的说明文档：&lt;a href=&#34;https://github.com/skywind3000/kcp&#34;&gt;传送门&lt;/a&gt;。本文的目的是深入 KCP 的实现细节去理解 KCP 。&lt;/p&gt;
&lt;h2 id=&#34;kcp&#34;&gt;什么是 KCP&lt;/h2&gt;
&lt;p&gt;KCP 是一个快速可靠协议，能够以比 TCP 更低的延迟来传送数据，数据重传更快，等待时间更短。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;TCP是为流量设计的（每秒内可以传输多少KB的数据），讲究的是充分利用带宽。而 KCP是为流速设计的（单个数据包从一端发送到一端需要多少时间），以10%-20%带宽浪费的代价换取了比 TCP快30%-40%的传输速度。TCP信道是一条流速很慢，但每秒流量很大的大运河，而KCP是水流湍急的小激流&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;以上是 KCP 文档上面写的，关键词是&lt;strong&gt;带宽&lt;/strong&gt;和&lt;strong&gt;流速&lt;/strong&gt;，KCP 会损耗带宽，带来的好处是更大更均衡的传输速率。更多的说明参考 KCP 自身的文档。&lt;/p&gt;
&lt;h2 id=&#34;kcp_1&#34;&gt;KCP 数据结构&lt;/h2&gt;
&lt;p&gt;KCP 源码在 &lt;code&gt;ikcp.h&lt;/code&gt; 和 &lt;code&gt;ikcp.c&lt;/code&gt; 里面，&lt;code&gt;ikcp.h&lt;/code&gt; 核心的是数据结构的声明，首先是 &lt;code&gt;SEGMENT&lt;/code&gt; 数据包，是 KCP 协议处理数据的最小单位：&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt; SEGMENT 结构（点击展开代码） &lt;/summary&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;//=====================================================================&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// SEGMENT 一个 SETMENT 就是一个数据包&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34; href=&#34;#__codelineno-0-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;//=====================================================================&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-4&#34; name=&#34;__codelineno-0-4&#34; href=&#34;#__codelineno-0-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;IKCPSEG&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-5&#34; name=&#34;__codelineno-0-5&#34; href=&#34;#__codelineno-0-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-6&#34; name=&#34;__codelineno-0-6&#34; href=&#34;#__codelineno-0-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 链表节点，发送和接受队列都是这里的链表的结构&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-7&#34; name=&#34;__codelineno-0-7&#34; href=&#34;#__codelineno-0-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;IQUEUEHEAD&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-8&#34; name=&#34;__codelineno-0-8&#34; href=&#34;#__codelineno-0-8&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-9&#34; name=&#34;__codelineno-0-9&#34; href=&#34;#__codelineno-0-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 会话编号，同一个会话编号相同&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-10&#34; name=&#34;__codelineno-0-10&#34; href=&#34;#__codelineno-0-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;conv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-11&#34; name=&#34;__codelineno-0-11&#34; href=&#34;#__codelineno-0-11&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-12&#34; name=&#34;__codelineno-0-12&#34; href=&#34;#__codelineno-0-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 数据包类型，譬如 DATA 或者 ACK&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-13&#34; name=&#34;__codelineno-0-13&#34; href=&#34;#__codelineno-0-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-14&#34; name=&#34;__codelineno-0-14&#34; href=&#34;#__codelineno-0-14&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-15&#34; name=&#34;__codelineno-0-15&#34; href=&#34;#__codelineno-0-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 由于 MTU 的限制，大数据包会拆分成多个小数据包，这个是小数据包的编号&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-16&#34; name=&#34;__codelineno-0-16&#34; href=&#34;#__codelineno-0-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;frg&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-17&#34; name=&#34;__codelineno-0-17&#34; href=&#34;#__codelineno-0-17&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-18&#34; name=&#34;__codelineno-0-18&#34; href=&#34;#__codelineno-0-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 每个数据包，都会附带上发送方的接受窗口大小&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-19&#34; name=&#34;__codelineno-0-19&#34; href=&#34;#__codelineno-0-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-20&#34; name=&#34;__codelineno-0-20&#34; href=&#34;#__codelineno-0-20&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-21&#34; name=&#34;__codelineno-0-21&#34; href=&#34;#__codelineno-0-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 发送时间，如果是 ACK 包，会设置为源数据包的 ts&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-22&#34; name=&#34;__codelineno-0-22&#34; href=&#34;#__codelineno-0-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-23&#34; name=&#34;__codelineno-0-23&#34; href=&#34;#__codelineno-0-23&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-24&#34; name=&#34;__codelineno-0-24&#34; href=&#34;#__codelineno-0-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 唯一标识数据包的编号&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-25&#34; name=&#34;__codelineno-0-25&#34; href=&#34;#__codelineno-0-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-26&#34; name=&#34;__codelineno-0-26&#34; href=&#34;#__codelineno-0-26&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-27&#34; name=&#34;__codelineno-0-27&#34; href=&#34;#__codelineno-0-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 代表小于 una 的数据包都接收成功，跟 TCP 含义一致：oldest unacknowledged sequence number SND&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-28&#34; name=&#34;__codelineno-0-28&#34; href=&#34;#__codelineno-0-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;una&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-29&#34; name=&#34;__codelineno-0-29&#34; href=&#34;#__codelineno-0-29&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-30&#34; name=&#34;__codelineno-0-30&#34; href=&#34;#__codelineno-0-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 数据长度&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-31&#34; name=&#34;__codelineno-0-31&#34; href=&#34;#__codelineno-0-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-32&#34; name=&#34;__codelineno-0-32&#34; href=&#34;#__codelineno-0-32&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-33&#34; name=&#34;__codelineno-0-33&#34; href=&#34;#__codelineno-0-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 超时重传时间&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-34&#34; name=&#34;__codelineno-0-34&#34; href=&#34;#__codelineno-0-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resendts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-35&#34; name=&#34;__codelineno-0-35&#34; href=&#34;#__codelineno-0-35&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-36&#34; name=&#34;__codelineno-0-36&#34; href=&#34;#__codelineno-0-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 下次超时等待时间&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-37&#34; name=&#34;__codelineno-0-37&#34; href=&#34;#__codelineno-0-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-38&#34; name=&#34;__codelineno-0-38&#34; href=&#34;#__codelineno-0-38&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-39&#34; name=&#34;__codelineno-0-39&#34; href=&#34;#__codelineno-0-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 快速重传，收到本数据包之后的数据包的数量，大于一定数量就触发快速重传&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-40&#34; name=&#34;__codelineno-0-40&#34; href=&#34;#__codelineno-0-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fastack&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-41&#34; name=&#34;__codelineno-0-41&#34; href=&#34;#__codelineno-0-41&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-42&#34; name=&#34;__codelineno-0-42&#34; href=&#34;#__codelineno-0-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 发送次数&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-43&#34; name=&#34;__codelineno-0-43&#34; href=&#34;#__codelineno-0-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-44&#34; name=&#34;__codelineno-0-44&#34; href=&#34;#__codelineno-0-44&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-45&#34; name=&#34;__codelineno-0-45&#34; href=&#34;#__codelineno-0-45&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 数据&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-46&#34; name=&#34;__codelineno-0-46&#34; href=&#34;#__codelineno-0-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-47&#34; name=&#34;__codelineno-0-47&#34; href=&#34;#__codelineno-0-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/details&gt;

&lt;p&gt;看完 &lt;code&gt;SEGMENT&lt;/code&gt; 的注释，大致能看出 KCP 的核心也是一个 ARQ 协议，通过自动超时重传来保证数据的送达。接着再来看看 KCP 结构 &lt;code&gt;KCPCB&lt;/code&gt; 的定义：&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt; KCP 结构（点击展开代码） &lt;/summary&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;//---------------------------------------------------------------------&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-2&#34; name=&#34;__codelineno-1-2&#34; href=&#34;#__codelineno-1-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// IKCPCB&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-3&#34; name=&#34;__codelineno-1-3&#34; href=&#34;#__codelineno-1-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;//---------------------------------------------------------------------&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-4&#34; name=&#34;__codelineno-1-4&#34; href=&#34;#__codelineno-1-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;IKCPCB&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-5&#34; name=&#34;__codelineno-1-5&#34; href=&#34;#__codelineno-1-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-6&#34; name=&#34;__codelineno-1-6&#34; href=&#34;#__codelineno-1-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// conv: 会话编号&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-7&#34; name=&#34;__codelineno-1-7&#34; href=&#34;#__codelineno-1-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// mtu, mss: 最大传输单元，最大报文段大小&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-8&#34; name=&#34;__codelineno-1-8&#34; href=&#34;#__codelineno-1-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// state: 会话状态，0 有效，-1 断开&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-9&#34; name=&#34;__codelineno-1-9&#34; href=&#34;#__codelineno-1-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;conv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mtu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mss&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;state&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-10&#34; name=&#34;__codelineno-1-10&#34; href=&#34;#__codelineno-1-10&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-11&#34; name=&#34;__codelineno-1-11&#34; href=&#34;#__codelineno-1-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// snd_una: 等待 ACK 的包编号&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-12&#34; name=&#34;__codelineno-1-12&#34; href=&#34;#__codelineno-1-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// snd_nxt: 下一个等待发送的数据包编号&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-13&#34; name=&#34;__codelineno-1-13&#34; href=&#34;#__codelineno-1-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// rcv_nxt: 下一个等待接收的数据包编号&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-14&#34; name=&#34;__codelineno-1-14&#34; href=&#34;#__codelineno-1-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_una&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_nxt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_nxt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-15&#34; name=&#34;__codelineno-1-15&#34; href=&#34;#__codelineno-1-15&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-16&#34; name=&#34;__codelineno-1-16&#34; href=&#34;#__codelineno-1-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ts_recent, ts_lastack: 未用到&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-17&#34; name=&#34;__codelineno-1-17&#34; href=&#34;#__codelineno-1-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ssthresh: 拥塞控制慢启动阈值&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-18&#34; name=&#34;__codelineno-1-18&#34; href=&#34;#__codelineno-1-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts_recent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts_lastack&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssthresh&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-19&#34; name=&#34;__codelineno-1-19&#34; href=&#34;#__codelineno-1-19&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-20&#34; name=&#34;__codelineno-1-20&#34; href=&#34;#__codelineno-1-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// rx_rto: rto (retransmission timeout)，超时重传时间&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-21&#34; name=&#34;__codelineno-1-21&#34; href=&#34;#__codelineno-1-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// rx_rttval, rx_srtt, rx_minrto: 计算 rto 的中间变量&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-22&#34; name=&#34;__codelineno-1-22&#34; href=&#34;#__codelineno-1-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rx_rttval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rx_srtt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rx_rto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rx_minrto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-23&#34; name=&#34;__codelineno-1-23&#34; href=&#34;#__codelineno-1-23&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-24&#34; name=&#34;__codelineno-1-24&#34; href=&#34;#__codelineno-1-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// snd_wnd, rcv_wnd: 最大发送和接收窗口大小&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-25&#34; name=&#34;__codelineno-1-25&#34; href=&#34;#__codelineno-1-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// rmt_wnd: remote wnd ，对端剩余接受窗口大小&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-26&#34; name=&#34;__codelineno-1-26&#34; href=&#34;#__codelineno-1-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// cwnd: 可发送窗口大小&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-27&#34; name=&#34;__codelineno-1-27&#34; href=&#34;#__codelineno-1-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// probe: 是否要发送控制报文的标志&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-28&#34; name=&#34;__codelineno-1-28&#34; href=&#34;#__codelineno-1-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_wnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_wnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rmt_wnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;probe&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-29&#34; name=&#34;__codelineno-1-29&#34; href=&#34;#__codelineno-1-29&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-30&#34; name=&#34;__codelineno-1-30&#34; href=&#34;#__codelineno-1-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// current: 当前时间&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-31&#34; name=&#34;__codelineno-1-31&#34; href=&#34;#__codelineno-1-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// interval: 更新间隔&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-32&#34; name=&#34;__codelineno-1-32&#34; href=&#34;#__codelineno-1-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ts_flush: 下次需要更新的时间&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-33&#34; name=&#34;__codelineno-1-33&#34; href=&#34;#__codelineno-1-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// xmit: 发送失败次数&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-34&#34; name=&#34;__codelineno-1-34&#34; href=&#34;#__codelineno-1-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts_flush&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-35&#34; name=&#34;__codelineno-1-35&#34; href=&#34;#__codelineno-1-35&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-36&#34; name=&#34;__codelineno-1-36&#34; href=&#34;#__codelineno-1-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 对应链表的长度&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-37&#34; name=&#34;__codelineno-1-37&#34; href=&#34;#__codelineno-1-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nrcv_buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nsnd_buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-38&#34; name=&#34;__codelineno-1-38&#34; href=&#34;#__codelineno-1-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nrcv_que&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nsnd_que&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-39&#34; name=&#34;__codelineno-1-39&#34; href=&#34;#__codelineno-1-39&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-40&#34; name=&#34;__codelineno-1-40&#34; href=&#34;#__codelineno-1-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// nodelay: 控制超时重传的 rto 增长速度&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-41&#34; name=&#34;__codelineno-1-41&#34; href=&#34;#__codelineno-1-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// updated: 是否调用过 ikcp_update&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-42&#34; name=&#34;__codelineno-1-42&#34; href=&#34;#__codelineno-1-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nodelay&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;updated&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-43&#34; name=&#34;__codelineno-1-43&#34; href=&#34;#__codelineno-1-43&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-44&#34; name=&#34;__codelineno-1-44&#34; href=&#34;#__codelineno-1-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ts_probe, probe_wait: 对端接收窗口长时间为 0 时主动定期发起询问&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-45&#34; name=&#34;__codelineno-1-45&#34; href=&#34;#__codelineno-1-45&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts_probe&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;probe_wait&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-46&#34; name=&#34;__codelineno-1-46&#34; href=&#34;#__codelineno-1-46&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-47&#34; name=&#34;__codelineno-1-47&#34; href=&#34;#__codelineno-1-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// deal_link: 对端长时间无应答&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-48&#34; name=&#34;__codelineno-1-48&#34; href=&#34;#__codelineno-1-48&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// incr: 参与计算发送窗口大小&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-49&#34; name=&#34;__codelineno-1-49&#34; href=&#34;#__codelineno-1-49&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dead_link&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;incr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-50&#34; name=&#34;__codelineno-1-50&#34; href=&#34;#__codelineno-1-50&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-51&#34; name=&#34;__codelineno-1-51&#34; href=&#34;#__codelineno-1-51&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// queue: 跟用户层接触的数据包&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-52&#34; name=&#34;__codelineno-1-52&#34; href=&#34;#__codelineno-1-52&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// buf: 协议缓存的数据包&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-53&#34; name=&#34;__codelineno-1-53&#34; href=&#34;#__codelineno-1-53&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;IQUEUEHEAD&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_queue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-54&#34; name=&#34;__codelineno-1-54&#34; href=&#34;#__codelineno-1-54&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;IQUEUEHEAD&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_queue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-55&#34; name=&#34;__codelineno-1-55&#34; href=&#34;#__codelineno-1-55&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;IQUEUEHEAD&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-56&#34; name=&#34;__codelineno-1-56&#34; href=&#34;#__codelineno-1-56&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;IQUEUEHEAD&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-57&#34; name=&#34;__codelineno-1-57&#34; href=&#34;#__codelineno-1-57&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-58&#34; name=&#34;__codelineno-1-58&#34; href=&#34;#__codelineno-1-58&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 需要发送 ack 的数据包信息&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-59&#34; name=&#34;__codelineno-1-59&#34; href=&#34;#__codelineno-1-59&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;acklist&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-60&#34; name=&#34;__codelineno-1-60&#34; href=&#34;#__codelineno-1-60&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-61&#34; name=&#34;__codelineno-1-61&#34; href=&#34;#__codelineno-1-61&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 需要 ack 的包数量&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-62&#34; name=&#34;__codelineno-1-62&#34; href=&#34;#__codelineno-1-62&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ackcount&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-63&#34; name=&#34;__codelineno-1-63&#34; href=&#34;#__codelineno-1-63&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-64&#34; name=&#34;__codelineno-1-64&#34; href=&#34;#__codelineno-1-64&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// acklist 内存大小&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-65&#34; name=&#34;__codelineno-1-65&#34; href=&#34;#__codelineno-1-65&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ackblock&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-66&#34; name=&#34;__codelineno-1-66&#34; href=&#34;#__codelineno-1-66&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-67&#34; name=&#34;__codelineno-1-67&#34; href=&#34;#__codelineno-1-67&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 用户层传进来的数据&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-68&#34; name=&#34;__codelineno-1-68&#34; href=&#34;#__codelineno-1-68&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-69&#34; name=&#34;__codelineno-1-69&#34; href=&#34;#__codelineno-1-69&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-70&#34; name=&#34;__codelineno-1-70&#34; href=&#34;#__codelineno-1-70&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 存放一个 kcp 包的空间&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-71&#34; name=&#34;__codelineno-1-71&#34; href=&#34;#__codelineno-1-71&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-72&#34; name=&#34;__codelineno-1-72&#34; href=&#34;#__codelineno-1-72&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-73&#34; name=&#34;__codelineno-1-73&#34; href=&#34;#__codelineno-1-73&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 触发快速重传的 fastack 次数&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-74&#34; name=&#34;__codelineno-1-74&#34; href=&#34;#__codelineno-1-74&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fastresend&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-75&#34; name=&#34;__codelineno-1-75&#34; href=&#34;#__codelineno-1-75&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-76&#34; name=&#34;__codelineno-1-76&#34; href=&#34;#__codelineno-1-76&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 快速重传最大次数&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-77&#34; name=&#34;__codelineno-1-77&#34; href=&#34;#__codelineno-1-77&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fastlimit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-78&#34; name=&#34;__codelineno-1-78&#34; href=&#34;#__codelineno-1-78&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-79&#34; name=&#34;__codelineno-1-79&#34; href=&#34;#__codelineno-1-79&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// nocwnd: 不考虑慢启动的发送窗口大小&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-80&#34; name=&#34;__codelineno-1-80&#34; href=&#34;#__codelineno-1-80&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// stream: 流模式&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-81&#34; name=&#34;__codelineno-1-81&#34; href=&#34;#__codelineno-1-81&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nocwnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stream&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-82&#34; name=&#34;__codelineno-1-82&#34; href=&#34;#__codelineno-1-82&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-83&#34; name=&#34;__codelineno-1-83&#34; href=&#34;#__codelineno-1-83&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// debug log&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-84&#34; name=&#34;__codelineno-1-84&#34; href=&#34;#__codelineno-1-84&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logmask&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-85&#34; name=&#34;__codelineno-1-85&#34; href=&#34;#__codelineno-1-85&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-86&#34; name=&#34;__codelineno-1-86&#34; href=&#34;#__codelineno-1-86&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 发送数据接口&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-87&#34; name=&#34;__codelineno-1-87&#34; href=&#34;#__codelineno-1-87&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;IKCPCB&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-88&#34; name=&#34;__codelineno-1-88&#34; href=&#34;#__codelineno-1-88&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-89&#34; name=&#34;__codelineno-1-89&#34; href=&#34;#__codelineno-1-89&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;writelog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;IKCPCB&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-90&#34; name=&#34;__codelineno-1-90&#34; href=&#34;#__codelineno-1-90&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/details&gt;

&lt;p&gt;逐一把 KCP 结构里面的字段注释上，可以初步感觉到，整套 KCP 的协议不太复杂，细细去分析代码，你我都能读懂并理解 KCP 协议 &lt;img alt=&#34;😄&#34; class=&#34;twemoji&#34; src=&#34;https://cdn.jsdelivr.net/gh/jdecked/twemoji@15.1.0/assets/svg/1f604.svg&#34; title=&#34;:smile:&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;kcp-arq&#34;&gt;KCP 的 ARQ 实现&lt;/h2&gt;
&lt;p&gt;KCP 本质上是一个 ARQ (Auto Repeat-reQuest，自动重传) 协议，最基本的是要保证可靠的传输。那么我们可以先来关注 KCP 的基本 ARQ 部分，KCP 是怎么实现可靠传输的。&lt;/p&gt;
&lt;p&gt;ARQ 顾名思义，当我们认为对端接收数据包失败时，自动重新发送对应的数据包，它是通过确认接收和超时重传两个机制，来实现可靠传输。具体的代码实现上， KCP 给每个数据包（就是上一节提到的 &lt;code&gt;SEGMENT&lt;/code&gt; ） 分配唯一的 &lt;code&gt;sn&lt;/code&gt; 标识符，一旦对端接收到数据包，会回复一个 ACK 包（同样是 &lt;code&gt;SEGMENT&lt;/code&gt;），ACK 包的 &lt;code&gt;sn&lt;/code&gt; 跟接收到的数据包 &lt;code&gt;sn&lt;/code&gt; 相同，通知接收到此数据包已经接收成功。&lt;code&gt;SEGMENT&lt;/code&gt; 上还有一个 &lt;code&gt;una&lt;/code&gt; 字段，表示下一个期待接收的数据包的编号，换句话说，即是所有在该编号之前的数据包都已经接收完，相当于一个全量的 ACK 包，发送端可以更快的更新发送缓冲和发送窗口。&lt;/p&gt;
&lt;p&gt;我们可以通过跟踪 KCP 包的发送和接受代码，来理解最基本的 ARQ 实现：&lt;/p&gt;
&lt;h3 id=&#34;_1&#34;&gt;发送&lt;/h3&gt;
&lt;p&gt;发送的过程是 &lt;code&gt;ikcp_send&lt;/code&gt; -&amp;gt; &lt;code&gt;ikcp_update&lt;/code&gt; -&amp;gt; &lt;code&gt;ikcp_output&lt;/code&gt;，上层调用 &lt;code&gt;ikcp_send&lt;/code&gt; 把数据传给 KCP，KCP 在 &lt;code&gt;ikcp_update&lt;/code&gt; 中处理数据的发送。&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt; ikcp_send（点击展开代码） &lt;/summary&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-2-1&#34; name=&#34;__codelineno-2-1&#34; href=&#34;#__codelineno-2-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;//---------------------------------------------------------------------&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-2&#34; name=&#34;__codelineno-2-2&#34; href=&#34;#__codelineno-2-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// 发送数据接口，用户调用 ikcp_send 来让 kcp 发送数据&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-3&#34; name=&#34;__codelineno-2-3&#34; href=&#34;#__codelineno-2-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// user/upper level send, returns below zero for error&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-4&#34; name=&#34;__codelineno-2-4&#34; href=&#34;#__codelineno-2-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;//---------------------------------------------------------------------&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-5&#34; name=&#34;__codelineno-2-5&#34; href=&#34;#__codelineno-2-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ikcp_send&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcpcb&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-6&#34; name=&#34;__codelineno-2-6&#34; href=&#34;#__codelineno-2-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-7&#34; name=&#34;__codelineno-2-7&#34; href=&#34;#__codelineno-2-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCPSEG&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-8&#34; name=&#34;__codelineno-2-8&#34; href=&#34;#__codelineno-2-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-9&#34; name=&#34;__codelineno-2-9&#34; href=&#34;#__codelineno-2-9&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-10&#34; name=&#34;__codelineno-2-10&#34; href=&#34;#__codelineno-2-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// mss 不能小于1&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-11&#34; name=&#34;__codelineno-2-11&#34; href=&#34;#__codelineno-2-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;assert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mss&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-12&#34; name=&#34;__codelineno-2-12&#34; href=&#34;#__codelineno-2-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-13&#34; name=&#34;__codelineno-2-13&#34; href=&#34;#__codelineno-2-13&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-14&#34; name=&#34;__codelineno-2-14&#34; href=&#34;#__codelineno-2-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// append to previous segment in streaming mode (if possible)&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-15&#34; name=&#34;__codelineno-2-15&#34; href=&#34;#__codelineno-2-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stream&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-16&#34; name=&#34;__codelineno-2-16&#34; href=&#34;#__codelineno-2-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 处理流模式&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-17&#34; name=&#34;__codelineno-2-17&#34; href=&#34;#__codelineno-2-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ......&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-18&#34; name=&#34;__codelineno-2-18&#34; href=&#34;#__codelineno-2-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-19&#34; name=&#34;__codelineno-2-19&#34; href=&#34;#__codelineno-2-19&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-20&#34; name=&#34;__codelineno-2-20&#34; href=&#34;#__codelineno-2-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 计算分包，如果数据长度 len 大于 mss，需要分成多个包发送，对端接受到之后再拼起来&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-21&#34; name=&#34;__codelineno-2-21&#34; href=&#34;#__codelineno-2-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mss&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-22&#34; name=&#34;__codelineno-2-22&#34; href=&#34;#__codelineno-2-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mss&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mss&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-23&#34; name=&#34;__codelineno-2-23&#34; href=&#34;#__codelineno-2-23&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-24&#34; name=&#34;__codelineno-2-24&#34; href=&#34;#__codelineno-2-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_WND_RCV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;-2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-25&#34; name=&#34;__codelineno-2-25&#34; href=&#34;#__codelineno-2-25&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-26&#34; name=&#34;__codelineno-2-26&#34; href=&#34;#__codelineno-2-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-27&#34; name=&#34;__codelineno-2-27&#34; href=&#34;#__codelineno-2-27&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-28&#34; name=&#34;__codelineno-2-28&#34; href=&#34;#__codelineno-2-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 分包&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-29&#34; name=&#34;__codelineno-2-29&#34; href=&#34;#__codelineno-2-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-30&#34; name=&#34;__codelineno-2-30&#34; href=&#34;#__codelineno-2-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 计算包的数据长度，并分配对应的 seg 结构&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-31&#34; name=&#34;__codelineno-2-31&#34; href=&#34;#__codelineno-2-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mss&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mss&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-32&#34; name=&#34;__codelineno-2-32&#34; href=&#34;#__codelineno-2-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_segment_new&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-33&#34; name=&#34;__codelineno-2-33&#34; href=&#34;#__codelineno-2-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;assert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-34&#34; name=&#34;__codelineno-2-34&#34; href=&#34;#__codelineno-2-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-35&#34; name=&#34;__codelineno-2-35&#34; href=&#34;#__codelineno-2-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;-2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-36&#34; name=&#34;__codelineno-2-36&#34; href=&#34;#__codelineno-2-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-37&#34; name=&#34;__codelineno-2-37&#34; href=&#34;#__codelineno-2-37&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-38&#34; name=&#34;__codelineno-2-38&#34; href=&#34;#__codelineno-2-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 设置 seg 的 数据信息，frg 表示分包编号&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-39&#34; name=&#34;__codelineno-2-39&#34; href=&#34;#__codelineno-2-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-40&#34; name=&#34;__codelineno-2-40&#34; href=&#34;#__codelineno-2-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;memcpy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-41&#34; name=&#34;__codelineno-2-41&#34; href=&#34;#__codelineno-2-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-42&#34; name=&#34;__codelineno-2-42&#34; href=&#34;#__codelineno-2-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-43&#34; name=&#34;__codelineno-2-43&#34; href=&#34;#__codelineno-2-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;frg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stream&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-44&#34; name=&#34;__codelineno-2-44&#34; href=&#34;#__codelineno-2-44&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-45&#34; name=&#34;__codelineno-2-45&#34; href=&#34;#__codelineno-2-45&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 加到 snd_queue 的末尾，nsnd_qua 加一&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-46&#34; name=&#34;__codelineno-2-46&#34; href=&#34;#__codelineno-2-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-47&#34; name=&#34;__codelineno-2-47&#34; href=&#34;#__codelineno-2-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_add_tail&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_queue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-48&#34; name=&#34;__codelineno-2-48&#34; href=&#34;#__codelineno-2-48&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nsnd_que&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-49&#34; name=&#34;__codelineno-2-49&#34; href=&#34;#__codelineno-2-49&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-50&#34; name=&#34;__codelineno-2-50&#34; href=&#34;#__codelineno-2-50&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-51&#34; name=&#34;__codelineno-2-51&#34; href=&#34;#__codelineno-2-51&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-52&#34; name=&#34;__codelineno-2-52&#34; href=&#34;#__codelineno-2-52&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-53&#34; name=&#34;__codelineno-2-53&#34; href=&#34;#__codelineno-2-53&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-54&#34; name=&#34;__codelineno-2-54&#34; href=&#34;#__codelineno-2-54&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-55&#34; name=&#34;__codelineno-2-55&#34; href=&#34;#__codelineno-2-55&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-56&#34; name=&#34;__codelineno-2-56&#34; href=&#34;#__codelineno-2-56&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/details&gt;

&lt;p&gt;&lt;code&gt;ikcp_send&lt;/code&gt; 是由 KCP 的上层来调用的发送数据接口，所有让 KCP 发送的数据，都应该通过这个接口。 &lt;code&gt;ikcp_send&lt;/code&gt; 做的事情很简单，主要就是把数据，根据 &lt;code&gt;kcp-&amp;gt;mss&lt;/code&gt; （一个包最大数据长度）来分成多个包，并设置分包编号，最后放到发送链表 &lt;code&gt;snd_queue&lt;/code&gt; 的末尾。流模式就是把多次调用 &lt;code&gt;ikcp_send&lt;/code&gt; 的数据都看成一个流，会先自动填充未满的 &lt;code&gt;SEGMENT&lt;/code&gt; 再分配新的，详细实现本文不讨论，感兴趣的，相信看完本文，再对应看看代码就能理解。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ikcp_send&lt;/code&gt; 调用完成之后，数据放在的 KCP 的 &lt;code&gt;snd_queue&lt;/code&gt; 中，那么后面 KCP 需要找个时机，把待发送的数据发送出去，这块代码都放在 &lt;code&gt;ikcp_update&lt;/code&gt; 和 &lt;code&gt;ikcp_flush&lt;/code&gt; 里面：&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt; ikcp_update（点击展开代码） &lt;/summary&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-3-1&#34; name=&#34;__codelineno-3-1&#34; href=&#34;#__codelineno-3-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;//---------------------------------------------------------------------&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-2&#34; name=&#34;__codelineno-3-2&#34; href=&#34;#__codelineno-3-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// ikcp_update 是给上层定期调用的接口，用来更新 kcp 的状态，发送数据&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-3&#34; name=&#34;__codelineno-3-3&#34; href=&#34;#__codelineno-3-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// update state (call it repeatedly, every 10ms-100ms), or you can ask &lt;/span&gt;
&lt;a id=&#34;__codelineno-3-4&#34; name=&#34;__codelineno-3-4&#34; href=&#34;#__codelineno-3-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// ikcp_check when to call it again (without ikcp_input/_send calling).&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-5&#34; name=&#34;__codelineno-3-5&#34; href=&#34;#__codelineno-3-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// &amp;#39;current&amp;#39; - current timestamp in millisec. &lt;/span&gt;
&lt;a id=&#34;__codelineno-3-6&#34; name=&#34;__codelineno-3-6&#34; href=&#34;#__codelineno-3-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;//---------------------------------------------------------------------&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-7&#34; name=&#34;__codelineno-3-7&#34; href=&#34;#__codelineno-3-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ikcp_update&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcpcb&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-8&#34; name=&#34;__codelineno-3-8&#34; href=&#34;#__codelineno-3-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-9&#34; name=&#34;__codelineno-3-9&#34; href=&#34;#__codelineno-3-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;slap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-10&#34; name=&#34;__codelineno-3-10&#34; href=&#34;#__codelineno-3-10&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-11&#34; name=&#34;__codelineno-3-11&#34; href=&#34;#__codelineno-3-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-12&#34; name=&#34;__codelineno-3-12&#34; href=&#34;#__codelineno-3-12&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-13&#34; name=&#34;__codelineno-3-13&#34; href=&#34;#__codelineno-3-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ikcp_flush 会检查这个，上层必须调用过 ikcp_update 才能调用 ikcp_flush，建议只使用 ikcp_update&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-14&#34; name=&#34;__codelineno-3-14&#34; href=&#34;#__codelineno-3-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;updated&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-15&#34; name=&#34;__codelineno-3-15&#34; href=&#34;#__codelineno-3-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;updated&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-16&#34; name=&#34;__codelineno-3-16&#34; href=&#34;#__codelineno-3-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts_flush&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-17&#34; name=&#34;__codelineno-3-17&#34; href=&#34;#__codelineno-3-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-18&#34; name=&#34;__codelineno-3-18&#34; href=&#34;#__codelineno-3-18&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-19&#34; name=&#34;__codelineno-3-19&#34; href=&#34;#__codelineno-3-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;slap&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_itimediff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts_flush&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-20&#34; name=&#34;__codelineno-3-20&#34; href=&#34;#__codelineno-3-20&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-21&#34; name=&#34;__codelineno-3-21&#34; href=&#34;#__codelineno-3-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;slap&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10000&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;slap&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;-10000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-22&#34; name=&#34;__codelineno-3-22&#34; href=&#34;#__codelineno-3-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts_flush&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-23&#34; name=&#34;__codelineno-3-23&#34; href=&#34;#__codelineno-3-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;slap&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-24&#34; name=&#34;__codelineno-3-24&#34; href=&#34;#__codelineno-3-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-25&#34; name=&#34;__codelineno-3-25&#34; href=&#34;#__codelineno-3-25&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-26&#34; name=&#34;__codelineno-3-26&#34; href=&#34;#__codelineno-3-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;slap&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-27&#34; name=&#34;__codelineno-3-27&#34; href=&#34;#__codelineno-3-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 下次 flush 的时间&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-28&#34; name=&#34;__codelineno-3-28&#34; href=&#34;#__codelineno-3-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts_flush&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-29&#34; name=&#34;__codelineno-3-29&#34; href=&#34;#__codelineno-3-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_itimediff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts_flush&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-30&#34; name=&#34;__codelineno-3-30&#34; href=&#34;#__codelineno-3-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts_flush&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-31&#34; name=&#34;__codelineno-3-31&#34; href=&#34;#__codelineno-3-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-32&#34; name=&#34;__codelineno-3-32&#34; href=&#34;#__codelineno-3-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_flush&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-33&#34; name=&#34;__codelineno-3-33&#34; href=&#34;#__codelineno-3-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-34&#34; name=&#34;__codelineno-3-34&#34; href=&#34;#__codelineno-3-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/details&gt;

&lt;p&gt;&lt;code&gt;ikcp_update&lt;/code&gt; 做的事情很简单，判断一下 &lt;code&gt;ts_flush&lt;/code&gt; 的时间，符合条件则调用 &lt;code&gt;ikcp_flush&lt;/code&gt;，主要的处理逻辑都在 &lt;code&gt;ikcp_flush&lt;/code&gt; 里面了，因为 &lt;code&gt;ikcp_flush&lt;/code&gt; 内容复杂一点，我们目前只关注跟 ARQ 发送相关的部分：&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt; 发送数据（点击展开代码） &lt;/summary&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-4-1&#34; name=&#34;__codelineno-4-1&#34; href=&#34;#__codelineno-4-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;//---------------------------------------------------------------------&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-2&#34; name=&#34;__codelineno-4-2&#34; href=&#34;#__codelineno-4-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// ikcp_flush&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-3&#34; name=&#34;__codelineno-4-3&#34; href=&#34;#__codelineno-4-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;//---------------------------------------------------------------------&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-4&#34; name=&#34;__codelineno-4-4&#34; href=&#34;#__codelineno-4-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ikcp_flush&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcpcb&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-5&#34; name=&#34;__codelineno-4-5&#34; href=&#34;#__codelineno-4-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-6&#34; name=&#34;__codelineno-4-6&#34; href=&#34;#__codelineno-4-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-7&#34; name=&#34;__codelineno-4-7&#34; href=&#34;#__codelineno-4-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-8&#34; name=&#34;__codelineno-4-8&#34; href=&#34;#__codelineno-4-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// buffer 是要传给 ikcp_output 的数据，初始化为 3 倍数据包大小&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-9&#34; name=&#34;__codelineno-4-9&#34; href=&#34;#__codelineno-4-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-10&#34; name=&#34;__codelineno-4-10&#34; href=&#34;#__codelineno-4-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-11&#34; name=&#34;__codelineno-4-11&#34; href=&#34;#__codelineno-4-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-12&#34; name=&#34;__codelineno-4-12&#34; href=&#34;#__codelineno-4-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-13&#34; name=&#34;__codelineno-4-13&#34; href=&#34;#__codelineno-4-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rtomin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-14&#34; name=&#34;__codelineno-4-14&#34; href=&#34;#__codelineno-4-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;IQUEUEHEAD&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-15&#34; name=&#34;__codelineno-4-15&#34; href=&#34;#__codelineno-4-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;change&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-16&#34; name=&#34;__codelineno-4-16&#34; href=&#34;#__codelineno-4-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lost&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-17&#34; name=&#34;__codelineno-4-17&#34; href=&#34;#__codelineno-4-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCPSEG&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-18&#34; name=&#34;__codelineno-4-18&#34; href=&#34;#__codelineno-4-18&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-19&#34; name=&#34;__codelineno-4-19&#34; href=&#34;#__codelineno-4-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// &amp;#39;ikcp_update&amp;#39; haven&amp;#39;t been called.&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-20&#34; name=&#34;__codelineno-4-20&#34; href=&#34;#__codelineno-4-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;updated&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-21&#34; name=&#34;__codelineno-4-21&#34; href=&#34;#__codelineno-4-21&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-22&#34; name=&#34;__codelineno-4-22&#34; href=&#34;#__codelineno-4-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;conv&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;conv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-23&#34; name=&#34;__codelineno-4-23&#34; href=&#34;#__codelineno-4-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_CMD_ACK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-24&#34; name=&#34;__codelineno-4-24&#34; href=&#34;#__codelineno-4-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;frg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-25&#34; name=&#34;__codelineno-4-25&#34; href=&#34;#__codelineno-4-25&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-26&#34; name=&#34;__codelineno-4-26&#34; href=&#34;#__codelineno-4-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// seg.wnd 是表示当前可接收窗口大小&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-27&#34; name=&#34;__codelineno-4-27&#34; href=&#34;#__codelineno-4-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_wnd_unused&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-28&#34; name=&#34;__codelineno-4-28&#34; href=&#34;#__codelineno-4-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;una&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_nxt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-29&#34; name=&#34;__codelineno-4-29&#34; href=&#34;#__codelineno-4-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-30&#34; name=&#34;__codelineno-4-30&#34; href=&#34;#__codelineno-4-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-31&#34; name=&#34;__codelineno-4-31&#34; href=&#34;#__codelineno-4-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-32&#34; name=&#34;__codelineno-4-32&#34; href=&#34;#__codelineno-4-32&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-33&#34; name=&#34;__codelineno-4-33&#34; href=&#34;#__codelineno-4-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 发送 ack&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-34&#34; name=&#34;__codelineno-4-34&#34; href=&#34;#__codelineno-4-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 计算 发送窗口&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-35&#34; name=&#34;__codelineno-4-35&#34; href=&#34;#__codelineno-4-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//...&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-36&#34; name=&#34;__codelineno-4-36&#34; href=&#34;#__codelineno-4-36&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-37&#34; name=&#34;__codelineno-4-37&#34; href=&#34;#__codelineno-4-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 把数据包从 snd_queue 移动到 snd_buf&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-38&#34; name=&#34;__codelineno-4-38&#34; href=&#34;#__codelineno-4-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 移动是需要满足 发送窗口 大小，发送窗口满了，就停止移动&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-39&#34; name=&#34;__codelineno-4-39&#34; href=&#34;#__codelineno-4-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 放在 snd_buf 的里面的数据，就是可以直接调用 ikcp_output 给对端发送的数据&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-40&#34; name=&#34;__codelineno-4-40&#34; href=&#34;#__codelineno-4-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_itimediff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_nxt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_una&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-41&#34; name=&#34;__codelineno-4-41&#34; href=&#34;#__codelineno-4-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCPSEG&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newseg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-42&#34; name=&#34;__codelineno-4-42&#34; href=&#34;#__codelineno-4-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_is_empty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_queue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-43&#34; name=&#34;__codelineno-4-43&#34; href=&#34;#__codelineno-4-43&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-44&#34; name=&#34;__codelineno-4-44&#34; href=&#34;#__codelineno-4-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newseg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_queue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCPSEG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-45&#34; name=&#34;__codelineno-4-45&#34; href=&#34;#__codelineno-4-45&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-46&#34; name=&#34;__codelineno-4-46&#34; href=&#34;#__codelineno-4-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_del&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newseg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-47&#34; name=&#34;__codelineno-4-47&#34; href=&#34;#__codelineno-4-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_add_tail&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newseg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-48&#34; name=&#34;__codelineno-4-48&#34; href=&#34;#__codelineno-4-48&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nsnd_que&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-49&#34; name=&#34;__codelineno-4-49&#34; href=&#34;#__codelineno-4-49&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nsnd_buf&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-50&#34; name=&#34;__codelineno-4-50&#34; href=&#34;#__codelineno-4-50&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-51&#34; name=&#34;__codelineno-4-51&#34; href=&#34;#__codelineno-4-51&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newseg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;conv&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;conv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-52&#34; name=&#34;__codelineno-4-52&#34; href=&#34;#__codelineno-4-52&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newseg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_CMD_PUSH&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-53&#34; name=&#34;__codelineno-4-53&#34; href=&#34;#__codelineno-4-53&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newseg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-54&#34; name=&#34;__codelineno-4-54&#34; href=&#34;#__codelineno-4-54&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newseg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-55&#34; name=&#34;__codelineno-4-55&#34; href=&#34;#__codelineno-4-55&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-56&#34; name=&#34;__codelineno-4-56&#34; href=&#34;#__codelineno-4-56&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// seg 唯一序号，其实就是一个递增的 kcp-&amp;gt;snd_nxt&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-57&#34; name=&#34;__codelineno-4-57&#34; href=&#34;#__codelineno-4-57&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newseg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_nxt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-58&#34; name=&#34;__codelineno-4-58&#34; href=&#34;#__codelineno-4-58&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-59&#34; name=&#34;__codelineno-4-59&#34; href=&#34;#__codelineno-4-59&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// una 在这里设置，通知对端下一个等待接收的包序号&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-60&#34; name=&#34;__codelineno-4-60&#34; href=&#34;#__codelineno-4-60&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newseg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;una&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_nxt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-61&#34; name=&#34;__codelineno-4-61&#34; href=&#34;#__codelineno-4-61&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newseg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resendts&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-62&#34; name=&#34;__codelineno-4-62&#34; href=&#34;#__codelineno-4-62&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newseg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rx_rto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-63&#34; name=&#34;__codelineno-4-63&#34; href=&#34;#__codelineno-4-63&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newseg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fastack&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-64&#34; name=&#34;__codelineno-4-64&#34; href=&#34;#__codelineno-4-64&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newseg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-65&#34; name=&#34;__codelineno-4-65&#34; href=&#34;#__codelineno-4-65&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-66&#34; name=&#34;__codelineno-4-66&#34; href=&#34;#__codelineno-4-66&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-67&#34; name=&#34;__codelineno-4-67&#34; href=&#34;#__codelineno-4-67&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 计算快速重传标志，超时等待时间&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-68&#34; name=&#34;__codelineno-4-68&#34; href=&#34;#__codelineno-4-68&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-69&#34; name=&#34;__codelineno-4-69&#34; href=&#34;#__codelineno-4-69&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-70&#34; name=&#34;__codelineno-4-70&#34; href=&#34;#__codelineno-4-70&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 发送 snd_buf&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-71&#34; name=&#34;__codelineno-4-71&#34; href=&#34;#__codelineno-4-71&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-72&#34; name=&#34;__codelineno-4-72&#34; href=&#34;#__codelineno-4-72&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCPSEG&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCPSEG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-73&#34; name=&#34;__codelineno-4-73&#34; href=&#34;#__codelineno-4-73&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;needsend&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-74&#34; name=&#34;__codelineno-4-74&#34; href=&#34;#__codelineno-4-74&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-75&#34; name=&#34;__codelineno-4-75&#34; href=&#34;#__codelineno-4-75&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 首次发送&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-76&#34; name=&#34;__codelineno-4-76&#34; href=&#34;#__codelineno-4-76&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// set-&amp;gt;xmit 表示发送次数&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-77&#34; name=&#34;__codelineno-4-77&#34; href=&#34;#__codelineno-4-77&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// resendts 超时重传的等待时间&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-78&#34; name=&#34;__codelineno-4-78&#34; href=&#34;#__codelineno-4-78&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;needsend&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-79&#34; name=&#34;__codelineno-4-79&#34; href=&#34;#__codelineno-4-79&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmit&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-80&#34; name=&#34;__codelineno-4-80&#34; href=&#34;#__codelineno-4-80&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rx_rto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-81&#34; name=&#34;__codelineno-4-81&#34; href=&#34;#__codelineno-4-81&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resendts&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rtomin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-82&#34; name=&#34;__codelineno-4-82&#34; href=&#34;#__codelineno-4-82&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-83&#34; name=&#34;__codelineno-4-83&#34; href=&#34;#__codelineno-4-83&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_itimediff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resendts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-84&#34; name=&#34;__codelineno-4-84&#34; href=&#34;#__codelineno-4-84&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 超时重传&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-85&#34; name=&#34;__codelineno-4-85&#34; href=&#34;#__codelineno-4-85&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-86&#34; name=&#34;__codelineno-4-86&#34; href=&#34;#__codelineno-4-86&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-87&#34; name=&#34;__codelineno-4-87&#34; href=&#34;#__codelineno-4-87&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fastack&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-88&#34; name=&#34;__codelineno-4-88&#34; href=&#34;#__codelineno-4-88&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 快速重传&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-89&#34; name=&#34;__codelineno-4-89&#34; href=&#34;#__codelineno-4-89&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-90&#34; name=&#34;__codelineno-4-90&#34; href=&#34;#__codelineno-4-90&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-91&#34; name=&#34;__codelineno-4-91&#34; href=&#34;#__codelineno-4-91&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-92&#34; name=&#34;__codelineno-4-92&#34; href=&#34;#__codelineno-4-92&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;needsend&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-93&#34; name=&#34;__codelineno-4-93&#34; href=&#34;#__codelineno-4-93&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;need&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-94&#34; name=&#34;__codelineno-4-94&#34; href=&#34;#__codelineno-4-94&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-95&#34; name=&#34;__codelineno-4-95&#34; href=&#34;#__codelineno-4-95&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-96&#34; name=&#34;__codelineno-4-96&#34; href=&#34;#__codelineno-4-96&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;una&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_nxt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-97&#34; name=&#34;__codelineno-4-97&#34; href=&#34;#__codelineno-4-97&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-98&#34; name=&#34;__codelineno-4-98&#34; href=&#34;#__codelineno-4-98&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-99&#34; name=&#34;__codelineno-4-99&#34; href=&#34;#__codelineno-4-99&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;need&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_OVERHEAD&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-100&#34; name=&#34;__codelineno-4-100&#34; href=&#34;#__codelineno-4-100&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-101&#34; name=&#34;__codelineno-4-101&#34; href=&#34;#__codelineno-4-101&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 每当 buffer 中的数据超过 mtu ，那就先发出去，尽量避免底层再分包&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-102&#34; name=&#34;__codelineno-4-102&#34; href=&#34;#__codelineno-4-102&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;need&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mtu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-103&#34; name=&#34;__codelineno-4-103&#34; href=&#34;#__codelineno-4-103&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_output&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-104&#34; name=&#34;__codelineno-4-104&#34; href=&#34;#__codelineno-4-104&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-105&#34; name=&#34;__codelineno-4-105&#34; href=&#34;#__codelineno-4-105&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-106&#34; name=&#34;__codelineno-4-106&#34; href=&#34;#__codelineno-4-106&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-107&#34; name=&#34;__codelineno-4-107&#34; href=&#34;#__codelineno-4-107&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 把 seg 控制数据复制到 buffer 上，kcp 自己来处理大小端问题&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-108&#34; name=&#34;__codelineno-4-108&#34; href=&#34;#__codelineno-4-108&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_encode_seg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-109&#34; name=&#34;__codelineno-4-109&#34; href=&#34;#__codelineno-4-109&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-110&#34; name=&#34;__codelineno-4-110&#34; href=&#34;#__codelineno-4-110&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 再复制数据&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-111&#34; name=&#34;__codelineno-4-111&#34; href=&#34;#__codelineno-4-111&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-112&#34; name=&#34;__codelineno-4-112&#34; href=&#34;#__codelineno-4-112&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;memcpy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-113&#34; name=&#34;__codelineno-4-113&#34; href=&#34;#__codelineno-4-113&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-114&#34; name=&#34;__codelineno-4-114&#34; href=&#34;#__codelineno-4-114&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-115&#34; name=&#34;__codelineno-4-115&#34; href=&#34;#__codelineno-4-115&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-116&#34; name=&#34;__codelineno-4-116&#34; href=&#34;#__codelineno-4-116&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-117&#34; name=&#34;__codelineno-4-117&#34; href=&#34;#__codelineno-4-117&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dead_link&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-118&#34; name=&#34;__codelineno-4-118&#34; href=&#34;#__codelineno-4-118&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;state&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-119&#34; name=&#34;__codelineno-4-119&#34; href=&#34;#__codelineno-4-119&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-120&#34; name=&#34;__codelineno-4-120&#34; href=&#34;#__codelineno-4-120&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-121&#34; name=&#34;__codelineno-4-121&#34; href=&#34;#__codelineno-4-121&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-122&#34; name=&#34;__codelineno-4-122&#34; href=&#34;#__codelineno-4-122&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-123&#34; name=&#34;__codelineno-4-123&#34; href=&#34;#__codelineno-4-123&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// flash remain segments&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-124&#34; name=&#34;__codelineno-4-124&#34; href=&#34;#__codelineno-4-124&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-125&#34; name=&#34;__codelineno-4-125&#34; href=&#34;#__codelineno-4-125&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-126&#34; name=&#34;__codelineno-4-126&#34; href=&#34;#__codelineno-4-126&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_output&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-127&#34; name=&#34;__codelineno-4-127&#34; href=&#34;#__codelineno-4-127&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-128&#34; name=&#34;__codelineno-4-128&#34; href=&#34;#__codelineno-4-128&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-129&#34; name=&#34;__codelineno-4-129&#34; href=&#34;#__codelineno-4-129&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 计算 ssthresh，更新慢启动窗口&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-130&#34; name=&#34;__codelineno-4-130&#34; href=&#34;#__codelineno-4-130&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-131&#34; name=&#34;__codelineno-4-131&#34; href=&#34;#__codelineno-4-131&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/details&gt;

&lt;p&gt;我们目前只关注 &lt;code&gt;ikcp_flush&lt;/code&gt; 里面有关发送数据的逻辑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;首先 KCP 会根据对端的接收窗口大小，把 &lt;code&gt;snd_queue&lt;/code&gt; 上的数据移动到 &lt;code&gt;snd_buf&lt;/code&gt; 上面，计算移动数量的公式是 &lt;code&gt;num = snd_nxt - (snd_una + cwnd)&lt;/code&gt;，也就是：已发送成功的最大包序号 &lt;code&gt;snd_una&lt;/code&gt; 加上 滑动窗口大小 &lt;code&gt;cwnd&lt;/code&gt; 大于 下个待发送的包序号&lt;code&gt;snd_nxt&lt;/code&gt;，则可以继续再发送新的数据包。移动 &lt;code&gt;SEG&lt;/code&gt; 的同时，设置控制字段。&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;遍历 &lt;code&gt;snd_buf&lt;/code&gt;，如果需要发送数据包，则把数据复制到 &lt;code&gt;buffer&lt;/code&gt; 上，复制的同时用 &lt;code&gt;ikcp_encode_seg&lt;/code&gt; 处理控制字段数据的大小端问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;最后调用 &lt;code&gt;ikcp_output&lt;/code&gt; 把 &lt;code&gt;buffer&lt;/code&gt; 上的数据发送出去&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;至此， KCP 完成数据的发送。&lt;/p&gt;
&lt;h3 id=&#34;_2&#34;&gt;接收&lt;/h3&gt;
&lt;p&gt;接收的过程是跟发送相反的：&lt;code&gt;ikcp_input&lt;/code&gt; -&amp;gt; &lt;code&gt;ikcp_update&lt;/code&gt; -&amp;gt; &lt;code&gt;ikcp_recv&lt;/code&gt;，用户接收到网络上的数据之后，需要调用 &lt;code&gt;ikcp_input&lt;/code&gt; 传给 KCP 解析，调用 &lt;code&gt;ikcp_update&lt;/code&gt; 的时候会给发送端回复 ACK 包，上层通过调用 &lt;code&gt;ikcp_recv&lt;/code&gt; 来接收 KCP 解析之后的数据。&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt; 接收数据（点击展开代码） &lt;/summary&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-5-1&#34; name=&#34;__codelineno-5-1&#34; href=&#34;#__codelineno-5-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;//---------------------------------------------------------------------&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-2&#34; name=&#34;__codelineno-5-2&#34; href=&#34;#__codelineno-5-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// input data&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-3&#34; name=&#34;__codelineno-5-3&#34; href=&#34;#__codelineno-5-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;//---------------------------------------------------------------------&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-4&#34; name=&#34;__codelineno-5-4&#34; href=&#34;#__codelineno-5-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ikcp_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcpcb&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;long&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-5&#34; name=&#34;__codelineno-5-5&#34; href=&#34;#__codelineno-5-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-6&#34; name=&#34;__codelineno-5-6&#34; href=&#34;#__codelineno-5-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev_una&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_una&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-7&#34; name=&#34;__codelineno-5-7&#34; href=&#34;#__codelineno-5-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;maxack&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;latest_ts&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-8&#34; name=&#34;__codelineno-5-8&#34; href=&#34;#__codelineno-5-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;flag&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-9&#34; name=&#34;__codelineno-5-9&#34; href=&#34;#__codelineno-5-9&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-10&#34; name=&#34;__codelineno-5-10&#34; href=&#34;#__codelineno-5-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 合法性检查&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-11&#34; name=&#34;__codelineno-5-11&#34; href=&#34;#__codelineno-5-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_OVERHEAD&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-12&#34; name=&#34;__codelineno-5-12&#34; href=&#34;#__codelineno-5-12&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-13&#34; name=&#34;__codelineno-5-13&#34; href=&#34;#__codelineno-5-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// data 可能是多个 KCP 包，循环处理&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-14&#34; name=&#34;__codelineno-5-14&#34; href=&#34;#__codelineno-5-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-15&#34; name=&#34;__codelineno-5-15&#34; href=&#34;#__codelineno-5-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;una&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;conv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-16&#34; name=&#34;__codelineno-5-16&#34; href=&#34;#__codelineno-5-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT16&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-17&#34; name=&#34;__codelineno-5-17&#34; href=&#34;#__codelineno-5-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT8&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;frg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-18&#34; name=&#34;__codelineno-5-18&#34; href=&#34;#__codelineno-5-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCPSEG&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-19&#34; name=&#34;__codelineno-5-19&#34; href=&#34;#__codelineno-5-19&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-20&#34; name=&#34;__codelineno-5-20&#34; href=&#34;#__codelineno-5-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 不够一个 KCP 包，退出&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-21&#34; name=&#34;__codelineno-5-21&#34; href=&#34;#__codelineno-5-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_OVERHEAD&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-22&#34; name=&#34;__codelineno-5-22&#34; href=&#34;#__codelineno-5-22&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-23&#34; name=&#34;__codelineno-5-23&#34; href=&#34;#__codelineno-5-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 先把控制字段解析出来&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-24&#34; name=&#34;__codelineno-5-24&#34; href=&#34;#__codelineno-5-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_decode32u&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;conv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-25&#34; name=&#34;__codelineno-5-25&#34; href=&#34;#__codelineno-5-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;conv&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;conv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-26&#34; name=&#34;__codelineno-5-26&#34; href=&#34;#__codelineno-5-26&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-27&#34; name=&#34;__codelineno-5-27&#34; href=&#34;#__codelineno-5-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_decode8u&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-28&#34; name=&#34;__codelineno-5-28&#34; href=&#34;#__codelineno-5-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_decode8u&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;frg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-29&#34; name=&#34;__codelineno-5-29&#34; href=&#34;#__codelineno-5-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_decode16u&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-30&#34; name=&#34;__codelineno-5-30&#34; href=&#34;#__codelineno-5-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_decode32u&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-31&#34; name=&#34;__codelineno-5-31&#34; href=&#34;#__codelineno-5-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_decode32u&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-32&#34; name=&#34;__codelineno-5-32&#34; href=&#34;#__codelineno-5-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_decode32u&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;una&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-33&#34; name=&#34;__codelineno-5-33&#34; href=&#34;#__codelineno-5-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_decode32u&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-34&#34; name=&#34;__codelineno-5-34&#34; href=&#34;#__codelineno-5-34&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-35&#34; name=&#34;__codelineno-5-35&#34; href=&#34;#__codelineno-5-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_OVERHEAD&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-36&#34; name=&#34;__codelineno-5-36&#34; href=&#34;#__codelineno-5-36&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-37&#34; name=&#34;__codelineno-5-37&#34; href=&#34;#__codelineno-5-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;long&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;long&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;-2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-38&#34; name=&#34;__codelineno-5-38&#34; href=&#34;#__codelineno-5-38&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-39&#34; name=&#34;__codelineno-5-39&#34; href=&#34;#__codelineno-5-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 数据包类型检查&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-40&#34; name=&#34;__codelineno-5-40&#34; href=&#34;#__codelineno-5-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_CMD_PUSH&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_CMD_ACK&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-41&#34; name=&#34;__codelineno-5-41&#34; href=&#34;#__codelineno-5-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_CMD_WASK&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_CMD_WINS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-5-42&#34; name=&#34;__codelineno-5-42&#34; href=&#34;#__codelineno-5-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;-3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-43&#34; name=&#34;__codelineno-5-43&#34; href=&#34;#__codelineno-5-43&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-44&#34; name=&#34;__codelineno-5-44&#34; href=&#34;#__codelineno-5-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rmt_wnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-45&#34; name=&#34;__codelineno-5-45&#34; href=&#34;#__codelineno-5-45&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-46&#34; name=&#34;__codelineno-5-46&#34; href=&#34;#__codelineno-5-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 这里的 una 是发送方的 kcp-&amp;gt;rcv_nxt，根据这个数据，可以去掉已确认接收的数据包&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-47&#34; name=&#34;__codelineno-5-47&#34; href=&#34;#__codelineno-5-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_parse_una&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;una&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-48&#34; name=&#34;__codelineno-5-48&#34; href=&#34;#__codelineno-5-48&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 去掉已确认接收的包后，更新 snd_una 下一个要发送的序号&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-49&#34; name=&#34;__codelineno-5-49&#34; href=&#34;#__codelineno-5-49&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_shrink_buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-50&#34; name=&#34;__codelineno-5-50&#34; href=&#34;#__codelineno-5-50&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-51&#34; name=&#34;__codelineno-5-51&#34; href=&#34;#__codelineno-5-51&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_CMD_ACK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-52&#34; name=&#34;__codelineno-5-52&#34; href=&#34;#__codelineno-5-52&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ack 包&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-53&#34; name=&#34;__codelineno-5-53&#34; href=&#34;#__codelineno-5-53&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-54&#34; name=&#34;__codelineno-5-54&#34; href=&#34;#__codelineno-5-54&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-55&#34; name=&#34;__codelineno-5-55&#34; href=&#34;#__codelineno-5-55&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_CMD_PUSH&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-56&#34; name=&#34;__codelineno-5-56&#34; href=&#34;#__codelineno-5-56&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 数据包&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-57&#34; name=&#34;__codelineno-5-57&#34; href=&#34;#__codelineno-5-57&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 如果接收到的数据包序号 sn，在接收窗口内，则正常处理，否则直接丢弃，等重传&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-58&#34; name=&#34;__codelineno-5-58&#34; href=&#34;#__codelineno-5-58&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_itimediff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_nxt&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_wnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-59&#34; name=&#34;__codelineno-5-59&#34; href=&#34;#__codelineno-5-59&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-60&#34; name=&#34;__codelineno-5-60&#34; href=&#34;#__codelineno-5-60&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 接收到的每个数据包，都要回一个 ack 包，记录下来&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-61&#34; name=&#34;__codelineno-5-61&#34; href=&#34;#__codelineno-5-61&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_ack_push&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-62&#34; name=&#34;__codelineno-5-62&#34; href=&#34;#__codelineno-5-62&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-63&#34; name=&#34;__codelineno-5-63&#34; href=&#34;#__codelineno-5-63&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 接收的数据调用 ikcp_parse_data 处理&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-64&#34; name=&#34;__codelineno-5-64&#34; href=&#34;#__codelineno-5-64&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_itimediff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_nxt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-65&#34; name=&#34;__codelineno-5-65&#34; href=&#34;#__codelineno-5-65&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_segment_new&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-66&#34; name=&#34;__codelineno-5-66&#34; href=&#34;#__codelineno-5-66&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;conv&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;conv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-67&#34; name=&#34;__codelineno-5-67&#34; href=&#34;#__codelineno-5-67&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-68&#34; name=&#34;__codelineno-5-68&#34; href=&#34;#__codelineno-5-68&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;frg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;frg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-69&#34; name=&#34;__codelineno-5-69&#34; href=&#34;#__codelineno-5-69&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-70&#34; name=&#34;__codelineno-5-70&#34; href=&#34;#__codelineno-5-70&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-71&#34; name=&#34;__codelineno-5-71&#34; href=&#34;#__codelineno-5-71&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-72&#34; name=&#34;__codelineno-5-72&#34; href=&#34;#__codelineno-5-72&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;una&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;una&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-73&#34; name=&#34;__codelineno-5-73&#34; href=&#34;#__codelineno-5-73&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-74&#34; name=&#34;__codelineno-5-74&#34; href=&#34;#__codelineno-5-74&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-75&#34; name=&#34;__codelineno-5-75&#34; href=&#34;#__codelineno-5-75&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-76&#34; name=&#34;__codelineno-5-76&#34; href=&#34;#__codelineno-5-76&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;memcpy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-77&#34; name=&#34;__codelineno-5-77&#34; href=&#34;#__codelineno-5-77&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-78&#34; name=&#34;__codelineno-5-78&#34; href=&#34;#__codelineno-5-78&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-79&#34; name=&#34;__codelineno-5-79&#34; href=&#34;#__codelineno-5-79&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_parse_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-80&#34; name=&#34;__codelineno-5-80&#34; href=&#34;#__codelineno-5-80&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-81&#34; name=&#34;__codelineno-5-81&#34; href=&#34;#__codelineno-5-81&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-82&#34; name=&#34;__codelineno-5-82&#34; href=&#34;#__codelineno-5-82&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-83&#34; name=&#34;__codelineno-5-83&#34; href=&#34;#__codelineno-5-83&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_CMD_WASK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-84&#34; name=&#34;__codelineno-5-84&#34; href=&#34;#__codelineno-5-84&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 查询窗口包&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-85&#34; name=&#34;__codelineno-5-85&#34; href=&#34;#__codelineno-5-85&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-86&#34; name=&#34;__codelineno-5-86&#34; href=&#34;#__codelineno-5-86&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-87&#34; name=&#34;__codelineno-5-87&#34; href=&#34;#__codelineno-5-87&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_CMD_WINS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-88&#34; name=&#34;__codelineno-5-88&#34; href=&#34;#__codelineno-5-88&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 查询窗口的回复包&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-89&#34; name=&#34;__codelineno-5-89&#34; href=&#34;#__codelineno-5-89&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-90&#34; name=&#34;__codelineno-5-90&#34; href=&#34;#__codelineno-5-90&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-91&#34; name=&#34;__codelineno-5-91&#34; href=&#34;#__codelineno-5-91&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-92&#34; name=&#34;__codelineno-5-92&#34; href=&#34;#__codelineno-5-92&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;-3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-93&#34; name=&#34;__codelineno-5-93&#34; href=&#34;#__codelineno-5-93&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-94&#34; name=&#34;__codelineno-5-94&#34; href=&#34;#__codelineno-5-94&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-95&#34; name=&#34;__codelineno-5-95&#34; href=&#34;#__codelineno-5-95&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-96&#34; name=&#34;__codelineno-5-96&#34; href=&#34;#__codelineno-5-96&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-97&#34; name=&#34;__codelineno-5-97&#34; href=&#34;#__codelineno-5-97&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-98&#34; name=&#34;__codelineno-5-98&#34; href=&#34;#__codelineno-5-98&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-99&#34; name=&#34;__codelineno-5-99&#34; href=&#34;#__codelineno-5-99&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 处理快速重传逻辑&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-100&#34; name=&#34;__codelineno-5-100&#34; href=&#34;#__codelineno-5-100&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-101&#34; name=&#34;__codelineno-5-101&#34; href=&#34;#__codelineno-5-101&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-102&#34; name=&#34;__codelineno-5-102&#34; href=&#34;#__codelineno-5-102&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 更新发送窗口&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-103&#34; name=&#34;__codelineno-5-103&#34; href=&#34;#__codelineno-5-103&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-104&#34; name=&#34;__codelineno-5-104&#34; href=&#34;#__codelineno-5-104&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-105&#34; name=&#34;__codelineno-5-105&#34; href=&#34;#__codelineno-5-105&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-106&#34; name=&#34;__codelineno-5-106&#34; href=&#34;#__codelineno-5-106&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/details&gt;

&lt;p&gt;&lt;code&gt;ikcp_input&lt;/code&gt; 循环处理每一个 &lt;code&gt;SEG&lt;/code&gt; 包，先检查数据包的合法性和类型，因为每个数据包都会带上 &lt;code&gt;una&lt;/code&gt;，存放的是发送端等待接收的包序号，需要小于 &lt;code&gt;una&lt;/code&gt; 的包对端都已经接受成功，所以可以把 &lt;code&gt;snd_buff&lt;/code&gt; 中需要小于 &lt;code&gt;una&lt;/code&gt; 的都删掉，并更新 &lt;code&gt;snd_nxt&lt;/code&gt;，这一部分由 &lt;code&gt;ikcp_parse_una&lt;/code&gt; 和 &lt;code&gt;ikcp_shrink_buf&lt;/code&gt; 来处理。接收到的每个数据包，都需要回复 ACK 包，由 &lt;code&gt;ikcp_ack_push&lt;/code&gt; 记录下来，最后调用 &lt;code&gt;ikcp_parse_data&lt;/code&gt; 处理数据。&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt; 解析数据（点击展开代码） &lt;/summary&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-6-1&#34; name=&#34;__codelineno-6-1&#34; href=&#34;#__codelineno-6-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ikcp_parse_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcpcb&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCPSEG&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newseg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-2&#34; name=&#34;__codelineno-6-2&#34; href=&#34;#__codelineno-6-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-3&#34; name=&#34;__codelineno-6-3&#34; href=&#34;#__codelineno-6-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;IQUEUEHEAD&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-4&#34; name=&#34;__codelineno-6-4&#34; href=&#34;#__codelineno-6-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newseg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-5&#34; name=&#34;__codelineno-6-5&#34; href=&#34;#__codelineno-6-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;repeat&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-6&#34; name=&#34;__codelineno-6-6&#34; href=&#34;#__codelineno-6-6&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-7&#34; name=&#34;__codelineno-6-7&#34; href=&#34;#__codelineno-6-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 序号检查&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-8&#34; name=&#34;__codelineno-6-8&#34; href=&#34;#__codelineno-6-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_itimediff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_nxt&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_wnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-9&#34; name=&#34;__codelineno-6-9&#34; href=&#34;#__codelineno-6-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_itimediff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_nxt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-10&#34; name=&#34;__codelineno-6-10&#34; href=&#34;#__codelineno-6-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_segment_delete&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newseg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-11&#34; name=&#34;__codelineno-6-11&#34; href=&#34;#__codelineno-6-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-12&#34; name=&#34;__codelineno-6-12&#34; href=&#34;#__codelineno-6-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-13&#34; name=&#34;__codelineno-6-13&#34; href=&#34;#__codelineno-6-13&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-14&#34; name=&#34;__codelineno-6-14&#34; href=&#34;#__codelineno-6-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 找出 newseg 应该放置的位置，因为接收到的 seg 可能是乱序的&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-15&#34; name=&#34;__codelineno-6-15&#34; href=&#34;#__codelineno-6-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-16&#34; name=&#34;__codelineno-6-16&#34; href=&#34;#__codelineno-6-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCPSEG&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCPSEG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-17&#34; name=&#34;__codelineno-6-17&#34; href=&#34;#__codelineno-6-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-18&#34; name=&#34;__codelineno-6-18&#34; href=&#34;#__codelineno-6-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-19&#34; name=&#34;__codelineno-6-19&#34; href=&#34;#__codelineno-6-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 重复收到&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-20&#34; name=&#34;__codelineno-6-20&#34; href=&#34;#__codelineno-6-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;repeat&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-21&#34; name=&#34;__codelineno-6-21&#34; href=&#34;#__codelineno-6-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-22&#34; name=&#34;__codelineno-6-22&#34; href=&#34;#__codelineno-6-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-23&#34; name=&#34;__codelineno-6-23&#34; href=&#34;#__codelineno-6-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_itimediff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-24&#34; name=&#34;__codelineno-6-24&#34; href=&#34;#__codelineno-6-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-25&#34; name=&#34;__codelineno-6-25&#34; href=&#34;#__codelineno-6-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-26&#34; name=&#34;__codelineno-6-26&#34; href=&#34;#__codelineno-6-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-27&#34; name=&#34;__codelineno-6-27&#34; href=&#34;#__codelineno-6-27&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-28&#34; name=&#34;__codelineno-6-28&#34; href=&#34;#__codelineno-6-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 把 newseg 放到 rcv_buf 正确的位置上&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-29&#34; name=&#34;__codelineno-6-29&#34; href=&#34;#__codelineno-6-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;repeat&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-30&#34; name=&#34;__codelineno-6-30&#34; href=&#34;#__codelineno-6-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newseg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-31&#34; name=&#34;__codelineno-6-31&#34; href=&#34;#__codelineno-6-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newseg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-32&#34; name=&#34;__codelineno-6-32&#34; href=&#34;#__codelineno-6-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nrcv_buf&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-33&#34; name=&#34;__codelineno-6-33&#34; href=&#34;#__codelineno-6-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-34&#34; name=&#34;__codelineno-6-34&#34; href=&#34;#__codelineno-6-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_segment_delete&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newseg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-35&#34; name=&#34;__codelineno-6-35&#34; href=&#34;#__codelineno-6-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-36&#34; name=&#34;__codelineno-6-36&#34; href=&#34;#__codelineno-6-36&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-37&#34; name=&#34;__codelineno-6-37&#34; href=&#34;#__codelineno-6-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 把数据从 rcv_buf 移动到 rcv_queue&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-38&#34; name=&#34;__codelineno-6-38&#34; href=&#34;#__codelineno-6-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_is_empty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-39&#34; name=&#34;__codelineno-6-39&#34; href=&#34;#__codelineno-6-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCPSEG&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCPSEG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-40&#34; name=&#34;__codelineno-6-40&#34; href=&#34;#__codelineno-6-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 如果 seg 序号是等待接收的序号，移动到 rcv_queue&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-41&#34; name=&#34;__codelineno-6-41&#34; href=&#34;#__codelineno-6-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_nxt&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nrcv_que&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_wnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-42&#34; name=&#34;__codelineno-6-42&#34; href=&#34;#__codelineno-6-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_del&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-43&#34; name=&#34;__codelineno-6-43&#34; href=&#34;#__codelineno-6-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nrcv_buf&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-44&#34; name=&#34;__codelineno-6-44&#34; href=&#34;#__codelineno-6-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_add_tail&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_queue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-45&#34; name=&#34;__codelineno-6-45&#34; href=&#34;#__codelineno-6-45&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nrcv_que&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-46&#34; name=&#34;__codelineno-6-46&#34; href=&#34;#__codelineno-6-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_nxt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-47&#34; name=&#34;__codelineno-6-47&#34; href=&#34;#__codelineno-6-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-48&#34; name=&#34;__codelineno-6-48&#34; href=&#34;#__codelineno-6-48&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-49&#34; name=&#34;__codelineno-6-49&#34; href=&#34;#__codelineno-6-49&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-50&#34; name=&#34;__codelineno-6-50&#34; href=&#34;#__codelineno-6-50&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-51&#34; name=&#34;__codelineno-6-51&#34; href=&#34;#__codelineno-6-51&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/details&gt;

&lt;p&gt;&lt;code&gt;ikcp_parse_data&lt;/code&gt; 主要的工作就是把 &lt;code&gt;newseg&lt;/code&gt; 放置到 &lt;code&gt;kcp-&amp;gt;rcv_buf&lt;/code&gt; 合适的位置上，并把数据从 &lt;code&gt;rcv_buf&lt;/code&gt; 移动到 &lt;code&gt;rcv_queue&lt;/code&gt;。&lt;code&gt;rcv_buf&lt;/code&gt; 合适的位置的意思是，&lt;code&gt;rcv_buf&lt;/code&gt; 是按照 &lt;code&gt;sn&lt;/code&gt; 的递增顺序排列的，&lt;code&gt;newseg&lt;/code&gt; 需要根据自己的 &lt;code&gt;sn&lt;/code&gt; 大小查找合适的位置。&lt;code&gt;rcv_buf&lt;/code&gt; 上的数据要移动到 &lt;code&gt;rcv_queue&lt;/code&gt;，条件是 &lt;code&gt;rcv_buf&lt;/code&gt; 上的数据包序号，等于 KCP 在等待接收的包序号 &lt;code&gt;kcp-&amp;gt;rcv_nxt&lt;/code&gt; ，移动一个数据包之后，需要更新 &lt;code&gt;kcp-&amp;gt;rvc_nxt&lt;/code&gt;，再处理下一个数据包。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ikcp_input&lt;/code&gt; 之后，上层调用 &lt;code&gt;ikcp_update&lt;/code&gt; 时候会发送 ACK 包，调用 &lt;code&gt;ikcp_recv&lt;/code&gt; 会给上层返回有效数据。&lt;code&gt;ikcp_update&lt;/code&gt; 和 &lt;code&gt;ikcp_recv&lt;/code&gt; 互相独立，没有调用顺序要求，视上层的调用时机而定。我们先来看 &lt;code&gt;ikcp_update&lt;/code&gt; 里面有关 ACK 发送的部分：&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt; 回复 ACK（点击展开代码） &lt;/summary&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-7-1&#34; name=&#34;__codelineno-7-1&#34; href=&#34;#__codelineno-7-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// 前面说过，ikcp_update 最终是调用 ikcp_flush&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-2&#34; name=&#34;__codelineno-7-2&#34; href=&#34;#__codelineno-7-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ikcp_flush&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcpcb&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-3&#34; name=&#34;__codelineno-7-3&#34; href=&#34;#__codelineno-7-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-4&#34; name=&#34;__codelineno-7-4&#34; href=&#34;#__codelineno-7-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-5&#34; name=&#34;__codelineno-7-5&#34; href=&#34;#__codelineno-7-5&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-6&#34; name=&#34;__codelineno-7-6&#34; href=&#34;#__codelineno-7-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 回复 ACK 包&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-7&#34; name=&#34;__codelineno-7-7&#34; href=&#34;#__codelineno-7-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ackcount&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-8&#34; name=&#34;__codelineno-7-8&#34; href=&#34;#__codelineno-7-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-9&#34; name=&#34;__codelineno-7-9&#34; href=&#34;#__codelineno-7-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-10&#34; name=&#34;__codelineno-7-10&#34; href=&#34;#__codelineno-7-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_OVERHEAD&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mtu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-11&#34; name=&#34;__codelineno-7-11&#34; href=&#34;#__codelineno-7-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_output&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-12&#34; name=&#34;__codelineno-7-12&#34; href=&#34;#__codelineno-7-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-13&#34; name=&#34;__codelineno-7-13&#34; href=&#34;#__codelineno-7-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-14&#34; name=&#34;__codelineno-7-14&#34; href=&#34;#__codelineno-7-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_ack_get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-15&#34; name=&#34;__codelineno-7-15&#34; href=&#34;#__codelineno-7-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_encode_seg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-16&#34; name=&#34;__codelineno-7-16&#34; href=&#34;#__codelineno-7-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-17&#34; name=&#34;__codelineno-7-17&#34; href=&#34;#__codelineno-7-17&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-18&#34; name=&#34;__codelineno-7-18&#34; href=&#34;#__codelineno-7-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ackcount&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-19&#34; name=&#34;__codelineno-7-19&#34; href=&#34;#__codelineno-7-19&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-20&#34; name=&#34;__codelineno-7-20&#34; href=&#34;#__codelineno-7-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-21&#34; name=&#34;__codelineno-7-21&#34; href=&#34;#__codelineno-7-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/details&gt;

&lt;p&gt;ACK 包的之前已经由 &lt;code&gt;ikcp_ack_push&lt;/code&gt; 保存起来了，所以这里只需要 &lt;code&gt;ikcp_ack_get&lt;/code&gt; 获取每个 ACK 包的信息，发送给对方。上层可以使用 &lt;code&gt;ikcp_recv&lt;/code&gt; 从 KCP 获取数据：&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt; ikcp_recv（点击展开代码） &lt;/summary&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-8-1&#34; name=&#34;__codelineno-8-1&#34; href=&#34;#__codelineno-8-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;//---------------------------------------------------------------------&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-2&#34; name=&#34;__codelineno-8-2&#34; href=&#34;#__codelineno-8-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// user/upper level recv: returns size, returns below zero for EAGAIN&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-3&#34; name=&#34;__codelineno-8-3&#34; href=&#34;#__codelineno-8-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;//---------------------------------------------------------------------&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-4&#34; name=&#34;__codelineno-8-4&#34; href=&#34;#__codelineno-8-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ikcp_recv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcpcb&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-5&#34; name=&#34;__codelineno-8-5&#34; href=&#34;#__codelineno-8-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-6&#34; name=&#34;__codelineno-8-6&#34; href=&#34;#__codelineno-8-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;IQUEUEHEAD&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-7&#34; name=&#34;__codelineno-8-7&#34; href=&#34;#__codelineno-8-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ispeek&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-8&#34; name=&#34;__codelineno-8-8&#34; href=&#34;#__codelineno-8-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;peeksize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-9&#34; name=&#34;__codelineno-8-9&#34; href=&#34;#__codelineno-8-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;recover&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-10&#34; name=&#34;__codelineno-8-10&#34; href=&#34;#__codelineno-8-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCPSEG&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-11&#34; name=&#34;__codelineno-8-11&#34; href=&#34;#__codelineno-8-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;assert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-12&#34; name=&#34;__codelineno-8-12&#34; href=&#34;#__codelineno-8-12&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-13&#34; name=&#34;__codelineno-8-13&#34; href=&#34;#__codelineno-8-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 一些有效性检查&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-14&#34; name=&#34;__codelineno-8-14&#34; href=&#34;#__codelineno-8-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_is_empty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_queue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-15&#34; name=&#34;__codelineno-8-15&#34; href=&#34;#__codelineno-8-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-16&#34; name=&#34;__codelineno-8-16&#34; href=&#34;#__codelineno-8-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-17&#34; name=&#34;__codelineno-8-17&#34; href=&#34;#__codelineno-8-17&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-18&#34; name=&#34;__codelineno-8-18&#34; href=&#34;#__codelineno-8-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 计算能返回的数据长度&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-19&#34; name=&#34;__codelineno-8-19&#34; href=&#34;#__codelineno-8-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;peeksize&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_peeksize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-20&#34; name=&#34;__codelineno-8-20&#34; href=&#34;#__codelineno-8-20&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-21&#34; name=&#34;__codelineno-8-21&#34; href=&#34;#__codelineno-8-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;peeksize&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-22&#34; name=&#34;__codelineno-8-22&#34; href=&#34;#__codelineno-8-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;-2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-23&#34; name=&#34;__codelineno-8-23&#34; href=&#34;#__codelineno-8-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;peeksize&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-24&#34; name=&#34;__codelineno-8-24&#34; href=&#34;#__codelineno-8-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;-3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-25&#34; name=&#34;__codelineno-8-25&#34; href=&#34;#__codelineno-8-25&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-26&#34; name=&#34;__codelineno-8-26&#34; href=&#34;#__codelineno-8-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 判断下接收窗口&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-27&#34; name=&#34;__codelineno-8-27&#34; href=&#34;#__codelineno-8-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nrcv_que&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_wnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-28&#34; name=&#34;__codelineno-8-28&#34; href=&#34;#__codelineno-8-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;recover&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-29&#34; name=&#34;__codelineno-8-29&#34; href=&#34;#__codelineno-8-29&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-30&#34; name=&#34;__codelineno-8-30&#34; href=&#34;#__codelineno-8-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 遍历 rcv_queue，把数据复制到 buffer 上&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-31&#34; name=&#34;__codelineno-8-31&#34; href=&#34;#__codelineno-8-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_queue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_queue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-32&#34; name=&#34;__codelineno-8-32&#34; href=&#34;#__codelineno-8-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fragment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-33&#34; name=&#34;__codelineno-8-33&#34; href=&#34;#__codelineno-8-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCPSEG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-34&#34; name=&#34;__codelineno-8-34&#34; href=&#34;#__codelineno-8-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-35&#34; name=&#34;__codelineno-8-35&#34; href=&#34;#__codelineno-8-35&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-36&#34; name=&#34;__codelineno-8-36&#34; href=&#34;#__codelineno-8-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-37&#34; name=&#34;__codelineno-8-37&#34; href=&#34;#__codelineno-8-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;memcpy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-38&#34; name=&#34;__codelineno-8-38&#34; href=&#34;#__codelineno-8-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-39&#34; name=&#34;__codelineno-8-39&#34; href=&#34;#__codelineno-8-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-40&#34; name=&#34;__codelineno-8-40&#34; href=&#34;#__codelineno-8-40&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-41&#34; name=&#34;__codelineno-8-41&#34; href=&#34;#__codelineno-8-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-42&#34; name=&#34;__codelineno-8-42&#34; href=&#34;#__codelineno-8-42&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-43&#34; name=&#34;__codelineno-8-43&#34; href=&#34;#__codelineno-8-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 判断分包&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-44&#34; name=&#34;__codelineno-8-44&#34; href=&#34;#__codelineno-8-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fragment&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;frg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-45&#34; name=&#34;__codelineno-8-45&#34; href=&#34;#__codelineno-8-45&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-46&#34; name=&#34;__codelineno-8-46&#34; href=&#34;#__codelineno-8-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 移除数据包&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-47&#34; name=&#34;__codelineno-8-47&#34; href=&#34;#__codelineno-8-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ispeek&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-48&#34; name=&#34;__codelineno-8-48&#34; href=&#34;#__codelineno-8-48&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_del&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-49&#34; name=&#34;__codelineno-8-49&#34; href=&#34;#__codelineno-8-49&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_segment_delete&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-50&#34; name=&#34;__codelineno-8-50&#34; href=&#34;#__codelineno-8-50&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nrcv_que&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-51&#34; name=&#34;__codelineno-8-51&#34; href=&#34;#__codelineno-8-51&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-52&#34; name=&#34;__codelineno-8-52&#34; href=&#34;#__codelineno-8-52&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-53&#34; name=&#34;__codelineno-8-53&#34; href=&#34;#__codelineno-8-53&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 所有分包都复制完，退出循环&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-54&#34; name=&#34;__codelineno-8-54&#34; href=&#34;#__codelineno-8-54&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fragment&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-55&#34; name=&#34;__codelineno-8-55&#34; href=&#34;#__codelineno-8-55&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-56&#34; name=&#34;__codelineno-8-56&#34; href=&#34;#__codelineno-8-56&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-57&#34; name=&#34;__codelineno-8-57&#34; href=&#34;#__codelineno-8-57&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-58&#34; name=&#34;__codelineno-8-58&#34; href=&#34;#__codelineno-8-58&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;assert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;peeksize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-59&#34; name=&#34;__codelineno-8-59&#34; href=&#34;#__codelineno-8-59&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-60&#34; name=&#34;__codelineno-8-60&#34; href=&#34;#__codelineno-8-60&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// rcv_queue 又空了一些，尝试继续从 rcv_buf 移动到 rcv_queue&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-61&#34; name=&#34;__codelineno-8-61&#34; href=&#34;#__codelineno-8-61&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_is_empty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-62&#34; name=&#34;__codelineno-8-62&#34; href=&#34;#__codelineno-8-62&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCPSEG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-63&#34; name=&#34;__codelineno-8-63&#34; href=&#34;#__codelineno-8-63&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_nxt&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nrcv_que&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_wnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-64&#34; name=&#34;__codelineno-8-64&#34; href=&#34;#__codelineno-8-64&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_del&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-65&#34; name=&#34;__codelineno-8-65&#34; href=&#34;#__codelineno-8-65&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nrcv_buf&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-66&#34; name=&#34;__codelineno-8-66&#34; href=&#34;#__codelineno-8-66&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_add_tail&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_queue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-67&#34; name=&#34;__codelineno-8-67&#34; href=&#34;#__codelineno-8-67&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nrcv_que&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-68&#34; name=&#34;__codelineno-8-68&#34; href=&#34;#__codelineno-8-68&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_nxt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-69&#34; name=&#34;__codelineno-8-69&#34; href=&#34;#__codelineno-8-69&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-70&#34; name=&#34;__codelineno-8-70&#34; href=&#34;#__codelineno-8-70&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-71&#34; name=&#34;__codelineno-8-71&#34; href=&#34;#__codelineno-8-71&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-72&#34; name=&#34;__codelineno-8-72&#34; href=&#34;#__codelineno-8-72&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-73&#34; name=&#34;__codelineno-8-73&#34; href=&#34;#__codelineno-8-73&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-74&#34; name=&#34;__codelineno-8-74&#34; href=&#34;#__codelineno-8-74&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-75&#34; name=&#34;__codelineno-8-75&#34; href=&#34;#__codelineno-8-75&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/details&gt;

&lt;p&gt;&lt;code&gt;ikcp_recv&lt;/code&gt; 一次调用只会返回一个完整的数据包，上层可以循环调用直到没有数据返回为止，函数的逻辑比较简单，就是从 &lt;code&gt;rcv_queue&lt;/code&gt; 中复制数据到上层传进来的 &lt;code&gt;buffer&lt;/code&gt; 里面，至此接收方对于接收到的数据包已经处理完毕。&lt;/p&gt;
&lt;p&gt;接收方处理数据包的时候，给发送方发送了 ACK 包，我们再来看看发送方接受 ACK 包的处理：&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt; 处理 ACK 包（点击展开代码） &lt;/summary&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-9-1&#34; name=&#34;__codelineno-9-1&#34; href=&#34;#__codelineno-9-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ikcp_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcpcb&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;long&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-2&#34; name=&#34;__codelineno-9-2&#34; href=&#34;#__codelineno-9-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-3&#34; name=&#34;__codelineno-9-3&#34; href=&#34;#__codelineno-9-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-4&#34; name=&#34;__codelineno-9-4&#34; href=&#34;#__codelineno-9-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;maxack&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;latest_ts&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-5&#34; name=&#34;__codelineno-9-5&#34; href=&#34;#__codelineno-9-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-6&#34; name=&#34;__codelineno-9-6&#34; href=&#34;#__codelineno-9-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-7&#34; name=&#34;__codelineno-9-7&#34; href=&#34;#__codelineno-9-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-8&#34; name=&#34;__codelineno-9-8&#34; href=&#34;#__codelineno-9-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ts 是对端的 kcp-&amp;gt; current&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-9&#34; name=&#34;__codelineno-9-9&#34; href=&#34;#__codelineno-9-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_decode32u&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-10&#34; name=&#34;__codelineno-9-10&#34; href=&#34;#__codelineno-9-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_decode32u&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-11&#34; name=&#34;__codelineno-9-11&#34; href=&#34;#__codelineno-9-11&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-12&#34; name=&#34;__codelineno-9-12&#34; href=&#34;#__codelineno-9-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_CMD_ACK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-13&#34; name=&#34;__codelineno-9-13&#34; href=&#34;#__codelineno-9-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 更新 rot&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-14&#34; name=&#34;__codelineno-9-14&#34; href=&#34;#__codelineno-9-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_itimediff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-15&#34; name=&#34;__codelineno-9-15&#34; href=&#34;#__codelineno-9-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_update_ack&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_itimediff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-16&#34; name=&#34;__codelineno-9-16&#34; href=&#34;#__codelineno-9-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-17&#34; name=&#34;__codelineno-9-17&#34; href=&#34;#__codelineno-9-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 更新 snd_buf&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-18&#34; name=&#34;__codelineno-9-18&#34; href=&#34;#__codelineno-9-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_parse_ack&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-19&#34; name=&#34;__codelineno-9-19&#34; href=&#34;#__codelineno-9-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_shrink_buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-20&#34; name=&#34;__codelineno-9-20&#34; href=&#34;#__codelineno-9-20&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-21&#34; name=&#34;__codelineno-9-21&#34; href=&#34;#__codelineno-9-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// maxack = 这次 input 的所有 ACK 包中最大的 sn&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-22&#34; name=&#34;__codelineno-9-22&#34; href=&#34;#__codelineno-9-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;flag&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-23&#34; name=&#34;__codelineno-9-23&#34; href=&#34;#__codelineno-9-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;flag&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-24&#34; name=&#34;__codelineno-9-24&#34; href=&#34;#__codelineno-9-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;maxack&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-25&#34; name=&#34;__codelineno-9-25&#34; href=&#34;#__codelineno-9-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;latest_ts&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-26&#34; name=&#34;__codelineno-9-26&#34; href=&#34;#__codelineno-9-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-27&#34; name=&#34;__codelineno-9-27&#34; href=&#34;#__codelineno-9-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_itimediff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;maxack&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-28&#34; name=&#34;__codelineno-9-28&#34; href=&#34;#__codelineno-9-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#ifndef IKCP_FASTACK_CONSERVE&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-29&#34; name=&#34;__codelineno-9-29&#34; href=&#34;#__codelineno-9-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;maxack&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-30&#34; name=&#34;__codelineno-9-30&#34; href=&#34;#__codelineno-9-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;latest_ts&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-31&#34; name=&#34;__codelineno-9-31&#34; href=&#34;#__codelineno-9-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#else&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-32&#34; name=&#34;__codelineno-9-32&#34; href=&#34;#__codelineno-9-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_itimediff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;latest_ts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-33&#34; name=&#34;__codelineno-9-33&#34; href=&#34;#__codelineno-9-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;maxack&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-34&#34; name=&#34;__codelineno-9-34&#34; href=&#34;#__codelineno-9-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;latest_ts&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-35&#34; name=&#34;__codelineno-9-35&#34; href=&#34;#__codelineno-9-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-36&#34; name=&#34;__codelineno-9-36&#34; href=&#34;#__codelineno-9-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#endif&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-37&#34; name=&#34;__codelineno-9-37&#34; href=&#34;#__codelineno-9-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-38&#34; name=&#34;__codelineno-9-38&#34; href=&#34;#__codelineno-9-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-39&#34; name=&#34;__codelineno-9-39&#34; href=&#34;#__codelineno-9-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-40&#34; name=&#34;__codelineno-9-40&#34; href=&#34;#__codelineno-9-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-41&#34; name=&#34;__codelineno-9-41&#34; href=&#34;#__codelineno-9-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-42&#34; name=&#34;__codelineno-9-42&#34; href=&#34;#__codelineno-9-42&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-43&#34; name=&#34;__codelineno-9-43&#34; href=&#34;#__codelineno-9-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 如果有收到 ACK 包，记录用来做快速重传&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-44&#34; name=&#34;__codelineno-9-44&#34; href=&#34;#__codelineno-9-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;flag&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-45&#34; name=&#34;__codelineno-9-45&#34; href=&#34;#__codelineno-9-45&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_parse_fastack&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;maxack&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;latest_ts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-46&#34; name=&#34;__codelineno-9-46&#34; href=&#34;#__codelineno-9-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-47&#34; name=&#34;__codelineno-9-47&#34; href=&#34;#__codelineno-9-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/details&gt;

&lt;p&gt;可以看到接收到 ACK 包后同样会需要 &lt;code&gt;ikcp_parse_ack&lt;/code&gt; 和 &lt;code&gt;ikcp_shrink_buf&lt;/code&gt; 来更新 &lt;code&gt;snd_buf&lt;/code&gt;，另外还需要调用 &lt;code&gt;ikcp_update_ack&lt;/code&gt; 来计算更新 rto （retransmission timeout，超时重传时间）。&lt;code&gt;ikcp_input&lt;/code&gt; 计算收到的 ACK 包中最大序号，来记录做快速重传用。就这样，发送方收到 ACK 包，把发送数据从 &lt;code&gt;snd_buf&lt;/code&gt; 中移除，该数据包可靠地送达到了接收方，一次完整的 ARQ 确认接收过程结束。&lt;/p&gt;
&lt;h3 id=&#34;_3&#34;&gt;超时重传&lt;/h3&gt;
&lt;p&gt;前面介绍的是 KCP 实现的 ARQ 中的 确认接收机制，ARQ 还需要一个超时重传来保证可靠性，下面我们来看看 KCP 是怎么做超时重传的。&lt;/p&gt;
&lt;p&gt;让我们回到 &lt;code&gt;ikcp_flush&lt;/code&gt; 函数：&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt; 超时重传（点击展开代码） &lt;/summary&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-10-1&#34; name=&#34;__codelineno-10-1&#34; href=&#34;#__codelineno-10-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ikcp_flush&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcpcb&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-2&#34; name=&#34;__codelineno-10-2&#34; href=&#34;#__codelineno-10-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-3&#34; name=&#34;__codelineno-10-3&#34; href=&#34;#__codelineno-10-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-4&#34; name=&#34;__codelineno-10-4&#34; href=&#34;#__codelineno-10-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 发送 snd_buf&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-5&#34; name=&#34;__codelineno-10-5&#34; href=&#34;#__codelineno-10-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-6&#34; name=&#34;__codelineno-10-6&#34; href=&#34;#__codelineno-10-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCPSEG&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCPSEG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-7&#34; name=&#34;__codelineno-10-7&#34; href=&#34;#__codelineno-10-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;needsend&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-8&#34; name=&#34;__codelineno-10-8&#34; href=&#34;#__codelineno-10-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-9&#34; name=&#34;__codelineno-10-9&#34; href=&#34;#__codelineno-10-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 首次发送&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-10&#34; name=&#34;__codelineno-10-10&#34; href=&#34;#__codelineno-10-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;needsend&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-11&#34; name=&#34;__codelineno-10-11&#34; href=&#34;#__codelineno-10-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmit&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-12&#34; name=&#34;__codelineno-10-12&#34; href=&#34;#__codelineno-10-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 设置 segment-&amp;gt;rto&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-13&#34; name=&#34;__codelineno-10-13&#34; href=&#34;#__codelineno-10-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 通过 segment-&amp;gt;rto 计算 segment-&amp;gt;resendts 超时重传时间&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-14&#34; name=&#34;__codelineno-10-14&#34; href=&#34;#__codelineno-10-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rx_rto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-15&#34; name=&#34;__codelineno-10-15&#34; href=&#34;#__codelineno-10-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resendts&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rtomin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-16&#34; name=&#34;__codelineno-10-16&#34; href=&#34;#__codelineno-10-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-17&#34; name=&#34;__codelineno-10-17&#34; href=&#34;#__codelineno-10-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_itimediff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resendts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-18&#34; name=&#34;__codelineno-10-18&#34; href=&#34;#__codelineno-10-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 超时重传&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-19&#34; name=&#34;__codelineno-10-19&#34; href=&#34;#__codelineno-10-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;needsend&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-20&#34; name=&#34;__codelineno-10-20&#34; href=&#34;#__codelineno-10-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmit&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-21&#34; name=&#34;__codelineno-10-21&#34; href=&#34;#__codelineno-10-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmit&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-22&#34; name=&#34;__codelineno-10-22&#34; href=&#34;#__codelineno-10-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// nodelay 控制下一次超时重传时间的计算&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-23&#34; name=&#34;__codelineno-10-23&#34; href=&#34;#__codelineno-10-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nodelay&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-24&#34; name=&#34;__codelineno-10-24&#34; href=&#34;#__codelineno-10-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rx_rto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-25&#34; name=&#34;__codelineno-10-25&#34; href=&#34;#__codelineno-10-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-26&#34; name=&#34;__codelineno-10-26&#34; href=&#34;#__codelineno-10-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rx_rto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-27&#34; name=&#34;__codelineno-10-27&#34; href=&#34;#__codelineno-10-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-28&#34; name=&#34;__codelineno-10-28&#34; href=&#34;#__codelineno-10-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resendts&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-29&#34; name=&#34;__codelineno-10-29&#34; href=&#34;#__codelineno-10-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lost&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-30&#34; name=&#34;__codelineno-10-30&#34; href=&#34;#__codelineno-10-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-31&#34; name=&#34;__codelineno-10-31&#34; href=&#34;#__codelineno-10-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fastack&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-32&#34; name=&#34;__codelineno-10-32&#34; href=&#34;#__codelineno-10-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 快速重传&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-33&#34; name=&#34;__codelineno-10-33&#34; href=&#34;#__codelineno-10-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-34&#34; name=&#34;__codelineno-10-34&#34; href=&#34;#__codelineno-10-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-35&#34; name=&#34;__codelineno-10-35&#34; href=&#34;#__codelineno-10-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;needsend&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-36&#34; name=&#34;__codelineno-10-36&#34; href=&#34;#__codelineno-10-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 发送数据&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-37&#34; name=&#34;__codelineno-10-37&#34; href=&#34;#__codelineno-10-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-38&#34; name=&#34;__codelineno-10-38&#34; href=&#34;#__codelineno-10-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-39&#34; name=&#34;__codelineno-10-39&#34; href=&#34;#__codelineno-10-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-40&#34; name=&#34;__codelineno-10-40&#34; href=&#34;#__codelineno-10-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/details&gt;

&lt;p&gt;一旦当前时间 &lt;code&gt;current&lt;/code&gt; 大于 &lt;code&gt;segment-&amp;gt;resendts&lt;/code&gt; 超时重传时间，说明在这段时间内，都没有收到接收方的 ACK 包，触发超时重传机制，&lt;code&gt;needsend = 1&lt;/code&gt;，重新发送数据。&lt;/p&gt;
&lt;p&gt;有了确认接收和超时重传机制，KCP 就可以保证基础的可靠数据传输了。但是为了能够保持更稳定的数据流速，KCP 还做了更多的事情，下面我们一起看看 KCP 还做了那些优化。&lt;/p&gt;
&lt;h2 id=&#34;kcp_2&#34;&gt;KCP 提升流速的策略&lt;/h2&gt;
&lt;h3 id=&#34;_4&#34;&gt;快速重传&lt;/h3&gt;
&lt;p&gt;发送方发送了序号为 &lt;code&gt;sn&lt;/code&gt; 和 &lt;code&gt;sn + 1&lt;/code&gt; 两个数据包，如果只收到了 &lt;code&gt;sn + 1&lt;/code&gt; 的 ACK 包，那可能是因为 &lt;code&gt;sn&lt;/code&gt; 的 ACK 包在网路中还没到达，又或者 ACK 包丢了，又或者 &lt;code&gt;sn&lt;/code&gt; 数据包丢了，如果此时还没到超时重传的时间，网络也还不太拥堵，只是因为某种原因而突发丢包，那么发送方主动提前发送 &lt;code&gt;sn&lt;/code&gt; 数据包，可以帮助接收方更快地接收数据，提高流速。&lt;/p&gt;
&lt;p&gt;KCP 里面也相应实现了快速重传机制，也在 &lt;code&gt;ikcp_flush&lt;/code&gt; 里面：&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt; 快速重传（点击展开代码） &lt;/summary&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-11-1&#34; name=&#34;__codelineno-11-1&#34; href=&#34;#__codelineno-11-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ikcp_flush&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcpcb&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-2&#34; name=&#34;__codelineno-11-2&#34; href=&#34;#__codelineno-11-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-3&#34; name=&#34;__codelineno-11-3&#34; href=&#34;#__codelineno-11-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-4&#34; name=&#34;__codelineno-11-4&#34; href=&#34;#__codelineno-11-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resent&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fastresend&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fastresend&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;0xffffffff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-5&#34; name=&#34;__codelineno-11-5&#34; href=&#34;#__codelineno-11-5&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-6&#34; name=&#34;__codelineno-11-6&#34; href=&#34;#__codelineno-11-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 发送 snd_buf&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-7&#34; name=&#34;__codelineno-11-7&#34; href=&#34;#__codelineno-11-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_buf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-8&#34; name=&#34;__codelineno-11-8&#34; href=&#34;#__codelineno-11-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCPSEG&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iqueue_entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCPSEG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-9&#34; name=&#34;__codelineno-11-9&#34; href=&#34;#__codelineno-11-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;needsend&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-10&#34; name=&#34;__codelineno-11-10&#34; href=&#34;#__codelineno-11-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-11&#34; name=&#34;__codelineno-11-11&#34; href=&#34;#__codelineno-11-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-12&#34; name=&#34;__codelineno-11-12&#34; href=&#34;#__codelineno-11-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-13&#34; name=&#34;__codelineno-11-13&#34; href=&#34;#__codelineno-11-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_itimediff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resendts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-14&#34; name=&#34;__codelineno-11-14&#34; href=&#34;#__codelineno-11-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-15&#34; name=&#34;__codelineno-11-15&#34; href=&#34;#__codelineno-11-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-16&#34; name=&#34;__codelineno-11-16&#34; href=&#34;#__codelineno-11-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fastack&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-17&#34; name=&#34;__codelineno-11-17&#34; href=&#34;#__codelineno-11-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 快速重传&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-18&#34; name=&#34;__codelineno-11-18&#34; href=&#34;#__codelineno-11-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fastlimit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-19&#34; name=&#34;__codelineno-11-19&#34; href=&#34;#__codelineno-11-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fastlimit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-20&#34; name=&#34;__codelineno-11-20&#34; href=&#34;#__codelineno-11-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;needsend&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-21&#34; name=&#34;__codelineno-11-21&#34; href=&#34;#__codelineno-11-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmit&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-22&#34; name=&#34;__codelineno-11-22&#34; href=&#34;#__codelineno-11-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fastack&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-23&#34; name=&#34;__codelineno-11-23&#34; href=&#34;#__codelineno-11-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resendts&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;segment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-24&#34; name=&#34;__codelineno-11-24&#34; href=&#34;#__codelineno-11-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;change&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-25&#34; name=&#34;__codelineno-11-25&#34; href=&#34;#__codelineno-11-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-26&#34; name=&#34;__codelineno-11-26&#34; href=&#34;#__codelineno-11-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-27&#34; name=&#34;__codelineno-11-27&#34; href=&#34;#__codelineno-11-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;needsend&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-28&#34; name=&#34;__codelineno-11-28&#34; href=&#34;#__codelineno-11-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 发送数据&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-29&#34; name=&#34;__codelineno-11-29&#34; href=&#34;#__codelineno-11-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-30&#34; name=&#34;__codelineno-11-30&#34; href=&#34;#__codelineno-11-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-31&#34; name=&#34;__codelineno-11-31&#34; href=&#34;#__codelineno-11-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-32&#34; name=&#34;__codelineno-11-32&#34; href=&#34;#__codelineno-11-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/details&gt;

&lt;p&gt;要出发快速重传，有两个条件：
* &lt;code&gt;segment-&amp;gt;fastack &amp;gt;= resent&lt;/code&gt;，resent 是可配置的参数 &lt;code&gt;kcp-&amp;gt;fastresend&lt;/code&gt;，配置为 0 会关闭快速重传。&lt;code&gt;segment-&amp;gt;fastack&lt;/code&gt; 是在函数 &lt;code&gt;ikcp_parse_fastack&lt;/code&gt; 里面设置的，这个函数是在 &lt;code&gt;ikcp_input&lt;/code&gt; 里面调用，会根据 &lt;code&gt;ikcp_input&lt;/code&gt; 算出的 &lt;code&gt;maxack&lt;/code&gt; 来给所有 &lt;code&gt;sn&lt;/code&gt; 小于 &lt;code&gt;maxack&lt;/code&gt; 的 &lt;code&gt;segment-&amp;gt;fastack&lt;/code&gt; 加一，所以 &lt;code&gt;segment-&amp;gt;fastack&lt;/code&gt; 就是表示收到比 &lt;code&gt;sn&lt;/code&gt; 大的包的次数。
* &lt;code&gt;segment-&amp;gt;xmit &amp;lt;= kcp-&amp;gt;fastlimit || kcp-&amp;gt;fastlimit &amp;lt;= 0&lt;/code&gt;，&lt;code&gt;setgment-&amp;gt;xmit&lt;/code&gt; 是发送次数，&lt;code&gt;kcp-&amp;gt;fastlimit&lt;/code&gt; 是可配置的最大快速重传次数，发送次数需要小于最大快速重传次数&lt;/p&gt;
&lt;p&gt;一旦满足快速重传的以上条件，KCP 就会执行快速重传，要注意快速重传并不会重置超时重传时间，原来的超时时间依然会生效。&lt;/p&gt;
&lt;h3 id=&#34;_5&#34;&gt;缩短超时重传时间&lt;/h3&gt;
&lt;p&gt;超时重传是个很好的机制，但就是太花时间了，按照 TCP 的策略，每次超时重传时间翻倍，等待时间膨胀得很快，在等待时间内，很可能由于接收端的接收窗口已耗尽，无法接收新数据，而等待重传的包序号是在最前面，接收方要接收到重传的包才能把所有数据返回给上层，这种情况，整个网路的流速几乎为 0。KCP 增加了配置可以减缓等待的时间增长，而且也不会是翻倍，通过配置 &lt;code&gt;kcp-&amp;gt;nodelay&lt;/code&gt; 控制每次等待时间只会增长 1 倍的 RTO 或者 0.5 倍的 RTO，有效减缓等待时间的增长，帮助网路尽快恢复流速。&lt;/p&gt;
&lt;h3 id=&#34;_6&#34;&gt;更新发送窗口&lt;/h3&gt;
&lt;p&gt;发送窗口表示的是同时传输的数据包数量，窗口越大，同时传输的数据越多，流速越大，但窗口过大，会导致网络拥塞，丢包率上升，数据重传增多，流速下降。所以发送窗口需要根据网络情况不断更新，慢慢趋近最优。 KCP 中关于发送窗口的代码：&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt; 发送窗口（点击展开代码） &lt;/summary&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-12-1&#34; name=&#34;__codelineno-12-1&#34; href=&#34;#__codelineno-12-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;ikcpcb&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ikcp_create&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;conv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-2&#34; name=&#34;__codelineno-12-2&#34; href=&#34;#__codelineno-12-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-3&#34; name=&#34;__codelineno-12-3&#34; href=&#34;#__codelineno-12-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-4&#34; name=&#34;__codelineno-12-4&#34; href=&#34;#__codelineno-12-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// snd_wnd，rcv_wnd 发送和接受的缓冲区大小&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-5&#34; name=&#34;__codelineno-12-5&#34; href=&#34;#__codelineno-12-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_wnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_WND_SND&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 32&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-6&#34; name=&#34;__codelineno-12-6&#34; href=&#34;#__codelineno-12-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rcv_wnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_WND_RCV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 128&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-7&#34; name=&#34;__codelineno-12-7&#34; href=&#34;#__codelineno-12-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 对端接收窗口大小              // 128&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-8&#34; name=&#34;__codelineno-12-8&#34; href=&#34;#__codelineno-12-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rmt_wnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_WND_RCV&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-9&#34; name=&#34;__codelineno-12-9&#34; href=&#34;#__codelineno-12-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 发送窗口 cwnd 初始化 0&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-10&#34; name=&#34;__codelineno-12-10&#34; href=&#34;#__codelineno-12-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-11&#34; name=&#34;__codelineno-12-11&#34; href=&#34;#__codelineno-12-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 发送窗口字节数大小，参与计算 cwnd&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-12&#34; name=&#34;__codelineno-12-12&#34; href=&#34;#__codelineno-12-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;incr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-13&#34; name=&#34;__codelineno-12-13&#34; href=&#34;#__codelineno-12-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 慢启动阈值，slow start threshold&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-14&#34; name=&#34;__codelineno-12-14&#34; href=&#34;#__codelineno-12-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssthresh&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_THRESH_INIT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-15&#34; name=&#34;__codelineno-12-15&#34; href=&#34;#__codelineno-12-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// nocwnd 是可配置参数，1 不考虑 cwnd&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-16&#34; name=&#34;__codelineno-12-16&#34; href=&#34;#__codelineno-12-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nocwnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-17&#34; name=&#34;__codelineno-12-17&#34; href=&#34;#__codelineno-12-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-18&#34; name=&#34;__codelineno-12-18&#34; href=&#34;#__codelineno-12-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-19&#34; name=&#34;__codelineno-12-19&#34; href=&#34;#__codelineno-12-19&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-12-20&#34; name=&#34;__codelineno-12-20&#34; href=&#34;#__codelineno-12-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ikcp_flush&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcpcb&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-21&#34; name=&#34;__codelineno-12-21&#34; href=&#34;#__codelineno-12-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-22&#34; name=&#34;__codelineno-12-22&#34; href=&#34;#__codelineno-12-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-23&#34; name=&#34;__codelineno-12-23&#34; href=&#34;#__codelineno-12-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 发送数据时先计算 发送窗口大小，是发送缓冲区大小和对方接收窗口大小的小值&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-24&#34; name=&#34;__codelineno-12-24&#34; href=&#34;#__codelineno-12-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_imin_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_wnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rmt_wnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-25&#34; name=&#34;__codelineno-12-25&#34; href=&#34;#__codelineno-12-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 默认还需要考虑 kcp-&amp;gt;cwnd，即是不断更新的发送窗口&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-26&#34; name=&#34;__codelineno-12-26&#34; href=&#34;#__codelineno-12-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nocwnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_imin_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-27&#34; name=&#34;__codelineno-12-27&#34; href=&#34;#__codelineno-12-27&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-12-28&#34; name=&#34;__codelineno-12-28&#34; href=&#34;#__codelineno-12-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 根据 cwnd 大小，snd_queue 移动到 snd_buf&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-29&#34; name=&#34;__codelineno-12-29&#34; href=&#34;#__codelineno-12-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_itimediff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_nxt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_una&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-30&#34; name=&#34;__codelineno-12-30&#34; href=&#34;#__codelineno-12-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-31&#34; name=&#34;__codelineno-12-31&#34; href=&#34;#__codelineno-12-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 发送数据&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-32&#34; name=&#34;__codelineno-12-32&#34; href=&#34;#__codelineno-12-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resent&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fastresend&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fastresend&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;0xffffffff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-33&#34; name=&#34;__codelineno-12-33&#34; href=&#34;#__codelineno-12-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 触发超时重传 lost = 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-34&#34; name=&#34;__codelineno-12-34&#34; href=&#34;#__codelineno-12-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 触发快速重传 change++&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-35&#34; name=&#34;__codelineno-12-35&#34; href=&#34;#__codelineno-12-35&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-12-36&#34; name=&#34;__codelineno-12-36&#34; href=&#34;#__codelineno-12-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 更新慢启动阈值和发送窗口&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-37&#34; name=&#34;__codelineno-12-37&#34; href=&#34;#__codelineno-12-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;change&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-38&#34; name=&#34;__codelineno-12-38&#34; href=&#34;#__codelineno-12-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 如果有触发快速重传，ssthresh 设置为网络上正在传输的数据包数量的一半&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-39&#34; name=&#34;__codelineno-12-39&#34; href=&#34;#__codelineno-12-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inflight&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_nxt&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_una&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-40&#34; name=&#34;__codelineno-12-40&#34; href=&#34;#__codelineno-12-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssthresh&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inflight&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-41&#34; name=&#34;__codelineno-12-41&#34; href=&#34;#__codelineno-12-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssthresh&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_THRESH_MIN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-42&#34; name=&#34;__codelineno-12-42&#34; href=&#34;#__codelineno-12-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssthresh&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_THRESH_MIN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-43&#34; name=&#34;__codelineno-12-43&#34; href=&#34;#__codelineno-12-43&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-12-44&#34; name=&#34;__codelineno-12-44&#34; href=&#34;#__codelineno-12-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 发送窗口为阈值再加上快速重传相关的 resent&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-45&#34; name=&#34;__codelineno-12-45&#34; href=&#34;#__codelineno-12-45&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssthresh&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-46&#34; name=&#34;__codelineno-12-46&#34; href=&#34;#__codelineno-12-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;incr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mss&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-47&#34; name=&#34;__codelineno-12-47&#34; href=&#34;#__codelineno-12-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-48&#34; name=&#34;__codelineno-12-48&#34; href=&#34;#__codelineno-12-48&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-12-49&#34; name=&#34;__codelineno-12-49&#34; href=&#34;#__codelineno-12-49&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lost&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-50&#34; name=&#34;__codelineno-12-50&#34; href=&#34;#__codelineno-12-50&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 如果有超时重传，触发慢启动, ssthresh 阈值为发送窗口的一半&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-51&#34; name=&#34;__codelineno-12-51&#34; href=&#34;#__codelineno-12-51&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssthresh&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-52&#34; name=&#34;__codelineno-12-52&#34; href=&#34;#__codelineno-12-52&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssthresh&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_THRESH_MIN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-53&#34; name=&#34;__codelineno-12-53&#34; href=&#34;#__codelineno-12-53&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssthresh&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IKCP_THRESH_MIN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-54&#34; name=&#34;__codelineno-12-54&#34; href=&#34;#__codelineno-12-54&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 发送窗口回到 1，重新慢启动增长&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-55&#34; name=&#34;__codelineno-12-55&#34; href=&#34;#__codelineno-12-55&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-56&#34; name=&#34;__codelineno-12-56&#34; href=&#34;#__codelineno-12-56&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;incr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mss&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-57&#34; name=&#34;__codelineno-12-57&#34; href=&#34;#__codelineno-12-57&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-58&#34; name=&#34;__codelineno-12-58&#34; href=&#34;#__codelineno-12-58&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-12-59&#34; name=&#34;__codelineno-12-59&#34; href=&#34;#__codelineno-12-59&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-60&#34; name=&#34;__codelineno-12-60&#34; href=&#34;#__codelineno-12-60&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 因为初始化为 0，来到这里会再设置成 1&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-61&#34; name=&#34;__codelineno-12-61&#34; href=&#34;#__codelineno-12-61&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-62&#34; name=&#34;__codelineno-12-62&#34; href=&#34;#__codelineno-12-62&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;incr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mss&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-63&#34; name=&#34;__codelineno-12-63&#34; href=&#34;#__codelineno-12-63&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-64&#34; name=&#34;__codelineno-12-64&#34; href=&#34;#__codelineno-12-64&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-65&#34; name=&#34;__codelineno-12-65&#34; href=&#34;#__codelineno-12-65&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-12-66&#34; name=&#34;__codelineno-12-66&#34; href=&#34;#__codelineno-12-66&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ikcp_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcpcb&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;long&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-67&#34; name=&#34;__codelineno-12-67&#34; href=&#34;#__codelineno-12-67&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-68&#34; name=&#34;__codelineno-12-68&#34; href=&#34;#__codelineno-12-68&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev_una&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_una&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-69&#34; name=&#34;__codelineno-12-69&#34; href=&#34;#__codelineno-12-69&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 处理接收的数据&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-70&#34; name=&#34;__codelineno-12-70&#34; href=&#34;#__codelineno-12-70&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-12-71&#34; name=&#34;__codelineno-12-71&#34; href=&#34;#__codelineno-12-71&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-72&#34; name=&#34;__codelineno-12-72&#34; href=&#34;#__codelineno-12-72&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-73&#34; name=&#34;__codelineno-12-73&#34; href=&#34;#__codelineno-12-73&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ikcp_decode16u&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-74&#34; name=&#34;__codelineno-12-74&#34; href=&#34;#__codelineno-12-74&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// rmt_wnd 是对方的接收窗口大小&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-75&#34; name=&#34;__codelineno-12-75&#34; href=&#34;#__codelineno-12-75&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rmt_wnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wnd&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-76&#34; name=&#34;__codelineno-12-76&#34; href=&#34;#__codelineno-12-76&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-77&#34; name=&#34;__codelineno-12-77&#34; href=&#34;#__codelineno-12-77&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 处理数据&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-78&#34; name=&#34;__codelineno-12-78&#34; href=&#34;#__codelineno-12-78&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-79&#34; name=&#34;__codelineno-12-79&#34; href=&#34;#__codelineno-12-79&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-12-80&#34; name=&#34;__codelineno-12-80&#34; href=&#34;#__codelineno-12-80&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 最后更新发送窗口&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-81&#34; name=&#34;__codelineno-12-81&#34; href=&#34;#__codelineno-12-81&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// kcp-&amp;gt;snd_una - prev_una &amp;gt; 0，表示本次 input 有接受到 ACK 并且发送缓冲 snd_buf 有变化&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-82&#34; name=&#34;__codelineno-12-82&#34; href=&#34;#__codelineno-12-82&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_itimediff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snd_una&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev_una&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-83&#34; name=&#34;__codelineno-12-83&#34; href=&#34;#__codelineno-12-83&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 再判断对方的接收窗口&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-84&#34; name=&#34;__codelineno-12-84&#34; href=&#34;#__codelineno-12-84&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rmt_wnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-85&#34; name=&#34;__codelineno-12-85&#34; href=&#34;#__codelineno-12-85&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUINT32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mss&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mss&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-86&#34; name=&#34;__codelineno-12-86&#34; href=&#34;#__codelineno-12-86&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-12-87&#34; name=&#34;__codelineno-12-87&#34; href=&#34;#__codelineno-12-87&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssthresh&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-88&#34; name=&#34;__codelineno-12-88&#34; href=&#34;#__codelineno-12-88&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 小于慢启动阈值，双倍增长&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-89&#34; name=&#34;__codelineno-12-89&#34; href=&#34;#__codelineno-12-89&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwnd&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-90&#34; name=&#34;__codelineno-12-90&#34; href=&#34;#__codelineno-12-90&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;incr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mss&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-91&#34; name=&#34;__codelineno-12-91&#34; href=&#34;#__codelineno-12-91&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-12-92&#34; name=&#34;__codelineno-12-92&#34; href=&#34;#__codelineno-12-92&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-93&#34; name=&#34;__codelineno-12-93&#34; href=&#34;#__codelineno-12-93&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 大于慢启动阈值之后，通过公式更新 incr ，进而计算 cwnd&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-94&#34; name=&#34;__codelineno-12-94&#34; href=&#34;#__codelineno-12-94&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;incr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mss&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;incr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mss&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-95&#34; name=&#34;__codelineno-12-95&#34; href=&#34;#__codelineno-12-95&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;incr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mss&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mss&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;incr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mss&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-96&#34; name=&#34;__codelineno-12-96&#34; href=&#34;#__codelineno-12-96&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mss&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;incr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-97&#34; name=&#34;__codelineno-12-97&#34; href=&#34;#__codelineno-12-97&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwnd&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-98&#34; name=&#34;__codelineno-12-98&#34; href=&#34;#__codelineno-12-98&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-99&#34; name=&#34;__codelineno-12-99&#34; href=&#34;#__codelineno-12-99&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-100&#34; name=&#34;__codelineno-12-100&#34; href=&#34;#__codelineno-12-100&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 更新出来的值还要再比较下 rmt_wnd&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-101&#34; name=&#34;__codelineno-12-101&#34; href=&#34;#__codelineno-12-101&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rmt_wnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-102&#34; name=&#34;__codelineno-12-102&#34; href=&#34;#__codelineno-12-102&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rmt_wnd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-103&#34; name=&#34;__codelineno-12-103&#34; href=&#34;#__codelineno-12-103&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;incr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;kcp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rmt_wnd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mss&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-104&#34; name=&#34;__codelineno-12-104&#34; href=&#34;#__codelineno-12-104&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-105&#34; name=&#34;__codelineno-12-105&#34; href=&#34;#__codelineno-12-105&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-106&#34; name=&#34;__codelineno-12-106&#34; href=&#34;#__codelineno-12-106&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-12-107&#34; name=&#34;__codelineno-12-107&#34; href=&#34;#__codelineno-12-107&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/details&gt;

&lt;p&gt;计算发送窗口 &lt;code&gt;kcp-&amp;gt;cwnd&lt;/code&gt; 的大小涉及的代码片段会稍微多一些，因为在发送和接收数据的时候，都会需要更新。&lt;code&gt;kcp-&amp;gt;cwnd&lt;/code&gt; 初始化为 0，
之后会在第一次调用 &lt;code&gt;ikcp_flush&lt;/code&gt; 的时候，判断小于 1 ，便修改成 1。之后发送方根据发送窗口大小，发送出相应数量的数据包，等待 ACK
回复包。ACK 包在 &lt;code&gt;kcp-&amp;gt;input&lt;/code&gt; 中进行处理，&lt;code&gt;kcp-&amp;gt;input&lt;/code&gt; 中如果判断有 ACK 包，并有清除发送缓冲中的发送数据包，说明有数据包已经完成送达，&lt;code&gt;kcp-&amp;gt;cwnd++&lt;/code&gt;。实际上很可能是一次 &lt;code&gt;kcp-&amp;gt;input&lt;/code&gt; 只处理到一个 ACK 包，可以理解为，每收到一个 ACK 包都会有 &lt;code&gt;kcp-&amp;gt;cwnd++&lt;/code&gt;，这句自增实现的是翻倍的效果，譬如当前 &lt;code&gt;kcp-&amp;gt;cwnd = 2&lt;/code&gt;，发送两个数据包，收到两个 ACK 包，触发了两次自增，最后就是 &lt;code&gt;kcp-&amp;gt;cwnd = 4&lt;/code&gt; 翻倍。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cwnd&lt;/code&gt; 可以一直指数增长，直到超过慢启动阈值，或者发生拥堵超时重传，快速重传的情况。发生了超时重传之后，会触发慢启动，慢启动阈值 &lt;code&gt;ssthresh = kcp-&amp;gt;cwnd / 2&lt;/code&gt;，发送窗口 &lt;code&gt;kcp-&amp;gt;cwnd = 1&lt;/code&gt;，回到最初重新指数增长。如果发生了快速重传，KCP 先提前减少 &lt;code&gt;ssthresh&lt;/code&gt;，也即是减少了 &lt;code&gt;cwnd&lt;/code&gt; 指数增长的空间，降低增长速度，提前减缓拥堵的情况。&lt;/p&gt;
&lt;p&gt;KCP 还增加了一个配置 &lt;code&gt;nocwnd&lt;/code&gt;，当 &lt;code&gt;nocwnd = 1&lt;/code&gt;，发送数据是不再考虑发送窗口大小，直接让最大能发送的数量发送数据包，满足高速模式下的要求。&lt;/p&gt;
&lt;h2 id=&#34;_7&#34;&gt;小结&lt;/h2&gt;
&lt;p&gt;本文简单地分析了 KCP 的源码，并讨论了 KCP 上 ARQ 的实现，和一些 KCP 提升流速的策略。还有很多细节没有提到，感兴趣的可以自己翻 KCP 的源码对照着看，相信也能有不少的收获。&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/cpp-KCP%E6%BA%90%E7%A0%81%E5%89%96%E6%9E%90/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 30 Nov 2023 20:09:36 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/cpp-KCP%E6%BA%90%E7%A0%81%E5%89%96%E6%9E%90/</guid>
      
    </item>
    
    <item>
      <title>编写 Windows 下的 Memory Leak Detector</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;编写 Windows 下的 Memory Leak Detector&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;https://img.shields.io/badge/windows-10-blue.svg&#34; style=&#34;display: inline-block&#34; /&gt;
&lt;img alt=&#34;&#34; src=&#34;https://img.shields.io/badge/vs-2015-68217A.svg&#34; style=&#34;display: inline-block&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_1&#34;&gt;前言&lt;/h2&gt;
&lt;p&gt;这一阵子读完了《程序员的自我修养：链接、装载与库》（后面简称《链接》），收获良多，寻思着能不能做些相关的小代码出来。刚好知道 Windows 下有个内存泄露检测工具 &lt;a href=&#34;https://vld.codeplex.com/&#34;&gt;Visual Leak Detector&lt;/a&gt;，这个工具是通过替换 Windows 下负责内存管理的 dll 接口来实现跟踪内存分配释放。所以决定参考 Visual Leak Detector （后面简称 VLD）来做个简易的内存泄露检测工具，理解 dll 链接。&lt;/p&gt;
&lt;h2 id=&#34;_2&#34;&gt;预备知识&lt;/h2&gt;
&lt;p&gt;《链接》一书详细解释了在 Linux 和 Windows 下可执行文件的链接原理，其中 Windows 下的可执行文件格式叫做 PE（Portable Executable）文件。而 DLL 文件的解释是这样的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;DLL 即动态链接库（Dynamic-Link Library）的缩写，它相当于 Linux 下的共享对象。Windows 系统中大量采用了这种 DLL 机制，甚至包括 Windows 的内核的结构都很大程度依赖于 DLL 机制。Windows 下的 DLL 文件和 EXE 文件实际上是一个概念，它们都是有 PE 格式的二进制文件，稍微有些不同的是 PE 文件头部中有个符号位表示该文件是 EXE 或是 DLL，而 DLL 文件的扩展名不一定是 .dll，也有可能是别的比如 .ocx（OCX控件）或是 .CPL（控制面板程序）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;还有比如 Python 的扩展文件 .pyd。而 DLL 中有关我们这里内存泄露检测的概念是&lt;strong&gt;符号导出导入表&lt;/strong&gt;。&lt;/p&gt;
&lt;h4 id=&#34;_3&#34;&gt;符号导出表&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;当一个 PE 需要将一些函数或变量提供给其他 PE 文件使用时，我们把这种行为叫做&lt;strong&gt;符号导出（Symbol Exporting）&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;简单地理解，在 Windows PE 中，所有导出的符号被集中存放在被称作&lt;strong&gt;导出表（Export Table）&lt;/strong&gt;的结构中，它提供了一个符号名与符号地址的映射关系。需要导出的符号需要加上修饰符&lt;code&gt;__declspec(dllexport)&lt;/code&gt;。&lt;/p&gt;
&lt;h4 id=&#34;_4&#34;&gt;符号导入表&lt;/h4&gt;
&lt;p&gt;符号导入表就是我们这里的关键概念，它跟符号导出表相对应，先来看概念解释：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果我们在某个程序中使用到了来自 DLL 的函数或者变量，那么我们就把这种行为叫做&lt;strong&gt;符号导入（Symbol Importing）&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Windows PE 中保存模块需要导入的变量和函数的符号以及所在的模块等信息的结构叫做&lt;strong&gt;导入表（Import Table）&lt;/strong&gt;。Windows 加载 PE 文件时，其中一个要做的事情就是将所有需要导入的函数地址确定并将导入表中的元素调整到正确的地址，使得运行时候，程序通过查询导入表来定位实际函数的地址，并进行调用。导入表中最重要的结构是&lt;strong&gt;导入地址数组（Import Address Table，IAT）&lt;/strong&gt;，里面存放的就是导入的函数实际地址。&lt;/p&gt;
&lt;p&gt;看到这里是不是已经猜到我们要实现的内存泄露检测是怎么做 :)。没错就是 hack 导入表，具体地说就是把需要检测的模块的导入表中，关于内存申请和释放的函数的地址改成我们自定义的函数，那么我们就可以知道模块每一次的内存申请和释放情况了，可以尽情做我们想做的检测。&lt;/p&gt;
&lt;p&gt;有关 DLL 链接的更详细知识可以自行查阅《链接》或者其他资料。&lt;/p&gt;
&lt;h2 id=&#34;memory-leak-detector&#34;&gt;Memory Leak Detector&lt;/h2&gt;
&lt;p&gt;知道了原理，下面就是根据原理来实现内存泄露检测。下面的讲解将基于我自己的实现，我放在了我的 Github 上：&lt;a href=&#34;https://github.com/disenone/LeakDetector&#34;&gt;LeakDetector&lt;/a&gt;。&lt;/p&gt;
&lt;h4 id=&#34;_5&#34;&gt;替换函数&lt;/h4&gt;
&lt;p&gt;先来看关键的函数，位于&lt;a href=&#34;https://github.com/disenone/LeakDetector/blob/master/LeakDetector/RealDetector.cpp&#34;&gt;RealDetector.cpp&lt;/a&gt;：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;table class=&#34;highlighttable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;linenos&#34;&gt;&lt;div class=&#34;linenodiv&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-1&#34;&gt; 1&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-2&#34;&gt; 2&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-3&#34;&gt; 3&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-4&#34;&gt; 4&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-5&#34;&gt; 5&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-6&#34;&gt; 6&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-7&#34;&gt; 7&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-8&#34;&gt; 8&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-9&#34;&gt; 9&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-10&#34;&gt;10&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-11&#34;&gt;11&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-12&#34;&gt;12&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-13&#34;&gt;13&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-14&#34;&gt;14&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-15&#34;&gt;15&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-16&#34;&gt;16&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-17&#34;&gt;17&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-18&#34;&gt;18&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-19&#34;&gt;19&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-20&#34;&gt;20&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-21&#34;&gt;21&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-22&#34;&gt;22&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-23&#34;&gt;23&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-24&#34;&gt;24&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-25&#34;&gt;25&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-26&#34;&gt;26&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-27&#34;&gt;27&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-28&#34;&gt;28&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-29&#34;&gt;29&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-30&#34;&gt;30&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-31&#34;&gt;31&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-32&#34;&gt;32&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-33&#34;&gt;33&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-34&#34;&gt;34&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-35&#34;&gt;35&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-36&#34;&gt;36&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-37&#34;&gt;37&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-38&#34;&gt;38&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-39&#34;&gt;39&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-40&#34;&gt;40&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-41&#34;&gt;41&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-42&#34;&gt;42&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-43&#34;&gt;43&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-44&#34;&gt;44&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-45&#34;&gt;45&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-46&#34;&gt;46&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-47&#34;&gt;47&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-48&#34;&gt;48&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-49&#34;&gt;49&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-50&#34;&gt;50&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-51&#34;&gt;51&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-52&#34;&gt;52&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-53&#34;&gt;53&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-54&#34;&gt;54&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-55&#34;&gt;55&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-56&#34;&gt;56&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-57&#34;&gt;57&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-58&#34;&gt;58&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-59&#34;&gt;59&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-60&#34;&gt;60&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-61&#34;&gt;61&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-62&#34;&gt;62&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-63&#34;&gt;63&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-64&#34;&gt;64&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-65&#34;&gt;65&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-66&#34;&gt;66&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-67&#34;&gt;67&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-68&#34;&gt;68&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-69&#34;&gt;69&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-70&#34;&gt;70&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-71&#34;&gt;71&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-72&#34;&gt;72&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-73&#34;&gt;73&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-74&#34;&gt;74&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-75&#34;&gt;75&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-76&#34;&gt;76&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-77&#34;&gt;77&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-78&#34;&gt;78&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-79&#34;&gt;79&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-80&#34;&gt;80&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-81&#34;&gt;81&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-82&#34;&gt;82&lt;/a&gt;&lt;/span&gt;
&lt;span class=&#34;normal&#34;&gt;&lt;a href=&#34;#__codelineno-0-83&#34;&gt;83&lt;/a&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cm&#34;&gt;/* 把 importModule 中的 IAT (Import Address Table) 的某个函数替换成别的函数，&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cm&#34;&gt; * importModule 会调用到别的 module 的函数，这个函数就是需要 patch 的函数，&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cm&#34;&gt; * 我们要做的就是让 import module 改成调用我们自定义的函数。&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-4&#34; name=&#34;__codelineno-0-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cm&#34;&gt; *&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-5&#34; name=&#34;__codelineno-0-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cm&#34;&gt; * - importModule (IN): 要处理的 module，这个 module 调用到别的 module 的需要 patch 的函数&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-6&#34; name=&#34;__codelineno-0-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cm&#34;&gt; *&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-7&#34; name=&#34;__codelineno-0-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cm&#34;&gt; * - exportModuleName (IN): 需要 patch 的函数来自的 module 名字&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-8&#34; name=&#34;__codelineno-0-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cm&#34;&gt; *&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-9&#34; name=&#34;__codelineno-0-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cm&#34;&gt; * - exportModulePath (IN): export module 所在的路径，首先尝试用 path 来加载 export module，&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-10&#34; name=&#34;__codelineno-0-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cm&#34;&gt; *          如果失败，则用 name 来加载&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-11&#34; name=&#34;__codelineno-0-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cm&#34;&gt; * - importName (IN): 函数名&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-12&#34; name=&#34;__codelineno-0-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cm&#34;&gt; *&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-13&#34; name=&#34;__codelineno-0-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cm&#34;&gt; * - replacement (IN): 替代的函数指针&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-14&#34; name=&#34;__codelineno-0-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cm&#34;&gt; *&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-15&#34; name=&#34;__codelineno-0-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cm&#34;&gt; * Return Valur: 成功 true，否则 false&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-16&#34; name=&#34;__codelineno-0-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cm&#34;&gt;*/&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-17&#34; name=&#34;__codelineno-0-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;RealDetector::patchImport&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-18&#34; name=&#34;__codelineno-0-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;HMODULE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;importModule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-19&#34; name=&#34;__codelineno-0-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LPCSTR&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exportModuleName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-20&#34; name=&#34;__codelineno-0-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LPCSTR&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exportModulePath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-21&#34; name=&#34;__codelineno-0-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LPCSTR&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;importName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-22&#34; name=&#34;__codelineno-0-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LPCVOID&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;replacement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-23&#34; name=&#34;__codelineno-0-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-24&#34; name=&#34;__codelineno-0-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;HMODULE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exportmodule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-25&#34; name=&#34;__codelineno-0-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IMAGE_THUNK_DATA&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-26&#34; name=&#34;__codelineno-0-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IMAGE_IMPORT_DESCRIPTOR&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;idte&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-27&#34; name=&#34;__codelineno-0-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FARPROC&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;import&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-28&#34; name=&#34;__codelineno-0-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DWORD&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;protect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-29&#34; name=&#34;__codelineno-0-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IMAGE_SECTION_HEADER&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;section&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-30&#34; name=&#34;__codelineno-0-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ULONG&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-31&#34; name=&#34;__codelineno-0-31&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-32&#34; name=&#34;__codelineno-0-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;assert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exportModuleName&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-33&#34; name=&#34;__codelineno-0-33&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-34&#34; name=&#34;__codelineno-0-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;idte&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IMAGE_IMPORT_DESCRIPTOR&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ImageDirectoryEntryToDataEx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PVOID&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;importModule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-0-35&#34; name=&#34;__codelineno-0-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TRUE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IMAGE_DIRECTORY_ENTRY_IMPORT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;section&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-36&#34; name=&#34;__codelineno-0-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;idte&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-0-37&#34; name=&#34;__codelineno-0-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-38&#34; name=&#34;__codelineno-0-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;patchImport failed: idte == NULL&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-39&#34; name=&#34;__codelineno-0-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-40&#34; name=&#34;__codelineno-0-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-41&#34; name=&#34;__codelineno-0-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;idte&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FirstThunk&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;0x0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-0-42&#34; name=&#34;__codelineno-0-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-43&#34; name=&#34;__codelineno-0-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;strcmp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PCHAR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;R2VA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;importModule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;idte&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exportModuleName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-0-44&#34; name=&#34;__codelineno-0-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-45&#34; name=&#34;__codelineno-0-45&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-46&#34; name=&#34;__codelineno-0-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-47&#34; name=&#34;__codelineno-0-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;idte&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-48&#34; name=&#34;__codelineno-0-48&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-49&#34; name=&#34;__codelineno-0-49&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;idte&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FirstThunk&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;0x0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-0-50&#34; name=&#34;__codelineno-0-50&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-51&#34; name=&#34;__codelineno-0-51&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;patchImport failed: idte-&amp;gt;FirstThunk == 0x0&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-52&#34; name=&#34;__codelineno-0-52&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-53&#34; name=&#34;__codelineno-0-53&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-54&#34; name=&#34;__codelineno-0-54&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-55&#34; name=&#34;__codelineno-0-55&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exportModulePath&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-0-56&#34; name=&#34;__codelineno-0-56&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-57&#34; name=&#34;__codelineno-0-57&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exportmodule&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetModuleHandleA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exportModulePath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-58&#34; name=&#34;__codelineno-0-58&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-59&#34; name=&#34;__codelineno-0-59&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-0-60&#34; name=&#34;__codelineno-0-60&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-61&#34; name=&#34;__codelineno-0-61&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exportmodule&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetModuleHandleA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exportModuleName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-62&#34; name=&#34;__codelineno-0-62&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-63&#34; name=&#34;__codelineno-0-63&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;assert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exportmodule&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-64&#34; name=&#34;__codelineno-0-64&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;import&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetProcAddress&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exportmodule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;importName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-65&#34; name=&#34;__codelineno-0-65&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;assert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;import&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-66&#34; name=&#34;__codelineno-0-66&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-67&#34; name=&#34;__codelineno-0-67&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iate&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IMAGE_THUNK_DATA&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;R2VA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;importModule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;idte&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FirstThunk&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-68&#34; name=&#34;__codelineno-0-68&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;u1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;0x0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-0-69&#34; name=&#34;__codelineno-0-69&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-70&#34; name=&#34;__codelineno-0-70&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;u1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DWORD_PTR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;import&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-0-71&#34; name=&#34;__codelineno-0-71&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-72&#34; name=&#34;__codelineno-0-72&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;VirtualProtect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;u1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;sizeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;u1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-0-73&#34; name=&#34;__codelineno-0-73&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PAGE_READWRITE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;protect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-74&#34; name=&#34;__codelineno-0-74&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;u1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DWORD_PTR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;replacement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-75&#34; name=&#34;__codelineno-0-75&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;VirtualProtect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;u1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;sizeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;u1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-0-76&#34; name=&#34;__codelineno-0-76&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;protect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;protect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-77&#34; name=&#34;__codelineno-0-77&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-78&#34; name=&#34;__codelineno-0-78&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-79&#34; name=&#34;__codelineno-0-79&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-80&#34; name=&#34;__codelineno-0-80&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-81&#34; name=&#34;__codelineno-0-81&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-82&#34; name=&#34;__codelineno-0-82&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-83&#34; name=&#34;__codelineno-0-83&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;我们来分析一下这个函数，就像注释所说的，这个函数实现的功能就是把 IAT 里面的某函数的地址改成另一个函数的地址。先来看第 34-35 行：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;idte&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IMAGE_IMPORT_DESCRIPTOR&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ImageDirectoryEntryToDataEx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PVOID&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;importModule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-1-2&#34; name=&#34;__codelineno-1-2&#34; href=&#34;#__codelineno-1-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TRUE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IMAGE_DIRECTORY_ENTRY_IMPORT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;section&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;ImageDirectoryEntryToDataEx&lt;/code&gt; 函数可以返回模块的文件头的某结构的地址，&lt;code&gt;IMAGE_DIRECTORY_ENTRY_IMPORT&lt;/code&gt; 指定要导入表结构，所以返回的 &lt;code&gt;idte&lt;/code&gt; 就指向了模块导入表了。&lt;/p&gt;
&lt;p&gt;36-40 行就是检查 &lt;code&gt;idte&lt;/code&gt; 有效。41 行 &lt;code&gt;idte-&amp;gt;FirstThunk&lt;/code&gt; 指向的就是实际的 IAT 了。所以 41-48 行就是在根据模块名字查找需要替换的函数的模块，如果找不到，说明没有调用到该模块的函数，只能提示错误并返回。&lt;/p&gt;
&lt;p&gt;找到模块后，自然地，我们需要找到替换的那个函数，55-62 行打开函数所属的模块，64 行找到函数地址。因为 IAT 没有保存名字，所以需要先根据原来的函数地址，定位到函数，再修改该函数地址，68-80 行就是在做这个事情。成功找到函数之后，就简单地把地址修改成 &lt;code&gt;replacement&lt;/code&gt; 的地址。&lt;/p&gt;
&lt;p&gt;至此，我们就成功地替换了 IAT 中的函数了。&lt;/p&gt;
&lt;h4 id=&#34;_6&#34;&gt;模块和函数名字&lt;/h4&gt;
&lt;p&gt;虽然我们已经实现了替换 IAT 函数 &lt;code&gt;patchImport&lt;/code&gt;，但这个函数需要指定模块名字和函数名字呀，那我们怎么知道程序的内存分配和释放用了什么模块和函数呢？为了搞清楚这个问题，我们需要借助 Windows 下的工具 &lt;a href=&#34;http://www.dependencywalker.com/&#34;&gt;Dependency Walker&lt;/a&gt;。Visual Studio 下新建一个工程，在 &lt;code&gt;main&lt;/code&gt; 函数里面使用 &lt;code&gt;new&lt;/code&gt; 来申请内存，编译 Debug 版，之后使用 &lt;code&gt;depends.exe&lt;/code&gt; 来打开编译出来的 exe 文件，可以看到一下类似的界面（以我的工程 &lt;a href=&#34;https://github.com/disenone/LeakDetector/tree/master/LeakDetectorTest&#34;&gt;LeakDetectorTest&lt;/a&gt; 为例）：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2016-6-11-memory-leak-detector/depends.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;可以看到 LeakDetectorTest.exe 使用了 uscrtbased.dll 里面的 &lt;code&gt;malloc&lt;/code&gt; 和 &lt;code&gt;_free_dbg&lt;/code&gt; （没有在图中显示出来），这两个函数就是我们需要替换的函数了。要注意实际的模块函数名字可能跟你的 Windows 和 Visual Studio 版本有关，我的是 Windows 10 和 Visual Studio 2015，你需要做的就是用 depends.exe 看看实际调用的是什么函数。&lt;/p&gt;
&lt;h4 id=&#34;_7&#34;&gt;分析调用栈&lt;/h4&gt;
&lt;p&gt;记录内存分配需要记录当时的调用栈信息，这里我不打算详细介绍 Windows 下如何拿到当前的调用栈信息，相关的函数是 &lt;code&gt;RtlCaptureStackBackTrace&lt;/code&gt;，网上有许多相关的资料，也可以看看我的代码里面的函数 &lt;a href=&#34;https://github.com/disenone/LeakDetector/blob/master/LeakDetector/RealDetector.cpp&#34;&gt;&lt;code&gt;printTrace&lt;/code&gt;&lt;/a&gt; 。&lt;/p&gt;
&lt;h4 id=&#34;_8&#34;&gt;检测内存泄露&lt;/h4&gt;
&lt;p&gt;至此，我们已经把龙珠都收集全了，下面正式召唤神龙。&lt;/p&gt;
&lt;p&gt;我想做成可以局部检测内存泄露（这是跟 VLD 不同的地方，VLD 做的是全局的检测，并支持多线程）。所以我在实际替换函数的类&lt;code&gt;RealDetector&lt;/code&gt;上又封装了一层&lt;code&gt;LeakDetector&lt;/code&gt;，并把&lt;code&gt;LeakDetector&lt;/code&gt;的接口暴露给使用者。使用时只需构造&lt;code&gt;LeakDetector&lt;/code&gt;，即完成函数的替换并开始检测内存泄露，&lt;code&gt;LeakDetector&lt;/code&gt;析构时会恢复原来的函数，中止内存泄露检测，并打印内存泄露检测结果。&lt;/p&gt;
&lt;p&gt;用下面代码测试一下：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-2-1&#34; name=&#34;__codelineno-2-1&#34; href=&#34;#__codelineno-2-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;quot;LeakDetector.h&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-2&#34; name=&#34;__codelineno-2-2&#34; href=&#34;#__codelineno-2-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-3&#34; name=&#34;__codelineno-2-3&#34; href=&#34;#__codelineno-2-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;namespace&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-4&#34; name=&#34;__codelineno-2-4&#34; href=&#34;#__codelineno-2-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-5&#34; name=&#34;__codelineno-2-5&#34; href=&#34;#__codelineno-2-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;new_some_mem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-6&#34; name=&#34;__codelineno-2-6&#34; href=&#34;#__codelineno-2-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-7&#34; name=&#34;__codelineno-2-7&#34; href=&#34;#__codelineno-2-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-8&#34; name=&#34;__codelineno-2-8&#34; href=&#34;#__codelineno-2-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-9&#34; name=&#34;__codelineno-2-9&#34; href=&#34;#__codelineno-2-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-10&#34; name=&#34;__codelineno-2-10&#34; href=&#34;#__codelineno-2-10&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-11&#34; name=&#34;__codelineno-2-11&#34; href=&#34;#__codelineno-2-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-12&#34; name=&#34;__codelineno-2-12&#34; href=&#34;#__codelineno-2-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-13&#34; name=&#34;__codelineno-2-13&#34; href=&#34;#__codelineno-2-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ld&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LDTools&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LeakDetector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;LeakDetectorTest.exe&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-14&#34; name=&#34;__codelineno-2-14&#34; href=&#34;#__codelineno-2-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new_some_mem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-15&#34; name=&#34;__codelineno-2-15&#34; href=&#34;#__codelineno-2-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-16&#34; name=&#34;__codelineno-2-16&#34; href=&#34;#__codelineno-2-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;代码直接 &lt;code&gt;new&lt;/code&gt; 了一些内存出来，没有释放掉就直接退出，程序打印的结果：&lt;/p&gt;
&lt;div class=&#34;language-text highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-3-1&#34; name=&#34;__codelineno-3-1&#34; href=&#34;#__codelineno-3-1&#34;&gt;&lt;/a&gt;============== LeakDetector::start ===============
&lt;a id=&#34;__codelineno-3-2&#34; name=&#34;__codelineno-3-2&#34; href=&#34;#__codelineno-3-2&#34;&gt;&lt;/a&gt;LeakDetector init success.
&lt;a id=&#34;__codelineno-3-3&#34; name=&#34;__codelineno-3-3&#34; href=&#34;#__codelineno-3-3&#34;&gt;&lt;/a&gt;============== LeakDetector::stop ================
&lt;a id=&#34;__codelineno-3-4&#34; name=&#34;__codelineno-3-4&#34; href=&#34;#__codelineno-3-4&#34;&gt;&lt;/a&gt;Memory Leak Detected: total 2
&lt;a id=&#34;__codelineno-3-5&#34; name=&#34;__codelineno-3-5&#34; href=&#34;#__codelineno-3-5&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-6&#34; name=&#34;__codelineno-3-6&#34; href=&#34;#__codelineno-3-6&#34;&gt;&lt;/a&gt;Num 1:
&lt;a id=&#34;__codelineno-3-7&#34; name=&#34;__codelineno-3-7&#34; href=&#34;#__codelineno-3-7&#34;&gt;&lt;/a&gt;    e:\program\github\leakdetector\leakdetector\realdetector.cpp (109): LeakDetector.dll!LDTools::RealDetector::_malloc() + 0x1c bytes
&lt;a id=&#34;__codelineno-3-8&#34; name=&#34;__codelineno-3-8&#34; href=&#34;#__codelineno-3-8&#34;&gt;&lt;/a&gt;    f:\dd\vctools\crt\vcstartup\src\heap\new_scalar.cpp (19): LeakDetectorTest.exe!operator new() + 0x9 bytes
&lt;a id=&#34;__codelineno-3-9&#34; name=&#34;__codelineno-3-9&#34; href=&#34;#__codelineno-3-9&#34;&gt;&lt;/a&gt;    f:\dd\vctools\crt\vcstartup\src\heap\new_array.cpp (15): LeakDetectorTest.exe!operator new[]() + 0x9 bytes
&lt;a id=&#34;__codelineno-3-10&#34; name=&#34;__codelineno-3-10&#34; href=&#34;#__codelineno-3-10&#34;&gt;&lt;/a&gt;    e:\program\github\leakdetector\leakdetectortest\leakdetectortest.cpp (12): LeakDetectorTest.exe!new_some_mem() + 0x7 bytes
&lt;a id=&#34;__codelineno-3-11&#34; name=&#34;__codelineno-3-11&#34; href=&#34;#__codelineno-3-11&#34;&gt;&lt;/a&gt;    e:\program\github\leakdetector\leakdetectortest\leakdetectortest.cpp (19): LeakDetectorTest.exe!main()
&lt;a id=&#34;__codelineno-3-12&#34; name=&#34;__codelineno-3-12&#34; href=&#34;#__codelineno-3-12&#34;&gt;&lt;/a&gt;    f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (74): LeakDetectorTest.exe!invoke_main() + 0x1b bytes
&lt;a id=&#34;__codelineno-3-13&#34; name=&#34;__codelineno-3-13&#34; href=&#34;#__codelineno-3-13&#34;&gt;&lt;/a&gt;    f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (264): LeakDetectorTest.exe!__scrt_common_main_seh() + 0x5 bytes
&lt;a id=&#34;__codelineno-3-14&#34; name=&#34;__codelineno-3-14&#34; href=&#34;#__codelineno-3-14&#34;&gt;&lt;/a&gt;    f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (309): LeakDetectorTest.exe!__scrt_common_main()
&lt;a id=&#34;__codelineno-3-15&#34; name=&#34;__codelineno-3-15&#34; href=&#34;#__codelineno-3-15&#34;&gt;&lt;/a&gt;    f:\dd\vctools\crt\vcstartup\src\startup\exe_main.cpp (17): LeakDetectorTest.exe!mainCRTStartup()
&lt;a id=&#34;__codelineno-3-16&#34; name=&#34;__codelineno-3-16&#34; href=&#34;#__codelineno-3-16&#34;&gt;&lt;/a&gt;    KERNEL32.DLL!BaseThreadInitThunk() + 0x24 bytes
&lt;a id=&#34;__codelineno-3-17&#34; name=&#34;__codelineno-3-17&#34; href=&#34;#__codelineno-3-17&#34;&gt;&lt;/a&gt;    ntdll.dll!RtlUnicodeStringToInteger() + 0x253 bytes
&lt;a id=&#34;__codelineno-3-18&#34; name=&#34;__codelineno-3-18&#34; href=&#34;#__codelineno-3-18&#34;&gt;&lt;/a&gt;    ntdll.dll!RtlUnicodeStringToInteger() + 0x21e bytes
&lt;a id=&#34;__codelineno-3-19&#34; name=&#34;__codelineno-3-19&#34; href=&#34;#__codelineno-3-19&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-20&#34; name=&#34;__codelineno-3-20&#34; href=&#34;#__codelineno-3-20&#34;&gt;&lt;/a&gt;Num 2:
&lt;a id=&#34;__codelineno-3-21&#34; name=&#34;__codelineno-3-21&#34; href=&#34;#__codelineno-3-21&#34;&gt;&lt;/a&gt;    e:\program\github\leakdetector\leakdetector\realdetector.cpp (109): LeakDetector.dll!LDTools::RealDetector::_malloc() + 0x1c bytes
&lt;a id=&#34;__codelineno-3-22&#34; name=&#34;__codelineno-3-22&#34; href=&#34;#__codelineno-3-22&#34;&gt;&lt;/a&gt;    f:\dd\vctools\crt\vcstartup\src\heap\new_scalar.cpp (19): LeakDetectorTest.exe!operator new() + 0x9 bytes
&lt;a id=&#34;__codelineno-3-23&#34; name=&#34;__codelineno-3-23&#34; href=&#34;#__codelineno-3-23&#34;&gt;&lt;/a&gt;    f:\dd\vctools\crt\vcstartup\src\heap\new_array.cpp (15): LeakDetectorTest.exe!operator new[]() + 0x9 bytes
&lt;a id=&#34;__codelineno-3-24&#34; name=&#34;__codelineno-3-24&#34; href=&#34;#__codelineno-3-24&#34;&gt;&lt;/a&gt;    e:\program\github\leakdetector\leakdetectortest\leakdetectortest.cpp (11): LeakDetectorTest.exe!new_some_mem() + 0x7 bytes
&lt;a id=&#34;__codelineno-3-25&#34; name=&#34;__codelineno-3-25&#34; href=&#34;#__codelineno-3-25&#34;&gt;&lt;/a&gt;    e:\program\github\leakdetector\leakdetectortest\leakdetectortest.cpp (19): LeakDetectorTest.exe!main()
&lt;a id=&#34;__codelineno-3-26&#34; name=&#34;__codelineno-3-26&#34; href=&#34;#__codelineno-3-26&#34;&gt;&lt;/a&gt;    f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (74): LeakDetectorTest.exe!invoke_main() + 0x1b bytes
&lt;a id=&#34;__codelineno-3-27&#34; name=&#34;__codelineno-3-27&#34; href=&#34;#__codelineno-3-27&#34;&gt;&lt;/a&gt;    f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (264): LeakDetectorTest.exe!__scrt_common_main_seh() + 0x5 bytes
&lt;a id=&#34;__codelineno-3-28&#34; name=&#34;__codelineno-3-28&#34; href=&#34;#__codelineno-3-28&#34;&gt;&lt;/a&gt;    f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (309): LeakDetectorTest.exe!__scrt_common_main()
&lt;a id=&#34;__codelineno-3-29&#34; name=&#34;__codelineno-3-29&#34; href=&#34;#__codelineno-3-29&#34;&gt;&lt;/a&gt;    f:\dd\vctools\crt\vcstartup\src\startup\exe_main.cpp (17): LeakDetectorTest.exe!mainCRTStartup()
&lt;a id=&#34;__codelineno-3-30&#34; name=&#34;__codelineno-3-30&#34; href=&#34;#__codelineno-3-30&#34;&gt;&lt;/a&gt;    KERNEL32.DLL!BaseThreadInitThunk() + 0x24 bytes
&lt;a id=&#34;__codelineno-3-31&#34; name=&#34;__codelineno-3-31&#34; href=&#34;#__codelineno-3-31&#34;&gt;&lt;/a&gt;    ntdll.dll!RtlUnicodeStringToInteger() + 0x253 bytes
&lt;a id=&#34;__codelineno-3-32&#34; name=&#34;__codelineno-3-32&#34; href=&#34;#__codelineno-3-32&#34;&gt;&lt;/a&gt;    ntdll.dll!RtlUnicodeStringToInteger() + 0x21e bytes
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;程序正确地找出有两个地方申请的内存没有释放，并且打印出了完整的调用栈信息，我们需要的功能至此已经完成了。&lt;/p&gt;
&lt;h3 id=&#34;_9&#34;&gt;结语&lt;/h3&gt;
&lt;p&gt;当你还不了解程序链接、装载与库的时候，你可能会对如何找到共享链接库的函数一头雾水，更不要说要把链接库的函数替换成我们自己的函数了。这里就以检测内存泄露为例子，探讨下了如何替换 Windows DLL 的函数，更详细的实现可以参考 VLD 的源码。&lt;/p&gt;
&lt;p&gt;另外想说的是，《程序员的自我修养：链接、装载与库》真是本不错的书呢，纯感慨非软广。&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/cpp-%E7%BC%96%E5%86%99Windows%E4%B8%8B%E7%9A%84MemoryLeakDetector/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 30 Nov 2023 20:09:36 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/cpp-%E7%BC%96%E5%86%99Windows%E4%B8%8B%E7%9A%84MemoryLeakDetector/</guid>
      
    </item>
    
    <item>
      <title>Python 杂谈 1 - 探究 __builtins__</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;Python 杂谈 1 - 探究 __builtins__ - Disenone&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_1&#34;&gt;引子&lt;/h2&gt;
&lt;p&gt;我们知道，&lt;code&gt;__builtins__&lt;/code&gt; 本身是在全局命名空间中就有的一个对象，是 &lt;code&gt;Python&lt;/code&gt; 故意暴露出来给代码层的，在代码的任意地方都可以直接使用。但是有点冷的知识是，&lt;code&gt;__builtins__&lt;/code&gt; 在 &lt;code&gt;main&lt;/code&gt; 模块（也就是 &lt;code&gt;__main__&lt;/code&gt;，指的都是同一个模块，后文可能会混用）里面是 &lt;code&gt;__builtin__&lt;/code&gt; 这个模块，但在其他模块里面，它表示的是 &lt;code&gt;__builtin__.__dict__&lt;/code&gt;，这就有点让人莫名其妙了。虽然官方不推荐直接使用 &lt;code&gt;__builtins__&lt;/code&gt;，但你给我搞两种情况是怎么回事？本文我们就来盘一盘这个设定的由来，在这个过程中，我们还可以找到这些问题的答案：&lt;code&gt;__builtin__&lt;/code&gt; 跟 &lt;code&gt;__builtins__&lt;/code&gt; 有什么区别？&lt;code&gt;__builtins__&lt;/code&gt; 在 &lt;code&gt;main&lt;/code&gt; 模块跟其他模块为什么会设定成不同？&lt;code&gt;__builtins__&lt;/code&gt; 是在哪里定义的？&lt;/p&gt;
&lt;h2 id=&#34;__builtin__&#34;&gt;&lt;code&gt;__builtin__&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;在探讨 &lt;code&gt;__builtins__&lt;/code&gt; 之前，我们需要先看看 &lt;code&gt;__builtin__&lt;/code&gt; 是什么。&lt;code&gt;__builtin__&lt;/code&gt; 是存放所有内建对象的模块，我们平常可以直接使用的 &lt;code&gt;Python&lt;/code&gt; 内建对象，本质上都是 &lt;code&gt;__builtin__&lt;/code&gt; 模块里的对象，即放在 &lt;code&gt;__builtin__.__dict__&lt;/code&gt; 里，对应着的是 &lt;code&gt;Python&lt;/code&gt; 的内建名字空间。记住这个关键知识点：&lt;code&gt;__buintin__&lt;/code&gt; 是一个模块 &lt;code&gt;module&lt;/code&gt;。我们可以在 &lt;code&gt;Python&lt;/code&gt; 源码中找到 &lt;code&gt;__builtin__&lt;/code&gt; 模块的定义和使用（注意，下文提到的 &lt;code&gt;Python&lt;/code&gt; 源码，都是指 CPython-2.7.18 源码）：&lt;/p&gt;
&lt;div class=&#34;language-c highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// pythonrun.c&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34; href=&#34;#__codelineno-0-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;nf&#34;&gt;Py_InitializeEx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;install_sigs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-4&#34; name=&#34;__codelineno-0-4&#34; href=&#34;#__codelineno-0-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-5&#34; name=&#34;__codelineno-0-5&#34; href=&#34;#__codelineno-0-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyInterpreterState&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;interp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-6&#34; name=&#34;__codelineno-0-6&#34; href=&#34;#__codelineno-0-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-7&#34; name=&#34;__codelineno-0-7&#34; href=&#34;#__codelineno-0-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 初始化 __builtin__&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-8&#34; name=&#34;__codelineno-0-8&#34; href=&#34;#__codelineno-0-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bimod&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_PyBuiltin_Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-9&#34; name=&#34;__codelineno-0-9&#34; href=&#34;#__codelineno-0-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// interp-&amp;gt;builtins = __builtin__.__dict__&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-10&#34; name=&#34;__codelineno-0-10&#34; href=&#34;#__codelineno-0-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;interp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;builtins&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyModule_GetDict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bimod&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-11&#34; name=&#34;__codelineno-0-11&#34; href=&#34;#__codelineno-0-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-12&#34; name=&#34;__codelineno-0-12&#34; href=&#34;#__codelineno-0-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-13&#34; name=&#34;__codelineno-0-13&#34; href=&#34;#__codelineno-0-13&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-14&#34; name=&#34;__codelineno-0-14&#34; href=&#34;#__codelineno-0-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// bltinmodule.c&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-15&#34; name=&#34;__codelineno-0-15&#34; href=&#34;#__codelineno-0-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-16&#34; name=&#34;__codelineno-0-16&#34; href=&#34;#__codelineno-0-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;nf&#34;&gt;_PyBuiltin_Init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-17&#34; name=&#34;__codelineno-0-17&#34; href=&#34;#__codelineno-0-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-18&#34; name=&#34;__codelineno-0-18&#34; href=&#34;#__codelineno-0-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mod&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;debug&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-19&#34; name=&#34;__codelineno-0-19&#34; href=&#34;#__codelineno-0-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mod&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Py_InitModule4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;__builtin__&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;builtin_methods&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-20&#34; name=&#34;__codelineno-0-20&#34; href=&#34;#__codelineno-0-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                         &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;builtin_doc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-21&#34; name=&#34;__codelineno-0-21&#34; href=&#34;#__codelineno-0-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                         &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PYTHON_API_VERSION&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-22&#34; name=&#34;__codelineno-0-22&#34; href=&#34;#__codelineno-0-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mod&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-23&#34; name=&#34;__codelineno-0-23&#34; href=&#34;#__codelineno-0-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-24&#34; name=&#34;__codelineno-0-24&#34; href=&#34;#__codelineno-0-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyModule_GetDict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mod&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-25&#34; name=&#34;__codelineno-0-25&#34; href=&#34;#__codelineno-0-25&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-26&#34; name=&#34;__codelineno-0-26&#34; href=&#34;#__codelineno-0-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 给 dict 加上内建的对象&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-27&#34; name=&#34;__codelineno-0-27&#34; href=&#34;#__codelineno-0-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-28&#34; name=&#34;__codelineno-0-28&#34; href=&#34;#__codelineno-0-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-29&#34; name=&#34;__codelineno-0-29&#34; href=&#34;#__codelineno-0-29&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-30&#34; name=&#34;__codelineno-0-30&#34; href=&#34;#__codelineno-0-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// ceval.c&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-31&#34; name=&#34;__codelineno-0-31&#34; href=&#34;#__codelineno-0-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// 获取 builtins&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-32&#34; name=&#34;__codelineno-0-32&#34; href=&#34;#__codelineno-0-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-33&#34; name=&#34;__codelineno-0-33&#34; href=&#34;#__codelineno-0-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;nf&#34;&gt;PyEval_GetBuiltins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-34&#34; name=&#34;__codelineno-0-34&#34; href=&#34;#__codelineno-0-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-35&#34; name=&#34;__codelineno-0-35&#34; href=&#34;#__codelineno-0-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyFrameObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current_frame&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyEval_GetFrame&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-36&#34; name=&#34;__codelineno-0-36&#34; href=&#34;#__codelineno-0-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current_frame&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-37&#34; name=&#34;__codelineno-0-37&#34; href=&#34;#__codelineno-0-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyThreadState_GET&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;interp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;builtins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-38&#34; name=&#34;__codelineno-0-38&#34; href=&#34;#__codelineno-0-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-39&#34; name=&#34;__codelineno-0-39&#34; href=&#34;#__codelineno-0-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current_frame&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_builtins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-40&#34; name=&#34;__codelineno-0-40&#34; href=&#34;#__codelineno-0-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Python&lt;/code&gt; 初始化的时候会调用 &lt;code&gt;_PyBuiltin_Init&lt;/code&gt; 来创建 &lt;code&gt;__builtin__&lt;/code&gt; 模块，并在里面添加上内建的对象，解释器本身会引用住 &lt;code&gt;interp-&amp;gt;builtins = __buintin__.__dict__&lt;/code&gt;，当前执行的栈帧结构同时也会引用一份 &lt;code&gt;current_frame-&amp;gt;f_builtins&lt;/code&gt;。那么很自然地，当执行代码需要根据名字寻找对象的时候，&lt;code&gt;Python&lt;/code&gt; 会去 &lt;code&gt;current_frame-&amp;gt;f_builtins&lt;/code&gt; 里面来找，自然就能拿到所有的内建对象：&lt;/p&gt;
&lt;div class=&#34;language-c highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// ceval.c&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-2&#34; name=&#34;__codelineno-1-2&#34; href=&#34;#__codelineno-1-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;TARGET&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOAD_NAME&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-3&#34; name=&#34;__codelineno-1-3&#34; href=&#34;#__codelineno-1-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-4&#34; name=&#34;__codelineno-1-4&#34; href=&#34;#__codelineno-1-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 先在 f-&amp;gt;f_locals 名字空间里面找&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-5&#34; name=&#34;__codelineno-1-5&#34; href=&#34;#__codelineno-1-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-6&#34; name=&#34;__codelineno-1-6&#34; href=&#34;#__codelineno-1-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-7&#34; name=&#34;__codelineno-1-7&#34; href=&#34;#__codelineno-1-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 再找找全局空间&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-8&#34; name=&#34;__codelineno-1-8&#34; href=&#34;#__codelineno-1-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyDict_GetItem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_globals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;w&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-9&#34; name=&#34;__codelineno-1-9&#34; href=&#34;#__codelineno-1-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-10&#34; name=&#34;__codelineno-1-10&#34; href=&#34;#__codelineno-1-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 这里就去内建空间找&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-11&#34; name=&#34;__codelineno-1-11&#34; href=&#34;#__codelineno-1-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyDict_GetItem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_builtins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;w&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-12&#34; name=&#34;__codelineno-1-12&#34; href=&#34;#__codelineno-1-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-13&#34; name=&#34;__codelineno-1-13&#34; href=&#34;#__codelineno-1-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;format_exc_check_arg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-14&#34; name=&#34;__codelineno-1-14&#34; href=&#34;#__codelineno-1-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyExc_NameError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-15&#34; name=&#34;__codelineno-1-15&#34; href=&#34;#__codelineno-1-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NAME_ERROR_MSG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;w&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-16&#34; name=&#34;__codelineno-1-16&#34; href=&#34;#__codelineno-1-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-17&#34; name=&#34;__codelineno-1-17&#34; href=&#34;#__codelineno-1-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-18&#34; name=&#34;__codelineno-1-18&#34; href=&#34;#__codelineno-1-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-19&#34; name=&#34;__codelineno-1-19&#34; href=&#34;#__codelineno-1-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Py_INCREF&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-20&#34; name=&#34;__codelineno-1-20&#34; href=&#34;#__codelineno-1-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-21&#34; name=&#34;__codelineno-1-21&#34; href=&#34;#__codelineno-1-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PUSH&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-22&#34; name=&#34;__codelineno-1-22&#34; href=&#34;#__codelineno-1-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DISPATCH&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-23&#34; name=&#34;__codelineno-1-23&#34; href=&#34;#__codelineno-1-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;最后，由于 &lt;code&gt;__builtin__&lt;/code&gt; 这个名字实在是太有迷惑性了，&lt;code&gt;Python3&lt;/code&gt; 中已经改名为 &lt;code&gt;builtins&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;__builtins__&#34;&gt;&lt;code&gt;__builtins__&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;__builtins__&lt;/code&gt; 的表现是有点奇怪的：
* 在 &lt;code&gt;main&lt;/code&gt; 模块中（&lt;code&gt;main&lt;/code&gt; 模块，或者叫&lt;code&gt;最高层级代码运行所在环境&lt;/code&gt;，是用户指定最先启动运行的 &lt;code&gt;Python&lt;/code&gt; 模块，也就是通常我们在命令行执行 &lt;code&gt;python xxx.py&lt;/code&gt; 时，&lt;code&gt;xxx.py&lt;/code&gt; 这个模块），&lt;code&gt;__builtins__ = __builtin__&lt;/code&gt;；
* 在其他模块中 &lt;code&gt;__builtins__ = __builtin__.__dict__&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;相同的名字，但在不同的模块下表现却是不相同的，这样的设定很容易让人疑惑。不过只要知道这个设定，就足够支持你在 &lt;code&gt;Python&lt;/code&gt; 中使用 &lt;code&gt;__builtins__&lt;/code&gt;，疑惑并不会影响你写出足够安全的代码，诸如：&lt;/p&gt;
&lt;div class=&#34;language-python highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-2-1&#34; name=&#34;__codelineno-2-1&#34; href=&#34;#__codelineno-2-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;SetBuiltins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;builtins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-2&#34; name=&#34;__codelineno-2-2&#34; href=&#34;#__codelineno-2-2&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;builtins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-3&#34; name=&#34;__codelineno-2-3&#34; href=&#34;#__codelineno-2-3&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;n&#34;&gt;builtins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;val&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-4&#34; name=&#34;__codelineno-2-4&#34; href=&#34;#__codelineno-2-4&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-5&#34; name=&#34;__codelineno-2-5&#34; href=&#34;#__codelineno-2-5&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;nb&#34;&gt;setattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;builtins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-6&#34; name=&#34;__codelineno-2-6&#34; href=&#34;#__codelineno-2-6&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-7&#34; name=&#34;__codelineno-2-7&#34; href=&#34;#__codelineno-2-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;SetBuiltins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;__builtins__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;需要注意，其实并不建议使用 &lt;code&gt;__builtins__&lt;/code&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;CPython implementation detail&lt;/strong&gt;: Users should not touch &lt;code&gt;__builtins__&lt;/code&gt;; it is strictly an implementation detail. Users wanting to override values in the builtins namespace should import the &lt;code&gt;__builtin__&lt;/code&gt; (no ‘s’) module and modify its attributes appropriately.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;当然，这样的疑惑，总有一天会让你心痒难耐，我这里就决定继续探究下去，也因为这样，才有了这篇文章。我们下面的内容会深入到 &lt;strong&gt;CPython implementation detail&lt;/strong&gt; 中去。&lt;/p&gt;
&lt;h2 id=&#34;restricted-execution&#34;&gt;Restricted Execution&lt;/h2&gt;
&lt;p&gt;Restricted Execution 可以理解为有限制地执行不安全的代码，所谓有限制，可以是限制网络、io 等等，把代码限制在一定的执行环境中，控制代码的执行权限，防止代码影响到外部的环境和系统。常见的用例就是一些在线代码执行网站，譬如这个：&lt;a href=&#34;https://pythonsandbox.dev/&#34;&gt;pythonsandbox&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;跟你猜想的一样，&lt;code&gt;Python&lt;/code&gt; 对 &lt;code&gt;__builtins__&lt;/code&gt; 的设定是跟 Restricted Execution 有关。&lt;code&gt;Python&lt;/code&gt; 在 2.3 版本之前，曾经提供过类似的功能 &lt;a href=&#34;https://docs.python.org/2.7/library/restricted.html&#34;&gt;Restricted Execution&lt;/a&gt;，只是由于后来被证实为不可行的，只好把这个功能作废了，但代码在 2.7.18 版本还保留着，所以我们可以来考古。&lt;/p&gt;
&lt;p&gt;首先来看 &lt;code&gt;Python&lt;/code&gt; 源码里面对 &lt;code&gt;__builtins__&lt;/code&gt; 的设置：&lt;/p&gt;
&lt;div class=&#34;language-c highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-3-1&#34; name=&#34;__codelineno-3-1&#34; href=&#34;#__codelineno-3-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// pythonrun.c&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-2&#34; name=&#34;__codelineno-3-2&#34; href=&#34;#__codelineno-3-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;initmain&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-3&#34; name=&#34;__codelineno-3-3&#34; href=&#34;#__codelineno-3-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-4&#34; name=&#34;__codelineno-3-4&#34; href=&#34;#__codelineno-3-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-5&#34; name=&#34;__codelineno-3-5&#34; href=&#34;#__codelineno-3-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 获取 __main__ 模块&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-6&#34; name=&#34;__codelineno-3-6&#34; href=&#34;#__codelineno-3-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyImport_AddModule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-7&#34; name=&#34;__codelineno-3-7&#34; href=&#34;#__codelineno-3-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-8&#34; name=&#34;__codelineno-3-8&#34; href=&#34;#__codelineno-3-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Py_FatalError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;can&amp;#39;t create __main__ module&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-9&#34; name=&#34;__codelineno-3-9&#34; href=&#34;#__codelineno-3-9&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-10&#34; name=&#34;__codelineno-3-10&#34; href=&#34;#__codelineno-3-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// d = __main__.__dict__&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-11&#34; name=&#34;__codelineno-3-11&#34; href=&#34;#__codelineno-3-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyModule_GetDict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-12&#34; name=&#34;__codelineno-3-12&#34; href=&#34;#__codelineno-3-12&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-13&#34; name=&#34;__codelineno-3-13&#34; href=&#34;#__codelineno-3-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 设置 __main__.__dict__[&amp;#39;__builtins__&amp;#39;]，如果已有，则跳过&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-14&#34; name=&#34;__codelineno-3-14&#34; href=&#34;#__codelineno-3-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyDict_GetItemString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;__builtins__&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-15&#34; name=&#34;__codelineno-3-15&#34; href=&#34;#__codelineno-3-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bimod&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyImport_ImportModule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;__builtin__&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-16&#34; name=&#34;__codelineno-3-16&#34; href=&#34;#__codelineno-3-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bimod&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-17&#34; name=&#34;__codelineno-3-17&#34; href=&#34;#__codelineno-3-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyDict_SetItemString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;__builtins__&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bimod&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-18&#34; name=&#34;__codelineno-3-18&#34; href=&#34;#__codelineno-3-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Py_FatalError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;can&amp;#39;t add __builtins__ to __main__&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-19&#34; name=&#34;__codelineno-3-19&#34; href=&#34;#__codelineno-3-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Py_XDECREF&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bimod&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-20&#34; name=&#34;__codelineno-3-20&#34; href=&#34;#__codelineno-3-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-21&#34; name=&#34;__codelineno-3-21&#34; href=&#34;#__codelineno-3-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;在 &lt;code&gt;initmain&lt;/code&gt; 中，&lt;code&gt;Python&lt;/code&gt; 会给 &lt;code&gt;__main__&lt;/code&gt; 模块设置 &lt;code&gt;__builtins__&lt;/code&gt; 属性，默认等于 &lt;code&gt;__builtin__&lt;/code&gt; 模块，但如果已有，则跳过不会重新设置。利用这个特点，我们就可以通过修改 &lt;code&gt;__main__.__builtins__&lt;/code&gt; 来修改内建的一些功能，以达到限制代码执行权限的目的，具体的方法先按下不表，我们看看 &lt;code&gt;__builtins__&lt;/code&gt; 是怎么被传递的。&lt;/p&gt;
&lt;h2 id=&#34;__builtins___1&#34;&gt;&lt;code&gt;__builtins__&lt;/code&gt; 的传递&lt;/h2&gt;
&lt;p&gt;在创建新的栈帧的时候：&lt;/p&gt;
&lt;div class=&#34;language-c highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-4-1&#34; name=&#34;__codelineno-4-1&#34; href=&#34;#__codelineno-4-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PyFrameObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-2&#34; name=&#34;__codelineno-4-2&#34; href=&#34;#__codelineno-4-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;nf&#34;&gt;PyFrame_New&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyThreadState&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tstate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyCodeObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;code&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;globals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-3&#34; name=&#34;__codelineno-4-3&#34; href=&#34;#__codelineno-4-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;locals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-4&#34; name=&#34;__codelineno-4-4&#34; href=&#34;#__codelineno-4-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-5&#34; name=&#34;__codelineno-4-5&#34; href=&#34;#__codelineno-4-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-6&#34; name=&#34;__codelineno-4-6&#34; href=&#34;#__codelineno-4-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;back&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;back&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_globals&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;globals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-7&#34; name=&#34;__codelineno-4-7&#34; href=&#34;#__codelineno-4-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 取 globals[&amp;#39;__builtins__&amp;#39;] 作为新栈帧的 __builtins__&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-8&#34; name=&#34;__codelineno-4-8&#34; href=&#34;#__codelineno-4-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// builtin_object 就是字符串 &amp;#39;__builtins__&amp;#39;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-9&#34; name=&#34;__codelineno-4-9&#34; href=&#34;#__codelineno-4-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;builtins&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyDict_GetItem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;globals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;builtin_object&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-10&#34; name=&#34;__codelineno-4-10&#34; href=&#34;#__codelineno-4-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;builtins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-11&#34; name=&#34;__codelineno-4-11&#34; href=&#34;#__codelineno-4-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyModule_Check&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;builtins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-12&#34; name=&#34;__codelineno-4-12&#34; href=&#34;#__codelineno-4-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;builtins&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyModule_GetDict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;builtins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-13&#34; name=&#34;__codelineno-4-13&#34; href=&#34;#__codelineno-4-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;assert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;builtins&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyDict_Check&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;builtins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-14&#34; name=&#34;__codelineno-4-14&#34; href=&#34;#__codelineno-4-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-15&#34; name=&#34;__codelineno-4-15&#34; href=&#34;#__codelineno-4-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyDict_Check&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;builtins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-16&#34; name=&#34;__codelineno-4-16&#34; href=&#34;#__codelineno-4-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;builtins&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-17&#34; name=&#34;__codelineno-4-17&#34; href=&#34;#__codelineno-4-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-18&#34; name=&#34;__codelineno-4-18&#34; href=&#34;#__codelineno-4-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-19&#34; name=&#34;__codelineno-4-19&#34; href=&#34;#__codelineno-4-19&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-20&#34; name=&#34;__codelineno-4-20&#34; href=&#34;#__codelineno-4-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-21&#34; name=&#34;__codelineno-4-21&#34; href=&#34;#__codelineno-4-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-22&#34; name=&#34;__codelineno-4-22&#34; href=&#34;#__codelineno-4-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;/* If we share the globals, we share the builtins.&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-23&#34; name=&#34;__codelineno-4-23&#34; href=&#34;#__codelineno-4-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cm&#34;&gt;           Save a lookup and a call. */&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-24&#34; name=&#34;__codelineno-4-24&#34; href=&#34;#__codelineno-4-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 或者直接继承上一层栈帧的 f_builtins&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-25&#34; name=&#34;__codelineno-4-25&#34; href=&#34;#__codelineno-4-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;builtins&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;back&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_builtins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-26&#34; name=&#34;__codelineno-4-26&#34; href=&#34;#__codelineno-4-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;assert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;builtins&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyDict_Check&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;builtins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-27&#34; name=&#34;__codelineno-4-27&#34; href=&#34;#__codelineno-4-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Py_INCREF&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;builtins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-28&#34; name=&#34;__codelineno-4-28&#34; href=&#34;#__codelineno-4-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-29&#34; name=&#34;__codelineno-4-29&#34; href=&#34;#__codelineno-4-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-30&#34; name=&#34;__codelineno-4-30&#34; href=&#34;#__codelineno-4-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_builtins&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;builtins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-31&#34; name=&#34;__codelineno-4-31&#34; href=&#34;#__codelineno-4-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_globals&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;globals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-32&#34; name=&#34;__codelineno-4-32&#34; href=&#34;#__codelineno-4-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;创建新的栈帧时，对于 &lt;code&gt;__builtins__&lt;/code&gt; 的处理主要有两种情况：一种是没有上层栈帧的情况下，取 &lt;code&gt;globals[&#39;__builtins__&#39;]&lt;/code&gt;；另一种是直接取上层栈帧的 &lt;code&gt;f_builtins&lt;/code&gt;。联合起来看的话，可以理解为，一般情况下，在 &lt;code&gt;__main__&lt;/code&gt; 中设置好的 &lt;code&gt;__builtins__&lt;/code&gt;，会一直继承给后面的栈帧，相当于共用同一份。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;import&lt;/code&gt; 模块时：&lt;/p&gt;
&lt;div class=&#34;language-c highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-5-1&#34; name=&#34;__codelineno-5-1&#34; href=&#34;#__codelineno-5-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-2&#34; name=&#34;__codelineno-5-2&#34; href=&#34;#__codelineno-5-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;nf&#34;&gt;load_compiled_module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cpathname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;FILE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-3&#34; name=&#34;__codelineno-5-3&#34; href=&#34;#__codelineno-5-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-4&#34; name=&#34;__codelineno-5-4&#34; href=&#34;#__codelineno-5-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;long&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;magic&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-5&#34; name=&#34;__codelineno-5-5&#34; href=&#34;#__codelineno-5-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyCodeObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;co&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-6&#34; name=&#34;__codelineno-5-6&#34; href=&#34;#__codelineno-5-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-7&#34; name=&#34;__codelineno-5-7&#34; href=&#34;#__codelineno-5-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-8&#34; name=&#34;__codelineno-5-8&#34; href=&#34;#__codelineno-5-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;co&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read_compiled_module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cpathname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-9&#34; name=&#34;__codelineno-5-9&#34; href=&#34;#__codelineno-5-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-10&#34; name=&#34;__codelineno-5-10&#34; href=&#34;#__codelineno-5-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyImport_ExecCodeModuleEx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;co&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cpathname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-11&#34; name=&#34;__codelineno-5-11&#34; href=&#34;#__codelineno-5-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-12&#34; name=&#34;__codelineno-5-12&#34; href=&#34;#__codelineno-5-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-13&#34; name=&#34;__codelineno-5-13&#34; href=&#34;#__codelineno-5-13&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-14&#34; name=&#34;__codelineno-5-14&#34; href=&#34;#__codelineno-5-14&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-15&#34; name=&#34;__codelineno-5-15&#34; href=&#34;#__codelineno-5-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-16&#34; name=&#34;__codelineno-5-16&#34; href=&#34;#__codelineno-5-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;nf&#34;&gt;PyImport_ExecCodeModuleEx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;co&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pathname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-17&#34; name=&#34;__codelineno-5-17&#34; href=&#34;#__codelineno-5-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-18&#34; name=&#34;__codelineno-5-18&#34; href=&#34;#__codelineno-5-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-19&#34; name=&#34;__codelineno-5-19&#34; href=&#34;#__codelineno-5-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyImport_AddModule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-20&#34; name=&#34;__codelineno-5-20&#34; href=&#34;#__codelineno-5-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-21&#34; name=&#34;__codelineno-5-21&#34; href=&#34;#__codelineno-5-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// d = m.__dict__&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-22&#34; name=&#34;__codelineno-5-22&#34; href=&#34;#__codelineno-5-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyModule_GetDict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-23&#34; name=&#34;__codelineno-5-23&#34; href=&#34;#__codelineno-5-23&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-24&#34; name=&#34;__codelineno-5-24&#34; href=&#34;#__codelineno-5-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 在这里设置新加载模块的 __builtins__ 属性&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-25&#34; name=&#34;__codelineno-5-25&#34; href=&#34;#__codelineno-5-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyDict_GetItemString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;__builtins__&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-26&#34; name=&#34;__codelineno-5-26&#34; href=&#34;#__codelineno-5-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyDict_SetItemString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;__builtins__&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-27&#34; name=&#34;__codelineno-5-27&#34; href=&#34;#__codelineno-5-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                                 &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyEval_GetBuiltins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-28&#34; name=&#34;__codelineno-5-28&#34; href=&#34;#__codelineno-5-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;goto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-29&#34; name=&#34;__codelineno-5-29&#34; href=&#34;#__codelineno-5-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-30&#34; name=&#34;__codelineno-5-30&#34; href=&#34;#__codelineno-5-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-31&#34; name=&#34;__codelineno-5-31&#34; href=&#34;#__codelineno-5-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// globals = d, locals = d&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-32&#34; name=&#34;__codelineno-5-32&#34; href=&#34;#__codelineno-5-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyEval_EvalCode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyCodeObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;co&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-33&#34; name=&#34;__codelineno-5-33&#34; href=&#34;#__codelineno-5-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-34&#34; name=&#34;__codelineno-5-34&#34; href=&#34;#__codelineno-5-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-35&#34; name=&#34;__codelineno-5-35&#34; href=&#34;#__codelineno-5-35&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-36&#34; name=&#34;__codelineno-5-36&#34; href=&#34;#__codelineno-5-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-37&#34; name=&#34;__codelineno-5-37&#34; href=&#34;#__codelineno-5-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;nf&#34;&gt;PyEval_EvalCode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyCodeObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;co&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;globals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;locals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-38&#34; name=&#34;__codelineno-5-38&#34; href=&#34;#__codelineno-5-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-39&#34; name=&#34;__codelineno-5-39&#34; href=&#34;#__codelineno-5-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyEval_EvalCodeEx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;co&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-40&#34; name=&#34;__codelineno-5-40&#34; href=&#34;#__codelineno-5-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                      &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;globals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;locals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-41&#34; name=&#34;__codelineno-5-41&#34; href=&#34;#__codelineno-5-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-42&#34; name=&#34;__codelineno-5-42&#34; href=&#34;#__codelineno-5-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-43&#34; name=&#34;__codelineno-5-43&#34; href=&#34;#__codelineno-5-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-44&#34; name=&#34;__codelineno-5-44&#34; href=&#34;#__codelineno-5-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-45&#34; name=&#34;__codelineno-5-45&#34; href=&#34;#__codelineno-5-45&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;import&lt;/code&gt; 其他模块的时候，会把该模块的 &lt;code&gt;__builtins__&lt;/code&gt; 设置为 &lt;code&gt;PyEval_GetBuiltins()&lt;/code&gt; 的返回结果，这个函数我们已经说过，大部分情况下相当于 &lt;code&gt;current_frame-&amp;gt;f_builtins&lt;/code&gt;。对于 &lt;code&gt;__main__&lt;/code&gt; 模块的里面的 &lt;code&gt;import&lt;/code&gt;，&lt;code&gt;current_frame&lt;/code&gt; 就是 &lt;code&gt;__main__&lt;/code&gt; 模块的栈帧，&lt;code&gt;current_frame-&amp;gt;f_builtins = __main__.__dict__[&#39;__builtins__&#39;]&lt;/code&gt;（上文 &lt;code&gt;PyFrame_New&lt;/code&gt; 的第一种情况）。&lt;/p&gt;
&lt;p&gt;加载的新模块，会使用 &lt;code&gt;PyEval_EvalCode&lt;/code&gt; 来执行新模块中的代码，可以看到，传给 &lt;code&gt;PyEval_EvalCode&lt;/code&gt; 的参数 &lt;code&gt;globals&lt;/code&gt;、&lt;code&gt;locals&lt;/code&gt; 其实都是模块自身的 &lt;code&gt;__dict__&lt;/code&gt;，并且模块 &lt;code&gt;m.__dict__[&#39;__builtins__&#39;] = PyEval_GetBuiltins()&lt;/code&gt; 。&lt;/p&gt;
&lt;p&gt;综合来看，我们可以得知，从 &lt;code&gt;__main__&lt;/code&gt; 模块开始 &lt;code&gt;import&lt;/code&gt; 的模块，也会继承 &lt;code&gt;__main__&lt;/code&gt; 中的 &lt;code&gt;__builtins__&lt;/code&gt;，并会在内部的 &lt;code&gt;import&lt;/code&gt; 中传递下去，这样就可以确保，所有从 &lt;code&gt;__main__&lt;/code&gt; 加载的模块和子模块，都能共用同一份来自 &lt;code&gt;__main__&lt;/code&gt; 的 &lt;code&gt;__builtins__&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;那么如果是在模块中调用的函数呢？对于模块中的函数，创建和调用时：&lt;/p&gt;
&lt;div class=&#34;language-c highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-6-1&#34; name=&#34;__codelineno-6-1&#34; href=&#34;#__codelineno-6-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// ceval.c&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-2&#34; name=&#34;__codelineno-6-2&#34; href=&#34;#__codelineno-6-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// 创建函数&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-3&#34; name=&#34;__codelineno-6-3&#34; href=&#34;#__codelineno-6-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;TARGET&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MAKE_FUNCTION&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-4&#34; name=&#34;__codelineno-6-4&#34; href=&#34;#__codelineno-6-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-5&#34; name=&#34;__codelineno-6-5&#34; href=&#34;#__codelineno-6-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;POP&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;/* code object */&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-6&#34; name=&#34;__codelineno-6-6&#34; href=&#34;#__codelineno-6-6&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-7&#34; name=&#34;__codelineno-6-7&#34; href=&#34;#__codelineno-6-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 这里的 f-&amp;gt;f_globals，相当于模块自身的 globals，由上文可知，也相当于 m.__dict__&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-8&#34; name=&#34;__codelineno-6-8&#34; href=&#34;#__codelineno-6-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyFunction_New&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_globals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-9&#34; name=&#34;__codelineno-6-9&#34; href=&#34;#__codelineno-6-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-10&#34; name=&#34;__codelineno-6-10&#34; href=&#34;#__codelineno-6-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-11&#34; name=&#34;__codelineno-6-11&#34; href=&#34;#__codelineno-6-11&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-12&#34; name=&#34;__codelineno-6-12&#34; href=&#34;#__codelineno-6-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-13&#34; name=&#34;__codelineno-6-13&#34; href=&#34;#__codelineno-6-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PyFunction_New&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;code&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;globals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-14&#34; name=&#34;__codelineno-6-14&#34; href=&#34;#__codelineno-6-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-15&#34; name=&#34;__codelineno-6-15&#34; href=&#34;#__codelineno-6-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyFunctionObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;op&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject_GC_New&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyFunctionObject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-16&#34; name=&#34;__codelineno-6-16&#34; href=&#34;#__codelineno-6-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                                        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyFunction_Type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-17&#34; name=&#34;__codelineno-6-17&#34; href=&#34;#__codelineno-6-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-18&#34; name=&#34;__codelineno-6-18&#34; href=&#34;#__codelineno-6-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 这里相当于 op-&amp;gt;func_globals = globals = f-&amp;gt;f_globals&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-19&#34; name=&#34;__codelineno-6-19&#34; href=&#34;#__codelineno-6-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;op&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func_globals&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;globals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-20&#34; name=&#34;__codelineno-6-20&#34; href=&#34;#__codelineno-6-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-21&#34; name=&#34;__codelineno-6-21&#34; href=&#34;#__codelineno-6-21&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-22&#34; name=&#34;__codelineno-6-22&#34; href=&#34;#__codelineno-6-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// 调用函数&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-23&#34; name=&#34;__codelineno-6-23&#34; href=&#34;#__codelineno-6-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-24&#34; name=&#34;__codelineno-6-24&#34; href=&#34;#__codelineno-6-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;fast_function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;***&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pp_stack&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;na&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nk&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-25&#34; name=&#34;__codelineno-6-25&#34; href=&#34;#__codelineno-6-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-26&#34; name=&#34;__codelineno-6-26&#34; href=&#34;#__codelineno-6-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyCodeObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;co&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyCodeObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyFunction_GET_CODE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-27&#34; name=&#34;__codelineno-6-27&#34; href=&#34;#__codelineno-6-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// globals = func-&amp;gt;func_globals&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-28&#34; name=&#34;__codelineno-6-28&#34; href=&#34;#__codelineno-6-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;globals&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyFunction_GET_GLOBALS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-29&#34; name=&#34;__codelineno-6-29&#34; href=&#34;#__codelineno-6-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-30&#34; name=&#34;__codelineno-6-30&#34; href=&#34;#__codelineno-6-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// globals 传给 PyEval_EvalCodeEx，里面就会传给 PyFrame_New 来创建新的栈帧&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-31&#34; name=&#34;__codelineno-6-31&#34; href=&#34;#__codelineno-6-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyEval_EvalCodeEx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;co&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;globals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-32&#34; name=&#34;__codelineno-6-32&#34; href=&#34;#__codelineno-6-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                             &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pp_stack&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;na&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-33&#34; name=&#34;__codelineno-6-33&#34; href=&#34;#__codelineno-6-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                             &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pp_stack&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;-2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nk&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nk&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-34&#34; name=&#34;__codelineno-6-34&#34; href=&#34;#__codelineno-6-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                             &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyFunction_GET_CLOSURE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-35&#34; name=&#34;__codelineno-6-35&#34; href=&#34;#__codelineno-6-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;创建函数时，会把 &lt;code&gt;f-&amp;gt;f_globals&lt;/code&gt; 存到函数结构体变量 &lt;code&gt;func_globals&lt;/code&gt; 里面，而对于模块 &lt;code&gt;m&lt;/code&gt;，&lt;code&gt;f-&amp;gt;f_globals = m.__dict__&lt;/code&gt;。函数执行的时候，传给 &lt;code&gt;PyFrame_New&lt;/code&gt; 的 &lt;code&gt;globals&lt;/code&gt; 参数，就是创建时候保存起来的 &lt;code&gt;func_globals&lt;/code&gt;，&lt;code&gt;__builtins__&lt;/code&gt; 自然就可以在 &lt;code&gt;func_globals&lt;/code&gt; 中获取。&lt;/p&gt;
&lt;p&gt;至此，&lt;code&gt;__builtins__&lt;/code&gt; 的传递是能保证一致性的，所有模块、子模块 、函数，栈帧等都能引用到同一个，也就是拥有相同的内建名字空间。&lt;/p&gt;
&lt;h2 id=&#34;__main__&#34;&gt;指定 &lt;code&gt;__main__&lt;/code&gt; 模块执行&lt;/h2&gt;
&lt;p&gt;我们已经知道 &lt;code&gt;__main__&lt;/code&gt; 模块自身的 &lt;code&gt;__builtins__&lt;/code&gt; 可以传递给所有子模块、函数和栈帧，而在命令行执行 &lt;code&gt;python a.py&lt;/code&gt; 时，Python 会把 &lt;code&gt;a.py&lt;/code&gt; 作为 &lt;code&gt;__main__&lt;/code&gt; 模块来执行，那这是如何做到的呢：&lt;/p&gt;
&lt;div class=&#34;language-c highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-7-1&#34; name=&#34;__codelineno-7-1&#34; href=&#34;#__codelineno-7-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// python.c&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-2&#34; name=&#34;__codelineno-7-2&#34; href=&#34;#__codelineno-7-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-3&#34; name=&#34;__codelineno-7-3&#34; href=&#34;#__codelineno-7-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-4&#34; name=&#34;__codelineno-7-4&#34; href=&#34;#__codelineno-7-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-5&#34; name=&#34;__codelineno-7-5&#34; href=&#34;#__codelineno-7-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-6&#34; name=&#34;__codelineno-7-6&#34; href=&#34;#__codelineno-7-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Py_Main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-7&#34; name=&#34;__codelineno-7-7&#34; href=&#34;#__codelineno-7-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-8&#34; name=&#34;__codelineno-7-8&#34; href=&#34;#__codelineno-7-8&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-9&#34; name=&#34;__codelineno-7-9&#34; href=&#34;#__codelineno-7-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// main.c&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-10&#34; name=&#34;__codelineno-7-10&#34; href=&#34;#__codelineno-7-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-11&#34; name=&#34;__codelineno-7-11&#34; href=&#34;#__codelineno-7-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;nf&#34;&gt;Py_Main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-12&#34; name=&#34;__codelineno-7-12&#34; href=&#34;#__codelineno-7-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-13&#34; name=&#34;__codelineno-7-13&#34; href=&#34;#__codelineno-7-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-14&#34; name=&#34;__codelineno-7-14&#34; href=&#34;#__codelineno-7-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 尝试用模块的 importer 来执行代码&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-15&#34; name=&#34;__codelineno-7-15&#34; href=&#34;#__codelineno-7-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-16&#34; name=&#34;__codelineno-7-16&#34; href=&#34;#__codelineno-7-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sts&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RunMainFromImporter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-17&#34; name=&#34;__codelineno-7-17&#34; href=&#34;#__codelineno-7-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-18&#34; name=&#34;__codelineno-7-18&#34; href=&#34;#__codelineno-7-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-19&#34; name=&#34;__codelineno-7-19&#34; href=&#34;#__codelineno-7-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 一般我们自己的 py 文件，会使用这个来执行&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-20&#34; name=&#34;__codelineno-7-20&#34; href=&#34;#__codelineno-7-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sts&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyRun_AnyFileExFlags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-21&#34; name=&#34;__codelineno-7-21&#34; href=&#34;#__codelineno-7-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-22&#34; name=&#34;__codelineno-7-22&#34; href=&#34;#__codelineno-7-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-23&#34; name=&#34;__codelineno-7-23&#34; href=&#34;#__codelineno-7-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-24&#34; name=&#34;__codelineno-7-24&#34; href=&#34;#__codelineno-7-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-25&#34; name=&#34;__codelineno-7-25&#34; href=&#34;#__codelineno-7-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-26&#34; name=&#34;__codelineno-7-26&#34; href=&#34;#__codelineno-7-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-27&#34; name=&#34;__codelineno-7-27&#34; href=&#34;#__codelineno-7-27&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-28&#34; name=&#34;__codelineno-7-28&#34; href=&#34;#__codelineno-7-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// pythonrun.c&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-29&#34; name=&#34;__codelineno-7-29&#34; href=&#34;#__codelineno-7-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-30&#34; name=&#34;__codelineno-7-30&#34; href=&#34;#__codelineno-7-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PyRun_AnyFileExFlags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;FILE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;closeit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-31&#34; name=&#34;__codelineno-7-31&#34; href=&#34;#__codelineno-7-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                     &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyCompilerFlags&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;flags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-32&#34; name=&#34;__codelineno-7-32&#34; href=&#34;#__codelineno-7-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-33&#34; name=&#34;__codelineno-7-33&#34; href=&#34;#__codelineno-7-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-34&#34; name=&#34;__codelineno-7-34&#34; href=&#34;#__codelineno-7-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyRun_SimpleFileExFlags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;closeit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;flags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-35&#34; name=&#34;__codelineno-7-35&#34; href=&#34;#__codelineno-7-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-36&#34; name=&#34;__codelineno-7-36&#34; href=&#34;#__codelineno-7-36&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-37&#34; name=&#34;__codelineno-7-37&#34; href=&#34;#__codelineno-7-37&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-38&#34; name=&#34;__codelineno-7-38&#34; href=&#34;#__codelineno-7-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-39&#34; name=&#34;__codelineno-7-39&#34; href=&#34;#__codelineno-7-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;PyRun_SimpleFileExFlags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;FILE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;closeit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-40&#34; name=&#34;__codelineno-7-40&#34; href=&#34;#__codelineno-7-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyCompilerFlags&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;flags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-41&#34; name=&#34;__codelineno-7-41&#34; href=&#34;#__codelineno-7-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-42&#34; name=&#34;__codelineno-7-42&#34; href=&#34;#__codelineno-7-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-43&#34; name=&#34;__codelineno-7-43&#34; href=&#34;#__codelineno-7-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyImport_AddModule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-44&#34; name=&#34;__codelineno-7-44&#34; href=&#34;#__codelineno-7-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyModule_GetDict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-45&#34; name=&#34;__codelineno-7-45&#34; href=&#34;#__codelineno-7-45&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-46&#34; name=&#34;__codelineno-7-46&#34; href=&#34;#__codelineno-7-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 设置 __file__ 属性&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-47&#34; name=&#34;__codelineno-7-47&#34; href=&#34;#__codelineno-7-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyDict_SetItemString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;__file__&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-48&#34; name=&#34;__codelineno-7-48&#34; href=&#34;#__codelineno-7-48&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-49&#34; name=&#34;__codelineno-7-49&#34; href=&#34;#__codelineno-7-49&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-50&#34; name=&#34;__codelineno-7-50&#34; href=&#34;#__codelineno-7-50&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-51&#34; name=&#34;__codelineno-7-51&#34; href=&#34;#__codelineno-7-51&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// globals = locals = d = __main__.__dict__&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-52&#34; name=&#34;__codelineno-7-52&#34; href=&#34;#__codelineno-7-52&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run_pyc_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;flags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-53&#34; name=&#34;__codelineno-7-53&#34; href=&#34;#__codelineno-7-53&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-54&#34; name=&#34;__codelineno-7-54&#34; href=&#34;#__codelineno-7-54&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-55&#34; name=&#34;__codelineno-7-55&#34; href=&#34;#__codelineno-7-55&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-56&#34; name=&#34;__codelineno-7-56&#34; href=&#34;#__codelineno-7-56&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-57&#34; name=&#34;__codelineno-7-57&#34; href=&#34;#__codelineno-7-57&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;run_pyc_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;FILE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;globals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-58&#34; name=&#34;__codelineno-7-58&#34; href=&#34;#__codelineno-7-58&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;locals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyCompilerFlags&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;flags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-59&#34; name=&#34;__codelineno-7-59&#34; href=&#34;#__codelineno-7-59&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-60&#34; name=&#34;__codelineno-7-60&#34; href=&#34;#__codelineno-7-60&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-61&#34; name=&#34;__codelineno-7-61&#34; href=&#34;#__codelineno-7-61&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 从 pyc 文件读取代码对象 co ，并执行代码&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-62&#34; name=&#34;__codelineno-7-62&#34; href=&#34;#__codelineno-7-62&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// PyEval_EvalCode 里面也同样会调用 PyFrame_New 创建新栈帧&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-63&#34; name=&#34;__codelineno-7-63&#34; href=&#34;#__codelineno-7-63&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PyEval_EvalCode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;co&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;globals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;locals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-64&#34; name=&#34;__codelineno-7-64&#34; href=&#34;#__codelineno-7-64&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-65&#34; name=&#34;__codelineno-7-65&#34; href=&#34;#__codelineno-7-65&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;当执行 &lt;code&gt;python a.py&lt;/code&gt; 时，一般情况下会走到 &lt;code&gt;PyRun_SimpleFileExFlags&lt;/code&gt;，&lt;code&gt;PyRun_SimpleFileExFlags&lt;/code&gt; 里面会取出来 &lt;code&gt;__main__.__dict__&lt;/code&gt;，作为代码执行时的 &lt;code&gt;globals&lt;/code&gt; 和 &lt;code&gt;locals&lt;/code&gt;，最终也会传到 &lt;code&gt;PyFrame_New&lt;/code&gt; 中创建新的栈帧来执行 &lt;code&gt;a.py&lt;/code&gt;。结合我们上文提到的 &lt;code&gt;__builtins__&lt;/code&gt; 在模块和函数中传递，就可以让后续执行的代码都能共用同一份 &lt;code&gt;current_frame-&amp;gt;f_builtins = __main__.__builtins__.__dict__&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;restricted-execution_1&#34;&gt;再论 Restricted Execution&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Python&lt;/code&gt; 在 2.3 版本之前，曾经提供过的 &lt;a href=&#34;https://docs.python.org/2.7/library/restricted.html&#34;&gt;Restricted Execution&lt;/a&gt;，就是基于 &lt;code&gt;__builtins__&lt;/code&gt; 的特性来制作的。或者可以认为，&lt;code&gt;__builtins__&lt;/code&gt; 之所以设计成在 &lt;code&gt;__main__&lt;/code&gt; 模块中是一个模块对象，而在其他模块中是一个 &lt;code&gt;dict&lt;/code&gt; 对象，就是为了可以实现 &lt;strong&gt;Restricted Execution&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;考虑这种情况：如果我们可以自由定制自己的 &lt;code&gt;__builtin__&lt;/code&gt; 模块，并设置成 &lt;code&gt;__main__.__builtins__&lt;/code&gt;，那就相当于后续所有执行的代码，都会使用我们定制的模块，我们可以定制特定版本的 &lt;code&gt;open&lt;/code&gt;、&lt;code&gt;__import__&lt;/code&gt;、&lt;code&gt;file&lt;/code&gt; 等内建函数和类型，更进一步，这种方式是不是可以帮助我们限制执行代码的权限，防止代码做一些不安全的函数调用，或者访问一些不安全的文件？&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Python&lt;/code&gt; 当时就做过这种尝试，实现这个功能的模块就叫做: &lt;code&gt;rexec&lt;/code&gt;。&lt;/p&gt;
&lt;h3 id=&#34;rexec&#34;&gt;&lt;code&gt;rexec&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;我无意太深入讲解 &lt;code&gt;rexec&lt;/code&gt; 的实现，因为原理其实上文已经讲清楚了，并且这个模块本身就已经废弃，我这些仅简单做一些关键代码的摘要，方便查阅。&lt;/p&gt;
&lt;div class=&#34;language-python highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-8-1&#34; name=&#34;__codelineno-8-1&#34; href=&#34;#__codelineno-8-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;# rexec.py&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-2&#34; name=&#34;__codelineno-8-2&#34; href=&#34;#__codelineno-8-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;RExec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ihooks&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_Verbose&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-3&#34; name=&#34;__codelineno-8-3&#34; href=&#34;#__codelineno-8-3&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-4&#34; name=&#34;__codelineno-8-4&#34; href=&#34;#__codelineno-8-4&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;n&#34;&gt;nok_builtin_names&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;open&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;file&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;reload&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;__import__&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-5&#34; name=&#34;__codelineno-8-5&#34; href=&#34;#__codelineno-8-5&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-6&#34; name=&#34;__codelineno-8-6&#34; href=&#34;#__codelineno-8-6&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;fm&#34;&gt;__init__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hooks&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;verbose&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-7&#34; name=&#34;__codelineno-8-7&#34; href=&#34;#__codelineno-8-7&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-8&#34; name=&#34;__codelineno-8-8&#34; href=&#34;#__codelineno-8-8&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;modules&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-9&#34; name=&#34;__codelineno-8-9&#34; href=&#34;#__codelineno-8-9&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-10&#34; name=&#34;__codelineno-8-10&#34; href=&#34;#__codelineno-8-10&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;make_builtin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-11&#34; name=&#34;__codelineno-8-11&#34; href=&#34;#__codelineno-8-11&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;make_initial_modules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-12&#34; name=&#34;__codelineno-8-12&#34; href=&#34;#__codelineno-8-12&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;make_sys&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-13&#34; name=&#34;__codelineno-8-13&#34; href=&#34;#__codelineno-8-13&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;loader&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RModuleLoader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hooks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;verbose&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-14&#34; name=&#34;__codelineno-8-14&#34; href=&#34;#__codelineno-8-14&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;importer&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RModuleImporter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;loader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;verbose&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-15&#34; name=&#34;__codelineno-8-15&#34; href=&#34;#__codelineno-8-15&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-16&#34; name=&#34;__codelineno-8-16&#34; href=&#34;#__codelineno-8-16&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;make_builtin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-17&#34; name=&#34;__codelineno-8-17&#34; href=&#34;#__codelineno-8-17&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;n&#34;&gt;m&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;copy_except&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;__builtin__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nok_builtin_names&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-18&#34; name=&#34;__codelineno-8-18&#34; href=&#34;#__codelineno-8-18&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;__import__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r_import&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-19&#34; name=&#34;__codelineno-8-19&#34; href=&#34;#__codelineno-8-19&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;reload&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r_reload&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-20&#34; name=&#34;__codelineno-8-20&#34; href=&#34;#__codelineno-8-20&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r_open&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-21&#34; name=&#34;__codelineno-8-21&#34; href=&#34;#__codelineno-8-21&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-22&#34; name=&#34;__codelineno-8-22&#34; href=&#34;#__codelineno-8-22&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;add_module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-23&#34; name=&#34;__codelineno-8-23&#34; href=&#34;#__codelineno-8-23&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;n&#34;&gt;m&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;modules&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-24&#34; name=&#34;__codelineno-8-24&#34; href=&#34;#__codelineno-8-24&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-25&#34; name=&#34;__codelineno-8-25&#34; href=&#34;#__codelineno-8-25&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;modules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hooks&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new_module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-26&#34; name=&#34;__codelineno-8-26&#34; href=&#34;#__codelineno-8-26&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;__builtins__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;modules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;__builtin__&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-27&#34; name=&#34;__codelineno-8-27&#34; href=&#34;#__codelineno-8-27&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-28&#34; name=&#34;__codelineno-8-28&#34; href=&#34;#__codelineno-8-28&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-29&#34; name=&#34;__codelineno-8-29&#34; href=&#34;#__codelineno-8-29&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;r_exec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;code&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-30&#34; name=&#34;__codelineno-8-30&#34; href=&#34;#__codelineno-8-30&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;n&#34;&gt;m&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-31&#34; name=&#34;__codelineno-8-31&#34; href=&#34;#__codelineno-8-31&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;n&#34;&gt;exec&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;code&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;vm&#34;&gt;__dict__&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-32&#34; name=&#34;__codelineno-8-32&#34; href=&#34;#__codelineno-8-32&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-33&#34; name=&#34;__codelineno-8-33&#34; href=&#34;#__codelineno-8-33&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;r_eval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;code&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-34&#34; name=&#34;__codelineno-8-34&#34; href=&#34;#__codelineno-8-34&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;n&#34;&gt;m&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-35&#34; name=&#34;__codelineno-8-35&#34; href=&#34;#__codelineno-8-35&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;eval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;code&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;vm&#34;&gt;__dict__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-36&#34; name=&#34;__codelineno-8-36&#34; href=&#34;#__codelineno-8-36&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-37&#34; name=&#34;__codelineno-8-37&#34; href=&#34;#__codelineno-8-37&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;r_execfile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-38&#34; name=&#34;__codelineno-8-38&#34; href=&#34;#__codelineno-8-38&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;n&#34;&gt;m&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-39&#34; name=&#34;__codelineno-8-39&#34; href=&#34;#__codelineno-8-39&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;n&#34;&gt;execfile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;vm&#34;&gt;__dict__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;r_execfile&lt;/code&gt; 函数会把文件当作 &lt;code&gt;__main__&lt;/code&gt; 模块来执行，只是 &lt;code&gt;__main__&lt;/code&gt; 是定制过的。&lt;code&gt;self.add_module(&#39;__main__&#39;)&lt;/code&gt; 里面，会设置模块的 &lt;code&gt;m.__builtins__ = self.modules[&#39;__builtin__&#39;]&lt;/code&gt;，这个 &lt;code&gt;__builtin__&lt;/code&gt; 是由 &lt;code&gt;make_builtin&lt;/code&gt; 来定制生成的，在里面替换了 &lt;code&gt;__import__&lt;/code&gt;、&lt;code&gt;reload&lt;/code&gt;、&lt;code&gt;open&lt;/code&gt; 函数，并删除了 &lt;code&gt;file&lt;/code&gt; 类型。这样，我们就能控制要执行的代码对内建命名空间的访问了。&lt;/p&gt;
&lt;p&gt;对于一些内建模块，&lt;code&gt;rexec&lt;/code&gt; 也做了定制，保护不安全的访问，譬如 &lt;code&gt;sys&lt;/code&gt; 模块，只保留了一部分的对象，并且通过定制的 &lt;code&gt;self.loader&lt;/code&gt;、&lt;code&gt;self.importer&lt;/code&gt;，来实现 &lt;code&gt;import&lt;/code&gt; 的时候，优先加载定制的模块。&lt;/p&gt;
&lt;p&gt;如果对代码细节感兴趣，请自行查阅相关源码。&lt;/p&gt;
&lt;h3 id=&#34;rexec_1&#34;&gt;&lt;code&gt;rexec&lt;/code&gt; 的失败&lt;/h3&gt;
&lt;p&gt;上文提到，&lt;code&gt;Python 2.3&lt;/code&gt; 之后，&lt;code&gt;rexec&lt;/code&gt; 就已经废弃了，因为这种方式已经被证实为不可行。带着好奇心，我们来简单溯源一下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在社区有人报告了 &lt;a href=&#34;https://mail.python.org/pipermail/python-dev/2002-December/031160.html&#34;&gt;Bug&lt;/a&gt;，并引发了开发者之间的讨论：&lt;blockquote&gt;
&lt;p&gt;it&#39;s never going to be safe, and I doubt it&#39;s very useful as long as it&#39;s not safe.&lt;/p&gt;
&lt;p&gt;Every change is a potential security hole.&lt;/p&gt;
&lt;p&gt;it&#39;s hard to predict what change is going to break it.&lt;/p&gt;
&lt;p&gt;I don&#39;t expect you&#39;ll ever reach the point where it&#39;ll be wise to advertise this as safe.  I certainly won&#39;t.&lt;/p&gt;
&lt;p&gt;this is only a useful occupation if you expect to eventually reach a point where you expect that there aren&#39;t any security flaws left.  Jeremy &amp;amp; I both doubt that Python will ever reach that level, meaning that the whole exercise of fixing security flaws is a waste of time (if you know you &lt;em&gt;can&#39;t&lt;/em&gt; make it safe, don&#39;t waste time trying).&lt;/p&gt;
&lt;p&gt;I agree (but I have said that in past) the best thing is to deprecate/rip out rexec.&lt;/p&gt;
&lt;p&gt;The code will still be in older versions if someone decides to pick it up and work on it as a separate project.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;该 Bug 的起因是 &lt;code&gt;Python&lt;/code&gt; 引入了新式类（new-style class） &lt;code&gt;object&lt;/code&gt;，导致 &lt;code&gt;rexec&lt;/code&gt; 不能正常工作。于是开发者表示，在可预见的未来，这种情况都很难避免，任意的修改都会可能导致 &lt;code&gt;rexec&lt;/code&gt; 出现漏洞，不能正常工作，或者被突破权限的限制，基本上无法实现没有漏洞地去提供一个安全环境的愿景，开发者需要不断地修修补补，浪费大量的时间。最终，&lt;code&gt;rexec&lt;/code&gt; 这个模块就被废弃掉了，&lt;code&gt;Python&lt;/code&gt; 也没有再提供类似的功能。但关于 &lt;code&gt;__builtins__&lt;/code&gt; 的设定，由于兼容性等问题，就继续保留下来了。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;后面在大概 2010 年的时候，有位程序员推出了 &lt;a href=&#34;https://github.com/vstinner/pysandbox&#34;&gt;pysandbox&lt;/a&gt;，致力于提供可以替代 &lt;code&gt;rexec&lt;/code&gt; 的 &lt;code&gt;Python&lt;/code&gt; 沙盒环境。但是 3 年后，作者主动放弃了这个项目，并详细说明了为什么作者认为这个项目是失败的：&lt;a href=&#34;https://mail.python.org/pipermail/python-dev/2013-November/130132.html&#34;&gt;The pysandbox project is broken&lt;/a&gt;，也有其他作者撰文总结了这个项目的失败：&lt;a href=&#34;https://lwn.net/Articles/574215/&#34;&gt;The failure of pysandbox&lt;/a&gt;。如果感兴趣的话，可以具体去翻翻原文，我这里也给一些摘要来帮助了解：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;After having work during 3 years on a pysandbox project to sandbox untrusted code, I now reached a point where I am convinced that pysandbox is broken by design. Different developers tried to convinced me before that pysandbox design is unsafe, but I had to experience it myself to be convineced.&lt;/p&gt;
&lt;p&gt;I now agree that putting a sandbox in CPython is the wrong design. There are too many ways to escape the untrusted namespace using the various introspection features of the Python language. To guarantee the [safety] of a security product, the code should be [carefully] audited and the code to review must be as small as possible. Using pysandbox, the &#34;code&#34; is the whole Python core which is a really huge code base. For example, the Python and Objects directories of Python 3.4 contain more than 126,000 lines of C code.&lt;/p&gt;
&lt;p&gt;The security of pysandbox is the security of its weakest part. A single bug is enough to escape the whole sandbox.&lt;/p&gt;
&lt;p&gt;pysandbox cannot be used in practice. To protect the untrusted namespace, pysandbox installs a lot of different protections. Because of all these protections, it becomes hard to write Python code. Basic features like &#34;del dict[key]&#34; are denied. Passing an object to a sandbox is not possible to sandbox, pysandbox is unable to proxify arbitary objects. For something more complex than evaluating &#34;1+(2*3)&#34;, pysandbox cannot be used in practice, because of all these protections.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;pysandbox&lt;/strong&gt; 的作者认为，在 &lt;code&gt;Python&lt;/code&gt; 里面放一个沙盒环境是错误的设计，有太多的方式可以从沙盒中逃逸出去，&lt;code&gt;Python&lt;/code&gt; 提供的语言特性很丰富，&lt;code&gt;CPython&lt;/code&gt; 源码的代码量很大，基本不可能保证有足够的安全性。而 &lt;strong&gt;pysandbox&lt;/strong&gt; 的开发过程就是在不断地打补丁，补丁太多，限制太多，以至于作者认为 &lt;strong&gt;pysandbox&lt;/strong&gt; 已经没法实际使用，因为很多的语法特性和功能都被限制不能使用了，譬如简单的 &lt;code&gt;del dict[key]&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;restricted-execution_2&#34;&gt;Restricted Execution 出路在哪&lt;/h2&gt;
&lt;p&gt;既然 &lt;code&gt;rexec&lt;/code&gt; 和 &lt;strong&gt;pysandbox&lt;/strong&gt; 这种通过 Patch Python 来提供沙盒环境的方法（这里姑且把这种方法称作 Patch Python）已经走不通了，那我不禁好奇：要怎么才能给 Python 提供一个能用的沙盒环境？&lt;/p&gt;
&lt;p&gt;在这里我继续收集了一些其他的实现方法或者案例，方便参考和查阅：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://doc.pypy.org/en/latest/sandbox.html&#34;&gt;PyPy&lt;/a&gt; 有一个&lt;a href=&#34;https://foss.heptapod.net/pypy/pypy/-/tree/branch/sandbox-2&#34;&gt;分支&lt;/a&gt;提供了沙盒的功能，结合额外的 &lt;a href=&#34;https://foss.heptapod.net/pypy/sandboxlib&#34;&gt;sandboxlib&lt;/a&gt;，可以自行编译出带沙盒环境版本的 PyPy。如果感兴趣，可以尝试自行配置，参考这里的一些&lt;a href=&#34;https://foss.heptapod.net/pypy/pypy/-/issues/3192&#34;&gt;说明&lt;/a&gt;。PyPy 实现的原理是创建一个子进程，子进程的所有输入输出和系统调用，都会重定向到外部进程，由外部进程控制这些权限，另外也可以控制内存和 CPU 的使用量。需要注意的是，这个分支也有段时间没有新的提交了，请谨慎使用。&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;借助操作系统提供的沙盒环境工具。&lt;a href=&#34;https://en.wikipedia.org/wiki/Seccomp&#34;&gt;seccomp&lt;/a&gt; 是 Linux 内核提供的计算安全工具，&lt;a href=&#34;https://github.com/seccomp/libseccomp/tree/main/src/python&#34;&gt;libsecoomp&lt;/a&gt; 提供了 Python 绑定，可以内嵌到代码里面使用；或者使用基于 seccomp 实现的工具来执行代码，譬如 &lt;a href=&#34;https://firejail.wordpress.com/&#34;&gt;Firejail&lt;/a&gt;。&lt;a href=&#34;https://apparmor.net/&#34;&gt;AppArmor&lt;/a&gt; 是一个 Linux 内核安全模块，允许管理员控制程序能访问的系统资源和功能，保护操作系统。&lt;a href=&#34;https://github.com/openedx/codejail&#34;&gt;codejail&lt;/a&gt; 是基于 AppArmor 实现的 Python 沙盒环境，有兴趣可以尝试。还有很多类似的工具，这里不一一列举。&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;使用沙盒虚拟环境或者容器。&lt;a href=&#34;https://learn.microsoft.com/zh-cn/windows/security/threat-protection/windows-sandbox/windows-sandbox-overview&#34;&gt;Windows 沙盒&lt;/a&gt;，&lt;a href=&#34;https://linuxcontainers.org/&#34;&gt;LXC&lt;/a&gt;, &lt;a href=&#34;https://www.docker.com/&#34;&gt;Docker&lt;/a&gt; 等等，这里不再详述。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;_2&#34;&gt;总结&lt;/h2&gt;
&lt;p&gt;本文篇幅有点长，感谢看到这里，文章一开始所列出的疑问，相信都已经解答完毕。&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/py-Python%E6%9D%82%E8%B0%881-%E6%8E%A2%E7%A9%B6__builtins__/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 30 Nov 2023 20:09:36 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/py-Python%E6%9D%82%E8%B0%881-%E6%8E%A2%E7%A9%B6__builtins__/</guid>
      
    </item>
    
    <item>
      <title>使用 Visual Studio 2015 编译 Python 2.7.11</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;使用 Visual Studio 2015 编译 Python 2.7.11&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;https://img.shields.io/badge/python-2.7.11-brightgreen.svg&#34; style=&#34;display: inline-block&#34; /&gt;
&lt;img alt=&#34;&#34; src=&#34;https://img.shields.io/badge/vs-2015-68217A.svg&#34; style=&#34;display: inline-block&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_1&#34;&gt;原因&lt;/h2&gt;
&lt;p&gt;Python 2.7 的官方版本支持 Visual Studio 2010 以下版本来编译，参考 &lt;code&gt;PCbuild\readme.txt&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;language-text highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;1.  Install Microsoft Visual Studio 2008, any edition.
2.  Install Microsoft Visual Studio 2010, any edition, or Windows SDK 7.1 and any version of Microsoft Visual Studio newer than 2010.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如果你想在 Windows 下自己倒腾 Python，譬如编译个 Debug 版本、自己改改源代码等，那么最简单的方法就是装一个 VS2010。
但是对我个人来说， 我更想要用 VS2015 来编译 Python，原因主要有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VS2010 实在有点过时，使用起来功能和体验比 VS2015 要差得多。一直用着 VS2015，要我再装个 VS2010 实在不愿意。&lt;/li&gt;
&lt;li&gt;由于一直用 VS2015，你会使用它来写一些自己的程序，如果你想要把 Python 嵌入进去，那你就需要使用相同版本的 VS 来编译你的程序，如果使用不同版本的 VS，那会出现各种无法预料的事情。&lt;a href=&#34;http://siomsystems.com/mixing-visual-studio-versions/&#34;&gt;这里有更详细的解释&lt;/a&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以我开始着手用 VS2015 搞定 Python 2.7.11 版本（当前的 Python 2.7 最新版本）。&lt;/p&gt;
&lt;p&gt;要注意，&lt;strong&gt;Python 3.x 已经支持用 VS2015 来编译&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id=&#34;_2&#34;&gt;源码下载&lt;/h2&gt;
&lt;p&gt;Python 的版本当然就是 2.7.11，另外还有一些第三方的模块，具体可以运行 Python 源码目录下 &lt;code&gt;PCbuild\get_externals.bat&lt;/code&gt; 脚本获取所有编译需要的模块，注意你需要安装 svn ，把 svn.exe 添加到系统 PATH 里面。&lt;/p&gt;
&lt;p&gt;下载可能很不稳定，并且整个过程都有可能因为网络问题而终止，所以还是推荐直接在我的github上下载externals目录：&lt;a href=&#34;https://github.com/disenone/wpython-2.7.11/tree/e13f43a3b72ae2bdf4d2950c6364750ae668cbf4/externals&#34;&gt;我的 Python 版本&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;_3&#34;&gt;编译过程&lt;/h2&gt;
&lt;h3 id=&#34;_4&#34;&gt;第三方模块&lt;/h3&gt;
&lt;p&gt;首先要解决的是第三方的模块，主要是 tcl, tk, tcltk。&lt;/p&gt;
&lt;p&gt;修改文件 &lt;code&gt;externals/tcl-8.5.15.0/win/makefile.vc&lt;/code&gt;，把 434 行改成&lt;/p&gt;
&lt;div class=&#34;language-text highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;- cdebug = -Zi -WX $(DEBUGFLAGS)
+ cdebug = -Zi -WX- $(DEBUGFLAGS)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;关于选项 &lt;code&gt;WX&lt;/code&gt;，可以看微软的官方文档：&lt;a href=&#34;https://msdn.microsoft.com/en-us/library/ms235592.aspx&#34;&gt;/WX (Treat Linker Warnings as Errors)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;再来改&lt;code&gt;PCbuild/tk.vcxproj&lt;/code&gt;，用文本编辑器打开，修改 63, 64 行&lt;/p&gt;
&lt;div class=&#34;language-text highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;- &amp;lt;TkOpts&amp;gt;msvcrt&amp;lt;/TkOpts&amp;gt;
- &amp;lt;TkOpts Condition=&amp;quot;$(Configuration) == &amp;#39;Debug&amp;#39;&amp;quot;&amp;gt;symbols,msvcrt&amp;lt;/TkOpts&amp;gt;
+ &amp;lt;TkOpts&amp;gt;msvcrt,noxp&amp;lt;/TkOpts&amp;gt;
+ &amp;lt;TkOpts Condition=&amp;quot;$(Configuration) == &amp;#39;Debug&amp;#39;&amp;quot;&amp;gt;symbols,msvcrt,noxp&amp;lt;/TkOpts&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;改&lt;code&gt;PCbuild/tcltk.props&lt;/code&gt;，用文本编辑器打开，修改41行&lt;/p&gt;
&lt;div class=&#34;language-text highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;- &amp;lt;BuildDirTop&amp;gt;$(BuildDirTop)_VC9&amp;lt;/BuildDirTop&amp;gt;
+ &amp;lt;BuildDirTop&amp;gt;$(BuildDirTop)_VC13&amp;lt;/BuildDirTop&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;由于 VS2015 取消了 &lt;code&gt;timezone&lt;/code&gt; 的定义，改为 &lt;code&gt;_timezone&lt;/code&gt;，所以代码里面用到 &lt;code&gt;timezone&lt;/code&gt; 的地方都要改成 &lt;code&gt;_timezone&lt;/code&gt;，第三方模块只需要改文件&lt;code&gt;externals/tcl-8.5.15.0/win/tclWinTime.c&lt;/code&gt;，在文件的前面加上：&lt;/p&gt;
&lt;div class=&#34;language-text highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;#if defined _MSC_VER &amp;amp;&amp;amp; _MSC_VER &amp;gt;= 1900
#define timezone _timezone
#endif
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;python&#34;&gt;改 Python 源码&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;timezone&lt;/code&gt;的问题在 Python 的模块 &lt;code&gt;time&lt;/code&gt; 里面也有，修改 767 行&lt;/p&gt;
&lt;div class=&#34;language-text highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;- #ifdef __CYGWIN__
+ #if defined(__CYGWIN__) || defined(_MSC_VER) &amp;amp;&amp;amp; _MSC_VER &amp;gt;= 1900
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;另外由于在 Windows 下 Python 用了一种特殊的方法来检查文件句柄的有效性，而这种方法在 VS2015 中被彻底禁止了，会出现编译错误，所以先改掉。文件 &lt;code&gt;Include/fileobject.h&lt;/code&gt;，73、80 行：&lt;/p&gt;
&lt;div class=&#34;language-text highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;73 - #if defined _MSC_VER &amp;amp;&amp;amp; _MSC_VER &amp;gt;= 1400
73 + #if defined _MSC_VER &amp;amp;&amp;amp; _MSC_VER &amp;gt;= 1400 &amp;amp;&amp;amp; _MSC_VER &amp;lt; 1900

80 - #elif defined _MSC_VER &amp;amp;&amp;amp; _MSC_VER &amp;gt;= 1200
80 + #elif defined _MSC_VER &amp;amp;&amp;amp; _MSC_VER &amp;gt;= 1200 &amp;amp;&amp;amp; _MSC_VER &amp;lt; 1400
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;文件&lt;code&gt;Modules/posixmodule.c&lt;/code&gt;，532 行：&lt;/p&gt;
&lt;div class=&#34;language-text highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;- #if defined _MSC_VER &amp;amp;&amp;amp; _MSC_VER &amp;gt;= 1400
+ #if defined _MSC_VER &amp;amp;&amp;amp; _MSC_VER &amp;gt;= 1400 &amp;amp;&amp;amp; _MSC_VER &amp;lt; 1900
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;至此，Python 就可以编译通过。更具体的修改可以看我 commit 的内容：&lt;a href=&#34;https://github.com/disenone/wpython-2.7.11/commit/4037e2d806518dbf06ffb8ee5c46f419ef8d7edf&#34;&gt;modify to build by vs2015&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;_5&#34;&gt;检查无效句柄&lt;/h3&gt;
&lt;p&gt;虽然编译通过了，但由于是粗暴地忽略无效文件句柄，直接导致的后果是一旦访问无效的句柄（譬如对同一个文件&lt;code&gt;close&lt;/code&gt;两次），Python 就会直接 assert failed，程序 crash，这样的 Python 根本没法用啊。Python 就是用了一种很特殊的方法来避免这种情况，可惜在 VS2015 里面不能用了，注释是这样解释的：&lt;/p&gt;
&lt;div class=&#34;language-text highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Microsoft CRT in VS2005 and higher will verify that a filehandle is valid and raise an assertion if it isn&amp;#39;t.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;幸好已经有了解决方法，我是在 Python 的 issue 里面看到的，地址在这里：&lt;a href=&#34;http://psf.upfronthosting.co.za/roundup/tracker/issue23524&#34;&gt;issue23524&lt;/a&gt;, &lt;a href=&#34;http://psf.upfronthosting.co.za/roundup/tracker/issue25759&#34;&gt;issue25759&lt;/a&gt;。这种方法也是用在现在 Python 3.x 里面。&lt;/p&gt;
&lt;p&gt;具体地说就是在使用文件句柄的时候禁止掉 Windows 的 assert crash 机制，改为检查错误码。那要怎么禁止 Windows 的 assert 机制呢？答案就是用自己的错误处理函数替代 Windows 默认的处理函数，关键的代码：&lt;/p&gt;
&lt;p&gt;新建文件&lt;code&gt;PC/invalid_parameter_handler.c&lt;/code&gt;，定义我们自己的错误处理函数，可以暂时忽略发生的错误&lt;/p&gt;
&lt;div class=&#34;language-c++ highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#ifdef _MSC_VER&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34; href=&#34;#__codelineno-0-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cpf&#34;&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-4&#34; name=&#34;__codelineno-0-4&#34; href=&#34;#__codelineno-0-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-5&#34; name=&#34;__codelineno-0-5&#34; href=&#34;#__codelineno-0-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#if _MSC_VER &amp;gt;= 1900&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-6&#34; name=&#34;__codelineno-0-6&#34; href=&#34;#__codelineno-0-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cm&#34;&gt;/* pyconfig.h uses this function in the _Py_BEGIN_SUPPRESS_IPH/_Py_END_SUPPRESS_IPH&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-7&#34; name=&#34;__codelineno-0-7&#34; href=&#34;#__codelineno-0-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cm&#34;&gt; * macros. It does not need to be defined when building using MSVC&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-8&#34; name=&#34;__codelineno-0-8&#34; href=&#34;#__codelineno-0-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cm&#34;&gt; * earlier than 14.0 (_MSC_VER == 1900).&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-9&#34; name=&#34;__codelineno-0-9&#34; href=&#34;#__codelineno-0-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cm&#34;&gt; */&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-10&#34; name=&#34;__codelineno-0-10&#34; href=&#34;#__codelineno-0-10&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-11&#34; name=&#34;__codelineno-0-11&#34; href=&#34;#__codelineno-0-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;__cdecl&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_silent_invalid_parameter_handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-12&#34; name=&#34;__codelineno-0-12&#34; href=&#34;#__codelineno-0-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;wchar_t&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;expression&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-13&#34; name=&#34;__codelineno-0-13&#34; href=&#34;#__codelineno-0-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;wchar_t&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-14&#34; name=&#34;__codelineno-0-14&#34; href=&#34;#__codelineno-0-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;wchar_t&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-15&#34; name=&#34;__codelineno-0-15&#34; href=&#34;#__codelineno-0-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;unsigned&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;line&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-16&#34; name=&#34;__codelineno-0-16&#34; href=&#34;#__codelineno-0-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;uintptr_t&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pReserved&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-0-17&#34; name=&#34;__codelineno-0-17&#34; href=&#34;#__codelineno-0-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-18&#34; name=&#34;__codelineno-0-18&#34; href=&#34;#__codelineno-0-18&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-19&#34; name=&#34;__codelineno-0-19&#34; href=&#34;#__codelineno-0-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;_invalid_parameter_handler&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_Py_silent_invalid_parameter_handler&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_silent_invalid_parameter_handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-20&#34; name=&#34;__codelineno-0-20&#34; href=&#34;#__codelineno-0-20&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-21&#34; name=&#34;__codelineno-0-21&#34; href=&#34;#__codelineno-0-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#endif&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-22&#34; name=&#34;__codelineno-0-22&#34; href=&#34;#__codelineno-0-22&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-23&#34; name=&#34;__codelineno-0-23&#34; href=&#34;#__codelineno-0-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#endif&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;定义两个宏方便更换错误处理函数，要注意是暂时的更换，之后是需要换回系统默认的&lt;/p&gt;
&lt;div class=&#34;language-c++ highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#if defined _MSC_VER &amp;amp;&amp;amp; _MSC_VER &amp;gt;= 1900&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-2&#34; name=&#34;__codelineno-1-2&#34; href=&#34;#__codelineno-1-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-3&#34; name=&#34;__codelineno-1-3&#34; href=&#34;#__codelineno-1-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;extern&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_invalid_parameter_handler&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_Py_silent_invalid_parameter_handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-4&#34; name=&#34;__codelineno-1-4&#34; href=&#34;#__codelineno-1-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define _Py_BEGIN_SUPPRESS_IPH { _invalid_parameter_handler _Py_old_handler = \&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-5&#34; name=&#34;__codelineno-1-5&#34; href=&#34;#__codelineno-1-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;    _set_thread_local_invalid_parameter_handler(_Py_silent_invalid_parameter_handler);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-6&#34; name=&#34;__codelineno-1-6&#34; href=&#34;#__codelineno-1-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define _Py_END_SUPPRESS_IPH _set_thread_local_invalid_parameter_handler(_Py_old_handler); }&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-7&#34; name=&#34;__codelineno-1-7&#34; href=&#34;#__codelineno-1-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-8&#34; name=&#34;__codelineno-1-8&#34; href=&#34;#__codelineno-1-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#else&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-9&#34; name=&#34;__codelineno-1-9&#34; href=&#34;#__codelineno-1-9&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-10&#34; name=&#34;__codelineno-1-10&#34; href=&#34;#__codelineno-1-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define _Py_BEGIN_SUPPRESS_IPH&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-11&#34; name=&#34;__codelineno-1-11&#34; href=&#34;#__codelineno-1-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#define _Py_END_SUPPRESS_IPH&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-12&#34; name=&#34;__codelineno-1-12&#34; href=&#34;#__codelineno-1-12&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-13&#34; name=&#34;__codelineno-1-13&#34; href=&#34;#__codelineno-1-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;cp&#34;&gt;#endif &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;/* _MSC_VER &amp;gt;= 1900 */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;之后在有可能触发 Windows 文件句柄错误的地方，前后分别加上宏&lt;code&gt;_Py_BEGIN_SUPPRESS_IPH&lt;/code&gt; 和 &lt;code&gt;_Py_END_SUPPRESS_IPH&lt;/code&gt;，之后再检查错误码就可以了，需要修改到的地方不少，参考别人的 commit 来修改：
&lt;a href=&#34;https://github.com/kovidgoyal/cpython/commit/a9ec814d466d3c0139d10b69666f88eed10e4940&#34;&gt;在这里&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;_6&#34;&gt;结束&lt;/h2&gt;
&lt;p&gt;至此 Python 2.7.11 就可以在 VS2015 里面正常编译和运行了，不过由于 Python 官方是不推荐这样设置&lt;/p&gt;
&lt;div class=&#34;language-text highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;***WARNING***
Building Python 2.7 for Windows using any toolchain that doesn&amp;#39;t link
against MSVCRT90.dll is *unsupported* as the resulting python.exe will
not be able to use precompiled extension modules that do link against
MSVCRT90.dll.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;所以使用的时候最好要注意一下。&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/py-%E4%BD%BF%E7%94%A8VisualStudio2015%E7%BC%96%E8%AF%91Python2.7.11/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 30 Nov 2023 20:09:36 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/py-%E4%BD%BF%E7%94%A8VisualStudio2015%E7%BC%96%E8%AF%91Python2.7.11/</guid>
      
    </item>
    
    <item>
      <title>Unity人物控制</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;Unity人物控制&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2014-3-15-unity-3rdperson-control0/run_jump.gif&#34; /&gt;&lt;/p&gt;
&lt;p&gt;人物的动作控制是游戏里面很重要的一部分，操作性强的游戏能够很好的吸引玩家。这里我就尝试做一个简单的人物操作控制，人物能够完成基本的移动，包括行走，跳跃。&lt;/p&gt;
&lt;h2 id=&#34;_1&#34;&gt;需求&lt;/h2&gt;
&lt;p&gt;先来考虑一下，我们的人物操作具体的需求：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;行走，能够在刚体的表面行走，由按键上下左右输入来控制，暂不考虑加速减速过程&lt;/li&gt;
&lt;li&gt;行走的速度在不同方向上可以不同，例如后退应该比前进慢&lt;/li&gt;
&lt;li&gt;跳跃，由jump按键控制，人物以一定初速度从上离开地面，并慢慢回落到地面&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;那么大致的思路就是：用速度来描述人物的运动，速度每个方向上的分量可以分别计算，最后速度乘以时间就是人物的位置偏移了。&lt;/p&gt;
&lt;h2 id=&#34;_2&#34;&gt;人物组件设置&lt;/h2&gt;
&lt;p&gt;在为人物写脚本来操作控制前，需要一些准备工作，把人物的相关组件先配置好：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;为了控制人物并使人物有一些刚性物理上的表现需要为人物添加一个&lt;code&gt;Character Controller Component&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;为了结构更分明一些，先把关于人物的操作输入分出来，读取输入并初步处理后把结果传给人物控制器，把这部分的脚本命名为&lt;code&gt;MyThirdPersonInput.cs&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;真正控制人物移动的脚本命名为&lt;code&gt;MyThirdPersonController.cs&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;配置后的结果是这样：
&lt;img alt=&#34;&#34; src=&#34;../assets/img/2014-3-15-unity-3rdperson-control0/setting.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_3&#34;&gt;输入&lt;/h2&gt;
&lt;p&gt;输入就是上下左右和跳跃，方向需要做一个归一化的处理：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// get movement from input&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;direction&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetAxis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Horizontal&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34; href=&#34;#__codelineno-0-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetAxis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Vertical&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-4&#34; name=&#34;__codelineno-0-4&#34; href=&#34;#__codelineno-0-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;direction&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zero&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-5&#34; name=&#34;__codelineno-0-5&#34; href=&#34;#__codelineno-0-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-6&#34; name=&#34;__codelineno-0-6&#34; href=&#34;#__codelineno-0-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// constrain length to [0, 1]&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-7&#34; name=&#34;__codelineno-0-7&#34; href=&#34;#__codelineno-0-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;directionLength&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;direction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;magnitude&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-8&#34; name=&#34;__codelineno-0-8&#34; href=&#34;#__codelineno-0-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;directionLength&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Math&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Min&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;directionLength&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-9&#34; name=&#34;__codelineno-0-9&#34; href=&#34;#__codelineno-0-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;direction&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;direction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;normalized&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;directionLength&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-10&#34; name=&#34;__codelineno-0-10&#34; href=&#34;#__codelineno-0-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-11&#34; name=&#34;__codelineno-0-11&#34; href=&#34;#__codelineno-0-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;person&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inputMoveDirction&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;direction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-12&#34; name=&#34;__codelineno-0-12&#34; href=&#34;#__codelineno-0-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;person&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inputJump&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetButton&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Jump&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-13&#34; name=&#34;__codelineno-0-13&#34; href=&#34;#__codelineno-0-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;err&#34;&gt;````&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-14&#34; name=&#34;__codelineno-0-14&#34; href=&#34;#__codelineno-0-14&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-15&#34; name=&#34;__codelineno-0-15&#34; href=&#34;#__codelineno-0-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;err&#34;&gt;##描述移动和跳跃&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-16&#34; name=&#34;__codelineno-0-16&#34; href=&#34;#__codelineno-0-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;err&#34;&gt;我们需要用一些变量来描述人物的动作，例如移动速度，跳跃速度等，移动用下面变量描述：&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-17&#34; name=&#34;__codelineno-0-17&#34; href=&#34;#__codelineno-0-17&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-18&#34; name=&#34;__codelineno-0-18&#34; href=&#34;#__codelineno-0-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;err&#34;&gt;```&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;
&lt;a id=&#34;__codelineno-0-19&#34; name=&#34;__codelineno-0-19&#34; href=&#34;#__codelineno-0-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;na&#34;&gt;[System.Serializable]&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-20&#34; name=&#34;__codelineno-0-20&#34; href=&#34;#__codelineno-0-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;Movement&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-21&#34; name=&#34;__codelineno-0-21&#34; href=&#34;#__codelineno-0-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-22&#34; name=&#34;__codelineno-0-22&#34; href=&#34;#__codelineno-0-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;forwardSpeed&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;5F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-23&#34; name=&#34;__codelineno-0-23&#34; href=&#34;#__codelineno-0-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;backwardSpeed&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;5F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-24&#34; name=&#34;__codelineno-0-24&#34; href=&#34;#__codelineno-0-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sidewardSpeed&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;5F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-25&#34; name=&#34;__codelineno-0-25&#34; href=&#34;#__codelineno-0-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-26&#34; name=&#34;__codelineno-0-26&#34; href=&#34;#__codelineno-0-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Movement&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;movement&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Movement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;[System.Serializable]&lt;/code&gt;是为了让这些参数暴露到Inspector上。跳跃的描述如下：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;na&#34;&gt;[System.Serializable]&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-2&#34; name=&#34;__codelineno-1-2&#34; href=&#34;#__codelineno-1-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;Jumping&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-1-3&#34; name=&#34;__codelineno-1-3&#34; href=&#34;#__codelineno-1-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-4&#34; name=&#34;__codelineno-1-4&#34; href=&#34;#__codelineno-1-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;enable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// true if can jump&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-5&#34; name=&#34;__codelineno-1-5&#34; href=&#34;#__codelineno-1-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jumpSpeed&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;5F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// original speed when jump&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-6&#34; name=&#34;__codelineno-1-6&#34; href=&#34;#__codelineno-1-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gravity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;10F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-7&#34; name=&#34;__codelineno-1-7&#34; href=&#34;#__codelineno-1-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;maxFallSpeed&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;20F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-8&#34; name=&#34;__codelineno-1-8&#34; href=&#34;#__codelineno-1-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jumping&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// true if now in the air&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-9&#34; name=&#34;__codelineno-1-9&#34; href=&#34;#__codelineno-1-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-10&#34; name=&#34;__codelineno-1-10&#34; href=&#34;#__codelineno-1-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Jumping&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jumping&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Jumping&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;_4&#34;&gt;分解速度&lt;/h2&gt;
&lt;p&gt;为了方便描述不同方向的移动，把方向分成三个分量：前后、左右、上下，分别求解。&lt;/p&gt;
&lt;p&gt;前后速度不同，根据数值的正负判断：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-2-1&#34; name=&#34;__codelineno-2-1&#34; href=&#34;#__codelineno-2-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;velocity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-2&#34; name=&#34;__codelineno-2-2&#34; href=&#34;#__codelineno-2-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;velocity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;movement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;forwardSpeed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-3&#34; name=&#34;__codelineno-2-3&#34; href=&#34;#__codelineno-2-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-4&#34; name=&#34;__codelineno-2-4&#34; href=&#34;#__codelineno-2-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;velocity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;movement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;backwardSpeed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;左右速度一致：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-3-1&#34; name=&#34;__codelineno-3-1&#34; href=&#34;#__codelineno-3-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;velocity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inputMoveDirction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;movement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sidewardSpeed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;跳跃麻烦一点，要判断当前人物的状态：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果已经在空中，用重力计算速度&lt;/li&gt;
&lt;li&gt;如果在地上：&lt;/li&gt;
&lt;li&gt;
&lt;ul&gt;
&lt;li&gt;如果按下跳跃键，速度为跳跃初始速度&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ul&gt;
&lt;li&gt;否则y方向速度为0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-4-1&#34; name=&#34;__codelineno-4-1&#34; href=&#34;#__codelineno-4-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isOnGround&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-2&#34; name=&#34;__codelineno-4-2&#34; href=&#34;#__codelineno-4-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-3&#34; name=&#34;__codelineno-4-3&#34; href=&#34;#__codelineno-4-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yVelocity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Math&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yVelocity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jumping&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gravity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;deltaTime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-4-4&#34; name=&#34;__codelineno-4-4&#34; href=&#34;#__codelineno-4-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jumping&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;maxFallSpeed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-5&#34; name=&#34;__codelineno-4-5&#34; href=&#34;#__codelineno-4-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-6&#34; name=&#34;__codelineno-4-6&#34; href=&#34;#__codelineno-4-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-7&#34; name=&#34;__codelineno-4-7&#34; href=&#34;#__codelineno-4-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-8&#34; name=&#34;__codelineno-4-8&#34; href=&#34;#__codelineno-4-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jumping&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;enable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inputJump&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-9&#34; name=&#34;__codelineno-4-9&#34; href=&#34;#__codelineno-4-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-10&#34; name=&#34;__codelineno-4-10&#34; href=&#34;#__codelineno-4-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yVelocity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jumping&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jumpSpeed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-11&#34; name=&#34;__codelineno-4-11&#34; href=&#34;#__codelineno-4-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-12&#34; name=&#34;__codelineno-4-12&#34; href=&#34;#__codelineno-4-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-13&#34; name=&#34;__codelineno-4-13&#34; href=&#34;#__codelineno-4-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yVelocity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-14&#34; name=&#34;__codelineno-4-14&#34; href=&#34;#__codelineno-4-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;_5&#34;&gt;更新人物位置&lt;/h2&gt;
&lt;p&gt;计算出来的速度假定为从本帧开始的速度，那么本帧计算位置的速度应该是前一帧计算出来的，因此在更新速度前，先计算人物的新位置：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-5-1&#34; name=&#34;__codelineno-5-1&#34; href=&#34;#__codelineno-5-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// move to new position&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-2&#34; name=&#34;__codelineno-5-2&#34; href=&#34;#__codelineno-5-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;collisionFlag&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;controller&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Move&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;velocity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;deltaTime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-3&#34; name=&#34;__codelineno-5-3&#34; href=&#34;#__codelineno-5-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;isOnGround&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;collisionFlag&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CollisionFlags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CollidedBelow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;controller.Move&lt;/code&gt;会返回&lt;code&gt;CollisionFlags&lt;/code&gt;来表示碰撞的状态，通过这个状态就可以知道人物是不是站在地面上。&lt;/p&gt;
&lt;p&gt;完整代码：&lt;/p&gt;
&lt;p&gt;MyThirdPersonInput.cs:&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-6-1&#34; name=&#34;__codelineno-6-1&#34; href=&#34;#__codelineno-6-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;UnityEngine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-2&#34; name=&#34;__codelineno-6-2&#34; href=&#34;#__codelineno-6-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;System&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-3&#34; name=&#34;__codelineno-6-3&#34; href=&#34;#__codelineno-6-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;System.Collections&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-4&#34; name=&#34;__codelineno-6-4&#34; href=&#34;#__codelineno-6-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;na&#34;&gt;[RequireComponent(typeof(MyThirdPersonController))]&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-5&#34; name=&#34;__codelineno-6-5&#34; href=&#34;#__codelineno-6-5&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-6&#34; name=&#34;__codelineno-6-6&#34; href=&#34;#__codelineno-6-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;MyThirdPersonInput&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MonoBehaviour&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-7&#34; name=&#34;__codelineno-6-7&#34; href=&#34;#__codelineno-6-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-8&#34; name=&#34;__codelineno-6-8&#34; href=&#34;#__codelineno-6-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;private&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MyThirdPersonController&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;person&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-9&#34; name=&#34;__codelineno-6-9&#34; href=&#34;#__codelineno-6-9&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-10&#34; name=&#34;__codelineno-6-10&#34; href=&#34;#__codelineno-6-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Awake&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-11&#34; name=&#34;__codelineno-6-11&#34; href=&#34;#__codelineno-6-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-12&#34; name=&#34;__codelineno-6-12&#34; href=&#34;#__codelineno-6-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;person&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetComponent&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MyThirdPersonController&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-13&#34; name=&#34;__codelineno-6-13&#34; href=&#34;#__codelineno-6-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-14&#34; name=&#34;__codelineno-6-14&#34; href=&#34;#__codelineno-6-14&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-15&#34; name=&#34;__codelineno-6-15&#34; href=&#34;#__codelineno-6-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Update is called once per frame&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-16&#34; name=&#34;__codelineno-6-16&#34; href=&#34;#__codelineno-6-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Update&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-6-17&#34; name=&#34;__codelineno-6-17&#34; href=&#34;#__codelineno-6-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-18&#34; name=&#34;__codelineno-6-18&#34; href=&#34;#__codelineno-6-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// get movement from input&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-19&#34; name=&#34;__codelineno-6-19&#34; href=&#34;#__codelineno-6-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;direction&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetAxis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Horizontal&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-6-20&#34; name=&#34;__codelineno-6-20&#34; href=&#34;#__codelineno-6-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetAxis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Vertical&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-21&#34; name=&#34;__codelineno-6-21&#34; href=&#34;#__codelineno-6-21&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-22&#34; name=&#34;__codelineno-6-22&#34; href=&#34;#__codelineno-6-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;direction&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zero&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-23&#34; name=&#34;__codelineno-6-23&#34; href=&#34;#__codelineno-6-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-24&#34; name=&#34;__codelineno-6-24&#34; href=&#34;#__codelineno-6-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// constrain length to [0, 1]&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-25&#34; name=&#34;__codelineno-6-25&#34; href=&#34;#__codelineno-6-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;directionLength&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;direction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;magnitude&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-26&#34; name=&#34;__codelineno-6-26&#34; href=&#34;#__codelineno-6-26&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-27&#34; name=&#34;__codelineno-6-27&#34; href=&#34;#__codelineno-6-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;directionLength&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Math&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Min&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;directionLength&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-28&#34; name=&#34;__codelineno-6-28&#34; href=&#34;#__codelineno-6-28&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-29&#34; name=&#34;__codelineno-6-29&#34; href=&#34;#__codelineno-6-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;direction&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;direction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;normalized&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;directionLength&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-30&#34; name=&#34;__codelineno-6-30&#34; href=&#34;#__codelineno-6-30&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-31&#34; name=&#34;__codelineno-6-31&#34; href=&#34;#__codelineno-6-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-32&#34; name=&#34;__codelineno-6-32&#34; href=&#34;#__codelineno-6-32&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-33&#34; name=&#34;__codelineno-6-33&#34; href=&#34;#__codelineno-6-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;person&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inputMoveDirction&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;direction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-34&#34; name=&#34;__codelineno-6-34&#34; href=&#34;#__codelineno-6-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;person&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inputJump&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetButton&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Jump&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-35&#34; name=&#34;__codelineno-6-35&#34; href=&#34;#__codelineno-6-35&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-36&#34; name=&#34;__codelineno-6-36&#34; href=&#34;#__codelineno-6-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-37&#34; name=&#34;__codelineno-6-37&#34; href=&#34;#__codelineno-6-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;MyThirdPersonController.cs:&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-7-1&#34; name=&#34;__codelineno-7-1&#34; href=&#34;#__codelineno-7-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;UnityEngine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-2&#34; name=&#34;__codelineno-7-2&#34; href=&#34;#__codelineno-7-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;System&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-3&#34; name=&#34;__codelineno-7-3&#34; href=&#34;#__codelineno-7-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;System.Collections&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-4&#34; name=&#34;__codelineno-7-4&#34; href=&#34;#__codelineno-7-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-5&#34; name=&#34;__codelineno-7-5&#34; href=&#34;#__codelineno-7-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;MyThirdPersonController&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MonoBehaviour&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-6&#34; name=&#34;__codelineno-7-6&#34; href=&#34;#__codelineno-7-6&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-7&#34; name=&#34;__codelineno-7-7&#34; href=&#34;#__codelineno-7-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// The current global direction we want the character to move in.&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-8&#34; name=&#34;__codelineno-7-8&#34; href=&#34;#__codelineno-7-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;[System.NonSerialized]&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-9&#34; name=&#34;__codelineno-7-9&#34; href=&#34;#__codelineno-7-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inputMoveDirction&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zero&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-10&#34; name=&#34;__codelineno-7-10&#34; href=&#34;#__codelineno-7-10&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-11&#34; name=&#34;__codelineno-7-11&#34; href=&#34;#__codelineno-7-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Is the jump button held down? We use this interface instead of checking&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-12&#34; name=&#34;__codelineno-7-12&#34; href=&#34;#__codelineno-7-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// for the jump button directly so this script can also be used by AIs.&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-13&#34; name=&#34;__codelineno-7-13&#34; href=&#34;#__codelineno-7-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;[System.NonSerialized]&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-14&#34; name=&#34;__codelineno-7-14&#34; href=&#34;#__codelineno-7-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inputJump&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-15&#34; name=&#34;__codelineno-7-15&#34; href=&#34;#__codelineno-7-15&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-16&#34; name=&#34;__codelineno-7-16&#34; href=&#34;#__codelineno-7-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;[System.Serializable]&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-17&#34; name=&#34;__codelineno-7-17&#34; href=&#34;#__codelineno-7-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;Movement&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-18&#34; name=&#34;__codelineno-7-18&#34; href=&#34;#__codelineno-7-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-19&#34; name=&#34;__codelineno-7-19&#34; href=&#34;#__codelineno-7-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;forwardSpeed&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;5F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-20&#34; name=&#34;__codelineno-7-20&#34; href=&#34;#__codelineno-7-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;backwardSpeed&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;5F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-21&#34; name=&#34;__codelineno-7-21&#34; href=&#34;#__codelineno-7-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sidewardSpeed&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;5F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-22&#34; name=&#34;__codelineno-7-22&#34; href=&#34;#__codelineno-7-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-23&#34; name=&#34;__codelineno-7-23&#34; href=&#34;#__codelineno-7-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Movement&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;movement&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Movement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-24&#34; name=&#34;__codelineno-7-24&#34; href=&#34;#__codelineno-7-24&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-25&#34; name=&#34;__codelineno-7-25&#34; href=&#34;#__codelineno-7-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;na&#34;&gt;[System.Serializable]&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-26&#34; name=&#34;__codelineno-7-26&#34; href=&#34;#__codelineno-7-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;Jumping&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-7-27&#34; name=&#34;__codelineno-7-27&#34; href=&#34;#__codelineno-7-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-28&#34; name=&#34;__codelineno-7-28&#34; href=&#34;#__codelineno-7-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;enable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// true if can jump&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-29&#34; name=&#34;__codelineno-7-29&#34; href=&#34;#__codelineno-7-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jumpSpeed&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;5F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// original speed when jump&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-30&#34; name=&#34;__codelineno-7-30&#34; href=&#34;#__codelineno-7-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gravity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;10F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;
&lt;a id=&#34;__codelineno-7-31&#34; name=&#34;__codelineno-7-31&#34; href=&#34;#__codelineno-7-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;maxFallSpeed&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;20F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-32&#34; name=&#34;__codelineno-7-32&#34; href=&#34;#__codelineno-7-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jumping&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// true if now in the air&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-33&#34; name=&#34;__codelineno-7-33&#34; href=&#34;#__codelineno-7-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-34&#34; name=&#34;__codelineno-7-34&#34; href=&#34;#__codelineno-7-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Jumping&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jumping&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Jumping&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-35&#34; name=&#34;__codelineno-7-35&#34; href=&#34;#__codelineno-7-35&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-36&#34; name=&#34;__codelineno-7-36&#34; href=&#34;#__codelineno-7-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;private&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CharacterController&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;controller&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-37&#34; name=&#34;__codelineno-7-37&#34; href=&#34;#__codelineno-7-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;private&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;velocity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zero&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-38&#34; name=&#34;__codelineno-7-38&#34; href=&#34;#__codelineno-7-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;private&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isOnGround&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-39&#34; name=&#34;__codelineno-7-39&#34; href=&#34;#__codelineno-7-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Use this for initialization&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-40&#34; name=&#34;__codelineno-7-40&#34; href=&#34;#__codelineno-7-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Start&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-7-41&#34; name=&#34;__codelineno-7-41&#34; href=&#34;#__codelineno-7-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-42&#34; name=&#34;__codelineno-7-42&#34; href=&#34;#__codelineno-7-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;controller&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetComponent&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CharacterController&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-43&#34; name=&#34;__codelineno-7-43&#34; href=&#34;#__codelineno-7-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-44&#34; name=&#34;__codelineno-7-44&#34; href=&#34;#__codelineno-7-44&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-45&#34; name=&#34;__codelineno-7-45&#34; href=&#34;#__codelineno-7-45&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Update is called once per frame&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-46&#34; name=&#34;__codelineno-7-46&#34; href=&#34;#__codelineno-7-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;FixedUpdate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-7-47&#34; name=&#34;__codelineno-7-47&#34; href=&#34;#__codelineno-7-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-48&#34; name=&#34;__codelineno-7-48&#34; href=&#34;#__codelineno-7-48&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// move to new position&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-49&#34; name=&#34;__codelineno-7-49&#34; href=&#34;#__codelineno-7-49&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;collisionFlag&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;controller&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Move&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;velocity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;deltaTime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-50&#34; name=&#34;__codelineno-7-50&#34; href=&#34;#__codelineno-7-50&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isOnGround&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;collisionFlag&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CollisionFlags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CollidedBelow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-51&#34; name=&#34;__codelineno-7-51&#34; href=&#34;#__codelineno-7-51&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-52&#34; name=&#34;__codelineno-7-52&#34; href=&#34;#__codelineno-7-52&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// update velocity&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-53&#34; name=&#34;__codelineno-7-53&#34; href=&#34;#__codelineno-7-53&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yVelocity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;velocity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-54&#34; name=&#34;__codelineno-7-54&#34; href=&#34;#__codelineno-7-54&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;velocity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zero&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-55&#34; name=&#34;__codelineno-7-55&#34; href=&#34;#__codelineno-7-55&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-56&#34; name=&#34;__codelineno-7-56&#34; href=&#34;#__codelineno-7-56&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// x-z plane velocity&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-57&#34; name=&#34;__codelineno-7-57&#34; href=&#34;#__codelineno-7-57&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inputMoveDirction&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zero&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-58&#34; name=&#34;__codelineno-7-58&#34; href=&#34;#__codelineno-7-58&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-59&#34; name=&#34;__codelineno-7-59&#34; href=&#34;#__codelineno-7-59&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;velocity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inputMoveDirction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-60&#34; name=&#34;__codelineno-7-60&#34; href=&#34;#__codelineno-7-60&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;velocity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-61&#34; name=&#34;__codelineno-7-61&#34; href=&#34;#__codelineno-7-61&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;velocity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;movement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;forwardSpeed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-62&#34; name=&#34;__codelineno-7-62&#34; href=&#34;#__codelineno-7-62&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-63&#34; name=&#34;__codelineno-7-63&#34; href=&#34;#__codelineno-7-63&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;velocity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;movement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;backwardSpeed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-64&#34; name=&#34;__codelineno-7-64&#34; href=&#34;#__codelineno-7-64&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-65&#34; name=&#34;__codelineno-7-65&#34; href=&#34;#__codelineno-7-65&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;velocity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inputMoveDirction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;movement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sidewardSpeed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-66&#34; name=&#34;__codelineno-7-66&#34; href=&#34;#__codelineno-7-66&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-67&#34; name=&#34;__codelineno-7-67&#34; href=&#34;#__codelineno-7-67&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-68&#34; name=&#34;__codelineno-7-68&#34; href=&#34;#__codelineno-7-68&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// y velocity&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-69&#34; name=&#34;__codelineno-7-69&#34; href=&#34;#__codelineno-7-69&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isOnGround&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-70&#34; name=&#34;__codelineno-7-70&#34; href=&#34;#__codelineno-7-70&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-71&#34; name=&#34;__codelineno-7-71&#34; href=&#34;#__codelineno-7-71&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yVelocity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Math&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yVelocity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jumping&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gravity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;deltaTime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-7-72&#34; name=&#34;__codelineno-7-72&#34; href=&#34;#__codelineno-7-72&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jumping&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;maxFallSpeed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-73&#34; name=&#34;__codelineno-7-73&#34; href=&#34;#__codelineno-7-73&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-74&#34; name=&#34;__codelineno-7-74&#34; href=&#34;#__codelineno-7-74&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-75&#34; name=&#34;__codelineno-7-75&#34; href=&#34;#__codelineno-7-75&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-76&#34; name=&#34;__codelineno-7-76&#34; href=&#34;#__codelineno-7-76&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jumping&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;enable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inputJump&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-77&#34; name=&#34;__codelineno-7-77&#34; href=&#34;#__codelineno-7-77&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-78&#34; name=&#34;__codelineno-7-78&#34; href=&#34;#__codelineno-7-78&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yVelocity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jumping&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jumpSpeed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-79&#34; name=&#34;__codelineno-7-79&#34; href=&#34;#__codelineno-7-79&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-80&#34; name=&#34;__codelineno-7-80&#34; href=&#34;#__codelineno-7-80&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-81&#34; name=&#34;__codelineno-7-81&#34; href=&#34;#__codelineno-7-81&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yVelocity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-82&#34; name=&#34;__codelineno-7-82&#34; href=&#34;#__codelineno-7-82&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-83&#34; name=&#34;__codelineno-7-83&#34; href=&#34;#__codelineno-7-83&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-7-84&#34; name=&#34;__codelineno-7-84&#34; href=&#34;#__codelineno-7-84&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;velocity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rotation&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;velocity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-85&#34; name=&#34;__codelineno-7-85&#34; href=&#34;#__codelineno-7-85&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;velocity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yVelocity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-86&#34; name=&#34;__codelineno-7-86&#34; href=&#34;#__codelineno-7-86&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-87&#34; name=&#34;__codelineno-7-87&#34; href=&#34;#__codelineno-7-87&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/unity-Unity%E4%BA%BA%E7%89%A9%E6%8E%A7%E5%88%B6/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 30 Nov 2023 20:09:36 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/unity-Unity%E4%BA%BA%E7%89%A9%E6%8E%A7%E5%88%B6/</guid>
      
    </item>
    
    <item>
      <title>Unity实现体积光照散射 (Volumetric Light Scattering，云隙光)</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;Unity实现体积光照散射 (Volumetric Light Scattering，云隙光)&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_1&#34;&gt;原理&lt;/h2&gt;
&lt;p&gt;Volumetric Light Scattering 的原理可以参考《GPU Gems 3》&lt;a href=&#34;http://http.developer.nvidia.com/GPUGems3/gpugems3_ch13.html&#34;&gt;第13章&lt;/a&gt;，书上有效果图：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2014-3-30-unity-light-scattering/goodeffect.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;好看吧，那好，我们的目标就是实现这种效果。&lt;/p&gt;
&lt;p&gt;书上介绍了原理，一条关键的公式是：&lt;/p&gt;
&lt;p&gt;\[ L(s, \theta, \phi) = exposure \times \sum_{i=0}^n decay^i \times weight \times \frac{L( s_i, \theta_i )}{n} \]&lt;/p&gt;
&lt;p&gt;我的理解是，对于图像上的每个像素，光线都有可能照射到，那么对该像素到光源(在投影到图像上的位置)的连线进行采样(对应公式上\(i\))，采样出的结果进行加权平均(对应公式上\(\sum\))并作为该像素的新的颜色值。另外还有关键的后置像素着色器，但是如果只是用那个着色器来对相机渲染的结果进行处理，会产生明显的人工痕迹，有许多的条纹：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2014-3-30-unity-light-scattering/badeffect.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;那么书上的效果是怎么做出来的？其实书上已经给出了答案，可以用一组图来阐述：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2014-3-30-unity-light-scattering/steps.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;图a 就是粗糙的效果，细心地可以看到有许多条纹，并且没有遮挡不够真实，b、c、 d就是为了获得好的效果需要进行的步骤：&lt;/p&gt;
&lt;p&gt;b. 把灯光辐射效果渲染到图像上，并加上物体的遮挡&lt;/p&gt;
&lt;p&gt;c. 对b执行 Volumetric Light Scattering 像素着色器，得到遮挡后的效果&lt;/p&gt;
&lt;p&gt;d. 添加上把真实场景的颜色&lt;/p&gt;
&lt;p&gt;那么下面我们就来一步一步地实现。&lt;/p&gt;
&lt;h2 id=&#34;_2&#34;&gt;画遮挡物体&lt;/h2&gt;
&lt;p&gt;在实际的操作中，我先用&lt;code&gt;RenderWithShader&lt;/code&gt;来把会发生遮挡的物体画成黑色，其他地方为白色，因为这需要对每个面片进行渲染，因此对于复杂的场景，会带来一定的性能消耗。场景中的物体有不透明和透明的，我们希望不透明的物体产生完全的光线遮挡，而透明的物体应该产生部分的遮挡，那么我们就需要针对不同RenderType的物体写不同的Shader，RenderType是SubShader的Tag，不清楚的话可以看&lt;a href=&#34;http://docs.unity3d.com/Documentation/Components/SL-SubshaderTags.html&#34;&gt;这里&lt;/a&gt;，写好之后调用：&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;camera&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RenderWithShader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;objectOcclusionShader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;RenderType&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;code&gt;RenderWithShader&lt;/code&gt;的第二个参数就是要求根据RenderType来替换Shader，简单来说，同一个物体的替换的Shader的RenderType要跟替换前一致，这样我们就可以为不同的RenderType的物体使用不同的Shader：&lt;/p&gt;
&lt;div class=&#34;language-glsl highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Shader&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Custom&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ObjectOcclusion&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-1-2&#34; name=&#34;__codelineno-1-2&#34; href=&#34;#__codelineno-1-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-3&#34; name=&#34;__codelineno-1-3&#34; href=&#34;#__codelineno-1-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Properties&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-1-4&#34; name=&#34;__codelineno-1-4&#34; href=&#34;#__codelineno-1-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-5&#34; name=&#34;__codelineno-1-5&#34; href=&#34;#__codelineno-1-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_MainTex&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RGB&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;D&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;white&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-6&#34; name=&#34;__codelineno-1-6&#34; href=&#34;#__codelineno-1-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-7&#34; name=&#34;__codelineno-1-7&#34; href=&#34;#__codelineno-1-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SubShader&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-1-8&#34; name=&#34;__codelineno-1-8&#34; href=&#34;#__codelineno-1-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-9&#34; name=&#34;__codelineno-1-9&#34; href=&#34;#__codelineno-1-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Tags&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-1-10&#34; name=&#34;__codelineno-1-10&#34; href=&#34;#__codelineno-1-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-11&#34; name=&#34;__codelineno-1-11&#34; href=&#34;#__codelineno-1-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Queue&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Geometry&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-12&#34; name=&#34;__codelineno-1-12&#34; href=&#34;#__codelineno-1-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RenderType&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Opaque&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-13&#34; name=&#34;__codelineno-1-13&#34; href=&#34;#__codelineno-1-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-14&#34; name=&#34;__codelineno-1-14&#34; href=&#34;#__codelineno-1-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOD&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-15&#34; name=&#34;__codelineno-1-15&#34; href=&#34;#__codelineno-1-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Pass&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-16&#34; name=&#34;__codelineno-1-16&#34; href=&#34;#__codelineno-1-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-17&#34; name=&#34;__codelineno-1-17&#34; href=&#34;#__codelineno-1-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Lighting&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Off&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-18&#34; name=&#34;__codelineno-1-18&#34; href=&#34;#__codelineno-1-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ZTest&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Always&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Cull&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Off&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ZWrite&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Off&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-19&#34; name=&#34;__codelineno-1-19&#34; href=&#34;#__codelineno-1-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Fog&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Mode&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;off&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-20&#34; name=&#34;__codelineno-1-20&#34; href=&#34;#__codelineno-1-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CGPROGRAM&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-21&#34; name=&#34;__codelineno-1-21&#34; href=&#34;#__codelineno-1-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#pragma vertex vert&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-22&#34; name=&#34;__codelineno-1-22&#34; href=&#34;#__codelineno-1-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#pragma fragment frag&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-23&#34; name=&#34;__codelineno-1-23&#34; href=&#34;#__codelineno-1-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#include &amp;quot;UnityCG.cginc&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-24&#34; name=&#34;__codelineno-1-24&#34; href=&#34;#__codelineno-1-24&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-25&#34; name=&#34;__codelineno-1-25&#34; href=&#34;#__codelineno-1-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;uniform&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;sampler2D&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_MainTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-26&#34; name=&#34;__codelineno-1-26&#34; href=&#34;#__codelineno-1-26&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-27&#34; name=&#34;__codelineno-1-27&#34; href=&#34;#__codelineno-1-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v2f_img&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;appdata_img&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-28&#34; name=&#34;__codelineno-1-28&#34; href=&#34;#__codelineno-1-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-29&#34; name=&#34;__codelineno-1-29&#34; href=&#34;#__codelineno-1-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v2f_img&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-30&#34; name=&#34;__codelineno-1-30&#34; href=&#34;#__codelineno-1-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mul&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UNITY_MATRIX_MVP&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vertex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-31&#34; name=&#34;__codelineno-1-31&#34; href=&#34;#__codelineno-1-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-32&#34; name=&#34;__codelineno-1-32&#34; href=&#34;#__codelineno-1-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-33&#34; name=&#34;__codelineno-1-33&#34; href=&#34;#__codelineno-1-33&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-34&#34; name=&#34;__codelineno-1-34&#34; href=&#34;#__codelineno-1-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;frag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v2f_img&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;COLOR&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-35&#34; name=&#34;__codelineno-1-35&#34; href=&#34;#__codelineno-1-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-36&#34; name=&#34;__codelineno-1-36&#34; href=&#34;#__codelineno-1-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mo&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mo&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mo&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-37&#34; name=&#34;__codelineno-1-37&#34; href=&#34;#__codelineno-1-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-38&#34; name=&#34;__codelineno-1-38&#34; href=&#34;#__codelineno-1-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ENDCG&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-39&#34; name=&#34;__codelineno-1-39&#34; href=&#34;#__codelineno-1-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-40&#34; name=&#34;__codelineno-1-40&#34; href=&#34;#__codelineno-1-40&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-41&#34; name=&#34;__codelineno-1-41&#34; href=&#34;#__codelineno-1-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-42&#34; name=&#34;__codelineno-1-42&#34; href=&#34;#__codelineno-1-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SubShader&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-1-43&#34; name=&#34;__codelineno-1-43&#34; href=&#34;#__codelineno-1-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-44&#34; name=&#34;__codelineno-1-44&#34; href=&#34;#__codelineno-1-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Tags&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-1-45&#34; name=&#34;__codelineno-1-45&#34; href=&#34;#__codelineno-1-45&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-46&#34; name=&#34;__codelineno-1-46&#34; href=&#34;#__codelineno-1-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Queue&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Geometry&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-47&#34; name=&#34;__codelineno-1-47&#34; href=&#34;#__codelineno-1-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RenderType&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Transparent&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-48&#34; name=&#34;__codelineno-1-48&#34; href=&#34;#__codelineno-1-48&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-49&#34; name=&#34;__codelineno-1-49&#34; href=&#34;#__codelineno-1-49&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOD&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-50&#34; name=&#34;__codelineno-1-50&#34; href=&#34;#__codelineno-1-50&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Pass&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-51&#34; name=&#34;__codelineno-1-51&#34; href=&#34;#__codelineno-1-51&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-52&#34; name=&#34;__codelineno-1-52&#34; href=&#34;#__codelineno-1-52&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Lighting&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Off&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-53&#34; name=&#34;__codelineno-1-53&#34; href=&#34;#__codelineno-1-53&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ZTest&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Always&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Cull&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Off&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ZWrite&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Off&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-54&#34; name=&#34;__codelineno-1-54&#34; href=&#34;#__codelineno-1-54&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Fog&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Mode&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;off&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-55&#34; name=&#34;__codelineno-1-55&#34; href=&#34;#__codelineno-1-55&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Blend&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SrcAlpha&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OneMinusSrcAlpha&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// blend for transparent objects&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-56&#34; name=&#34;__codelineno-1-56&#34; href=&#34;#__codelineno-1-56&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CGPROGRAM&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-57&#34; name=&#34;__codelineno-1-57&#34; href=&#34;#__codelineno-1-57&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#pragma vertex vert&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-58&#34; name=&#34;__codelineno-1-58&#34; href=&#34;#__codelineno-1-58&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#pragma fragment frag&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-59&#34; name=&#34;__codelineno-1-59&#34; href=&#34;#__codelineno-1-59&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#include &amp;quot;UnityCG.cginc&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-60&#34; name=&#34;__codelineno-1-60&#34; href=&#34;#__codelineno-1-60&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-61&#34; name=&#34;__codelineno-1-61&#34; href=&#34;#__codelineno-1-61&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;uniform&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;sampler2D&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_MainTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-62&#34; name=&#34;__codelineno-1-62&#34; href=&#34;#__codelineno-1-62&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-63&#34; name=&#34;__codelineno-1-63&#34; href=&#34;#__codelineno-1-63&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v2f_img&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;appdata_img&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-64&#34; name=&#34;__codelineno-1-64&#34; href=&#34;#__codelineno-1-64&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-65&#34; name=&#34;__codelineno-1-65&#34; href=&#34;#__codelineno-1-65&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v2f_img&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-66&#34; name=&#34;__codelineno-1-66&#34; href=&#34;#__codelineno-1-66&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mul&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UNITY_MATRIX_MVP&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vertex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-67&#34; name=&#34;__codelineno-1-67&#34; href=&#34;#__codelineno-1-67&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MultiplyUV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UNITY_MATRIX_TEXTURE0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;texcoord&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-68&#34; name=&#34;__codelineno-1-68&#34; href=&#34;#__codelineno-1-68&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-69&#34; name=&#34;__codelineno-1-69&#34; href=&#34;#__codelineno-1-69&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-70&#34; name=&#34;__codelineno-1-70&#34; href=&#34;#__codelineno-1-70&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-71&#34; name=&#34;__codelineno-1-71&#34; href=&#34;#__codelineno-1-71&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;frag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v2f_img&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;COLOR&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-72&#34; name=&#34;__codelineno-1-72&#34; href=&#34;#__codelineno-1-72&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-73&#34; name=&#34;__codelineno-1-73&#34; href=&#34;#__codelineno-1-73&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;output&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-74&#34; name=&#34;__codelineno-1-74&#34; href=&#34;#__codelineno-1-74&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tex2D&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_MainTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-75&#34; name=&#34;__codelineno-1-75&#34; href=&#34;#__codelineno-1-75&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;half&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;alpha&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-76&#34; name=&#34;__codelineno-1-76&#34; href=&#34;#__codelineno-1-76&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;output&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;alpha&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;alpha&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-77&#34; name=&#34;__codelineno-1-77&#34; href=&#34;#__codelineno-1-77&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-78&#34; name=&#34;__codelineno-1-78&#34; href=&#34;#__codelineno-1-78&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ENDCG&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-79&#34; name=&#34;__codelineno-1-79&#34; href=&#34;#__codelineno-1-79&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-80&#34; name=&#34;__codelineno-1-80&#34; href=&#34;#__codelineno-1-80&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-81&#34; name=&#34;__codelineno-1-81&#34; href=&#34;#__codelineno-1-81&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-82&#34; name=&#34;__codelineno-1-82&#34; href=&#34;#__codelineno-1-82&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-83&#34; name=&#34;__codelineno-1-83&#34; href=&#34;#__codelineno-1-83&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FallBack&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Diffuse&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-84&#34; name=&#34;__codelineno-1-84&#34; href=&#34;#__codelineno-1-84&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;注意不透明和透明物体的Shader间的差别：不透明的物体直接画成黑色；不透明物体需要执行blending，获取物体纹理上的alpha通道，并基于这个alpha进行blending。上面代码只是列举了Opaque和Transparent，另外还有TreeOpaque (Shader跟Opaque一样，只是改变RenderType) ，TreeTransparentCutout (同Transparent) 等。由于指定了RenderType，所以为了全面，需要尽可能穷尽场景中的会发生遮挡的物体，我这里就只有前面提到的四种。结果大致如下：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2014-3-30-unity-light-scattering/objectocclusion.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_3&#34;&gt;结合物体遮挡画光源辐射&lt;/h2&gt;
&lt;p&gt;画光源的辐射不难，需要注意的是需要根据屏幕的大小做一些处理，使得光源的辐射状是圆形的：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-2-1&#34; name=&#34;__codelineno-2-1&#34; href=&#34;#__codelineno-2-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Shader&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Custom/LightRadiate&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-2-2&#34; name=&#34;__codelineno-2-2&#34; href=&#34;#__codelineno-2-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-3&#34; name=&#34;__codelineno-2-3&#34; href=&#34;#__codelineno-2-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Properties&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-2-4&#34; name=&#34;__codelineno-2-4&#34; href=&#34;#__codelineno-2-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-5&#34; name=&#34;__codelineno-2-5&#34; href=&#34;#__codelineno-2-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_MainTex&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Base (RGB)&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RECT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;white&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-6&#34; name=&#34;__codelineno-2-6&#34; href=&#34;#__codelineno-2-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_LightPos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Light Pos In Screen Space(XY)&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-7&#34; name=&#34;__codelineno-2-7&#34; href=&#34;#__codelineno-2-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_LightRadius&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Light radiation radius (Pixel)&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;50&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-8&#34; name=&#34;__codelineno-2-8&#34; href=&#34;#__codelineno-2-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-9&#34; name=&#34;__codelineno-2-9&#34; href=&#34;#__codelineno-2-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SubShader&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-2-10&#34; name=&#34;__codelineno-2-10&#34; href=&#34;#__codelineno-2-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-11&#34; name=&#34;__codelineno-2-11&#34; href=&#34;#__codelineno-2-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Tags&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;RenderType&amp;quot;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Opaque&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-12&#34; name=&#34;__codelineno-2-12&#34; href=&#34;#__codelineno-2-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOD&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-13&#34; name=&#34;__codelineno-2-13&#34; href=&#34;#__codelineno-2-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Pass&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-14&#34; name=&#34;__codelineno-2-14&#34; href=&#34;#__codelineno-2-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-15&#34; name=&#34;__codelineno-2-15&#34; href=&#34;#__codelineno-2-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ZTest&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Always&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Cull&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Off&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ZWrite&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Off&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-16&#34; name=&#34;__codelineno-2-16&#34; href=&#34;#__codelineno-2-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Fog&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Mode&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;off&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-17&#34; name=&#34;__codelineno-2-17&#34; href=&#34;#__codelineno-2-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CGPROGRAM&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-18&#34; name=&#34;__codelineno-2-18&#34; href=&#34;#__codelineno-2-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#pragma vertex vert&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-19&#34; name=&#34;__codelineno-2-19&#34; href=&#34;#__codelineno-2-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#pragma fragment frag&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-20&#34; name=&#34;__codelineno-2-20&#34; href=&#34;#__codelineno-2-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;UnityCG.cginc&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-21&#34; name=&#34;__codelineno-2-21&#34; href=&#34;#__codelineno-2-21&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-22&#34; name=&#34;__codelineno-2-22&#34; href=&#34;#__codelineno-2-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uniform&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sampler2D&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_MainTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-23&#34; name=&#34;__codelineno-2-23&#34; href=&#34;#__codelineno-2-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;float4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_LightPos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-24&#34; name=&#34;__codelineno-2-24&#34; href=&#34;#__codelineno-2-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_LightRadius&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-25&#34; name=&#34;__codelineno-2-25&#34; href=&#34;#__codelineno-2-25&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-26&#34; name=&#34;__codelineno-2-26&#34; href=&#34;#__codelineno-2-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v2f_img&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;vert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;appdata_img&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-27&#34; name=&#34;__codelineno-2-27&#34; href=&#34;#__codelineno-2-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-28&#34; name=&#34;__codelineno-2-28&#34; href=&#34;#__codelineno-2-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v2f_img&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-29&#34; name=&#34;__codelineno-2-29&#34; href=&#34;#__codelineno-2-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mul&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UNITY_MATRIX_MVP&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vertex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-30&#34; name=&#34;__codelineno-2-30&#34; href=&#34;#__codelineno-2-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MultiplyUV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UNITY_MATRIX_TEXTURE0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;texcoord&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-31&#34; name=&#34;__codelineno-2-31&#34; href=&#34;#__codelineno-2-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-32&#34; name=&#34;__codelineno-2-32&#34; href=&#34;#__codelineno-2-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-33&#34; name=&#34;__codelineno-2-33&#34; href=&#34;#__codelineno-2-33&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-34&#34; name=&#34;__codelineno-2-34&#34; href=&#34;#__codelineno-2-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;frag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v2f_img&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;COLOR&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-35&#34; name=&#34;__codelineno-2-35&#34; href=&#34;#__codelineno-2-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-36&#34; name=&#34;__codelineno-2-36&#34; href=&#34;#__codelineno-2-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;deltaTexCoord&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_LightPos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_ScreenParams&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_ScreenParams&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-37&#34; name=&#34;__codelineno-2-37&#34; href=&#34;#__codelineno-2-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dis&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dot&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;deltaTexCoord&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;deltaTexCoord&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-38&#34; name=&#34;__codelineno-2-38&#34; href=&#34;#__codelineno-2-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;maxDis&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_LightRadius&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_LightRadius&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-39&#34; name=&#34;__codelineno-2-39&#34; href=&#34;#__codelineno-2-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dis&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;saturate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;maxDis&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;maxDis&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-40&#34; name=&#34;__codelineno-2-40&#34; href=&#34;#__codelineno-2-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;half4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tex2D&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_MainTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rgb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;               &lt;/span&gt;
&lt;a id=&#34;__codelineno-2-41&#34; name=&#34;__codelineno-2-41&#34; href=&#34;#__codelineno-2-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-42&#34; name=&#34;__codelineno-2-42&#34; href=&#34;#__codelineno-2-42&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-43&#34; name=&#34;__codelineno-2-43&#34; href=&#34;#__codelineno-2-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ENDCG&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-44&#34; name=&#34;__codelineno-2-44&#34; href=&#34;#__codelineno-2-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-45&#34; name=&#34;__codelineno-2-45&#34; href=&#34;#__codelineno-2-45&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-2-46&#34; name=&#34;__codelineno-2-46&#34; href=&#34;#__codelineno-2-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FallBack&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Diffuse&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-47&#34; name=&#34;__codelineno-2-47&#34; href=&#34;#__codelineno-2-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这个Shader需要输入光源在屏幕上的位置(可以用&lt;code&gt;camera.WorldToViewportPoint&lt;/code&gt;来计算，得到的是uv坐标)，然后根据指定的半径画一个亮度往外衰减的圆，并把结果跟前面得到的物体遮挡图像(放在&lt;code&gt;_MainTex&lt;/code&gt;里)结合，结果大致为：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2014-3-30-unity-light-scattering/light.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;light-scattering&#34;&gt;Light Scattering处理，并结合真实颜色&lt;/h2&gt;
&lt;p&gt;这里就要用到书上提供的Pixel Shader，我的版本：&lt;/p&gt;
&lt;div class=&#34;language-glsl highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-3-1&#34; name=&#34;__codelineno-3-1&#34; href=&#34;#__codelineno-3-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Shader&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Custom&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LightScattering&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-3-2&#34; name=&#34;__codelineno-3-2&#34; href=&#34;#__codelineno-3-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-3&#34; name=&#34;__codelineno-3-3&#34; href=&#34;#__codelineno-3-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Properties&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-3-4&#34; name=&#34;__codelineno-3-4&#34; href=&#34;#__codelineno-3-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-5&#34; name=&#34;__codelineno-3-5&#34; href=&#34;#__codelineno-3-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_MainTex&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RGB&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;D&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;white&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-6&#34; name=&#34;__codelineno-3-6&#34; href=&#34;#__codelineno-3-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_LightRadTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Light&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Radiate&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Tex&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RGB&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;D&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;white&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-7&#34; name=&#34;__codelineno-3-7&#34; href=&#34;#__codelineno-3-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_LightPos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Light&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;In&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Screen&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Space&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;XY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mo&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mo&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mo&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-8&#34; name=&#34;__codelineno-3-8&#34; href=&#34;#__codelineno-3-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_Params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Density&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Weight&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Decay&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Exposure&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-9&#34; name=&#34;__codelineno-3-9&#34; href=&#34;#__codelineno-3-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-10&#34; name=&#34;__codelineno-3-10&#34; href=&#34;#__codelineno-3-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SubShader&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-3-11&#34; name=&#34;__codelineno-3-11&#34; href=&#34;#__codelineno-3-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-12&#34; name=&#34;__codelineno-3-12&#34; href=&#34;#__codelineno-3-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOD&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-13&#34; name=&#34;__codelineno-3-13&#34; href=&#34;#__codelineno-3-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Pass&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-14&#34; name=&#34;__codelineno-3-14&#34; href=&#34;#__codelineno-3-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-15&#34; name=&#34;__codelineno-3-15&#34; href=&#34;#__codelineno-3-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ZTest&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Always&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Cull&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Off&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ZWrite&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Off&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-16&#34; name=&#34;__codelineno-3-16&#34; href=&#34;#__codelineno-3-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Fog&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Mode&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;off&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;
&lt;a id=&#34;__codelineno-3-17&#34; name=&#34;__codelineno-3-17&#34; href=&#34;#__codelineno-3-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CGPROGRAM&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-18&#34; name=&#34;__codelineno-3-18&#34; href=&#34;#__codelineno-3-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#pragma vertex vert&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-19&#34; name=&#34;__codelineno-3-19&#34; href=&#34;#__codelineno-3-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#pragma fragment frag&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-20&#34; name=&#34;__codelineno-3-20&#34; href=&#34;#__codelineno-3-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#pragma target 3.0&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-21&#34; name=&#34;__codelineno-3-21&#34; href=&#34;#__codelineno-3-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#include &amp;quot;UnityCG.cginc&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-22&#34; name=&#34;__codelineno-3-22&#34; href=&#34;#__codelineno-3-22&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-23&#34; name=&#34;__codelineno-3-23&#34; href=&#34;#__codelineno-3-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;uniform&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;sampler2D&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_MainTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-24&#34; name=&#34;__codelineno-3-24&#34; href=&#34;#__codelineno-3-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;uniform&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;sampler2D&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_LightRadTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-25&#34; name=&#34;__codelineno-3-25&#34; href=&#34;#__codelineno-3-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;uniform&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;float4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_LightPos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-26&#34; name=&#34;__codelineno-3-26&#34; href=&#34;#__codelineno-3-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;uniform&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;float4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_Params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-27&#34; name=&#34;__codelineno-3-27&#34; href=&#34;#__codelineno-3-27&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-28&#34; name=&#34;__codelineno-3-28&#34; href=&#34;#__codelineno-3-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v2f_img&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;appdata_img&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-29&#34; name=&#34;__codelineno-3-29&#34; href=&#34;#__codelineno-3-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-30&#34; name=&#34;__codelineno-3-30&#34; href=&#34;#__codelineno-3-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v2f_img&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-31&#34; name=&#34;__codelineno-3-31&#34; href=&#34;#__codelineno-3-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mul&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UNITY_MATRIX_MVP&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vertex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-32&#34; name=&#34;__codelineno-3-32&#34; href=&#34;#__codelineno-3-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MultiplyUV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UNITY_MATRIX_TEXTURE0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;texcoord&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-33&#34; name=&#34;__codelineno-3-33&#34; href=&#34;#__codelineno-3-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-34&#34; name=&#34;__codelineno-3-34&#34; href=&#34;#__codelineno-3-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-35&#34; name=&#34;__codelineno-3-35&#34; href=&#34;#__codelineno-3-35&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-36&#34; name=&#34;__codelineno-3-36&#34; href=&#34;#__codelineno-3-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;frag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v2f_img&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;COLOR&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-37&#34; name=&#34;__codelineno-3-37&#34; href=&#34;#__codelineno-3-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;
&lt;a id=&#34;__codelineno-3-38&#34; name=&#34;__codelineno-3-38&#34; href=&#34;#__codelineno-3-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Calculate vector from pixel to light source in screen space&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-39&#34; name=&#34;__codelineno-3-39&#34; href=&#34;#__codelineno-3-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;float2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;deltaTexCoord&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_LightPos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-40&#34; name=&#34;__codelineno-3-40&#34; href=&#34;#__codelineno-3-40&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-41&#34; name=&#34;__codelineno-3-41&#34; href=&#34;#__codelineno-3-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Divide by number of samples and scale by control factor, here I use 32 samples&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-42&#34; name=&#34;__codelineno-3-42&#34; href=&#34;#__codelineno-3-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;deltaTexCoord&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_Params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//density;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-43&#34; name=&#34;__codelineno-3-43&#34; href=&#34;#__codelineno-3-43&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-44&#34; name=&#34;__codelineno-3-44&#34; href=&#34;#__codelineno-3-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Store color.&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-45&#34; name=&#34;__codelineno-3-45&#34; href=&#34;#__codelineno-3-45&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tex2D&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_MainTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rgb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-46&#34; name=&#34;__codelineno-3-46&#34; href=&#34;#__codelineno-3-46&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-47&#34; name=&#34;__codelineno-3-47&#34; href=&#34;#__codelineno-3-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Store initial sample.&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-48&#34; name=&#34;__codelineno-3-48&#34; href=&#34;#__codelineno-3-48&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;light&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tex2D&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_LightRadTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rgb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-49&#34; name=&#34;__codelineno-3-49&#34; href=&#34;#__codelineno-3-49&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-50&#34; name=&#34;__codelineno-3-50&#34; href=&#34;#__codelineno-3-50&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Set up illumination decay factor.&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-51&#34; name=&#34;__codelineno-3-51&#34; href=&#34;#__codelineno-3-51&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;half&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;illuminationDecay&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-52&#34; name=&#34;__codelineno-3-52&#34; href=&#34;#__codelineno-3-52&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-53&#34; name=&#34;__codelineno-3-53&#34; href=&#34;#__codelineno-3-53&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;j&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mo&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;j&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;31&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;j&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-54&#34; name=&#34;__codelineno-3-54&#34; href=&#34;#__codelineno-3-54&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-55&#34; name=&#34;__codelineno-3-55&#34; href=&#34;#__codelineno-3-55&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Step sample location along ray.&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-56&#34; name=&#34;__codelineno-3-56&#34; href=&#34;#__codelineno-3-56&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;deltaTexCoord&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-57&#34; name=&#34;__codelineno-3-57&#34; href=&#34;#__codelineno-3-57&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-58&#34; name=&#34;__codelineno-3-58&#34; href=&#34;#__codelineno-3-58&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Retrieve sample at new location.&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-59&#34; name=&#34;__codelineno-3-59&#34; href=&#34;#__codelineno-3-59&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;sample&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tex2D&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_LightRadTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rgb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-60&#34; name=&#34;__codelineno-3-60&#34; href=&#34;#__codelineno-3-60&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-61&#34; name=&#34;__codelineno-3-61&#34; href=&#34;#__codelineno-3-61&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Apply sample attenuation scale/decay factors.&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-62&#34; name=&#34;__codelineno-3-62&#34; href=&#34;#__codelineno-3-62&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;sample&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;illuminationDecay&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.03125&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_Params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//weight;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-63&#34; name=&#34;__codelineno-3-63&#34; href=&#34;#__codelineno-3-63&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-64&#34; name=&#34;__codelineno-3-64&#34; href=&#34;#__codelineno-3-64&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Accumulate combined light.&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-65&#34; name=&#34;__codelineno-3-65&#34; href=&#34;#__codelineno-3-65&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;light&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;sample&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-66&#34; name=&#34;__codelineno-3-66&#34; href=&#34;#__codelineno-3-66&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-67&#34; name=&#34;__codelineno-3-67&#34; href=&#34;#__codelineno-3-67&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Update exponential decay factor.&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-68&#34; name=&#34;__codelineno-3-68&#34; href=&#34;#__codelineno-3-68&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;illuminationDecay&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_Params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//decay;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-69&#34; name=&#34;__codelineno-3-69&#34; href=&#34;#__codelineno-3-69&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-70&#34; name=&#34;__codelineno-3-70&#34; href=&#34;#__codelineno-3-70&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-71&#34; name=&#34;__codelineno-3-71&#34; href=&#34;#__codelineno-3-71&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Output final color with a further scale control factor.&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-72&#34; name=&#34;__codelineno-3-72&#34; href=&#34;#__codelineno-3-72&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;light&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_Params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;w&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// exposure&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-73&#34; name=&#34;__codelineno-3-73&#34; href=&#34;#__codelineno-3-73&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-74&#34; name=&#34;__codelineno-3-74&#34; href=&#34;#__codelineno-3-74&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-75&#34; name=&#34;__codelineno-3-75&#34; href=&#34;#__codelineno-3-75&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ENDCG&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;
&lt;a id=&#34;__codelineno-3-76&#34; name=&#34;__codelineno-3-76&#34; href=&#34;#__codelineno-3-76&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-77&#34; name=&#34;__codelineno-3-77&#34; href=&#34;#__codelineno-3-77&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-78&#34; name=&#34;__codelineno-3-78&#34; href=&#34;#__codelineno-3-78&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-3-79&#34; name=&#34;__codelineno-3-79&#34; href=&#34;#__codelineno-3-79&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FallBack&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Diffuse&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-80&#34; name=&#34;__codelineno-3-80&#34; href=&#34;#__codelineno-3-80&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;大体上跟书上的一致，只是我的参数需要在程序中传进来，并且结合了真实的颜色图和Light Scattering图，结果：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2014-3-30-unity-light-scattering/effect.gif&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;_4&#34;&gt;完整代码&lt;/h2&gt;
&lt;p&gt;代码在&lt;a href=&#34;../assets/img/2014-3-30-unity-light-scattering/2014-3-30-unity-light-scattering.zip&#34;&gt;这里&lt;/a&gt;，把&lt;code&gt;cs&lt;/code&gt;脚本添加到相机上。&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/unity-Unity%E5%AE%9E%E7%8E%B0%E4%BD%93%E7%A7%AF%E5%85%89%E7%85%A7%E6%95%A3%E5%B0%84/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 30 Nov 2023 20:09:36 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/unity-Unity%E5%AE%9E%E7%8E%B0%E4%BD%93%E7%A7%AF%E5%85%89%E7%85%A7%E6%95%A3%E5%B0%84/</guid>
      
    </item>
    
    <item>
      <title>Unity画深度图(Depth Map)和边缘检测(Edge Detection)</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;Unity画深度图(Depth Map)和边缘检测(Edge Detection)&#34; /&gt;&lt;/p&gt;
&lt;p&gt;刚接触Unity没多久，对Unity的ShaderLab一直很感兴趣，感觉它可以快速地实现各种各样的显示效果，很有意思。嘛，作为一个门都还没入的人，我就来搞一搞深度图和边缘检测吧。&lt;/p&gt;
&lt;h1 id=&#34;_1&#34;&gt;小地图设置&lt;/h1&gt;
&lt;p&gt;因为我只是做了一个小雏形，所以我不打算详细地讲如何去在场景上画小地图，大致上说我做了以下一些事情：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;获取场景的 bounding box，这个在设置相机的参数和位置时有用&lt;/li&gt;
&lt;li&gt;把小地图相机配置成正交投影，根据 bounding box 设置相机的近平面和远平面&lt;/li&gt;
&lt;li&gt;为该相机增加一个人物目标，目标会显示在地图的中心&lt;/li&gt;
&lt;li&gt;每次更新相机的位置，根据目标的位置，还有场景的最大 y 值&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;具体的配置可以参考后面给出的代码。&lt;/p&gt;
&lt;h1 id=&#34;_2&#34;&gt;获取深度图&lt;/h1&gt;
&lt;h2 id=&#34;depthtexturemode&#34;&gt;depthTextureMode 来获取深度图&lt;/h2&gt;
&lt;p&gt;相机自己可以保存DepthBuffer或者一个DepthNormalBuffer(可用来做边缘检测)，只需要设置&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Camera&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;depthTextureMode&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DepthTextureMode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DepthNormals&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;然后在Shader里面引用&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;sampler2D&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_CameraDepthNormalsTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;就可以了，具体的做法可以参考我后面给出的代码。关于在Z-Buffer里面保存的深度值跟真实世界的深度的关系可以参考这两篇文章：
&lt;a href=&#34;http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html&#34;&gt;Learning to Love your Z-buffer&lt;/a&gt;,&lt;a href=&#34;http://www.humus.name/temp/Linearize%20depth.txt&#34;&gt;Linearize depth&lt;/a&gt;。另外 Unity 也提供了一些函数来计算深度: &lt;code&gt;Linear01Depth&lt;/code&gt;, &lt;code&gt;LinearEyeDepth&lt;/code&gt; 等。&lt;/p&gt;
&lt;p&gt;这不是我这里讨论的重点，我想说的是，本来我的相机设置为正交投影，深度应该是线性的，但我测试出来却不是线性。然后我用上面链接介绍的方法来计算真实世界的深度，也一直都不正确，以至于一直计算不出真实的线性深度，不知道是Unity的Z_Buffer的问题还是什么，那位朋友知道的请教教我。当然，如果不需要真实的深度值，单单是比较深度的大小之类的，用上面的方法就足够了，而且很简单。但是对于我这里来说，我想要把真实深度映射为颜色值，需要获得真实的线性的深度值（虽然也是[0, 1]），我只好用另外一种用 RenderWithShader 方法了。&lt;/p&gt;
&lt;h2 id=&#34;renderwithshader&#34;&gt;RenderWithShader 来获取深度图&lt;/h2&gt;
&lt;p&gt;这种方法其实就是用Unity Reference里面的一个例子：&lt;a href=&#34;http://docs.unity3d.com/Documentation/Components/SL-ShaderReplacement.html&#34;&gt;Rendering with Replaced Shaders&lt;/a&gt;。需要理解的是，&lt;code&gt;RenderWithShader&lt;/code&gt;会把场景中的相应的Mesh画一遍。&lt;/p&gt;
&lt;p&gt;创建一个 Shader :&lt;/p&gt;
&lt;div class=&#34;language-glsl highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-2-1&#34; name=&#34;__codelineno-2-1&#34; href=&#34;#__codelineno-2-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Shader&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Custom&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DepthByReplaceShader&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-2-2&#34; name=&#34;__codelineno-2-2&#34; href=&#34;#__codelineno-2-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-3&#34; name=&#34;__codelineno-2-3&#34; href=&#34;#__codelineno-2-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;SubShader&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-2-4&#34; name=&#34;__codelineno-2-4&#34; href=&#34;#__codelineno-2-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-5&#34; name=&#34;__codelineno-2-5&#34; href=&#34;#__codelineno-2-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Tags&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RenderType&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Opaque&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-6&#34; name=&#34;__codelineno-2-6&#34; href=&#34;#__codelineno-2-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Pass&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-7&#34; name=&#34;__codelineno-2-7&#34; href=&#34;#__codelineno-2-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Fog&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Mode&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Off&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-8&#34; name=&#34;__codelineno-2-8&#34; href=&#34;#__codelineno-2-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CGPROGRAM&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-9&#34; name=&#34;__codelineno-2-9&#34; href=&#34;#__codelineno-2-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#pragma vertex vert&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-10&#34; name=&#34;__codelineno-2-10&#34; href=&#34;#__codelineno-2-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#pragma fragment frag&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-11&#34; name=&#34;__codelineno-2-11&#34; href=&#34;#__codelineno-2-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#include &amp;quot;UnityCG.cginc&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-12&#34; name=&#34;__codelineno-2-12&#34; href=&#34;#__codelineno-2-12&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-13&#34; name=&#34;__codelineno-2-13&#34; href=&#34;#__codelineno-2-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v2f&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-14&#34; name=&#34;__codelineno-2-14&#34; href=&#34;#__codelineno-2-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;float4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SV_POSITION&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-15&#34; name=&#34;__codelineno-2-15&#34; href=&#34;#__codelineno-2-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;float2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;depth&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXCOORD0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-16&#34; name=&#34;__codelineno-2-16&#34; href=&#34;#__codelineno-2-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-17&#34; name=&#34;__codelineno-2-17&#34; href=&#34;#__codelineno-2-17&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-18&#34; name=&#34;__codelineno-2-18&#34; href=&#34;#__codelineno-2-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v2f&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vert&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;appdata_base&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-19&#34; name=&#34;__codelineno-2-19&#34; href=&#34;#__codelineno-2-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v2f&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-20&#34; name=&#34;__codelineno-2-20&#34; href=&#34;#__codelineno-2-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mul&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UNITY_MATRIX_MVP&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vertex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-21&#34; name=&#34;__codelineno-2-21&#34; href=&#34;#__codelineno-2-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UNITY_TRANSFER_DEPTH&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;depth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-22&#34; name=&#34;__codelineno-2-22&#34; href=&#34;#__codelineno-2-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-23&#34; name=&#34;__codelineno-2-23&#34; href=&#34;#__codelineno-2-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-24&#34; name=&#34;__codelineno-2-24&#34; href=&#34;#__codelineno-2-24&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-25&#34; name=&#34;__codelineno-2-25&#34; href=&#34;#__codelineno-2-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;float4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;frag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v2f&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;COLOR&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-26&#34; name=&#34;__codelineno-2-26&#34; href=&#34;#__codelineno-2-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//UNITY_OUTPUT_DEPTH(i.depth);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-27&#34; name=&#34;__codelineno-2-27&#34; href=&#34;#__codelineno-2-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;depth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;depth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-28&#34; name=&#34;__codelineno-2-28&#34; href=&#34;#__codelineno-2-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;float4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-29&#34; name=&#34;__codelineno-2-29&#34; href=&#34;#__codelineno-2-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-30&#34; name=&#34;__codelineno-2-30&#34; href=&#34;#__codelineno-2-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ENDCG&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-31&#34; name=&#34;__codelineno-2-31&#34; href=&#34;#__codelineno-2-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-32&#34; name=&#34;__codelineno-2-32&#34; href=&#34;#__codelineno-2-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-33&#34; name=&#34;__codelineno-2-33&#34; href=&#34;#__codelineno-2-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;为你的小地图相机(没有的话创建之)添加一个脚本，把相机配置成正交投影等，并且在 &lt;code&gt;Update()&lt;/code&gt; 里面使用这个 Shader 来渲染场景：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-3-1&#34; name=&#34;__codelineno-3-1&#34; href=&#34;#__codelineno-3-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;camera&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;targetTexture&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;depthTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-2&#34; name=&#34;__codelineno-3-2&#34; href=&#34;#__codelineno-3-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;camera&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RenderWithShader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;depthShader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;渲染的结果就会保存在 &lt;code&gt;depthTexture&lt;/code&gt;里面，很简单吧。&lt;/p&gt;
&lt;h2 id=&#34;_3&#34;&gt;把深度映射成颜色&lt;/h2&gt;
&lt;p&gt;要完成这个工作，首先需要一张颜色图，这张图可以用 Matlab 很简单地生成，例如我用的是 Matlab 里面的 jet 图：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2014-3-27-unity-depth-minimap/jet.png&#34; width=&#34;200&#34; /&gt;&lt;/p&gt;
&lt;p&gt;把这张图放到项目目录 &lt;code&gt;Assets\Resources&lt;/code&gt; 里面，就可以在程序中读取：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-4-1&#34; name=&#34;__codelineno-4-1&#34; href=&#34;#__codelineno-4-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;colorMap&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Load&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Texture2D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;colormap&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;需要注意的是，这张图片的 &lt;code&gt;Wrap Mode&lt;/code&gt; 应该是 &lt;code&gt;Clamp&lt;/code&gt;，防止在两边缘的颜色值之间进行插值。&lt;/p&gt;
&lt;p&gt;之后就需要使用 &lt;code&gt;OnRenderImage&lt;/code&gt; 和 &lt;code&gt;Graphics.Blit&lt;/code&gt; 函数，函数的原型为：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-5-1&#34; name=&#34;__codelineno-5-1&#34; href=&#34;#__codelineno-5-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;OnRenderImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RenderTexture&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RenderTexture&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-2&#34; name=&#34;__codelineno-5-2&#34; href=&#34;#__codelineno-5-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Blit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Texture&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RenderTexture&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Material&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pass&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这个函数的 src 是相机渲染的结果，dst 是处理后传回给相机的结果，因此这个函数通常是用来在相机渲染完成后做图片的一些效果，例如我们这里的对深度做颜色映射，还有边缘检测。做法就是在&lt;code&gt;OnRenderImage&lt;/code&gt;中调用&lt;code&gt;Graphics.Blit&lt;/code&gt;，传入特定的&lt;code&gt;Material&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-6-1&#34; name=&#34;__codelineno-6-1&#34; href=&#34;#__codelineno-6-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;depthEdgeMaterial&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;_DepthTex&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-2&#34; name=&#34;__codelineno-6-2&#34; href=&#34;#__codelineno-6-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Graphics&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Blit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;depthEdgeMaterial&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-3&#34; name=&#34;__codelineno-6-3&#34; href=&#34;#__codelineno-6-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;需要注意的是，&lt;code&gt;Graphics.Blit&lt;/code&gt;实际上做了这样一件事情：在相机前面画一个跟屏幕大小一样的平面，把&lt;code&gt;src&lt;/code&gt;作为这个平面的&lt;code&gt;_MainTex&lt;/code&gt;传进&lt;code&gt;Shader&lt;/code&gt;中，然后把结果放到&lt;code&gt;dst&lt;/code&gt;里面，而不是把实际场景中的Mesh重新画一遍。&lt;/p&gt;
&lt;p&gt;对颜色映射其实就是把深度 [0, 1] 看成图片的 uv，因为我想距离相机近的为红色，所以我对深度取了反：&lt;/p&gt;
&lt;div class=&#34;language-glsl highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-7-1&#34; name=&#34;__codelineno-7-1&#34; href=&#34;#__codelineno-7-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;half4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tex2D&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_ColorMap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;float2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;saturate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;depth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;_4&#34;&gt;边缘检测&lt;/h1&gt;
&lt;p&gt;边缘检测需要用到了相机自己的 &lt;code&gt;_CameraDepthNormalsTexture&lt;/code&gt;，主要是用 Normal 的值，深度还是用之前计算出来的。在 &lt;code&gt;_CameraDepthNormalsTexture&lt;/code&gt; 的每个像素 (x, y, z, w) 中，(x, y) 是法向，(z, w)是深度，法向是用了一种方法来存放的，有兴趣可以自己搜索。&lt;/p&gt;
&lt;p&gt;代码是参考了 Unity 自带的 Image Effect 里面的边缘检测，需要做的事情就是，比较当前像素的法向深度和邻近像素的差别，足够大我们就认为存在边缘：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-8-1&#34; name=&#34;__codelineno-8-1&#34; href=&#34;#__codelineno-8-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;inline&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;CheckSame&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;centerNormal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sampleNormal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;centerDepth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sampleDepth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-2&#34; name=&#34;__codelineno-8-2&#34; href=&#34;#__codelineno-8-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-3&#34; name=&#34;__codelineno-8-3&#34; href=&#34;#__codelineno-8-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// difference in normals&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-4&#34; name=&#34;__codelineno-8-4&#34; href=&#34;#__codelineno-8-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// do not bother decoding normals - there&amp;#39;s no need here&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-5&#34; name=&#34;__codelineno-8-5&#34; href=&#34;#__codelineno-8-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;diff&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;abs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;centerNormal&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sampleNormal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-6&#34; name=&#34;__codelineno-8-6&#34; href=&#34;#__codelineno-8-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isSameNormal&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;diff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;diff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-7&#34; name=&#34;__codelineno-8-7&#34; href=&#34;#__codelineno-8-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-8&#34; name=&#34;__codelineno-8-8&#34; href=&#34;#__codelineno-8-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// difference in depth&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-9&#34; name=&#34;__codelineno-8-9&#34; href=&#34;#__codelineno-8-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zdiff&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;abs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;centerDepth&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sampleDepth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-10&#34; name=&#34;__codelineno-8-10&#34; href=&#34;#__codelineno-8-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// scale the required threshold by the distance&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-11&#34; name=&#34;__codelineno-8-11&#34; href=&#34;#__codelineno-8-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isSameDepth&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zdiff&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.09&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;centerDepth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;centerDepth&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-12&#34; name=&#34;__codelineno-8-12&#34; href=&#34;#__codelineno-8-12&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-13&#34; name=&#34;__codelineno-8-13&#34; href=&#34;#__codelineno-8-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// return:&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-14&#34; name=&#34;__codelineno-8-14&#34; href=&#34;#__codelineno-8-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 1 - if normals and depth are similar enough&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-15&#34; name=&#34;__codelineno-8-15&#34; href=&#34;#__codelineno-8-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 0 - otherwise&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-16&#34; name=&#34;__codelineno-8-16&#34; href=&#34;#__codelineno-8-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isSameNormal&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isSameDepth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-17&#34; name=&#34;__codelineno-8-17&#34; href=&#34;#__codelineno-8-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;完整的 Shader 如下：&lt;/p&gt;
&lt;div class=&#34;language-glsl highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-9-1&#34; name=&#34;__codelineno-9-1&#34; href=&#34;#__codelineno-9-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Shader&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Custom&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DepthColorEdge&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-2&#34; name=&#34;__codelineno-9-2&#34; href=&#34;#__codelineno-9-2&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-3&#34; name=&#34;__codelineno-9-3&#34; href=&#34;#__codelineno-9-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Properties&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-9-4&#34; name=&#34;__codelineno-9-4&#34; href=&#34;#__codelineno-9-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-5&#34; name=&#34;__codelineno-9-5&#34; href=&#34;#__codelineno-9-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_DepthTex&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Depth&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Tex&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;D&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;white&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-6&#34; name=&#34;__codelineno-9-6&#34; href=&#34;#__codelineno-9-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_ColorMap&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Map&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;D&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;white&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-7&#34; name=&#34;__codelineno-9-7&#34; href=&#34;#__codelineno-9-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-8&#34; name=&#34;__codelineno-9-8&#34; href=&#34;#__codelineno-9-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SubShader&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-9-9&#34; name=&#34;__codelineno-9-9&#34; href=&#34;#__codelineno-9-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-10&#34; name=&#34;__codelineno-9-10&#34; href=&#34;#__codelineno-9-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Tags&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RenderType&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Opaque&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-11&#34; name=&#34;__codelineno-9-11&#34; href=&#34;#__codelineno-9-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOD&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-12&#34; name=&#34;__codelineno-9-12&#34; href=&#34;#__codelineno-9-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Pass&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-13&#34; name=&#34;__codelineno-9-13&#34; href=&#34;#__codelineno-9-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-14&#34; name=&#34;__codelineno-9-14&#34; href=&#34;#__codelineno-9-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ZTest&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Always&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Cull&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Off&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ZWrite&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Off&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-15&#34; name=&#34;__codelineno-9-15&#34; href=&#34;#__codelineno-9-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Fog&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Mode&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;off&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-16&#34; name=&#34;__codelineno-9-16&#34; href=&#34;#__codelineno-9-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CGPROGRAM&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-17&#34; name=&#34;__codelineno-9-17&#34; href=&#34;#__codelineno-9-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#pragma vertex vert&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-18&#34; name=&#34;__codelineno-9-18&#34; href=&#34;#__codelineno-9-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#pragma fragment frag&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-19&#34; name=&#34;__codelineno-9-19&#34; href=&#34;#__codelineno-9-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#include &amp;quot;UnityCG.cginc&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-20&#34; name=&#34;__codelineno-9-20&#34; href=&#34;#__codelineno-9-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;sampler2D&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_CameraDepthNormalsTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-21&#34; name=&#34;__codelineno-9-21&#34; href=&#34;#__codelineno-9-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;sampler2D&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_DepthTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-22&#34; name=&#34;__codelineno-9-22&#34; href=&#34;#__codelineno-9-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;uniform&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;float4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_DepthTex_TexelSize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-23&#34; name=&#34;__codelineno-9-23&#34; href=&#34;#__codelineno-9-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;sampler2D&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_ColorMap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-24&#34; name=&#34;__codelineno-9-24&#34; href=&#34;#__codelineno-9-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_ZNear&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-25&#34; name=&#34;__codelineno-9-25&#34; href=&#34;#__codelineno-9-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_ZFar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-26&#34; name=&#34;__codelineno-9-26&#34; href=&#34;#__codelineno-9-26&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-27&#34; name=&#34;__codelineno-9-27&#34; href=&#34;#__codelineno-9-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v2f&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-9-28&#34; name=&#34;__codelineno-9-28&#34; href=&#34;#__codelineno-9-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-29&#34; name=&#34;__codelineno-9-29&#34; href=&#34;#__codelineno-9-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;float4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SV_POSITION&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-30&#34; name=&#34;__codelineno-9-30&#34; href=&#34;#__codelineno-9-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;float2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TEXCOORD0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-31&#34; name=&#34;__codelineno-9-31&#34; href=&#34;#__codelineno-9-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-32&#34; name=&#34;__codelineno-9-32&#34; href=&#34;#__codelineno-9-32&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-33&#34; name=&#34;__codelineno-9-33&#34; href=&#34;#__codelineno-9-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v2f&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vert&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;appdata_base&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-34&#34; name=&#34;__codelineno-9-34&#34; href=&#34;#__codelineno-9-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-35&#34; name=&#34;__codelineno-9-35&#34; href=&#34;#__codelineno-9-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v2f&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-36&#34; name=&#34;__codelineno-9-36&#34; href=&#34;#__codelineno-9-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mul&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UNITY_MATRIX_MVP&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vertex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-37&#34; name=&#34;__codelineno-9-37&#34; href=&#34;#__codelineno-9-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mo&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MultiplyUV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UNITY_MATRIX_TEXTURE0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;texcoord&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-38&#34; name=&#34;__codelineno-9-38&#34; href=&#34;#__codelineno-9-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mo&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;float2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_DepthTex_TexelSize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_DepthTex_TexelSize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-39&#34; name=&#34;__codelineno-9-39&#34; href=&#34;#__codelineno-9-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mo&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;float2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_DepthTex_TexelSize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_DepthTex_TexelSize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-40&#34; name=&#34;__codelineno-9-40&#34; href=&#34;#__codelineno-9-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-41&#34; name=&#34;__codelineno-9-41&#34; href=&#34;#__codelineno-9-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-42&#34; name=&#34;__codelineno-9-42&#34; href=&#34;#__codelineno-9-42&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-43&#34; name=&#34;__codelineno-9-43&#34; href=&#34;#__codelineno-9-43&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-44&#34; name=&#34;__codelineno-9-44&#34; href=&#34;#__codelineno-9-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;inline&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;half&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CheckSame&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;centerNormal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sampleNormal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;centerDepth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sampleDepth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-45&#34; name=&#34;__codelineno-9-45&#34; href=&#34;#__codelineno-9-45&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-46&#34; name=&#34;__codelineno-9-46&#34; href=&#34;#__codelineno-9-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// difference in normals&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-47&#34; name=&#34;__codelineno-9-47&#34; href=&#34;#__codelineno-9-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// do not bother decoding normals - there&amp;#39;s no need here&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-48&#34; name=&#34;__codelineno-9-48&#34; href=&#34;#__codelineno-9-48&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;diff&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;abs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;centerNormal&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sampleNormal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-49&#34; name=&#34;__codelineno-9-49&#34; href=&#34;#__codelineno-9-49&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;half&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isSameNormal&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;diff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;diff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-50&#34; name=&#34;__codelineno-9-50&#34; href=&#34;#__codelineno-9-50&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-51&#34; name=&#34;__codelineno-9-51&#34; href=&#34;#__codelineno-9-51&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// difference in depth&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-52&#34; name=&#34;__codelineno-9-52&#34; href=&#34;#__codelineno-9-52&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zdiff&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;abs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;centerDepth&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sampleDepth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-53&#34; name=&#34;__codelineno-9-53&#34; href=&#34;#__codelineno-9-53&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// scale the required threshold by the distance&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-54&#34; name=&#34;__codelineno-9-54&#34; href=&#34;#__codelineno-9-54&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;half&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isSameDepth&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zdiff&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.09&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;centerDepth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;centerDepth&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-55&#34; name=&#34;__codelineno-9-55&#34; href=&#34;#__codelineno-9-55&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-56&#34; name=&#34;__codelineno-9-56&#34; href=&#34;#__codelineno-9-56&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// return:&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-57&#34; name=&#34;__codelineno-9-57&#34; href=&#34;#__codelineno-9-57&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 1 - if normals and depth are similar enough&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-58&#34; name=&#34;__codelineno-9-58&#34; href=&#34;#__codelineno-9-58&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 0 - otherwise&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-59&#34; name=&#34;__codelineno-9-59&#34; href=&#34;#__codelineno-9-59&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isSameNormal&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isSameDepth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-60&#34; name=&#34;__codelineno-9-60&#34; href=&#34;#__codelineno-9-60&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-61&#34; name=&#34;__codelineno-9-61&#34; href=&#34;#__codelineno-9-61&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-62&#34; name=&#34;__codelineno-9-62&#34; href=&#34;#__codelineno-9-62&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;frag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v2f&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;COLOR&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-9-63&#34; name=&#34;__codelineno-9-63&#34; href=&#34;#__codelineno-9-63&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-64&#34; name=&#34;__codelineno-9-64&#34; href=&#34;#__codelineno-9-64&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// get color based on depth&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-65&#34; name=&#34;__codelineno-9-65&#34; href=&#34;#__codelineno-9-65&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;depth&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tex2D&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_DepthTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mo&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-66&#34; name=&#34;__codelineno-9-66&#34; href=&#34;#__codelineno-9-66&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tex2D&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_ColorMap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;float2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;saturate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;depth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-67&#34; name=&#34;__codelineno-9-67&#34; href=&#34;#__codelineno-9-67&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-68&#34; name=&#34;__codelineno-9-68&#34; href=&#34;#__codelineno-9-68&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// detect normal diff&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-69&#34; name=&#34;__codelineno-9-69&#34; href=&#34;#__codelineno-9-69&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;centerNormal&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tex2D&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_CameraDepthNormalsTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mo&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-70&#34; name=&#34;__codelineno-9-70&#34; href=&#34;#__codelineno-9-70&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sampleNormal1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tex2D&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_CameraDepthNormalsTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-71&#34; name=&#34;__codelineno-9-71&#34; href=&#34;#__codelineno-9-71&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sampleNormal2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tex2D&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_CameraDepthNormalsTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-72&#34; name=&#34;__codelineno-9-72&#34; href=&#34;#__codelineno-9-72&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sampleDepth1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tex2D&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_DepthTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-73&#34; name=&#34;__codelineno-9-73&#34; href=&#34;#__codelineno-9-73&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sampleDepth2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tex2D&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_DepthTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-74&#34; name=&#34;__codelineno-9-74&#34; href=&#34;#__codelineno-9-74&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CheckSame&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;centerNormal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sampleNormal1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;depth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sampleDepth1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-75&#34; name=&#34;__codelineno-9-75&#34; href=&#34;#__codelineno-9-75&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CheckSame&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;centerNormal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sampleNormal2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;depth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sampleDepth2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-76&#34; name=&#34;__codelineno-9-76&#34; href=&#34;#__codelineno-9-76&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-77&#34; name=&#34;__codelineno-9-77&#34; href=&#34;#__codelineno-9-77&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-78&#34; name=&#34;__codelineno-9-78&#34; href=&#34;#__codelineno-9-78&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-79&#34; name=&#34;__codelineno-9-79&#34; href=&#34;#__codelineno-9-79&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ENDCG&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-80&#34; name=&#34;__codelineno-9-80&#34; href=&#34;#__codelineno-9-80&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-81&#34; name=&#34;__codelineno-9-81&#34; href=&#34;#__codelineno-9-81&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-9-82&#34; name=&#34;__codelineno-9-82&#34; href=&#34;#__codelineno-9-82&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-83&#34; name=&#34;__codelineno-9-83&#34; href=&#34;#__codelineno-9-83&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FallBack&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Diffuse&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-9-84&#34; name=&#34;__codelineno-9-84&#34; href=&#34;#__codelineno-9-84&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;结果类似于这个：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2014-3-27-unity-depth-minimap/topview.png&#34; width=&#34;200&#34; /&gt;&lt;/p&gt;
&lt;h1 id=&#34;_5&#34;&gt;混合真实世界图像&lt;/h1&gt;
&lt;p&gt;单单是深度的颜色图可能有点无趣，那么我们可以混合上真实场景的颜色图，只需要再建一个 Shader，传入前面的图像和相机的真实图像，在 &lt;code&gt;OnRenderImage&lt;/code&gt; 中进行混合：&lt;/p&gt;
&lt;div class=&#34;language-glsl highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-10-1&#34; name=&#34;__codelineno-10-1&#34; href=&#34;#__codelineno-10-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Shader&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Custom&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ColorMixDepth&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-2&#34; name=&#34;__codelineno-10-2&#34; href=&#34;#__codelineno-10-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Properties&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-3&#34; name=&#34;__codelineno-10-3&#34; href=&#34;#__codelineno-10-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_MainTex&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RGBA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;D&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;white&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-4&#34; name=&#34;__codelineno-10-4&#34; href=&#34;#__codelineno-10-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_DepthTex&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Depth&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RGBA&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;D&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;white&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-5&#34; name=&#34;__codelineno-10-5&#34; href=&#34;#__codelineno-10-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-6&#34; name=&#34;__codelineno-10-6&#34; href=&#34;#__codelineno-10-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SubShader&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-7&#34; name=&#34;__codelineno-10-7&#34; href=&#34;#__codelineno-10-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Tags&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RenderType&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Opaque&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-8&#34; name=&#34;__codelineno-10-8&#34; href=&#34;#__codelineno-10-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LOD&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-9&#34; name=&#34;__codelineno-10-9&#34; href=&#34;#__codelineno-10-9&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-10-10&#34; name=&#34;__codelineno-10-10&#34; href=&#34;#__codelineno-10-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CGPROGRAM&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-11&#34; name=&#34;__codelineno-10-11&#34; href=&#34;#__codelineno-10-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;#pragma surface surf Lambert&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-12&#34; name=&#34;__codelineno-10-12&#34; href=&#34;#__codelineno-10-12&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-10-13&#34; name=&#34;__codelineno-10-13&#34; href=&#34;#__codelineno-10-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;sampler2D&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_MainTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-14&#34; name=&#34;__codelineno-10-14&#34; href=&#34;#__codelineno-10-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;sampler2D&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_DepthTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-15&#34; name=&#34;__codelineno-10-15&#34; href=&#34;#__codelineno-10-15&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-10-16&#34; name=&#34;__codelineno-10-16&#34; href=&#34;#__codelineno-10-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-17&#34; name=&#34;__codelineno-10-17&#34; href=&#34;#__codelineno-10-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;float2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv_MainTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-18&#34; name=&#34;__codelineno-10-18&#34; href=&#34;#__codelineno-10-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;float2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv_DepthTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-19&#34; name=&#34;__codelineno-10-19&#34; href=&#34;#__codelineno-10-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-20&#34; name=&#34;__codelineno-10-20&#34; href=&#34;#__codelineno-10-20&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-10-21&#34; name=&#34;__codelineno-10-21&#34; href=&#34;#__codelineno-10-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;surf&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;inout&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SurfaceOutput&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-22&#34; name=&#34;__codelineno-10-22&#34; href=&#34;#__codelineno-10-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tex2D&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_MainTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv_MainTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-23&#34; name=&#34;__codelineno-10-23&#34; href=&#34;#__codelineno-10-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;half4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tex2D&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_DepthTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv_DepthTex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-24&#34; name=&#34;__codelineno-10-24&#34; href=&#34;#__codelineno-10-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//d = d.x == 1? 0 : d;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-25&#34; name=&#34;__codelineno-10-25&#34; href=&#34;#__codelineno-10-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Albedo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rgb&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rgb&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.9&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-26&#34; name=&#34;__codelineno-10-26&#34; href=&#34;#__codelineno-10-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Alpha&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-27&#34; name=&#34;__codelineno-10-27&#34; href=&#34;#__codelineno-10-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-28&#34; name=&#34;__codelineno-10-28&#34; href=&#34;#__codelineno-10-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ENDCG&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-29&#34; name=&#34;__codelineno-10-29&#34; href=&#34;#__codelineno-10-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-10-30&#34; name=&#34;__codelineno-10-30&#34; href=&#34;#__codelineno-10-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FallBack&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Diffuse&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-31&#34; name=&#34;__codelineno-10-31&#34; href=&#34;#__codelineno-10-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-11-1&#34; name=&#34;__codelineno-11-1&#34; href=&#34;#__codelineno-11-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;OnRenderImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RenderTexture&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RenderTexture&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-2&#34; name=&#34;__codelineno-11-2&#34; href=&#34;#__codelineno-11-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-3&#34; name=&#34;__codelineno-11-3&#34; href=&#34;#__codelineno-11-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// if now rendering depth map&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-4&#34; name=&#34;__codelineno-11-4&#34; href=&#34;#__codelineno-11-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isRenderDepth&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-5&#34; name=&#34;__codelineno-11-5&#34; href=&#34;#__codelineno-11-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-6&#34; name=&#34;__codelineno-11-6&#34; href=&#34;#__codelineno-11-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;depthEdgeMaterial&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;_DepthTex&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-7&#34; name=&#34;__codelineno-11-7&#34; href=&#34;#__codelineno-11-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isUseColorMap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-8&#34; name=&#34;__codelineno-11-8&#34; href=&#34;#__codelineno-11-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Graphics&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Blit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;depthEdgeMaterial&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-9&#34; name=&#34;__codelineno-11-9&#34; href=&#34;#__codelineno-11-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-10&#34; name=&#34;__codelineno-11-10&#34; href=&#34;#__codelineno-11-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Graphics&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Blit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-11&#34; name=&#34;__codelineno-11-11&#34; href=&#34;#__codelineno-11-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-12&#34; name=&#34;__codelineno-11-12&#34; href=&#34;#__codelineno-11-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-13&#34; name=&#34;__codelineno-11-13&#34; href=&#34;#__codelineno-11-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// else rendering real color scene, mix the real color with depth map&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-14&#34; name=&#34;__codelineno-11-14&#34; href=&#34;#__codelineno-11-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-15&#34; name=&#34;__codelineno-11-15&#34; href=&#34;#__codelineno-11-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-16&#34; name=&#34;__codelineno-11-16&#34; href=&#34;#__codelineno-11-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mixMaterial&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;_MainTex&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-17&#34; name=&#34;__codelineno-11-17&#34; href=&#34;#__codelineno-11-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mixMaterial&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SetTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;_DepthTex&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;depthTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-18&#34; name=&#34;__codelineno-11-18&#34; href=&#34;#__codelineno-11-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Graphics&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Blit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mixMaterial&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-19&#34; name=&#34;__codelineno-11-19&#34; href=&#34;#__codelineno-11-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ReleaseTexture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-20&#34; name=&#34;__codelineno-11-20&#34; href=&#34;#__codelineno-11-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-21&#34; name=&#34;__codelineno-11-21&#34; href=&#34;#__codelineno-11-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
上面的代码就是完成这个工作，需要理解的是，我们在调用 &lt;code&gt;RenderWithShader&lt;/code&gt; 的时候，&lt;code&gt;OnRenderImage&lt;/code&gt; 也会被调用，也就是这个函数被调用了两次，而两次调用需要完成的功能是不同的，所以我这里用一个变量来指示当前的渲染状态是做深度图还是混合。&lt;/p&gt;
&lt;h1 id=&#34;_6&#34;&gt;完整的代码&lt;/h1&gt;
&lt;p&gt;代码文件有点多，就放到这里了&lt;a href=&#34;../assets/img/2014-3-27-unity-depth-minimap/2014-3-27-unity-depth-minimap.zip&#34;&gt;depth-minimap&lt;/a&gt;。&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/unity-Unity%E7%94%BB%E6%B7%B1%E5%BA%A6%E5%9B%BE%E5%92%8C%E8%BE%B9%E7%BC%98%E6%A3%80%E6%B5%8B/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 30 Nov 2023 20:09:36 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/unity-Unity%E7%94%BB%E6%B7%B1%E5%BA%A6%E5%9B%BE%E5%92%8C%E8%BE%B9%E7%BC%98%E6%A3%80%E6%B5%8B/</guid>
      
    </item>
    
    <item>
      <title>Unity第三人称相机构建(上)</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;Unity第三人称相机构建(上)&#34; /&gt;&lt;/p&gt;
&lt;p&gt;我想在Unity中创建一个第三人称相机，相机的行为参考《魔兽世界》的第三人称相机，具体的需求是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;鼠标左键：控制相机围绕人物旋转，人物不旋转&lt;/li&gt;
&lt;li&gt;鼠标右键：控制相机围绕人物旋转，人物的前方向(Unity中的tranform.forward)相应旋转，人物上方向不变&lt;/li&gt;
&lt;li&gt;鼠标左键旋转后，再右键旋转，角色前方向马上根据左键的旋转做调整，再根据右键旋转，此时等价于两次都是右键旋转&lt;/li&gt;
&lt;li&gt;鼠标滚轮：控制相机远近&lt;/li&gt;
&lt;li&gt;相机不能穿过任何刚性物体&lt;/li&gt;
&lt;li&gt;相机在离开碰撞的刚性物体后，慢慢回到原来的距离上&lt;/li&gt;
&lt;li&gt;如果相机在碰到物体时，使用鼠标滚轮操作相机拉近，相机需要马上反应，此后第6点不再发生&lt;/li&gt;
&lt;li&gt;相机在旋转中碰到地面，停止围绕人物上下旋转，改为围绕自身上下旋转，左右旋转依然是围绕人物&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这个需求可以先分成两部分：相机旋转，相机刚性。简单起见，这里先来解决相机旋转的问题，也就是需求的前3点。&lt;/p&gt;
&lt;h2 id=&#34;_1&#34;&gt;相机位置表示&lt;/h2&gt;
&lt;p&gt;在正式解决相机操作前，还有一个问题需要解决：相机位置的表示。这可以用多种方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;相机的世界坐标&lt;/li&gt;
&lt;li&gt;相机相对于人物的坐标&lt;/li&gt;
&lt;li&gt;相机在人物坐标系中的方向和距离&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因为在我们的需求中，相机是根据人物位置进行变换的，所以我这里使用第三种方式，而且在控制中相机一直瞄准人物，所以在相机内只需要保存距离信息：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curDistance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;5F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;_2&#34;&gt;相机旋转&lt;/h2&gt;
&lt;p&gt;继续细分相机旋转的行为，可以分成左键旋转和右键旋转，下面我们来一步一步地完成这两个旋转。首先我把相机设为人物的子物体(children)，这样人物的一些基本的移动相机都会自动的跟踪。&lt;/p&gt;
&lt;h3 id=&#34;_3&#34;&gt;左键旋转&lt;/h3&gt;
&lt;p&gt;单单看左键旋转，需求很简单：&lt;strong&gt;相机旋转，人物不旋转&lt;/strong&gt;，这就相当于一个观察模型的相机，相机可以任意角度观察中心物体。&lt;/p&gt;
&lt;p&gt;在Unity中获取鼠标左键状态使用语句：&lt;code&gt;Input.GetMouseButton(0)&lt;/code&gt;（注：后面涉及到代码的地方，都是使用C#），明显，右键就是&lt;code&gt;Input.GetMouseButton(1)&lt;/code&gt;。获取鼠标光标的移动位置（可以理解为帧之间光标在X-Y上的偏移量）信息是：&lt;code&gt;Input.GetAxis(&#34;Mouse X&#34;); Input.GetAxis(&#34;Mouse Y&#34;)&lt;/code&gt;。那么我们可以先来获取鼠标左键按下后光标的移动信息：&lt;/p&gt;
&lt;div class=&#34;language-csharp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetMouseButton&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-2&#34; name=&#34;__codelineno-1-2&#34; href=&#34;#__codelineno-1-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-3&#34; name=&#34;__codelineno-1-3&#34; href=&#34;#__codelineno-1-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetAxis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Mouse X&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-4&#34; name=&#34;__codelineno-1-4&#34; href=&#34;#__codelineno-1-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetAxis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Mouse Y&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-5&#34; name=&#34;__codelineno-1-5&#34; href=&#34;#__codelineno-1-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;代码很简单，那下面就是关键的地方：如何控制相机来旋转。要理解旋转，这里需要一些关于四元数的知识（网上资料很多，这里就不列举了），四元数重要的一点是它可以很简单地构造旋转，特别是围绕某个向量的旋转，理解四元数后，实现相机围绕人物的旋转就不难了。&lt;/p&gt;
&lt;p&gt;另外还有一点要注意的是，四元数旋转轴只是一个向量，以原点为出发点，如果要以世界坐标系中的某点&lt;code&gt;O&lt;/code&gt;为原点，以该点为出发点的向量&lt;code&gt;V&lt;/code&gt;为旋转轴，就需要进行坐标系的变换，简单地说，就是把需要旋转的点&lt;code&gt;P&lt;/code&gt;变换到，以&lt;code&gt;O&lt;/code&gt;为原点的坐标系中，根据&lt;code&gt;V&lt;/code&gt;旋转，再变换会世界坐标系。根据这些操作，可以写出一个功能函数：&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-2-1&#34; name=&#34;__codelineno-2-1&#34; href=&#34;#__codelineno-2-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;MyRotate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;oldPosition&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;angle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;axis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;axisPosition&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-2&#34; name=&#34;__codelineno-2-2&#34; href=&#34;#__codelineno-2-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-3&#34; name=&#34;__codelineno-2-3&#34; href=&#34;#__codelineno-2-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 构造一个四元数，以axis为旋转轴，这是在人物坐标系中的旋转&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-4&#34; name=&#34;__codelineno-2-4&#34; href=&#34;#__codelineno-2-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Quaternion&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rotation&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Quaternion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AngleAxis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;angle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;axis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-5&#34; name=&#34;__codelineno-2-5&#34; href=&#34;#__codelineno-2-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 这里做的就是坐标系的变换，把相机的世界坐标变换到人物坐标系下的坐标&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-6&#34; name=&#34;__codelineno-2-6&#34; href=&#34;#__codelineno-2-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;oldPosition&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;axisPosition&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-7&#34; name=&#34;__codelineno-2-7&#34; href=&#34;#__codelineno-2-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 计算旋转并变换回世界坐标系中&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-8&#34; name=&#34;__codelineno-2-8&#34; href=&#34;#__codelineno-2-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;axisPosition&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rotation&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-9&#34; name=&#34;__codelineno-2-9&#34; href=&#34;#__codelineno-2-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;code&gt;Quaternion&lt;/code&gt;是Unity中表示四元数的类型，加上之前鼠标左键的检测，就可以完成左键控制相机左右旋转。&lt;/p&gt;
&lt;p&gt;鼠标左右移动控制相机左右旋转的代码就可以直接给出：&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-3-1&#34; name=&#34;__codelineno-3-1&#34; href=&#34;#__codelineno-3-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;newForward&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MyRotate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newForward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;up&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zero&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
因为这里只有前向量做旋转，没有涉及到坐标系的转换，所以第四个参数为&lt;code&gt;Vector3.zero&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;控制上下旋转比左右旋转难理解一点，因为此时的旋转轴是会一直变化的(这里假设人物的up一直是Y轴的正方向)。注意的相机也是一直在旋转，并且视点中心一直对准人物，那么相机的右方向(right)就是我们想要围绕着旋转的轴了(把相机right想象成人物的right)，这样理解，那么上下旋转的代码也很简单了：&lt;/p&gt;
&lt;div class=&#34;language-csharp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-4-1&#34; name=&#34;__codelineno-4-1&#34; href=&#34;#__codelineno-4-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;newForward&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MyRotate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newForward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;right&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zero&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;_4&#34;&gt;右键旋转&lt;/h3&gt;
&lt;p&gt;做了左键旋转，右键旋转就很简单了，只需要在左右旋转的时候设置人物的前方向：&lt;/p&gt;
&lt;div class=&#34;language-csharp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-5-1&#34; name=&#34;__codelineno-5-1&#34; href=&#34;#__codelineno-5-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;player&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;forward&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Normalize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;oldForward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;oldForward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;上下旋转跟左键的代码一样。&lt;/p&gt;
&lt;h3 id=&#34;_5&#34;&gt;先左键，后右键&lt;/h3&gt;
&lt;p&gt;上面虽然可以分别左键旋转，右键旋转，但是一旦先用左键旋转，再用右键操作的时候，问题就会出现：人物的前方向和相机的前方向不同了！那么相机和人物的正方向就从此分离，实际操作起来很奇怪。那么我们在用右键旋转的时候就要先把人物调整为跟相机的正方向一致：&lt;/p&gt;
&lt;div class=&#34;language-csharp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-6-1&#34; name=&#34;__codelineno-6-1&#34; href=&#34;#__codelineno-6-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;player&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;forward&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Normalize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;oldForward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;oldForward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;_6&#34;&gt;欧拉角万向锁&lt;/h3&gt;
&lt;p&gt;至此，相机的旋转差不多就完成，不过还有一个问题要注意：欧拉角万向锁。原理这里就不细讲，有兴趣的朋友可以自行搜索，针对这里相机的情况，就是当相机上下旋转到跟人物的上方向重合的时候，相机的视角会发生突变。这是因为相机到达人物的头顶或者脚底，相机的上方向会发生突变(因为相机的上方向的Y值一直都要大于零)，所以我们需要限制相机的上下旋转范围，防止发生万向锁。操作很简单，就是限制相机的前方向与人物的上方向的夹角的范围：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-7-1&#34; name=&#34;__codelineno-7-1&#34; href=&#34;#__codelineno-7-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Dot&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;forward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;up&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.95F&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-2&#34; name=&#34;__codelineno-7-2&#34; href=&#34;#__codelineno-7-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Dot&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;forward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;up&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.95F&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;_7&#34;&gt;完整代码&lt;/h3&gt;
&lt;div class=&#34;language-csharp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-8-1&#34; name=&#34;__codelineno-8-1&#34; href=&#34;#__codelineno-8-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// rotate oldPosition around a axis starting at axisPosition&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-2&#34; name=&#34;__codelineno-8-2&#34; href=&#34;#__codelineno-8-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;MyRotate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;oldPosition&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;angle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;axis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;axisPosition&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-3&#34; name=&#34;__codelineno-8-3&#34; href=&#34;#__codelineno-8-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-4&#34; name=&#34;__codelineno-8-4&#34; href=&#34;#__codelineno-8-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Quaternion&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rotation&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Quaternion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AngleAxis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;angle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;axis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-5&#34; name=&#34;__codelineno-8-5&#34; href=&#34;#__codelineno-8-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;oldPosition&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;axisPosition&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-6&#34; name=&#34;__codelineno-8-6&#34; href=&#34;#__codelineno-8-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;axisPosition&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rotation&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-7&#34; name=&#34;__codelineno-8-7&#34; href=&#34;#__codelineno-8-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-8&#34; name=&#34;__codelineno-8-8&#34; href=&#34;#__codelineno-8-8&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-9&#34; name=&#34;__codelineno-8-9&#34; href=&#34;#__codelineno-8-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// rotate oldForward, player forward may change when use mouse RB&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-10&#34; name=&#34;__codelineno-8-10&#34; href=&#34;#__codelineno-8-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;RotateIt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;oldForward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;up&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;right&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Transform&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;player&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-11&#34; name=&#34;__codelineno-8-11&#34; href=&#34;#__codelineno-8-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-12&#34; name=&#34;__codelineno-8-12&#34; href=&#34;#__codelineno-8-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newForward&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;oldForward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-13&#34; name=&#34;__codelineno-8-13&#34; href=&#34;#__codelineno-8-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// mouse LB RB rotate camera and character&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-14&#34; name=&#34;__codelineno-8-14&#34; href=&#34;#__codelineno-8-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetMouseButton&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;^&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetMouseButton&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-15&#34; name=&#34;__codelineno-8-15&#34; href=&#34;#__codelineno-8-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-16&#34; name=&#34;__codelineno-8-16&#34; href=&#34;#__codelineno-8-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetAxis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Mouse X&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rotateSpeed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-17&#34; name=&#34;__codelineno-8-17&#34; href=&#34;#__codelineno-8-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetAxis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Mouse Y&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rotateSpeed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-18&#34; name=&#34;__codelineno-8-18&#34; href=&#34;#__codelineno-8-18&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-19&#34; name=&#34;__codelineno-8-19&#34; href=&#34;#__codelineno-8-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-20&#34; name=&#34;__codelineno-8-20&#34; href=&#34;#__codelineno-8-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-21&#34; name=&#34;__codelineno-8-21&#34; href=&#34;#__codelineno-8-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newForward&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MyRotate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newForward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;up&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zero&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-22&#34; name=&#34;__codelineno-8-22&#34; href=&#34;#__codelineno-8-22&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-23&#34; name=&#34;__codelineno-8-23&#34; href=&#34;#__codelineno-8-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// mouse RB, character rotate together&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-24&#34; name=&#34;__codelineno-8-24&#34; href=&#34;#__codelineno-8-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetMouseButton&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-25&#34; name=&#34;__codelineno-8-25&#34; href=&#34;#__codelineno-8-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-26&#34; name=&#34;__codelineno-8-26&#34; href=&#34;#__codelineno-8-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;player&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;forward&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Normalize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;oldForward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-8-27&#34; name=&#34;__codelineno-8-27&#34; href=&#34;#__codelineno-8-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;oldForward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-28&#34; name=&#34;__codelineno-8-28&#34; href=&#34;#__codelineno-8-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-29&#34; name=&#34;__codelineno-8-29&#34; href=&#34;#__codelineno-8-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-30&#34; name=&#34;__codelineno-8-30&#34; href=&#34;#__codelineno-8-30&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-31&#34; name=&#34;__codelineno-8-31&#34; href=&#34;#__codelineno-8-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-32&#34; name=&#34;__codelineno-8-32&#34; href=&#34;#__codelineno-8-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-33&#34; name=&#34;__codelineno-8-33&#34; href=&#34;#__codelineno-8-33&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-34&#34; name=&#34;__codelineno-8-34&#34; href=&#34;#__codelineno-8-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Dot&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;forward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;up&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.95F&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-35&#34; name=&#34;__codelineno-8-35&#34; href=&#34;#__codelineno-8-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Dot&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;forward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;up&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.95F&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-36&#34; name=&#34;__codelineno-8-36&#34; href=&#34;#__codelineno-8-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-37&#34; name=&#34;__codelineno-8-37&#34; href=&#34;#__codelineno-8-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newForward&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MyRotate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newForward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;right&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zero&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-38&#34; name=&#34;__codelineno-8-38&#34; href=&#34;#__codelineno-8-38&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-39&#34; name=&#34;__codelineno-8-39&#34; href=&#34;#__codelineno-8-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-40&#34; name=&#34;__codelineno-8-40&#34; href=&#34;#__codelineno-8-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-41&#34; name=&#34;__codelineno-8-41&#34; href=&#34;#__codelineno-8-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-42&#34; name=&#34;__codelineno-8-42&#34; href=&#34;#__codelineno-8-42&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-8-43&#34; name=&#34;__codelineno-8-43&#34; href=&#34;#__codelineno-8-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newForward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-44&#34; name=&#34;__codelineno-8-44&#34; href=&#34;#__codelineno-8-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/unity-Unity%E7%AC%AC%E4%B8%89%E4%BA%BA%E7%A7%B0%E7%9B%B8%E6%9C%BA%E6%9E%84%E5%BB%BA%28%E4%B8%8A%29/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 30 Nov 2023 20:09:36 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/unity-Unity%E7%AC%AC%E4%B8%89%E4%BA%BA%E7%A7%B0%E7%9B%B8%E6%9C%BA%E6%9E%84%E5%BB%BA%28%E4%B8%8A%29/</guid>
      
    </item>
    
    <item>
      <title>Unity第三人称相机构建(下)</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;Unity第三人称相机构建(下)&#34; /&gt;&lt;/p&gt;
&lt;p&gt;上一集讲完了&lt;a href=&#34;../unity-Unity%E7%AC%AC%E4%B8%89%E4%BA%BA%E7%A7%B0%E7%9B%B8%E6%9C%BA%E6%9E%84%E5%BB%BA%28%E4%B8%8A%29/&#34;&gt;相机的旋转&lt;/a&gt;，那么现在我们要解决的问题是相机的刚性，要怎么做呢？&lt;/p&gt;
&lt;h2 id=&#34;_1&#34;&gt;相机刚性&lt;/h2&gt;
&lt;p&gt;回顾之前提的需求：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;鼠标滚轮：控制相机远近&lt;/li&gt;
&lt;li&gt;相机不能穿过任何刚性物体&lt;/li&gt;
&lt;li&gt;相机在离开碰撞的刚性物体后，慢慢回到原来的距离上&lt;/li&gt;
&lt;li&gt;如果相机在碰到刚体时，使用鼠标滚轮操作相机拉近，相机需要马上反应，此后第6点不再发生；碰撞地面后不能进行缩放操作&lt;/li&gt;
&lt;li&gt;相机在旋转中碰到地面，停止围绕人物上下旋转，改为围绕自身上下旋转，左右旋转依然是围绕人物&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这几点的意思是：相机在碰到刚性物体时，会被迫拉近跟人物的距离，那么我们想要相机在离开的时候，可以慢慢地回到原来的距离；但是如果在自动拉近距离后，用滚轮再手动拉近，说明相机离开碰撞的物体，那么这个拉近的距离就是相机的实际距离。下面我们来一点一点的解这些需求。&lt;/p&gt;
&lt;h2 id=&#34;_2&#34;&gt;滚轮控制&lt;/h2&gt;
&lt;p&gt;鼠标滚轮控制很简单，只需要知道获取滚轮信息是&lt;code&gt;Input.GetAxis(&#34;Mouse ScrollWheel&#34;)&lt;/code&gt;，并设定距离的最大值最小值就ok：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mouseWheelSensitivity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// control zoom speed&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mouseWheelZoomMin&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// min distance&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34; href=&#34;#__codelineno-0-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mouseWheelZoomMax&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// max distance&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-4&#34; name=&#34;__codelineno-0-4&#34; href=&#34;#__codelineno-0-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curDistance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;5F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-5&#34; name=&#34;__codelineno-0-5&#34; href=&#34;#__codelineno-0-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zoom&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetAxis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Mouse ScrollWheel&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-6&#34; name=&#34;__codelineno-0-6&#34; href=&#34;#__codelineno-0-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zoom&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-7&#34; name=&#34;__codelineno-0-7&#34; href=&#34;#__codelineno-0-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-8&#34; name=&#34;__codelineno-0-8&#34; href=&#34;#__codelineno-0-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;distance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curDistance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-9&#34; name=&#34;__codelineno-0-9&#34; href=&#34;#__codelineno-0-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;distance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zoom&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mouseWheelSensitivity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-10&#34; name=&#34;__codelineno-0-10&#34; href=&#34;#__codelineno-0-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;distance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Math&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Min&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mouseWheelZoomMax&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Math&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mouseWheelZoomMin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;distance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-11&#34; name=&#34;__codelineno-0-11&#34; href=&#34;#__codelineno-0-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;distance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-12&#34; name=&#34;__codelineno-0-12&#34; href=&#34;#__codelineno-0-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这里&lt;code&gt;playerTransform&lt;/code&gt;指向人物。&lt;/p&gt;
&lt;h2 id=&#34;_3&#34;&gt;不能穿过任何刚性物体&lt;/h2&gt;
&lt;p&gt;这需要检测相机跟刚体的接触，有一个函数可以实现这个功能：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Raycast&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Ray&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RaycastHit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hitInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;distance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Mathf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Infinity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;layerMask&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DefaultRaycastLayers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;具体用法参考Unity的&lt;a href=&#34;http://docs.unity3d.com/Documentation/ScriptReference/Physics.Raycast.html&#34;&gt;Reference&lt;/a&gt;，我们可以这样实现碰撞的检测：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-2-1&#34; name=&#34;__codelineno-2-1&#34; href=&#34;#__codelineno-2-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;RaycastHit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hitInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-2&#34; name=&#34;__codelineno-2-2&#34; href=&#34;#__codelineno-2-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Physics&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Raycast&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desiredPosition&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-3&#34; name=&#34;__codelineno-2-3&#34; href=&#34;#__codelineno-2-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hitInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desiredPosition&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;magnitude&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-4&#34; name=&#34;__codelineno-2-4&#34; href=&#34;#__codelineno-2-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-5&#34; name=&#34;__codelineno-2-5&#34; href=&#34;#__codelineno-2-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curDistance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hitInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;distance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-6&#34; name=&#34;__codelineno-2-6&#34; href=&#34;#__codelineno-2-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;targetPosition&lt;/code&gt;就是碰撞的位置，把相机的位置设到碰撞的位置就可以。&lt;/p&gt;
&lt;h2 id=&#34;_4&#34;&gt;离开刚体后，慢慢回到原来的距离上&lt;/h2&gt;
&lt;p&gt;要完成这个功能，首先要分别记录下相机应该处于的距离(&lt;code&gt;desiredDistance&lt;/code&gt;)和目前距离(&lt;code&gt;curDistance&lt;/code&gt;)，把滚轮操作的结果用&lt;code&gt;desiredDistance&lt;/code&gt;先存起来，再根据碰撞计算物体的新距离；
在检测到相机离开刚体，或者碰撞到更远的刚体时候，不能直接把碰撞的位置赋值给相机，需要用一个移动速度来向新的距离移动。先来获取新的距离：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-3-1&#34; name=&#34;__codelineno-3-1&#34; href=&#34;#__codelineno-3-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newDistance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desiredDistance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-2&#34; name=&#34;__codelineno-3-2&#34; href=&#34;#__codelineno-3-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;RaycastHit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hitInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-3&#34; name=&#34;__codelineno-3-3&#34; href=&#34;#__codelineno-3-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Physics&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Raycast&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desiredPosition&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-4&#34; name=&#34;__codelineno-3-4&#34; href=&#34;#__codelineno-3-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hitInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desiredPosition&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;magnitude&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-5&#34; name=&#34;__codelineno-3-5&#34; href=&#34;#__codelineno-3-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-6&#34; name=&#34;__codelineno-3-6&#34; href=&#34;#__codelineno-3-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newDistance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hitInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;distance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-7&#34; name=&#34;__codelineno-3-7&#34; href=&#34;#__codelineno-3-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;那么怎么判断相机正在向更远的距离移动呢？可以用&lt;code&gt;newDistances&lt;/code&gt;和当前的距离进行比较：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-4-1&#34; name=&#34;__codelineno-4-1&#34; href=&#34;#__codelineno-4-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// 向更近的距离移动&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-2&#34; name=&#34;__codelineno-4-2&#34; href=&#34;#__codelineno-4-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newDistance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curDistance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-3&#34; name=&#34;__codelineno-4-3&#34; href=&#34;#__codelineno-4-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-4&#34; name=&#34;__codelineno-4-4&#34; href=&#34;#__codelineno-4-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curDistance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newDistance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-5&#34; name=&#34;__codelineno-4-5&#34; href=&#34;#__codelineno-4-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-6&#34; name=&#34;__codelineno-4-6&#34; href=&#34;#__codelineno-4-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// 向更远的距离移动&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-7&#34; name=&#34;__codelineno-4-7&#34; href=&#34;#__codelineno-4-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newDistance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curDistance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-8&#34; name=&#34;__codelineno-4-8&#34; href=&#34;#__codelineno-4-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-9&#34; name=&#34;__codelineno-4-9&#34; href=&#34;#__codelineno-4-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;那么判断到向更远距离移动后，就很直观了，直接加个速度来移动：&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-5-1&#34; name=&#34;__codelineno-5-1&#34; href=&#34;#__codelineno-5-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;curDistance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Math&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Min&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curDistance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;deltaTime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;autoZoomOutSpeed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newDistance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
相机的大致行为我们已经完成了，还有一些细节需要处理。&lt;/p&gt;
&lt;h2 id=&#34;_5&#34;&gt;碰到刚体后滚轮拉近，地面不缩放&lt;/h2&gt;
&lt;p&gt;这里有两个要求：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;碰到刚体后只能拉近，不能拉远&lt;/li&gt;
&lt;li&gt;碰到地面后不能缩放&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;首先用变量来保存相机的碰撞状态：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-6-1&#34; name=&#34;__codelineno-6-1&#34; href=&#34;#__codelineno-6-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isHitGround&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 表示是否碰撞地面&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-2&#34; name=&#34;__codelineno-6-2&#34; href=&#34;#__codelineno-6-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isHitObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 表示是否碰撞刚体(除开地面)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;在判断滚轮缩放的时候加上条件判断：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-7-1&#34; name=&#34;__codelineno-7-1&#34; href=&#34;#__codelineno-7-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zoom&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0F&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isHitGround&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isHitObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zoom&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-2&#34; name=&#34;__codelineno-7-2&#34; href=&#34;#__codelineno-7-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-3&#34; name=&#34;__codelineno-7-3&#34; href=&#34;#__codelineno-7-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// calculate distance&lt;/span&gt;
&lt;a id=&#34;__codelineno-7-4&#34; name=&#34;__codelineno-7-4&#34; href=&#34;#__codelineno-7-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;_6&#34;&gt;碰到地面绕自身上下旋转&lt;/h2&gt;
&lt;p&gt;这个功能实现起来有点麻烦，需要因为这时候我们之前假设相机一直对准人物不成立了，这时分成两个向量：&lt;strong&gt;相机自身的朝向(&lt;code&gt;desireForward&lt;/code&gt;)&lt;/strong&gt;和&lt;strong&gt;人物到相机的方向(&lt;code&gt;cameraToPlayer&lt;/code&gt;)&lt;/strong&gt;，分别计算这两个向量的值，前者就决定相机的朝向，后者就决定相机的位置。为了方便，把&lt;a href=&#34;../unity-Unity%E7%AC%AC%E4%B8%89%E4%BA%BA%E7%A7%B0%E7%9B%B8%E6%9C%BA%E6%9E%84%E5%BB%BA%28%E4%B8%8A%29/&#34;&gt;上一集&lt;/a&gt;的旋转函数拆成X旋转(&lt;code&gt;RotateX&lt;/code&gt;)和Y旋转(&lt;code&gt;RotateY&lt;/code&gt;)，那么在计算&lt;code&gt;cameraToPlayer&lt;/code&gt;的&lt;code&gt;RotateY&lt;/code&gt;时加上条件：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-8-1&#34; name=&#34;__codelineno-8-1&#34; href=&#34;#__codelineno-8-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isHitGround&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-8-2&#34; name=&#34;__codelineno-8-2&#34; href=&#34;#__codelineno-8-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isHitGround&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;forward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cameraToPlayer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yAngle&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-3&#34; name=&#34;__codelineno-8-3&#34; href=&#34;#__codelineno-8-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-4&#34; name=&#34;__codelineno-8-4&#34; href=&#34;#__codelineno-8-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cameraToPlayer&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RotateY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cameraToPlayer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;up&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-8-5&#34; name=&#34;__codelineno-8-5&#34; href=&#34;#__codelineno-8-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;right&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yAngle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-8-6&#34; name=&#34;__codelineno-8-6&#34; href=&#34;#__codelineno-8-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这个条件有两部分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;没有碰到地面&lt;/li&gt;
&lt;li&gt;碰到地面，但是准备离开地面&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;然后用&lt;code&gt;cameraToPlayer&lt;/code&gt;计算相机的位置：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-9-1&#34; name=&#34;__codelineno-9-1&#34; href=&#34;#__codelineno-9-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cameraToPlayer&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curDistance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;并且在有需要的时候(也就是碰到地面)计算相机的朝向：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-10-1&#34; name=&#34;__codelineno-10-1&#34; href=&#34;#__codelineno-10-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isHitGround&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-2&#34; name=&#34;__codelineno-10-2&#34; href=&#34;#__codelineno-10-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-3&#34; name=&#34;__codelineno-10-3&#34; href=&#34;#__codelineno-10-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LookAt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-4&#34; name=&#34;__codelineno-10-4&#34; href=&#34;#__codelineno-10-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-5&#34; name=&#34;__codelineno-10-5&#34; href=&#34;#__codelineno-10-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-6&#34; name=&#34;__codelineno-10-6&#34; href=&#34;#__codelineno-10-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-7&#34; name=&#34;__codelineno-10-7&#34; href=&#34;#__codelineno-10-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desireForward&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RotateX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desireForward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;up&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xAngle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-8&#34; name=&#34;__codelineno-10-8&#34; href=&#34;#__codelineno-10-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desireForward&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RotateY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desireForward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;up&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;right&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yAngle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-9&#34; name=&#34;__codelineno-10-9&#34; href=&#34;#__codelineno-10-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;forward&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desireForward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-10-10&#34; name=&#34;__codelineno-10-10&#34; href=&#34;#__codelineno-10-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这样相机的行为我们都实现了。&lt;/p&gt;
&lt;p&gt;完整代码：&lt;/p&gt;
&lt;div class=&#34;language-c# highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-11-1&#34; name=&#34;__codelineno-11-1&#34; href=&#34;#__codelineno-11-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;UnityEngine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-2&#34; name=&#34;__codelineno-11-2&#34; href=&#34;#__codelineno-11-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;System&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-3&#34; name=&#34;__codelineno-11-3&#34; href=&#34;#__codelineno-11-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;System.Collections&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-4&#34; name=&#34;__codelineno-11-4&#34; href=&#34;#__codelineno-11-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-5&#34; name=&#34;__codelineno-11-5&#34; href=&#34;#__codelineno-11-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;c1&#34;&gt;// use a forward vector and distance to describe the camera position&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-6&#34; name=&#34;__codelineno-11-6&#34; href=&#34;#__codelineno-11-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;MyThirdPersonCamera&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MonoBehaviour&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-7&#34; name=&#34;__codelineno-11-7&#34; href=&#34;#__codelineno-11-7&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-8&#34; name=&#34;__codelineno-11-8&#34; href=&#34;#__codelineno-11-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;private&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Transform&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// reference to player&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-9&#34; name=&#34;__codelineno-11-9&#34; href=&#34;#__codelineno-11-9&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-10&#34; name=&#34;__codelineno-11-10&#34; href=&#34;#__codelineno-11-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mouseWheelSensitivity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// control zoom speed&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-11&#34; name=&#34;__codelineno-11-11&#34; href=&#34;#__codelineno-11-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mouseWheelZoomMin&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// min distance&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-12&#34; name=&#34;__codelineno-11-12&#34; href=&#34;#__codelineno-11-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mouseWheelZoomMax&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// max distance&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-13&#34; name=&#34;__codelineno-11-13&#34; href=&#34;#__codelineno-11-13&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-14&#34; name=&#34;__codelineno-11-14&#34; href=&#34;#__codelineno-11-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rotateSpeed&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;5F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// speed of rotate around player    &lt;/span&gt;
&lt;a id=&#34;__codelineno-11-15&#34; name=&#34;__codelineno-11-15&#34; href=&#34;#__codelineno-11-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;autoZoomOutSpeed&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;10F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// speed of auto zoom out, camera will auto zoom out &lt;/span&gt;
&lt;a id=&#34;__codelineno-11-16&#34; name=&#34;__codelineno-11-16&#34; href=&#34;#__codelineno-11-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                                            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// to pre distance when stop colliding object&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-17&#34; name=&#34;__codelineno-11-17&#34; href=&#34;#__codelineno-11-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curDistance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;5F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                 &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// distance to player&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-18&#34; name=&#34;__codelineno-11-18&#34; href=&#34;#__codelineno-11-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desiredDistance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;5F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;             &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// distance should be      &lt;/span&gt;
&lt;a id=&#34;__codelineno-11-19&#34; name=&#34;__codelineno-11-19&#34; href=&#34;#__codelineno-11-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isHitGround&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;               &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// hit ground flag&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-20&#34; name=&#34;__codelineno-11-20&#34; href=&#34;#__codelineno-11-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isHitObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;               &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// hit object(except ground) flag&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-21&#34; name=&#34;__codelineno-11-21&#34; href=&#34;#__codelineno-11-21&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-22&#34; name=&#34;__codelineno-11-22&#34; href=&#34;#__codelineno-11-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Use this for initialization&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-23&#34; name=&#34;__codelineno-11-23&#34; href=&#34;#__codelineno-11-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Awake&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-24&#34; name=&#34;__codelineno-11-24&#34; href=&#34;#__codelineno-11-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-25&#34; name=&#34;__codelineno-11-25&#34; href=&#34;#__codelineno-11-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-26&#34; name=&#34;__codelineno-11-26&#34; href=&#34;#__codelineno-11-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-27&#34; name=&#34;__codelineno-11-27&#34; href=&#34;#__codelineno-11-27&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-28&#34; name=&#34;__codelineno-11-28&#34; href=&#34;#__codelineno-11-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Start&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-11-29&#34; name=&#34;__codelineno-11-29&#34; href=&#34;#__codelineno-11-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-30&#34; name=&#34;__codelineno-11-30&#34; href=&#34;#__codelineno-11-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;forward&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-11-31&#34; name=&#34;__codelineno-11-31&#34; href=&#34;#__codelineno-11-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curDistance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-32&#34; name=&#34;__codelineno-11-32&#34; href=&#34;#__codelineno-11-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LookAt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-33&#34; name=&#34;__codelineno-11-33&#34; href=&#34;#__codelineno-11-33&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-34&#34; name=&#34;__codelineno-11-34&#34; href=&#34;#__codelineno-11-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-35&#34; name=&#34;__codelineno-11-35&#34; href=&#34;#__codelineno-11-35&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-36&#34; name=&#34;__codelineno-11-36&#34; href=&#34;#__codelineno-11-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Update is called once per frame&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-37&#34; name=&#34;__codelineno-11-37&#34; href=&#34;#__codelineno-11-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Update&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-11-38&#34; name=&#34;__codelineno-11-38&#34; href=&#34;#__codelineno-11-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-39&#34; name=&#34;__codelineno-11-39&#34; href=&#34;#__codelineno-11-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cameraToPlayer&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-11-40&#34; name=&#34;__codelineno-11-40&#34; href=&#34;#__codelineno-11-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;normalized&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-41&#34; name=&#34;__codelineno-11-41&#34; href=&#34;#__codelineno-11-41&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-42&#34; name=&#34;__codelineno-11-42&#34; href=&#34;#__codelineno-11-42&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desireForward&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;forward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-43&#34; name=&#34;__codelineno-11-43&#34; href=&#34;#__codelineno-11-43&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-44&#34; name=&#34;__codelineno-11-44&#34; href=&#34;#__codelineno-11-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// get new distance of zoom&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-45&#34; name=&#34;__codelineno-11-45&#34; href=&#34;#__codelineno-11-45&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desiredDistance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ZoomIt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curDistance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desiredDistance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-46&#34; name=&#34;__codelineno-11-46&#34; href=&#34;#__codelineno-11-46&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-47&#34; name=&#34;__codelineno-11-47&#34; href=&#34;#__codelineno-11-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xAngle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yAngle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-48&#34; name=&#34;__codelineno-11-48&#34; href=&#34;#__codelineno-11-48&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isRightDown&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-49&#34; name=&#34;__codelineno-11-49&#34; href=&#34;#__codelineno-11-49&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-50&#34; name=&#34;__codelineno-11-50&#34; href=&#34;#__codelineno-11-50&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// get mouse LB, RB status&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-51&#34; name=&#34;__codelineno-11-51&#34; href=&#34;#__codelineno-11-51&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetMouseButtonStatus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xAngle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yAngle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isRightDown&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-52&#34; name=&#34;__codelineno-11-52&#34; href=&#34;#__codelineno-11-52&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-53&#34; name=&#34;__codelineno-11-53&#34; href=&#34;#__codelineno-11-53&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// rotate camera by x-axis movement&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-54&#34; name=&#34;__codelineno-11-54&#34; href=&#34;#__codelineno-11-54&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cameraToPlayer&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RotateX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cameraToPlayer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;up&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xAngle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-55&#34; name=&#34;__codelineno-11-55&#34; href=&#34;#__codelineno-11-55&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-56&#34; name=&#34;__codelineno-11-56&#34; href=&#34;#__codelineno-11-56&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// if RB on, change player orientation&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-57&#34; name=&#34;__codelineno-11-57&#34; href=&#34;#__codelineno-11-57&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isRightDown&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-58&#34; name=&#34;__codelineno-11-58&#34; href=&#34;#__codelineno-11-58&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-59&#34; name=&#34;__codelineno-11-59&#34; href=&#34;#__codelineno-11-59&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;forward&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Normalize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cameraToPlayer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-60&#34; name=&#34;__codelineno-11-60&#34; href=&#34;#__codelineno-11-60&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cameraToPlayer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-61&#34; name=&#34;__codelineno-11-61&#34; href=&#34;#__codelineno-11-61&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-62&#34; name=&#34;__codelineno-11-62&#34; href=&#34;#__codelineno-11-62&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-63&#34; name=&#34;__codelineno-11-63&#34; href=&#34;#__codelineno-11-63&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// rotate camera by y-axis, if camera is not on ground or camera is going to leave ground&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-64&#34; name=&#34;__codelineno-11-64&#34; href=&#34;#__codelineno-11-64&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isHitGround&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-11-65&#34; name=&#34;__codelineno-11-65&#34; href=&#34;#__codelineno-11-65&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isHitGround&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;forward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cameraToPlayer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yAngle&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-66&#34; name=&#34;__codelineno-11-66&#34; href=&#34;#__codelineno-11-66&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-67&#34; name=&#34;__codelineno-11-67&#34; href=&#34;#__codelineno-11-67&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cameraToPlayer&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RotateY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cameraToPlayer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;up&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-68&#34; name=&#34;__codelineno-11-68&#34; href=&#34;#__codelineno-11-68&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;right&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yAngle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-69&#34; name=&#34;__codelineno-11-69&#34; href=&#34;#__codelineno-11-69&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-70&#34; name=&#34;__codelineno-11-70&#34; href=&#34;#__codelineno-11-70&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-71&#34; name=&#34;__codelineno-11-71&#34; href=&#34;#__codelineno-11-71&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// detect collision of camera to rigid body, get the distance camera should be&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-72&#34; name=&#34;__codelineno-11-72&#34; href=&#34;#__codelineno-11-72&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newDistance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DealWithCollision&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-11-73&#34; name=&#34;__codelineno-11-73&#34; href=&#34;#__codelineno-11-73&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cameraToPlayer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desiredDistance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ref&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isHitGround&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ref&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isHitObject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-74&#34; name=&#34;__codelineno-11-74&#34; href=&#34;#__codelineno-11-74&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-75&#34; name=&#34;__codelineno-11-75&#34; href=&#34;#__codelineno-11-75&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// check the distance&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-76&#34; name=&#34;__codelineno-11-76&#34; href=&#34;#__codelineno-11-76&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newDistance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curDistance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-77&#34; name=&#34;__codelineno-11-77&#34; href=&#34;#__codelineno-11-77&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-78&#34; name=&#34;__codelineno-11-78&#34; href=&#34;#__codelineno-11-78&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curDistance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newDistance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-79&#34; name=&#34;__codelineno-11-79&#34; href=&#34;#__codelineno-11-79&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-80&#34; name=&#34;__codelineno-11-80&#34; href=&#34;#__codelineno-11-80&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-81&#34; name=&#34;__codelineno-11-81&#34; href=&#34;#__codelineno-11-81&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-82&#34; name=&#34;__codelineno-11-82&#34; href=&#34;#__codelineno-11-82&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// now moving to farther position, use a speed to move it&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-83&#34; name=&#34;__codelineno-11-83&#34; href=&#34;#__codelineno-11-83&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curDistance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Math&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Min&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curDistance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;deltaTime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;autoZoomOutSpeed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-11-84&#34; name=&#34;__codelineno-11-84&#34; href=&#34;#__codelineno-11-84&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newDistance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-85&#34; name=&#34;__codelineno-11-85&#34; href=&#34;#__codelineno-11-85&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-86&#34; name=&#34;__codelineno-11-86&#34; href=&#34;#__codelineno-11-86&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-87&#34; name=&#34;__codelineno-11-87&#34; href=&#34;#__codelineno-11-87&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// now calculate the position&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-88&#34; name=&#34;__codelineno-11-88&#34; href=&#34;#__codelineno-11-88&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cameraToPlayer&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curDistance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-89&#34; name=&#34;__codelineno-11-89&#34; href=&#34;#__codelineno-11-89&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-90&#34; name=&#34;__codelineno-11-90&#34; href=&#34;#__codelineno-11-90&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// calculate the camera forward, if on ground, camera will rotate on self.Space&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-91&#34; name=&#34;__codelineno-11-91&#34; href=&#34;#__codelineno-11-91&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isHitGround&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-92&#34; name=&#34;__codelineno-11-92&#34; href=&#34;#__codelineno-11-92&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-93&#34; name=&#34;__codelineno-11-93&#34; href=&#34;#__codelineno-11-93&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LookAt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-94&#34; name=&#34;__codelineno-11-94&#34; href=&#34;#__codelineno-11-94&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-95&#34; name=&#34;__codelineno-11-95&#34; href=&#34;#__codelineno-11-95&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-96&#34; name=&#34;__codelineno-11-96&#34; href=&#34;#__codelineno-11-96&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-97&#34; name=&#34;__codelineno-11-97&#34; href=&#34;#__codelineno-11-97&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desireForward&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RotateX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desireForward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;up&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xAngle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-98&#34; name=&#34;__codelineno-11-98&#34; href=&#34;#__codelineno-11-98&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desireForward&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RotateY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desireForward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;up&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-99&#34; name=&#34;__codelineno-11-99&#34; href=&#34;#__codelineno-11-99&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;right&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yAngle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-100&#34; name=&#34;__codelineno-11-100&#34; href=&#34;#__codelineno-11-100&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;forward&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desireForward&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-101&#34; name=&#34;__codelineno-11-101&#34; href=&#34;#__codelineno-11-101&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-102&#34; name=&#34;__codelineno-11-102&#34; href=&#34;#__codelineno-11-102&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-103&#34; name=&#34;__codelineno-11-103&#34; href=&#34;#__codelineno-11-103&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-104&#34; name=&#34;__codelineno-11-104&#34; href=&#34;#__codelineno-11-104&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// zoom in and zoom out&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-105&#34; name=&#34;__codelineno-11-105&#34; href=&#34;#__codelineno-11-105&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ZoomIt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curDistance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desiredDistance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-106&#34; name=&#34;__codelineno-11-106&#34; href=&#34;#__codelineno-11-106&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-107&#34; name=&#34;__codelineno-11-107&#34; href=&#34;#__codelineno-11-107&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zoom&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetAxis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Mouse ScrollWheel&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-108&#34; name=&#34;__codelineno-11-108&#34; href=&#34;#__codelineno-11-108&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-109&#34; name=&#34;__codelineno-11-109&#34; href=&#34;#__codelineno-11-109&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//  zoom when hit rigid body and zoom in, or not on ground&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-110&#34; name=&#34;__codelineno-11-110&#34; href=&#34;#__codelineno-11-110&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zoom&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0F&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isHitGround&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isHitObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zoom&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-111&#34; name=&#34;__codelineno-11-111&#34; href=&#34;#__codelineno-11-111&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-112&#34; name=&#34;__codelineno-11-112&#34; href=&#34;#__codelineno-11-112&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;distance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;curDistance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-113&#34; name=&#34;__codelineno-11-113&#34; href=&#34;#__codelineno-11-113&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-114&#34; name=&#34;__codelineno-11-114&#34; href=&#34;#__codelineno-11-114&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;distance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zoom&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mouseWheelSensitivity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-115&#34; name=&#34;__codelineno-11-115&#34; href=&#34;#__codelineno-11-115&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;distance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Math&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Min&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mouseWheelZoomMax&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Math&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mouseWheelZoomMin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;distance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-116&#34; name=&#34;__codelineno-11-116&#34; href=&#34;#__codelineno-11-116&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-117&#34; name=&#34;__codelineno-11-117&#34; href=&#34;#__codelineno-11-117&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;distance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-118&#34; name=&#34;__codelineno-11-118&#34; href=&#34;#__codelineno-11-118&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-119&#34; name=&#34;__codelineno-11-119&#34; href=&#34;#__codelineno-11-119&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desiredDistance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-120&#34; name=&#34;__codelineno-11-120&#34; href=&#34;#__codelineno-11-120&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-121&#34; name=&#34;__codelineno-11-121&#34; href=&#34;#__codelineno-11-121&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-122&#34; name=&#34;__codelineno-11-122&#34; href=&#34;#__codelineno-11-122&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// rotate oldPosition around a axis starting at axisPosition&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-123&#34; name=&#34;__codelineno-11-123&#34; href=&#34;#__codelineno-11-123&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;RotateAroundAxis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;point&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;angle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;axis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;axisPosition&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-124&#34; name=&#34;__codelineno-11-124&#34; href=&#34;#__codelineno-11-124&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-125&#34; name=&#34;__codelineno-11-125&#34; href=&#34;#__codelineno-11-125&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Quaternion&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rotation&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Quaternion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AngleAxis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;angle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;axis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-126&#34; name=&#34;__codelineno-11-126&#34; href=&#34;#__codelineno-11-126&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;point&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;axisPosition&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-127&#34; name=&#34;__codelineno-11-127&#34; href=&#34;#__codelineno-11-127&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;axisPosition&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rotation&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-128&#34; name=&#34;__codelineno-11-128&#34; href=&#34;#__codelineno-11-128&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-129&#34; name=&#34;__codelineno-11-129&#34; href=&#34;#__codelineno-11-129&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-130&#34; name=&#34;__codelineno-11-130&#34; href=&#34;#__codelineno-11-130&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;GetMouseButtonStatus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isRightDown&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-131&#34; name=&#34;__codelineno-11-131&#34; href=&#34;#__codelineno-11-131&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-132&#34; name=&#34;__codelineno-11-132&#34; href=&#34;#__codelineno-11-132&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-133&#34; name=&#34;__codelineno-11-133&#34; href=&#34;#__codelineno-11-133&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isRightDown&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-134&#34; name=&#34;__codelineno-11-134&#34; href=&#34;#__codelineno-11-134&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetMouseButton&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;^&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetMouseButton&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-135&#34; name=&#34;__codelineno-11-135&#34; href=&#34;#__codelineno-11-135&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-136&#34; name=&#34;__codelineno-11-136&#34; href=&#34;#__codelineno-11-136&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetAxis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Mouse X&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rotateSpeed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-137&#34; name=&#34;__codelineno-11-137&#34; href=&#34;#__codelineno-11-137&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetAxis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;Mouse Y&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rotateSpeed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-138&#34; name=&#34;__codelineno-11-138&#34; href=&#34;#__codelineno-11-138&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetMouseButton&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-139&#34; name=&#34;__codelineno-11-139&#34; href=&#34;#__codelineno-11-139&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-140&#34; name=&#34;__codelineno-11-140&#34; href=&#34;#__codelineno-11-140&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isRightDown&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-141&#34; name=&#34;__codelineno-11-141&#34; href=&#34;#__codelineno-11-141&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-142&#34; name=&#34;__codelineno-11-142&#34; href=&#34;#__codelineno-11-142&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-143&#34; name=&#34;__codelineno-11-143&#34; href=&#34;#__codelineno-11-143&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-144&#34; name=&#34;__codelineno-11-144&#34; href=&#34;#__codelineno-11-144&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-145&#34; name=&#34;__codelineno-11-145&#34; href=&#34;#__codelineno-11-145&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// rotate vectorP2C(player to camera) around up while mouse x is on, return true if do rotate&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-146&#34; name=&#34;__codelineno-11-146&#34; href=&#34;#__codelineno-11-146&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;RotateX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vectorP2C&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;up&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;angle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-147&#34; name=&#34;__codelineno-11-147&#34; href=&#34;#__codelineno-11-147&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-148&#34; name=&#34;__codelineno-11-148&#34; href=&#34;#__codelineno-11-148&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newVector&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vectorP2C&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-149&#34; name=&#34;__codelineno-11-149&#34; href=&#34;#__codelineno-11-149&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;angle&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-150&#34; name=&#34;__codelineno-11-150&#34; href=&#34;#__codelineno-11-150&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-151&#34; name=&#34;__codelineno-11-151&#34; href=&#34;#__codelineno-11-151&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newVector&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RotateAroundAxis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newVector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;angle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;up&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zero&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-152&#34; name=&#34;__codelineno-11-152&#34; href=&#34;#__codelineno-11-152&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-153&#34; name=&#34;__codelineno-11-153&#34; href=&#34;#__codelineno-11-153&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newVector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-154&#34; name=&#34;__codelineno-11-154&#34; href=&#34;#__codelineno-11-154&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-155&#34; name=&#34;__codelineno-11-155&#34; href=&#34;#__codelineno-11-155&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-156&#34; name=&#34;__codelineno-11-156&#34; href=&#34;#__codelineno-11-156&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// rotate vectorP2C(player to camera) around right while mouse y is on, return true is do rotate&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-157&#34; name=&#34;__codelineno-11-157&#34; href=&#34;#__codelineno-11-157&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;RotateY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vectorP2C&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;up&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;right&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;angle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-158&#34; name=&#34;__codelineno-11-158&#34; href=&#34;#__codelineno-11-158&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-159&#34; name=&#34;__codelineno-11-159&#34; href=&#34;#__codelineno-11-159&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newVector&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vectorP2C&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-160&#34; name=&#34;__codelineno-11-160&#34; href=&#34;#__codelineno-11-160&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;angle&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-161&#34; name=&#34;__codelineno-11-161&#34; href=&#34;#__codelineno-11-161&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-162&#34; name=&#34;__codelineno-11-162&#34; href=&#34;#__codelineno-11-162&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Dot&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vectorP2C&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;up&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.99F&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;angle&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-163&#34; name=&#34;__codelineno-11-163&#34; href=&#34;#__codelineno-11-163&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Dot&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vectorP2C&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;up&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.99F&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;angle&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-164&#34; name=&#34;__codelineno-11-164&#34; href=&#34;#__codelineno-11-164&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-165&#34; name=&#34;__codelineno-11-165&#34; href=&#34;#__codelineno-11-165&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newVector&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RotateAroundAxis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newVector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;angle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;right&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zero&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-166&#34; name=&#34;__codelineno-11-166&#34; href=&#34;#__codelineno-11-166&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-167&#34; name=&#34;__codelineno-11-167&#34; href=&#34;#__codelineno-11-167&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-168&#34; name=&#34;__codelineno-11-168&#34; href=&#34;#__codelineno-11-168&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newVector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-169&#34; name=&#34;__codelineno-11-169&#34; href=&#34;#__codelineno-11-169&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-170&#34; name=&#34;__codelineno-11-170&#34; href=&#34;#__codelineno-11-170&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-171&#34; name=&#34;__codelineno-11-171&#34; href=&#34;#__codelineno-11-171&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// return distance if no collision, else return distance to rigid body&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-172&#34; name=&#34;__codelineno-11-172&#34; href=&#34;#__codelineno-11-172&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;DealWithCollision&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;origin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Vector3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;direction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;distance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;a id=&#34;__codelineno-11-173&#34; name=&#34;__codelineno-11-173&#34; href=&#34;#__codelineno-11-173&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ref&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ishitGround&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ref&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ishitObject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-174&#34; name=&#34;__codelineno-11-174&#34; href=&#34;#__codelineno-11-174&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-175&#34; name=&#34;__codelineno-11-175&#34; href=&#34;#__codelineno-11-175&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// collision detection&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-176&#34; name=&#34;__codelineno-11-176&#34; href=&#34;#__codelineno-11-176&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RaycastHit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hitInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-177&#34; name=&#34;__codelineno-11-177&#34; href=&#34;#__codelineno-11-177&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newDistance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;distance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-178&#34; name=&#34;__codelineno-11-178&#34; href=&#34;#__codelineno-11-178&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Physics&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Raycast&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;playerTransform&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;direction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hitInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desiredDistance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-179&#34; name=&#34;__codelineno-11-179&#34; href=&#34;#__codelineno-11-179&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-180&#34; name=&#34;__codelineno-11-180&#34; href=&#34;#__codelineno-11-180&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hitInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;collider&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TerrainCollider&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-181&#34; name=&#34;__codelineno-11-181&#34; href=&#34;#__codelineno-11-181&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-182&#34; name=&#34;__codelineno-11-182&#34; href=&#34;#__codelineno-11-182&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ishitGround&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-183&#34; name=&#34;__codelineno-11-183&#34; href=&#34;#__codelineno-11-183&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ishitObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-184&#34; name=&#34;__codelineno-11-184&#34; href=&#34;#__codelineno-11-184&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-185&#34; name=&#34;__codelineno-11-185&#34; href=&#34;#__codelineno-11-185&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-186&#34; name=&#34;__codelineno-11-186&#34; href=&#34;#__codelineno-11-186&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-187&#34; name=&#34;__codelineno-11-187&#34; href=&#34;#__codelineno-11-187&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ishitObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-188&#34; name=&#34;__codelineno-11-188&#34; href=&#34;#__codelineno-11-188&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ishitGround&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-189&#34; name=&#34;__codelineno-11-189&#34; href=&#34;#__codelineno-11-189&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-190&#34; name=&#34;__codelineno-11-190&#34; href=&#34;#__codelineno-11-190&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newDistance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hitInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;distance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-191&#34; name=&#34;__codelineno-11-191&#34; href=&#34;#__codelineno-11-191&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-192&#34; name=&#34;__codelineno-11-192&#34; href=&#34;#__codelineno-11-192&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-193&#34; name=&#34;__codelineno-11-193&#34; href=&#34;#__codelineno-11-193&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-194&#34; name=&#34;__codelineno-11-194&#34; href=&#34;#__codelineno-11-194&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ishitGround&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ishitObject&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-195&#34; name=&#34;__codelineno-11-195&#34; href=&#34;#__codelineno-11-195&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-196&#34; name=&#34;__codelineno-11-196&#34; href=&#34;#__codelineno-11-196&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-11-197&#34; name=&#34;__codelineno-11-197&#34; href=&#34;#__codelineno-11-197&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newDistance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-198&#34; name=&#34;__codelineno-11-198&#34; href=&#34;#__codelineno-11-198&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-11-199&#34; name=&#34;__codelineno-11-199&#34; href=&#34;#__codelineno-11-199&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/unity-Unity%E7%AC%AC%E4%B8%89%E4%BA%BA%E7%A7%B0%E7%9B%B8%E6%9C%BA%E6%9E%84%E5%BB%BA%28%E4%B8%8B%29/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 30 Nov 2023 20:09:36 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/unity-Unity%E7%AC%AC%E4%B8%89%E4%BA%BA%E7%A7%B0%E7%9B%B8%E6%9C%BA%E6%9E%84%E5%BB%BA%28%E4%B8%8B%29/</guid>
      
    </item>
    
    <item>
      <title>Home</title>
      
      
      
      
      <description>&lt;!-- no translate --&gt;

&lt;h1 id=&#34;disenones-wiki&#34;&gt;Disenone&#39;s Wiki&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/disenone/wiki_blog/actions&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://github.com/disenone/wiki_blog/actions/workflows/Build.yml/badge.svg?label=Build&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://github.com/disenone/wiki_blog/commits/main&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/github/last-commit/disenone/wiki_blog?color=FCD734&amp;amp;label=Last%20commit&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;contact-and-subscribe&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/Contact%20%26%20Subscribe-me-34ABE0?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;无止境&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Hi there~ 欢迎来到我的知识库。&lt;/p&gt;
&lt;p&gt;为了避免遗忘、便于分享，我在这里收录知识。
请随意浏览～&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;md-button&#34; href=&#34;cpp-C%E5%92%8CCpp%E7%9A%84%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0%E5%A4%84%E7%90%86%E6%80%BB%E7%BB%93/&#34;&gt;编程技术&lt;/a&gt;
&lt;a class=&#34;md-button&#34; href=&#34;game-%E6%B8%B8%E6%88%8FAOI%E7%AE%97%E6%B3%95%E8%A7%A3%E6%9E%90%E5%92%8C%E6%80%A7%E8%83%BD%E5%AE%9E%E6%B5%8B/&#34;&gt;游戏开发&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;md-button&#34; href=&#34;ue-%E6%8F%92%E4%BB%B6-AIChatPlus/&#34;&gt;UE.AIChatPlus&lt;/a&gt;&lt;/p&gt;</description>
      <link>https://wiki.disenone.site/zh-Hant/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 30 Nov 2023 20:09:36 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/zh-Hant/</guid>
      
    </item>
    
    <item>
      <title>Home</title>
      
      
      
      
      <description>&lt;!-- no translate --&gt;

&lt;h1 id=&#34;disenones-wiki&#34;&gt;Disenone&#39;s Wiki&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/disenone/wiki_blog/actions&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://github.com/disenone/wiki_blog/actions/workflows/Build.yml/badge.svg?label=Build&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://github.com/disenone/wiki_blog/commits/main&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/github/last-commit/disenone/wiki_blog?color=FCD734&amp;amp;label=Last%20commit&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;contact-and-subscribe&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/Contact%20%26%20Subscribe-me-34ABE0?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;无止境&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Hi there~ 欢迎来到我的知识库。&lt;/p&gt;
&lt;p&gt;为了避免遗忘、便于分享，我在这里收录知识。
请随意浏览～&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;md-button&#34; href=&#34;cpp-C%E5%92%8CCpp%E7%9A%84%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0%E5%A4%84%E7%90%86%E6%80%BB%E7%BB%93/&#34;&gt;编程技术&lt;/a&gt;
&lt;a class=&#34;md-button&#34; href=&#34;game-%E6%B8%B8%E6%88%8FAOI%E7%AE%97%E6%B3%95%E8%A7%A3%E6%9E%90%E5%92%8C%E6%80%A7%E8%83%BD%E5%AE%9E%E6%B5%8B/&#34;&gt;游戏开发&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;md-button&#34; href=&#34;ue-%E6%8F%92%E4%BB%B6-AIChatPlus/&#34;&gt;UE.AIChatPlus&lt;/a&gt;&lt;/p&gt;</description>
      <link>https://wiki.disenone.site/ja/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 30 Nov 2023 20:09:36 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ja/</guid>
      
    </item>
    
    <item>
      <title>Home</title>
      
      
      
      
      <description>&lt;!-- no translate --&gt;

&lt;h1 id=&#34;disenones-wiki&#34;&gt;Disenone&#39;s Wiki&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/disenone/wiki_blog/actions&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://github.com/disenone/wiki_blog/actions/workflows/Build.yml/badge.svg?label=Build&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://github.com/disenone/wiki_blog/commits/main&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/github/last-commit/disenone/wiki_blog?color=FCD734&amp;amp;label=Last%20commit&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;contact-and-subscribe&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/Contact%20%26%20Subscribe-me-34ABE0?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;无止境&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Hi there~ 欢迎来到我的知识库。&lt;/p&gt;
&lt;p&gt;为了避免遗忘、便于分享，我在这里收录知识。
请随意浏览～&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;md-button&#34; href=&#34;cpp-C%E5%92%8CCpp%E7%9A%84%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0%E5%A4%84%E7%90%86%E6%80%BB%E7%BB%93/&#34;&gt;编程技术&lt;/a&gt;
&lt;a class=&#34;md-button&#34; href=&#34;game-%E6%B8%B8%E6%88%8FAOI%E7%AE%97%E6%B3%95%E8%A7%A3%E6%9E%90%E5%92%8C%E6%80%A7%E8%83%BD%E5%AE%9E%E6%B5%8B/&#34;&gt;游戏开发&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;md-button&#34; href=&#34;ue-%E6%8F%92%E4%BB%B6-AIChatPlus/&#34;&gt;UE.AIChatPlus&lt;/a&gt;&lt;/p&gt;</description>
      <link>https://wiki.disenone.site/de/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 30 Nov 2023 20:09:36 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/de/</guid>
      
    </item>
    
    <item>
      <title>Home</title>
      
      
      
      
      <description>&lt;!-- no translate --&gt;

&lt;h1 id=&#34;disenones-wiki&#34;&gt;Disenone&#39;s Wiki&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/disenone/wiki_blog/actions&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://github.com/disenone/wiki_blog/actions/workflows/Build.yml/badge.svg?label=Build&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://github.com/disenone/wiki_blog/commits/main&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/github/last-commit/disenone/wiki_blog?color=FCD734&amp;amp;label=Last%20commit&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;contact-and-subscribe&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/Contact%20%26%20Subscribe-me-34ABE0?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;无止境&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Hi there~ 欢迎来到我的知识库。&lt;/p&gt;
&lt;p&gt;为了避免遗忘、便于分享，我在这里收录知识。
请随意浏览～&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;md-button&#34; href=&#34;cpp-C%E5%92%8CCpp%E7%9A%84%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0%E5%A4%84%E7%90%86%E6%80%BB%E7%BB%93/&#34;&gt;编程技术&lt;/a&gt;
&lt;a class=&#34;md-button&#34; href=&#34;game-%E6%B8%B8%E6%88%8FAOI%E7%AE%97%E6%B3%95%E8%A7%A3%E6%9E%90%E5%92%8C%E6%80%A7%E8%83%BD%E5%AE%9E%E6%B5%8B/&#34;&gt;游戏开发&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;md-button&#34; href=&#34;ue-%E6%8F%92%E4%BB%B6-AIChatPlus/&#34;&gt;UE.AIChatPlus&lt;/a&gt;&lt;/p&gt;</description>
      <link>https://wiki.disenone.site/fr/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 30 Nov 2023 20:09:36 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/fr/</guid>
      
    </item>
    
    <item>
      <title>Home</title>
      
      
      
      
      <description>&lt;!-- no translate --&gt;

&lt;h1 id=&#34;disenones-wiki&#34;&gt;Disenone&#39;s Wiki&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/disenone/wiki_blog/actions&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://github.com/disenone/wiki_blog/actions/workflows/Build.yml/badge.svg?label=Build&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://github.com/disenone/wiki_blog/commits/main&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/github/last-commit/disenone/wiki_blog?color=FCD734&amp;amp;label=Last%20commit&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;contact-and-subscribe&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/Contact%20%26%20Subscribe-me-34ABE0?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;无止境&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Hi there~ 欢迎来到我的知识库。&lt;/p&gt;
&lt;p&gt;为了避免遗忘、便于分享，我在这里收录知识。
请随意浏览～&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;md-button&#34; href=&#34;cpp-C%E5%92%8CCpp%E7%9A%84%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0%E5%A4%84%E7%90%86%E6%80%BB%E7%BB%93/&#34;&gt;编程技术&lt;/a&gt;
&lt;a class=&#34;md-button&#34; href=&#34;game-%E6%B8%B8%E6%88%8FAOI%E7%AE%97%E6%B3%95%E8%A7%A3%E6%9E%90%E5%92%8C%E6%80%A7%E8%83%BD%E5%AE%9E%E6%B5%8B/&#34;&gt;游戏开发&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;md-button&#34; href=&#34;ue-%E6%8F%92%E4%BB%B6-AIChatPlus/&#34;&gt;UE.AIChatPlus&lt;/a&gt;&lt;/p&gt;</description>
      <link>https://wiki.disenone.site/ar/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 30 Nov 2023 20:09:36 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ar/</guid>
      
    </item>
    
    <item>
      <title>Home</title>
      
      
      
      
      <description>&lt;!-- no translate --&gt;

&lt;h1 id=&#34;disenones-wiki&#34;&gt;Disenone&#39;s Wiki&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/disenone/wiki_blog/actions&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://github.com/disenone/wiki_blog/actions/workflows/Build.yml/badge.svg?label=Build&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;https://github.com/disenone/wiki_blog/commits/main&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/github/last-commit/disenone/wiki_blog?color=FCD734&amp;amp;label=Last%20commit&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;
&lt;a href=&#34;contact-and-subscribe&#34;&gt;&lt;img alt=&#34;badge&#34; loading=&#34;lazy&#34; src=&#34;https://img.shields.io/badge/Contact%20%26%20Subscribe-me-34ABE0?&amp;amp;style=flat-square&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;无止境&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Hi there~ 欢迎来到我的知识库。&lt;/p&gt;
&lt;p&gt;为了避免遗忘、便于分享，我在这里收录知识。
请随意浏览～&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;md-button&#34; href=&#34;cpp-C%E5%92%8CCpp%E7%9A%84%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0%E5%A4%84%E7%90%86%E6%80%BB%E7%BB%93/&#34;&gt;编程技术&lt;/a&gt;
&lt;a class=&#34;md-button&#34; href=&#34;game-%E6%B8%B8%E6%88%8FAOI%E7%AE%97%E6%B3%95%E8%A7%A3%E6%9E%90%E5%92%8C%E6%80%A7%E8%83%BD%E5%AE%9E%E6%B5%8B/&#34;&gt;游戏开发&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;md-button&#34; href=&#34;ue-%E6%8F%92%E4%BB%B6-AIChatPlus/&#34;&gt;UE.AIChatPlus&lt;/a&gt;&lt;/p&gt;</description>
      <link>https://wiki.disenone.site/ko/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 30 Nov 2023 20:09:36 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/ko/</guid>
      
    </item>
    
    <item>
      <title>游戏 AOI 算法解析和性能实测</title>
      
      
      
      
      <description>&lt;p&gt;&lt;meta property=&#34;og:title&#34; content=&#34;游戏 AOI 算法解析和性能实测&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_1&#34;&gt;引子&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;AOI&lt;/code&gt; (Area Of Interest) 在多人在线游戏中是很基本的功能，玩家需要接收进入视野范围内的其他玩家或者实体 (Entity) 的信息。计算玩家视野范围内存在哪些实体，有哪些实体进入或离开视野的算法，我们一般称之为 &lt;code&gt;AOI&lt;/code&gt; 算法。&lt;/p&gt;
&lt;p&gt;本文讨论九宫格和十字链两种 &lt;code&gt;AOI&lt;/code&gt; 算法，并给出两种算法的实测性能分析，让你用起来心中有数，遇事不慌。&lt;/p&gt;
&lt;p&gt;文中会提到玩家和实体两种词，实体是游戏中物体的概念，玩家是拥有 AOI 的实体。&lt;/p&gt;
&lt;p&gt;文中代码可在这里找到：&lt;a href=&#34;https://github.com/disenone/AoiTesting&#34;&gt;AoiTesting&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&#34;_2&#34;&gt;九宫格&lt;/h3&gt;
&lt;p&gt;所谓九宫格，是把场景内所有实体的位置按照格子划分，譬如划分成边长 200 的正方形，要找出中心玩家 AOI 范围内的其他实体，就把这个范围内涉及到的格子内的玩家都做一遍比较。&lt;/p&gt;
&lt;p&gt;例如场景每 100 毫秒会 Tick 一次，在 Tick 中我们可以这样更新玩家的 AOI：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;以玩家位置为中心，AOI 半径计算涉及到的格子集合&lt;/li&gt;
&lt;li&gt;对格子集合中的实体逐个计算跟玩家的距离&lt;/li&gt;
&lt;li&gt;距离小于 AOI 半径的实体集合则是玩家的新的 AOI&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;九宫格算法做起来很简单，算法用几句话就能描述清楚了，具体的性能分析我们留到后面，先来看看十字链表算法。&lt;/p&gt;
&lt;h3 id=&#34;_3&#34;&gt;十字链表&lt;/h3&gt;
&lt;p&gt;对于 3D 游戏，我们一般会给 X 轴和 Z 轴坐标分别构建有序的链表，每个实体在链表上都有一个节点，存放的是该坐标轴值，按照值递增的顺序来存放。但如果只是存放实体本身的坐标点，这两个链表做查询的效率依然很低。&lt;/p&gt;
&lt;p&gt;真正关键的是，我们在链表上还会给拥有 AOI 的每个玩家增加左右两个哨兵节点。两个哨兵的坐标值跟玩家本身坐标正好相差了 AOI 半径，譬如玩家 &lt;code&gt;P&lt;/code&gt; 坐标为 &lt;code&gt;(a, b, c)&lt;/code&gt;，AOI 半径为 &lt;code&gt;r&lt;/code&gt; ，那么在 X 轴上会有两个哨兵 &lt;code&gt;left_x, right_x&lt;/code&gt;，坐标值分别为 &lt;code&gt;a - r&lt;/code&gt; 和 &lt;code&gt;a + r&lt;/code&gt;。由于有哨兵的存在，我们通过跟踪哨兵跟其他实体节点的移动来更新 AOI。继续前面的例子，一个实体 &lt;code&gt;E&lt;/code&gt; 移动导致在 X 轴上的节点从 &lt;code&gt;left_x&lt;/code&gt; 的右边想左跨过 &lt;code&gt;left_x&lt;/code&gt; 来到 &lt;code&gt;left_x&lt;/code&gt; 的左边，那么说明 &lt;code&gt;E&lt;/code&gt; 肯定是离开了 &lt;code&gt;P&lt;/code&gt; 的 AOI；同理如果向右跨过了 &lt;code&gt;right_x&lt;/code&gt; 也是离开了 AOI。相反，如果是向右跨过 &lt;code&gt;left_x&lt;/code&gt;，或者向左跨过 &lt;code&gt;right_x&lt;/code&gt;，说明有可能会进入到 &lt;code&gt;P&lt;/code&gt; 的 AOI 中。&lt;/p&gt;
&lt;p&gt;可以看到，十字链表算法要比九宫格复杂得多，我们需要维护两条有序的链表，并且在每个实体坐标更新的时候，同步移动链表上的节点，并且在移动跨过其他节点时更新 AOI。&lt;/p&gt;
&lt;h3 id=&#34;_4&#34;&gt;九宫格的实现&lt;/h3&gt;
&lt;p&gt;因为涉及到实测的性能，所以我们先来稍微深入一点九宫格算法的实现细节：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-0-1&#34; name=&#34;__codelineno-0-1&#34; href=&#34;#__codelineno-0-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;Sensor&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-2&#34; name=&#34;__codelineno-0-2&#34; href=&#34;#__codelineno-0-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-3&#34; name=&#34;__codelineno-0-3&#34; href=&#34;#__codelineno-0-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Nuid&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sensor_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-4&#34; name=&#34;__codelineno-0-4&#34; href=&#34;#__codelineno-0-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;radius&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-5&#34; name=&#34;__codelineno-0-5&#34; href=&#34;#__codelineno-0-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;radius_square&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-6&#34; name=&#34;__codelineno-0-6&#34; href=&#34;#__codelineno-0-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PlayerPtrList&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;aoi_players&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-7&#34; name=&#34;__codelineno-0-7&#34; href=&#34;#__codelineno-0-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-8&#34; name=&#34;__codelineno-0-8&#34; href=&#34;#__codelineno-0-8&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-0-9&#34; name=&#34;__codelineno-0-9&#34; href=&#34;#__codelineno-0-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;PlayerAoi&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-10&#34; name=&#34;__codelineno-0-10&#34; href=&#34;#__codelineno-0-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...    &lt;/span&gt;
&lt;a id=&#34;__codelineno-0-11&#34; name=&#34;__codelineno-0-11&#34; href=&#34;#__codelineno-0-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Nuid&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nuid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-12&#34; name=&#34;__codelineno-0-12&#34; href=&#34;#__codelineno-0-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SquareId&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;square_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-13&#34; name=&#34;__codelineno-0-13&#34; href=&#34;#__codelineno-0-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;square_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-14&#34; name=&#34;__codelineno-0-14&#34; href=&#34;#__codelineno-0-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-15&#34; name=&#34;__codelineno-0-15&#34; href=&#34;#__codelineno-0-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;last_pos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-16&#34; name=&#34;__codelineno-0-16&#34; href=&#34;#__codelineno-0-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Uint32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;flags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-17&#34; name=&#34;__codelineno-0-17&#34; href=&#34;#__codelineno-0-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vector&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Sensor&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sensors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-0-18&#34; name=&#34;__codelineno-0-18&#34; href=&#34;#__codelineno-0-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;PlayerAoi&lt;/code&gt; 存放玩家的数据，其中有一个 &lt;code&gt;sensors&lt;/code&gt; 数组，&lt;code&gt;sensors&lt;/code&gt; 就是用来计算一定范围内的实体，每次 &lt;code&gt;Tick&lt;/code&gt; 之后把计算出来的实体计划放在 &lt;code&gt;aoi_players&lt;/code&gt;。&lt;code&gt;aoi_players&lt;/code&gt; 是存放了两个数组，用于上一次 &lt;code&gt;Tick&lt;/code&gt; 结果做比较，求出进入和离开玩家。 &lt;code&gt;Tick&lt;/code&gt; 的大致流程是这样：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-1-1&#34; name=&#34;__codelineno-1-1&#34; href=&#34;#__codelineno-1-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;AoiUpdateInfos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;SquareAoi::Tick&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-2&#34; name=&#34;__codelineno-1-2&#34; href=&#34;#__codelineno-1-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AoiUpdateInfos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;update_infos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-3&#34; name=&#34;__codelineno-1-3&#34; href=&#34;#__codelineno-1-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PlayerPtrList&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;remove_list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-4&#34; name=&#34;__codelineno-1-4&#34; href=&#34;#__codelineno-1-4&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-5&#34; name=&#34;__codelineno-1-5&#34; href=&#34;#__codelineno-1-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;elem&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;player_map_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-6&#34; name=&#34;__codelineno-1-6&#34; href=&#34;#__codelineno-1-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;player&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;elem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;second&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-7&#34; name=&#34;__codelineno-1-7&#34; href=&#34;#__codelineno-1-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-8&#34; name=&#34;__codelineno-1-8&#34; href=&#34;#__codelineno-1-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 对有 sensors 的玩家计算 Aoi&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-9&#34; name=&#34;__codelineno-1-9&#34; href=&#34;#__codelineno-1-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;player&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sensors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;empty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-10&#34; name=&#34;__codelineno-1-10&#34; href=&#34;#__codelineno-1-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;update_info&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_UpdatePlayerAoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur_aoi_map_idx_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;player&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-11&#34; name=&#34;__codelineno-1-11&#34; href=&#34;#__codelineno-1-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;update_info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sensor_update_list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;empty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-12&#34; name=&#34;__codelineno-1-12&#34; href=&#34;#__codelineno-1-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;update_infos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;emplace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;update_info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nuid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;move&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;update_info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-13&#34; name=&#34;__codelineno-1-13&#34; href=&#34;#__codelineno-1-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-14&#34; name=&#34;__codelineno-1-14&#34; href=&#34;#__codelineno-1-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-15&#34; name=&#34;__codelineno-1-15&#34; href=&#34;#__codelineno-1-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-16&#34; name=&#34;__codelineno-1-16&#34; href=&#34;#__codelineno-1-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-17&#34; name=&#34;__codelineno-1-17&#34; href=&#34;#__codelineno-1-17&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-1-18&#34; name=&#34;__codelineno-1-18&#34; href=&#34;#__codelineno-1-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-19&#34; name=&#34;__codelineno-1-19&#34; href=&#34;#__codelineno-1-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// 记录玩家上次的位置&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-20&#34; name=&#34;__codelineno-1-20&#34; href=&#34;#__codelineno-1-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;elem&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;player_map_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-21&#34; name=&#34;__codelineno-1-21&#34; href=&#34;#__codelineno-1-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;player&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;elem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;second&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-22&#34; name=&#34;__codelineno-1-22&#34; href=&#34;#__codelineno-1-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;player&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;last_pos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;player&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-23&#34; name=&#34;__codelineno-1-23&#34; href=&#34;#__codelineno-1-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-24&#34; name=&#34;__codelineno-1-24&#34; href=&#34;#__codelineno-1-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur_aoi_map_idx_&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur_aoi_map_idx_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-25&#34; name=&#34;__codelineno-1-25&#34; href=&#34;#__codelineno-1-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;update_infos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-1-26&#34; name=&#34;__codelineno-1-26&#34; href=&#34;#__codelineno-1-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Tick&lt;/code&gt; 做的事情很简单，遍历有 &lt;code&gt;sensors&lt;/code&gt; 的玩家，逐个计算 &lt;code&gt;sensor&lt;/code&gt; 范围内的实体，即为 AOI。&lt;code&gt;last_pos&lt;/code&gt; 是用来参与判断实体是否有进入或者离开 AOI，&lt;code&gt;_UpdatePlayerAoi&lt;/code&gt; 的代码如下：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-2-1&#34; name=&#34;__codelineno-2-1&#34; href=&#34;#__codelineno-2-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;AoiUpdateInfo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;SquareAoi::_UpdatePlayerAoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Uint32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur_aoi_map_idx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PlayerAoi&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-2&#34; name=&#34;__codelineno-2-2&#34; href=&#34;#__codelineno-2-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AoiUpdateInfo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;aoi_update_info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-3&#34; name=&#34;__codelineno-2-3&#34; href=&#34;#__codelineno-2-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;aoi_update_info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nuid&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pptr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nuid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-4&#34; name=&#34;__codelineno-2-4&#34; href=&#34;#__codelineno-2-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Uint32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new_aoi_map_idx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur_aoi_map_idx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-5&#34; name=&#34;__codelineno-2-5&#34; href=&#34;#__codelineno-2-5&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-6&#34; name=&#34;__codelineno-2-6&#34; href=&#34;#__codelineno-2-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sensor&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pptr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sensors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-7&#34; name=&#34;__codelineno-2-7&#34; href=&#34;#__codelineno-2-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;old_aoi&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sensor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;aoi_players&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur_aoi_map_idx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-8&#34; name=&#34;__codelineno-2-8&#34; href=&#34;#__codelineno-2-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new_aoi&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sensor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;aoi_players&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new_aoi_map_idx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-9&#34; name=&#34;__codelineno-2-9&#34; href=&#34;#__codelineno-2-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;calc_aoi_players_func_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sensor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new_aoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-10&#34; name=&#34;__codelineno-2-10&#34; href=&#34;#__codelineno-2-10&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-11&#34; name=&#34;__codelineno-2-11&#34; href=&#34;#__codelineno-2-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SensorUpdateInfo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;update_info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-12&#34; name=&#34;__codelineno-2-12&#34; href=&#34;#__codelineno-2-12&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-13&#34; name=&#34;__codelineno-2-13&#34; href=&#34;#__codelineno-2-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;enters&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;update_info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;enters&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-14&#34; name=&#34;__codelineno-2-14&#34; href=&#34;#__codelineno-2-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;leaves&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;update_info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;leaves&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-15&#34; name=&#34;__codelineno-2-15&#34; href=&#34;#__codelineno-2-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;radius_square&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sensor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;radius_square&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-16&#34; name=&#34;__codelineno-2-16&#34; href=&#34;#__codelineno-2-16&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-17&#34; name=&#34;__codelineno-2-17&#34; href=&#34;#__codelineno-2-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_CheckLeave&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;radius_square&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;old_aoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;leaves&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-18&#34; name=&#34;__codelineno-2-18&#34; href=&#34;#__codelineno-2-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_CheckEnter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;radius_square&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new_aoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;enters&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-19&#34; name=&#34;__codelineno-2-19&#34; href=&#34;#__codelineno-2-19&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-20&#34; name=&#34;__codelineno-2-20&#34; href=&#34;#__codelineno-2-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;enters&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;empty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;leaves&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;empty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-21&#34; name=&#34;__codelineno-2-21&#34; href=&#34;#__codelineno-2-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-22&#34; name=&#34;__codelineno-2-22&#34; href=&#34;#__codelineno-2-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-23&#34; name=&#34;__codelineno-2-23&#34; href=&#34;#__codelineno-2-23&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-24&#34; name=&#34;__codelineno-2-24&#34; href=&#34;#__codelineno-2-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;update_info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sensor_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sensor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sensor_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-25&#34; name=&#34;__codelineno-2-25&#34; href=&#34;#__codelineno-2-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;aoi_update_info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sensor_update_list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;push_back&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;move&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;update_info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-26&#34; name=&#34;__codelineno-2-26&#34; href=&#34;#__codelineno-2-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-27&#34; name=&#34;__codelineno-2-27&#34; href=&#34;#__codelineno-2-27&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-2-28&#34; name=&#34;__codelineno-2-28&#34; href=&#34;#__codelineno-2-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;aoi_update_info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-2-29&#34; name=&#34;__codelineno-2-29&#34; href=&#34;#__codelineno-2-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;old_aoi&lt;/code&gt; 是上一个 &lt;code&gt;Tick&lt;/code&gt; 计算出来的 AOI，&lt;code&gt;new_aoi&lt;/code&gt; 是本次 &lt;code&gt;Tick&lt;/code&gt; 需要计算的 AOI。&lt;code&gt;new_aoi&lt;/code&gt; 通过遍历 AOI 范围内的所有格子的实体，选出跟玩家距离小于 AOI 半径来获得。之后用 &lt;code&gt;_CheckLeave&lt;/code&gt; 和 &lt;code&gt;_CheckEnter&lt;/code&gt; 两个函数，计算本次 &lt;code&gt;Tick&lt;/code&gt; 离开和进入 AOI 的实体，譬如如果 &lt;code&gt;new_aoi&lt;/code&gt; 中的实体 &lt;code&gt;last_pos&lt;/code&gt; 不在 AOI范围内，说明该实体是在本次 &lt;code&gt;Tick&lt;/code&gt; 进入到了 AOI 范围。具体的代码可以看源文件，这里不再赘述。&lt;/p&gt;
&lt;h3 id=&#34;_5&#34;&gt;十字链表的实现&lt;/h3&gt;
&lt;p&gt;相比起九宫格，十字链表实现起来更复杂，先来看基本的数据结构：&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-3-1&#34; name=&#34;__codelineno-3-1&#34; href=&#34;#__codelineno-3-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;CoordNode&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-2&#34; name=&#34;__codelineno-3-2&#34; href=&#34;#__codelineno-3-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-3&#34; name=&#34;__codelineno-3-3&#34; href=&#34;#__codelineno-3-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Uint8&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-4&#34; name=&#34;__codelineno-3-4&#34; href=&#34;#__codelineno-3-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-5&#34; name=&#34;__codelineno-3-5&#34; href=&#34;#__codelineno-3-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CoordNode&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;nullptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-6&#34; name=&#34;__codelineno-3-6&#34; href=&#34;#__codelineno-3-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CoordNode&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;nullptr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-7&#34; name=&#34;__codelineno-3-7&#34; href=&#34;#__codelineno-3-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PlayerAoi&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pplayer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-8&#34; name=&#34;__codelineno-3-8&#34; href=&#34;#__codelineno-3-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Sensor&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;psensor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-9&#34; name=&#34;__codelineno-3-9&#34; href=&#34;#__codelineno-3-9&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-10&#34; name=&#34;__codelineno-3-10&#34; href=&#34;#__codelineno-3-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-11&#34; name=&#34;__codelineno-3-11&#34; href=&#34;#__codelineno-3-11&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-12&#34; name=&#34;__codelineno-3-12&#34; href=&#34;#__codelineno-3-12&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;KHASH_MAP_INIT_INT64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SensorHashMap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PlayerAoi&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-13&#34; name=&#34;__codelineno-3-13&#34; href=&#34;#__codelineno-3-13&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-14&#34; name=&#34;__codelineno-3-14&#34; href=&#34;#__codelineno-3-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;Sensor&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-15&#34; name=&#34;__codelineno-3-15&#34; href=&#34;#__codelineno-3-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-16&#34; name=&#34;__codelineno-3-16&#34; href=&#34;#__codelineno-3-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Nuid&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sensor_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-17&#34; name=&#34;__codelineno-3-17&#34; href=&#34;#__codelineno-3-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;radius&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-18&#34; name=&#34;__codelineno-3-18&#34; href=&#34;#__codelineno-3-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;radius_square&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-19&#34; name=&#34;__codelineno-3-19&#34; href=&#34;#__codelineno-3-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PlayerAoi&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pplayer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-20&#34; name=&#34;__codelineno-3-20&#34; href=&#34;#__codelineno-3-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CoordNode&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;left_x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-21&#34; name=&#34;__codelineno-3-21&#34; href=&#34;#__codelineno-3-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CoordNode&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;right_x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-22&#34; name=&#34;__codelineno-3-22&#34; href=&#34;#__codelineno-3-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CoordNode&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;left_z&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-23&#34; name=&#34;__codelineno-3-23&#34; href=&#34;#__codelineno-3-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CoordNode&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;right_z&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-24&#34; name=&#34;__codelineno-3-24&#34; href=&#34;#__codelineno-3-24&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PlayerPtrList&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;aoi_players&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;];&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-25&#34; name=&#34;__codelineno-3-25&#34; href=&#34;#__codelineno-3-25&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-26&#34; name=&#34;__codelineno-3-26&#34; href=&#34;#__codelineno-3-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;shared_ptr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;khash_t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SensorHashMap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;aoi_player_candidates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-27&#34; name=&#34;__codelineno-3-27&#34; href=&#34;#__codelineno-3-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-28&#34; name=&#34;__codelineno-3-28&#34; href=&#34;#__codelineno-3-28&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-3-29&#34; name=&#34;__codelineno-3-29&#34; href=&#34;#__codelineno-3-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nc&#34;&gt;PlayerAoi&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-30&#34; name=&#34;__codelineno-3-30&#34; href=&#34;#__codelineno-3-30&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-31&#34; name=&#34;__codelineno-3-31&#34; href=&#34;#__codelineno-3-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Nuid&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nuid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-32&#34; name=&#34;__codelineno-3-32&#34; href=&#34;#__codelineno-3-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-33&#34; name=&#34;__codelineno-3-33&#34; href=&#34;#__codelineno-3-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;last_pos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-34&#34; name=&#34;__codelineno-3-34&#34; href=&#34;#__codelineno-3-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Uint32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;flags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-35&#34; name=&#34;__codelineno-3-35&#34; href=&#34;#__codelineno-3-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CoordNode&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node_x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-36&#34; name=&#34;__codelineno-3-36&#34; href=&#34;#__codelineno-3-36&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CoordNode&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node_z&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-37&#34; name=&#34;__codelineno-3-37&#34; href=&#34;#__codelineno-3-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vector&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Sensor&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sensors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-38&#34; name=&#34;__codelineno-3-38&#34; href=&#34;#__codelineno-3-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;shared_ptr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;boost&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;unordered_map&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Nuid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vector&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Nuid&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;detected_by&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-3-39&#34; name=&#34;__codelineno-3-39&#34; href=&#34;#__codelineno-3-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Sensor&lt;/code&gt; 和 &lt;code&gt;PlayerAoi&lt;/code&gt; 跟九宫格有部分相似，不过多了链表相关的节点结构 &lt;code&gt;CoordNode&lt;/code&gt;。&lt;code&gt;CoordNode&lt;/code&gt; 就是链表上的一个节点，记录了本身节点的类型和数值，类型有三种：玩家节点，&lt;code&gt;Sensor&lt;/code&gt; 左节点，&lt;code&gt;Sensor&lt;/code&gt; 右节点。&lt;/p&gt;
&lt;p&gt;十字链表的大部分工作都是在维持链表的有序：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;玩家加入时需要把玩家节点移动到有序的位置上，并且在移动玩家节点的同时，处理进入或者离开其他玩家 AOI 事件。&lt;/li&gt;
&lt;li&gt;玩家移动到正确的位置后，&lt;code&gt;Sensor&lt;/code&gt; 左右节点从玩家前后位置出发，移动到正确的位置，并处理跨过其他玩家节点时触发的进入和离开事件。&lt;/li&gt;
&lt;li&gt;玩家移动时，更新玩家的坐标，并移动玩家节点和 &lt;code&gt;Sensor&lt;/code&gt; 左右节点，处理 AOI 进入离开。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;移动节点的代码如下，每跨过一个节点，都会调用一次 &lt;code&gt;MoveCross&lt;/code&gt; 函数，由 &lt;code&gt;MoveCross&lt;/code&gt; 函数根据移动方向，移动节点和跨过节点的类型来决定是进入还是离开 AOI。&lt;/p&gt;
&lt;div class=&#34;language-cpp highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-4-1&#34; name=&#34;__codelineno-4-1&#34; href=&#34;#__codelineno-4-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ListUpdateNode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CoordNode&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CoordNode&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pnode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-2&#34; name=&#34;__codelineno-4-2&#34; href=&#34;#__codelineno-4-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pnode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-3&#34; name=&#34;__codelineno-4-3&#34; href=&#34;#__codelineno-4-3&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-4&#34; name=&#34;__codelineno-4-4&#34; href=&#34;#__codelineno-4-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pnode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pnode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-5&#34; name=&#34;__codelineno-4-5&#34; href=&#34;#__codelineno-4-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// move right&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-6&#34; name=&#34;__codelineno-4-6&#34; href=&#34;#__codelineno-4-6&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur_node&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pnode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-7&#34; name=&#34;__codelineno-4-7&#34; href=&#34;#__codelineno-4-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-8&#34; name=&#34;__codelineno-4-8&#34; href=&#34;#__codelineno-4-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MoveCross&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MOVE_DIRECTION_RIGHT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pnode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur_node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-9&#34; name=&#34;__codelineno-4-9&#34; href=&#34;#__codelineno-4-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur_node&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur_node&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-10&#34; name=&#34;__codelineno-4-10&#34; href=&#34;#__codelineno-4-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur_node&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur_node&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-11&#34; name=&#34;__codelineno-4-11&#34; href=&#34;#__codelineno-4-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-12&#34; name=&#34;__codelineno-4-12&#34; href=&#34;#__codelineno-4-12&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-13&#34; name=&#34;__codelineno-4-13&#34; href=&#34;#__codelineno-4-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ListRemove&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pnode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-14&#34; name=&#34;__codelineno-4-14&#34; href=&#34;#__codelineno-4-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ListInsertAfter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur_node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pnode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-15&#34; name=&#34;__codelineno-4-15&#34; href=&#34;#__codelineno-4-15&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-16&#34; name=&#34;__codelineno-4-16&#34; href=&#34;#__codelineno-4-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pnode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pnode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-17&#34; name=&#34;__codelineno-4-17&#34; href=&#34;#__codelineno-4-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// move left&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-18&#34; name=&#34;__codelineno-4-18&#34; href=&#34;#__codelineno-4-18&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur_node&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pnode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-19&#34; name=&#34;__codelineno-4-19&#34; href=&#34;#__codelineno-4-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-20&#34; name=&#34;__codelineno-4-20&#34; href=&#34;#__codelineno-4-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MoveCross&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MOVE_DIRECTION_LEFT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pnode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur_node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-21&#34; name=&#34;__codelineno-4-21&#34; href=&#34;#__codelineno-4-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur_node&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur_node&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-22&#34; name=&#34;__codelineno-4-22&#34; href=&#34;#__codelineno-4-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur_node&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur_node&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prev&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-23&#34; name=&#34;__codelineno-4-23&#34; href=&#34;#__codelineno-4-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-24&#34; name=&#34;__codelineno-4-24&#34; href=&#34;#__codelineno-4-24&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-4-25&#34; name=&#34;__codelineno-4-25&#34; href=&#34;#__codelineno-4-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ListRemove&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pnode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-26&#34; name=&#34;__codelineno-4-26&#34; href=&#34;#__codelineno-4-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ListInsertBefore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cur_node&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pnode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-27&#34; name=&#34;__codelineno-4-27&#34; href=&#34;#__codelineno-4-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;a id=&#34;__codelineno-4-28&#34; name=&#34;__codelineno-4-28&#34; href=&#34;#__codelineno-4-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;链表的移动很慢，是 &lt;code&gt;O(n)&lt;/code&gt; 的复杂度，特别是在玩家新加入场景时，玩家需要从无穷远的地方，逐步移动到正确的位置上，为此需要大量遍历的节点，消耗很大。为了优化性能，我们可以在场景中固定位置放置灯塔，这种灯塔处理上跟玩家大致相同，只是比玩家多记录了一份 &lt;code&gt;detected_by&lt;/code&gt; 数据，&lt;code&gt;detected_by&lt;/code&gt; 是用来记录该哨兵实体处在哪些 &lt;code&gt;Sensor&lt;/code&gt; 范围内。玩家首次进入场景时，不再从最远处开始移动，而是找到一个最近的灯塔，把节点插入到灯塔旁边，并通过灯塔身上的 &lt;code&gt;detected_by&lt;/code&gt; 数据，快速进入到跟灯塔一致的其他玩家的 AOI 范围内，然后开始移动到正确的位置上，当然移动的时候也要处理进入和离开。同理，对于 &lt;code&gt;Sensor&lt;/code&gt;，也可以通过先继承灯塔的数据，然后从灯塔的位置上移动到正确位置上。通过这两种优化能够提升一倍以上的插入玩家性能。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Sensor&lt;/code&gt; 身上还有一个名叫 &lt;code&gt;aoi_player_candidates&lt;/code&gt; 的 &lt;code&gt;HashMap&lt;/code&gt;（这里为了性能，使用了&lt;a href=&#34;https://github.com/attractivechaos/klib/blob/master/khash.h&#34;&gt;khash&lt;/a&gt;）。节点移动触发的 AOI 事件，其实只能检测到 X-Z 坐标轴上边长为 &lt;code&gt;2r&lt;/code&gt; 的正方形区域，不是我们严格意义上的圆形区域的 AOI，这个正方形的区域内的实体都被记录在 &lt;code&gt;aoi_player_candidates&lt;/code&gt; 上，并在 &lt;code&gt;Tick&lt;/code&gt; 中遍历计算圆形区域内的 AOI 范围，所以称为 &lt;code&gt;candidates&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;所有十字链表的操作都是为了一直维护正方形区域内的实体 &lt;code&gt;candidates&lt;/code&gt;，十字链表中 &lt;code&gt;Tick&lt;/code&gt; 做的操作跟九宫格几乎一致，只是遍历计算 AOI 的 &lt;code&gt;candidates&lt;/code&gt; 不相同。九宫格的 &lt;code&gt;candidates&lt;/code&gt; 是 AOI 圆形区域所覆盖到的格子的实体，而十字链表则是由 &lt;code&gt;Sensor&lt;/code&gt; 左右节点所界定的边长为 &lt;code&gt;2r&lt;/code&gt; 的正方形区域中的实体。定性的来说，十字链表的 &lt;code&gt;candidates&lt;/code&gt; 一般都要比九宫格少，所以在 &lt;code&gt;Tick&lt;/code&gt; 中的遍历次数少，性能更优，只是十字链表还有大量额外的性能消耗在了维护链表上，这两者整体的性能到底孰优孰劣，我们接下来实测看看。&lt;/p&gt;
&lt;h3 id=&#34;_6&#34;&gt;性能实测&lt;/h3&gt;
&lt;p&gt;我这里分别测了玩家加入场景（&lt;code&gt;Add Player&lt;/code&gt;），计算 AOI 进出事件（&lt;code&gt;Tick&lt;/code&gt;），玩家更新坐标位置（&lt;code&gt;Update Pos&lt;/code&gt;）三种情况的时间消耗。&lt;/p&gt;
&lt;p&gt;玩家初始位置在地图范围内随机生成，然后把玩家加入场景。&lt;code&gt;player_num&lt;/code&gt; 是玩家数量，&lt;code&gt;map_size&lt;/code&gt; 则是地图 X-Z 坐标轴范围，玩家的位置在此范围内均匀随机生成，每个玩家都有一个半径 &lt;code&gt;100&lt;/code&gt; 的 &lt;code&gt;Sensor&lt;/code&gt; 作为 AOI，计算时间用的是 &lt;code&gt;boost::timer::cpu_timer&lt;/code&gt;。&lt;code&gt;player_num&lt;/code&gt; 分别选了 &lt;code&gt;100, 1000, 10000&lt;/code&gt; 三种情况，而 &lt;code&gt;map_size&lt;/code&gt; 则选了 &lt;code&gt;[-50, 50], [-100, 100], [-1000, 1000], [-10000, 10000]&lt;/code&gt; 四种情况。&lt;/p&gt;
&lt;p&gt;更新玩家位置会让玩家固定随机方向，以 &lt;code&gt;6m/s&lt;/code&gt; 的速度移动。&lt;/p&gt;
&lt;p&gt;本次测试环境为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CPU: Intel(R) Core(TM) i5-4590 CPU @ 3.30GHz&lt;/li&gt;
&lt;li&gt;系统: Debian GNU/Linux 10 (buster)&lt;/li&gt;
&lt;li&gt;gcc 版本: gcc version 8.3.0 (Debian 8.3.0-6)&lt;/li&gt;
&lt;li&gt;boost 版本: boost_1_75_0&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;_7&#34;&gt;九宫格实测&lt;/h4&gt;
&lt;p&gt;九宫格的测试结果如下：&lt;/p&gt;
&lt;div class=&#34;language-python highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-5-1&#34; name=&#34;__codelineno-5-1&#34; href=&#34;#__codelineno-5-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;50.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;50.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-2&#34; name=&#34;__codelineno-5-2&#34; href=&#34;#__codelineno-5-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000081&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-3&#34; name=&#34;__codelineno-5-3&#34; href=&#34;#__codelineno-5-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000452&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-4&#34; name=&#34;__codelineno-5-4&#34; href=&#34;#__codelineno-5-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000230&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-5&#34; name=&#34;__codelineno-5-5&#34; href=&#34;#__codelineno-5-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-6&#34; name=&#34;__codelineno-5-6&#34; href=&#34;#__codelineno-5-6&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-7&#34; name=&#34;__codelineno-5-7&#34; href=&#34;#__codelineno-5-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;100.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;100.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-8&#34; name=&#34;__codelineno-5-8&#34; href=&#34;#__codelineno-5-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000070&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-9&#34; name=&#34;__codelineno-5-9&#34; href=&#34;#__codelineno-5-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000338&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-10&#34; name=&#34;__codelineno-5-10&#34; href=&#34;#__codelineno-5-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000185&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-11&#34; name=&#34;__codelineno-5-11&#34; href=&#34;#__codelineno-5-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-12&#34; name=&#34;__codelineno-5-12&#34; href=&#34;#__codelineno-5-12&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-13&#34; name=&#34;__codelineno-5-13&#34; href=&#34;#__codelineno-5-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-14&#34; name=&#34;__codelineno-5-14&#34; href=&#34;#__codelineno-5-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000084&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-15&#34; name=&#34;__codelineno-5-15&#34; href=&#34;#__codelineno-5-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000103&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-16&#34; name=&#34;__codelineno-5-16&#34; href=&#34;#__codelineno-5-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000187&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-17&#34; name=&#34;__codelineno-5-17&#34; href=&#34;#__codelineno-5-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-18&#34; name=&#34;__codelineno-5-18&#34; href=&#34;#__codelineno-5-18&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-19&#34; name=&#34;__codelineno-5-19&#34; href=&#34;#__codelineno-5-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;10000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;10000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-20&#34; name=&#34;__codelineno-5-20&#34; href=&#34;#__codelineno-5-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000084&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-21&#34; name=&#34;__codelineno-5-21&#34; href=&#34;#__codelineno-5-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000080&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-22&#34; name=&#34;__codelineno-5-22&#34; href=&#34;#__codelineno-5-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000185&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-23&#34; name=&#34;__codelineno-5-23&#34; href=&#34;#__codelineno-5-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-24&#34; name=&#34;__codelineno-5-24&#34; href=&#34;#__codelineno-5-24&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-25&#34; name=&#34;__codelineno-5-25&#34; href=&#34;#__codelineno-5-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;50.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;50.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-26&#34; name=&#34;__codelineno-5-26&#34; href=&#34;#__codelineno-5-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000673&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-27&#34; name=&#34;__codelineno-5-27&#34; href=&#34;#__codelineno-5-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.035298&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.030000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.030000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;85.0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-28&#34; name=&#34;__codelineno-5-28&#34; href=&#34;#__codelineno-5-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.001841&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-29&#34; name=&#34;__codelineno-5-29&#34; href=&#34;#__codelineno-5-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-30&#34; name=&#34;__codelineno-5-30&#34; href=&#34;#__codelineno-5-30&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-31&#34; name=&#34;__codelineno-5-31&#34; href=&#34;#__codelineno-5-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;100.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;100.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-32&#34; name=&#34;__codelineno-5-32&#34; href=&#34;#__codelineno-5-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000664&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-33&#34; name=&#34;__codelineno-5-33&#34; href=&#34;#__codelineno-5-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.025806&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.030000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.030000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;116.3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-34&#34; name=&#34;__codelineno-5-34&#34; href=&#34;#__codelineno-5-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.001842&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-35&#34; name=&#34;__codelineno-5-35&#34; href=&#34;#__codelineno-5-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-36&#34; name=&#34;__codelineno-5-36&#34; href=&#34;#__codelineno-5-36&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-37&#34; name=&#34;__codelineno-5-37&#34; href=&#34;#__codelineno-5-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-38&#34; name=&#34;__codelineno-5-38&#34; href=&#34;#__codelineno-5-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000721&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-39&#34; name=&#34;__codelineno-5-39&#34; href=&#34;#__codelineno-5-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.001793&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-40&#34; name=&#34;__codelineno-5-40&#34; href=&#34;#__codelineno-5-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.001849&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;540.8&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-41&#34; name=&#34;__codelineno-5-41&#34; href=&#34;#__codelineno-5-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-42&#34; name=&#34;__codelineno-5-42&#34; href=&#34;#__codelineno-5-42&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-43&#34; name=&#34;__codelineno-5-43&#34; href=&#34;#__codelineno-5-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;10000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;10000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-44&#34; name=&#34;__codelineno-5-44&#34; href=&#34;#__codelineno-5-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000885&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-45&#34; name=&#34;__codelineno-5-45&#34; href=&#34;#__codelineno-5-45&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000804&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-46&#34; name=&#34;__codelineno-5-46&#34; href=&#34;#__codelineno-5-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.001855&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-47&#34; name=&#34;__codelineno-5-47&#34; href=&#34;#__codelineno-5-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-48&#34; name=&#34;__codelineno-5-48&#34; href=&#34;#__codelineno-5-48&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-49&#34; name=&#34;__codelineno-5-49&#34; href=&#34;#__codelineno-5-49&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;50.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;50.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-50&#34; name=&#34;__codelineno-5-50&#34; href=&#34;#__codelineno-5-50&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.006454&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;154.9&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-51&#34; name=&#34;__codelineno-5-51&#34; href=&#34;#__codelineno-5-51&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;3.822028&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;3.800000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.020000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;3.820000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;99.9&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-52&#34; name=&#34;__codelineno-5-52&#34; href=&#34;#__codelineno-5-52&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.018402&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.020000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.020000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;108.7&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-53&#34; name=&#34;__codelineno-5-53&#34; href=&#34;#__codelineno-5-53&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-54&#34; name=&#34;__codelineno-5-54&#34; href=&#34;#__codelineno-5-54&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-55&#34; name=&#34;__codelineno-5-55&#34; href=&#34;#__codelineno-5-55&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;100.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;100.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-56&#34; name=&#34;__codelineno-5-56&#34; href=&#34;#__codelineno-5-56&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.006439&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-57&#34; name=&#34;__codelineno-5-57&#34; href=&#34;#__codelineno-5-57&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;2.805551&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;2.760000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.040000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;2.800000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;99.8&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-58&#34; name=&#34;__codelineno-5-58&#34; href=&#34;#__codelineno-5-58&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.018489&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;54.1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-59&#34; name=&#34;__codelineno-5-59&#34; href=&#34;#__codelineno-5-59&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-60&#34; name=&#34;__codelineno-5-60&#34; href=&#34;#__codelineno-5-60&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-61&#34; name=&#34;__codelineno-5-61&#34; href=&#34;#__codelineno-5-61&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-62&#34; name=&#34;__codelineno-5-62&#34; href=&#34;#__codelineno-5-62&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.006698&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;149.3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-63&#34; name=&#34;__codelineno-5-63&#34; href=&#34;#__codelineno-5-63&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.093759&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.100000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.100000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;106.7&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-64&#34; name=&#34;__codelineno-5-64&#34; href=&#34;#__codelineno-5-64&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.018350&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;54.5&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-65&#34; name=&#34;__codelineno-5-65&#34; href=&#34;#__codelineno-5-65&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-66&#34; name=&#34;__codelineno-5-66&#34; href=&#34;#__codelineno-5-66&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-5-67&#34; name=&#34;__codelineno-5-67&#34; href=&#34;#__codelineno-5-67&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;10000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;10000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-68&#34; name=&#34;__codelineno-5-68&#34; href=&#34;#__codelineno-5-68&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.009046&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;110.6&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-69&#34; name=&#34;__codelineno-5-69&#34; href=&#34;#__codelineno-5-69&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.012091&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;82.7&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-70&#34; name=&#34;__codelineno-5-70&#34; href=&#34;#__codelineno-5-70&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.019033&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.020000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.020000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;105.1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-5-71&#34; name=&#34;__codelineno-5-71&#34; href=&#34;#__codelineno-5-71&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;九宫格在玩家数量 &lt;code&gt;100&lt;/code&gt; 时，三种操作耗时都很小，极限情况 &lt;code&gt;map_size = [-50, 50]&lt;/code&gt;，所有玩家互相都处于 AOI 范围内，&lt;code&gt;Tick&lt;/code&gt; 耗时大概 &lt;code&gt;0.4ms&lt;/code&gt;。玩家加入场景和更新坐标都是线性复杂度 &lt;code&gt;O(player_num)&lt;/code&gt;，性能表现都不错。在 &lt;code&gt;player_num = 10000, map_size = [-50, 50]&lt;/code&gt; 玩家人数达到 1 万的时候，&lt;code&gt;Add Player&lt;/code&gt; 和 &lt;code&gt;Update Pos&lt;/code&gt; 由于都是线性，几毫秒内就能完成，但 &lt;code&gt;Tick&lt;/code&gt; 耗时就去到 &lt;code&gt;3.8s&lt;/code&gt;，需要消耗大量 CPU，属于不可用了。人数 1 万，地图大小 &lt;code&gt;[-1000, 1000]&lt;/code&gt;，情况下，&lt;code&gt;Tick&lt;/code&gt; 时间消耗大概 &lt;code&gt;94ms&lt;/code&gt;，如果能够降低 &lt;code&gt;Tick&lt;/code&gt; 频率的话，譬如一秒两次，还是勉强属于可用的范围内。&lt;/p&gt;
&lt;h4 id=&#34;_8&#34;&gt;十字链表实测&lt;/h4&gt;
&lt;p&gt;十字链表的测试结果如下：&lt;/p&gt;
&lt;div class=&#34;language-python highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;a id=&#34;__codelineno-6-1&#34; name=&#34;__codelineno-6-1&#34; href=&#34;#__codelineno-6-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;50.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;50.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-2&#34; name=&#34;__codelineno-6-2&#34; href=&#34;#__codelineno-6-2&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.002057&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-3&#34; name=&#34;__codelineno-6-3&#34; href=&#34;#__codelineno-6-3&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000330&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-4&#34; name=&#34;__codelineno-6-4&#34; href=&#34;#__codelineno-6-4&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000232&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-5&#34; name=&#34;__codelineno-6-5&#34; href=&#34;#__codelineno-6-5&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-6&#34; name=&#34;__codelineno-6-6&#34; href=&#34;#__codelineno-6-6&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-7&#34; name=&#34;__codelineno-6-7&#34; href=&#34;#__codelineno-6-7&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;100.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;100.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-8&#34; name=&#34;__codelineno-6-8&#34; href=&#34;#__codelineno-6-8&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.001201&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-9&#34; name=&#34;__codelineno-6-9&#34; href=&#34;#__codelineno-6-9&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000222&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-10&#34; name=&#34;__codelineno-6-10&#34; href=&#34;#__codelineno-6-10&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000272&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-11&#34; name=&#34;__codelineno-6-11&#34; href=&#34;#__codelineno-6-11&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-12&#34; name=&#34;__codelineno-6-12&#34; href=&#34;#__codelineno-6-12&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-13&#34; name=&#34;__codelineno-6-13&#34; href=&#34;#__codelineno-6-13&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-14&#34; name=&#34;__codelineno-6-14&#34; href=&#34;#__codelineno-6-14&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000288&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-15&#34; name=&#34;__codelineno-6-15&#34; href=&#34;#__codelineno-6-15&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000048&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-16&#34; name=&#34;__codelineno-6-16&#34; href=&#34;#__codelineno-6-16&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000200&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-17&#34; name=&#34;__codelineno-6-17&#34; href=&#34;#__codelineno-6-17&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-18&#34; name=&#34;__codelineno-6-18&#34; href=&#34;#__codelineno-6-18&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-19&#34; name=&#34;__codelineno-6-19&#34; href=&#34;#__codelineno-6-19&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;10000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;10000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-20&#34; name=&#34;__codelineno-6-20&#34; href=&#34;#__codelineno-6-20&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000194&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-21&#34; name=&#34;__codelineno-6-21&#34; href=&#34;#__codelineno-6-21&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000041&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-22&#34; name=&#34;__codelineno-6-22&#34; href=&#34;#__codelineno-6-22&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000192&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-23&#34; name=&#34;__codelineno-6-23&#34; href=&#34;#__codelineno-6-23&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-24&#34; name=&#34;__codelineno-6-24&#34; href=&#34;#__codelineno-6-24&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-25&#34; name=&#34;__codelineno-6-25&#34; href=&#34;#__codelineno-6-25&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;50.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;50.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-26&#34; name=&#34;__codelineno-6-26&#34; href=&#34;#__codelineno-6-26&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.130766&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.130000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.130000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;99.4&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-27&#34; name=&#34;__codelineno-6-27&#34; href=&#34;#__codelineno-6-27&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.028091&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.020000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.020000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;71.2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-28&#34; name=&#34;__codelineno-6-28&#34; href=&#34;#__codelineno-6-28&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.005369&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;186.2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-29&#34; name=&#34;__codelineno-6-29&#34; href=&#34;#__codelineno-6-29&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-30&#34; name=&#34;__codelineno-6-30&#34; href=&#34;#__codelineno-6-30&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-31&#34; name=&#34;__codelineno-6-31&#34; href=&#34;#__codelineno-6-31&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;100.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;100.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-32&#34; name=&#34;__codelineno-6-32&#34; href=&#34;#__codelineno-6-32&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.103015&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.100000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.100000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;97.1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-33&#34; name=&#34;__codelineno-6-33&#34; href=&#34;#__codelineno-6-33&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.019545&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.020000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.020000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;102.3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-34&#34; name=&#34;__codelineno-6-34&#34; href=&#34;#__codelineno-6-34&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.009208&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;108.6&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-35&#34; name=&#34;__codelineno-6-35&#34; href=&#34;#__codelineno-6-35&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-36&#34; name=&#34;__codelineno-6-36&#34; href=&#34;#__codelineno-6-36&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-37&#34; name=&#34;__codelineno-6-37&#34; href=&#34;#__codelineno-6-37&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-38&#34; name=&#34;__codelineno-6-38&#34; href=&#34;#__codelineno-6-38&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010150&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;98.5&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-39&#34; name=&#34;__codelineno-6-39&#34; href=&#34;#__codelineno-6-39&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000845&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-40&#34; name=&#34;__codelineno-6-40&#34; href=&#34;#__codelineno-6-40&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.003023&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-41&#34; name=&#34;__codelineno-6-41&#34; href=&#34;#__codelineno-6-41&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-42&#34; name=&#34;__codelineno-6-42&#34; href=&#34;#__codelineno-6-42&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-43&#34; name=&#34;__codelineno-6-43&#34; href=&#34;#__codelineno-6-43&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;10000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;10000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-44&#34; name=&#34;__codelineno-6-44&#34; href=&#34;#__codelineno-6-44&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.004950&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;202.0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-45&#34; name=&#34;__codelineno-6-45&#34; href=&#34;#__codelineno-6-45&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000427&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-46&#34; name=&#34;__codelineno-6-46&#34; href=&#34;#__codelineno-6-46&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.002234&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-47&#34; name=&#34;__codelineno-6-47&#34; href=&#34;#__codelineno-6-47&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-48&#34; name=&#34;__codelineno-6-48&#34; href=&#34;#__codelineno-6-48&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-49&#34; name=&#34;__codelineno-6-49&#34; href=&#34;#__codelineno-6-49&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;50.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;50.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-50&#34; name=&#34;__codelineno-6-50&#34; href=&#34;#__codelineno-6-50&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;21.606402&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;21.040000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.570000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;21.610000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;100.0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-51&#34; name=&#34;__codelineno-6-51&#34; href=&#34;#__codelineno-6-51&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;3.696885&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;3.680000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.030000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;3.710000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;100.4&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-52&#34; name=&#34;__codelineno-6-52&#34; href=&#34;#__codelineno-6-52&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.434396&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.430000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.430000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;99.0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-53&#34; name=&#34;__codelineno-6-53&#34; href=&#34;#__codelineno-6-53&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-54&#34; name=&#34;__codelineno-6-54&#34; href=&#34;#__codelineno-6-54&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-55&#34; name=&#34;__codelineno-6-55&#34; href=&#34;#__codelineno-6-55&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;100.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;100.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-56&#34; name=&#34;__codelineno-6-56&#34; href=&#34;#__codelineno-6-56&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;18.499235&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;18.470000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.020000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;18.490000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;100.0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-57&#34; name=&#34;__codelineno-6-57&#34; href=&#34;#__codelineno-6-57&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;2.292608&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;2.290000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;2.290000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;99.9&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-58&#34; name=&#34;__codelineno-6-58&#34; href=&#34;#__codelineno-6-58&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.522617&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.530000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.530000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;100.5&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-59&#34; name=&#34;__codelineno-6-59&#34; href=&#34;#__codelineno-6-59&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-60&#34; name=&#34;__codelineno-6-60&#34; href=&#34;#__codelineno-6-60&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-61&#34; name=&#34;__codelineno-6-61&#34; href=&#34;#__codelineno-6-61&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-62&#34; name=&#34;__codelineno-6-62&#34; href=&#34;#__codelineno-6-62&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.642519&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.640000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.640000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;99.8&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-63&#34; name=&#34;__codelineno-6-63&#34; href=&#34;#__codelineno-6-63&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.042767&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.050000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.050000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;116.9&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-64&#34; name=&#34;__codelineno-6-64&#34; href=&#34;#__codelineno-6-64&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.202949&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.200000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.200000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;98.5&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-65&#34; name=&#34;__codelineno-6-65&#34; href=&#34;#__codelineno-6-65&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-66&#34; name=&#34;__codelineno-6-66&#34; href=&#34;#__codelineno-6-66&#34;&gt;&lt;/a&gt;
&lt;a id=&#34;__codelineno-6-67&#34; name=&#34;__codelineno-6-67&#34; href=&#34;#__codelineno-6-67&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Begin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;player_num&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;10000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;10000.000000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-68&#34; name=&#34;__codelineno-6-68&#34; href=&#34;#__codelineno-6-68&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Player&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.571257&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.570000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.570000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;99.8&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-69&#34; name=&#34;__codelineno-6-69&#34; href=&#34;#__codelineno-6-69&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.006325&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.010000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;158.1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-70&#34; name=&#34;__codelineno-6-70&#34; href=&#34;#__codelineno-6-70&#34;&gt;&lt;/a&gt;&lt;span class=&#34;n&#34;&gt;Update&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pos&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.042568&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.040000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.000000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;system&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.040000&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CPU&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;94.0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;a id=&#34;__codelineno-6-71&#34; name=&#34;__codelineno-6-71&#34; href=&#34;#__codelineno-6-71&#34;&gt;&lt;/a&gt;&lt;span class=&#34;o&#34;&gt;===&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Milestore&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如我们分析一致，十字链表在 &lt;code&gt;Add Player&lt;/code&gt; 和 &lt;code&gt;Update Pos&lt;/code&gt; 上耗时更长，特别是 &lt;code&gt;Add Player&lt;/code&gt;，相比九宫格性能差了几百甚至上万倍（&lt;code&gt;100, [-50, 50]&lt;/code&gt; 十字链耗时 &lt;code&gt;2ms&lt;/code&gt;，而九宫格只有 &lt;code&gt;0.08ms&lt;/code&gt;；&lt;code&gt;10000, [-50, 50]&lt;/code&gt; 十字链 &lt;code&gt;21.6s&lt;/code&gt;，九宫格只有 &lt;code&gt;6ms&lt;/code&gt;。&lt;code&gt;Update Pos&lt;/code&gt; 的耗时也最多会有百倍的差距，&lt;code&gt;10000, [-100, 100]&lt;/code&gt; 十字链更新玩家位置耗时 &lt;code&gt;1.5s&lt;/code&gt;，而九宫格是 &lt;code&gt;18ms&lt;/code&gt;。可以看出，十字链在 &lt;code&gt;Add Player&lt;/code&gt; 和 &lt;code&gt;Update Pos&lt;/code&gt; 耗时的上下限范围比九宫格要大，受人数和地图大小影响更大，在玩家密集的区域，这两个操作的性能会急速下降，直至不可用。&lt;/p&gt;
&lt;p&gt;反观十字链的 &lt;code&gt;Tick&lt;/code&gt; 操作，整体性能确实是比九宫格好，最好的情况耗时大概只有九宫格的一半左右（ &lt;code&gt;1000, [-1000, 1000]&lt;/code&gt; 下十字链耗时 &lt;code&gt;0.8ms&lt;/code&gt;，九宫格 &lt;code&gt;1.8ms&lt;/code&gt;），但是最差的情况十字链会退化到跟九宫格的性能接近（&lt;code&gt;10000, [-10000, 10000]&lt;/code&gt; 下十字链耗时 &lt;code&gt;3.7s&lt;/code&gt;，九宫格 &lt;code&gt;3.8s&lt;/code&gt;。这是因为由于场景小，玩家互相都在彼此的 AOI 范围内，十字链 &lt;code&gt;Tick&lt;/code&gt; 遍历的 &lt;code&gt;candidates&lt;/code&gt; 数量, 其实已经跟九宫格很接近了。&lt;/p&gt;
&lt;p&gt;十字链使用起来要达到比九宫格性能更优，需要一些更强的假设，譬如 &lt;code&gt;player_num = 1000, map_size = [-1000, 1000]&lt;/code&gt; 情况下，&lt;code&gt;Tick&lt;/code&gt; 耗时十字链为 &lt;code&gt;0.8ms&lt;/code&gt; 九宫格 &lt;code&gt;1.8ms&lt;/code&gt;，&lt;code&gt;Update Pos&lt;/code&gt; 十字链为 &lt;code&gt;0.3ms&lt;/code&gt; 九宫格 &lt;code&gt;0.18ms&lt;/code&gt;（注意测试 &lt;code&gt;Update Pos&lt;/code&gt; 时间为执行了 10 次的时间总和）。&lt;code&gt;Tick + Update Pos&lt;/code&gt; 总时间下，十字链如果要比九宫格更少，那 &lt;code&gt;Update Pos&lt;/code&gt; 的次数不能超过 &lt;code&gt;Tick&lt;/code&gt; 的 &lt;code&gt;8&lt;/code&gt; 倍，或者说两个 &lt;code&gt;Tick&lt;/code&gt; 之间，&lt;code&gt;Update Pos&lt;/code&gt; 的次数需要小于 &lt;code&gt;8&lt;/code&gt; 次。另外因为十字链 &lt;code&gt;Add Player&lt;/code&gt; 耗时巨大，不适用于玩家短时间频繁出入场景或者在场景内大范围传送的情况，另外如果短时间内有大量玩家进入场景，也很容易导致性能下降，大量占用 CPU。&lt;/p&gt;
&lt;p&gt;对于十字链表，在一个前提之下还能做一个优化：干掉 &lt;code&gt;Tick&lt;/code&gt;，前提是游戏能接受正方形的 AOI，并且需要实测正方形 AOI 带来的其他诸如网络等消耗是能接受的。其实前提是比较苛刻的，因为在游戏中 AOI 计费能占用的 CPU 通常占比是不大的，但把圆形 AOI 改成方形 AOI 导致 AOI 范围面积增大，范围内的玩家数量也增多，均匀分布下玩家数量可能会增多到原来的 &lt;code&gt;1.27&lt;/code&gt; 倍。但是，一旦能满足前提，十字链表可以做到不需要 &lt;code&gt;Tick&lt;/code&gt; 来定期更新 AOI 事件，因为实现上十字链表的 &lt;code&gt;candidates&lt;/code&gt; 就维护了一份方形下 AOI，原来只是为了计算圆形 AOI，而不得不在 &lt;code&gt;Tick&lt;/code&gt; 中再遍历计算距离。在这种情况下，十字链是有可能能够达到很好的性能，因为十字链表 &lt;code&gt;Update Pos&lt;/code&gt; 的性能可以跟 &lt;code&gt;Tick&lt;/code&gt; 相差几倍到几十倍。&lt;/p&gt;
&lt;p&gt;最后给出两者的对比柱状图：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2021-11-18-aoi-tesing/add_player.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2021-11-18-aoi-tesing/tick.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../assets/img/2021-11-18-aoi-tesing/update_pos.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;_9&#34;&gt;总结&lt;/h3&gt;
&lt;p&gt;本文我们介绍了两种 AOI 算法（九宫格和十字链）的原理和基本实现，并通过实测的数据分析了这两种算法的性能优劣，希望能够给读者带来一些帮助或者启发。&lt;/p&gt;
&lt;p&gt;总的来说，九宫格法实现简单，性能均衡不容易拉胯，非常适合 AOI 不是性能瓶颈的游戏来使用，九宫格法的性能波动范围是在可预期的范围内，性能下限比较高，也不容易导致瓶颈，但另一方面可优化空间也不大，时间复杂度比较固定。反观十字链法，实现要更复杂，性能下限比九宫格法低，但是如果能够满足一些假设和前提，十字链可优化空间更高，换句话说是上限是可以更高。这两种方法各有优劣，游戏业界内也有不同的引擎分别选择了两者之一，各取所需，见仁见智。&lt;/p&gt;
&lt;p&gt;本人能力有限，文中内容仅代表本人想法，如有不足不妥之处欢迎留言讨论。&lt;/p&gt;
&lt;script async src=&#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&#34;&gt;&lt;/script&gt;

&lt;!-- 转载声明 &amp;&amp; visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;https://wiki.disenone.site&#34;&gt;https://wiki.disenone.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本篇文章受 &lt;a href=&#34;https://creativecommons.org/licenses/by/4.0/deed.zh&#34;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议保护，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- 转载 --&gt;
&lt;div class=&#34;a2a_kit a2a_kit_size_32 a2a_default_style&#34; data-a2a-icon-color=&#34;#4051b5&#34;&gt;
    &lt;a class=&#34;a2a_dd&#34; href=&#34;https://www.addtoany.com/share&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_copy_link&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_wechat&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_reddit&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_google_gmail&#34;&gt;&lt;/a&gt;
    &lt;a class=&#34;a2a_button_pocket&#34;&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://static.addtoany.com/menu/page.js&#34;&gt;&lt;/script&gt;

&lt;!-- 评论 --&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34;
        data-repo=&#34;disenone/wiki&#34;
        data-repo-id=&#34;R_kgDOKz9PQg&#34;
        data-category=&#34;Announcements&#34;
        data-category-id=&#34;DIC_kwDOKz9PQs4Cbbvv&#34;
        data-mapping=&#34;og:title&#34;
        data-strict=&#34;1&#34;
        data-reactions-enabled=&#34;1&#34;
        data-emit-metadata=&#34;0&#34;
        data-input-position=&#34;top&#34;
        data-theme=&#34;preferred_color_scheme&#34;
        data-lang=&#34;zh-CN&#34;
        data-loading=&#34;lazy&#34;
        crossorigin=&#34;anonymous&#34;
        async&gt;
&lt;/script&gt;

&lt;!-- visit --&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;p class=&#34;copyright text-muted&#34;&gt;&lt;span id=&#34;busuanzi_container_site_uv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_uv&#34;&gt;&lt;/span&gt; Visitors. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_site_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_site_pv&#34;&gt;&lt;/span&gt; Total Visits. &lt;/span&gt; &lt;span id=&#34;busuanzi_container_page_pv&#34;&gt; &lt;span id=&#34;busuanzi_value_page_pv&#34;&gt;&lt;/span&gt; Page Visits. &lt;/span&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <link>https://wiki.disenone.site/game-%E6%B8%B8%E6%88%8FAOI%E7%AE%97%E6%B3%95%E8%A7%A3%E6%9E%90%E5%92%8C%E6%80%A7%E8%83%BD%E5%AE%9E%E6%B5%8B/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 18 Nov 2021 00:00:00 +0000</pubDate>
      <source url="https://wiki.disenone.site/feed_rss_created.xml">Disenone's Wiki</source>
      
      <guid isPermaLink="true">https://wiki.disenone.site/game-%E6%B8%B8%E6%88%8FAOI%E7%AE%97%E6%B3%95%E8%A7%A3%E6%9E%90%E5%92%8C%E6%80%A7%E8%83%BD%E5%AE%9E%E6%B5%8B/</guid>
      
    </item>
    
  </channel>
</rss>