UE4SS脚本注入系统:从原理到实战,解锁虚幻引擎游戏Mod开发
1. 项目概述UE4SS是什么以及为什么你需要它如果你是一个热衷于《幻兽帕鲁》、《艾尔登法环》或者任何基于虚幻引擎4/5开发的PC游戏的玩家或开发者那么“UE4SS”这个名字你大概率已经听过。它不是一个游戏而是一个强大的脚本注入系统简单来说它就像一把能打开游戏内部世界的“万能钥匙”。通过UE4SS你可以加载自定义的Lua脚本实现从简单的游戏功能修改比如无限耐力、物品生成到复杂的游戏机制分析、自动化测试甚至是开发功能完整的Mod。最近在社区里很多朋友在尝试安装UE4SS时遇到了一个经典的Windows权限问题“npm : 无法加载文件 C:\nvm4w\nodejs\npm.ps1因为在此系统上禁止运行脚本。” 这个错误虽然不直接源于UE4SS但它恰恰是许多现代脚本化工具生态比如通过Node.js环境来管理或构建脚本的“入门第一坑”。这从侧面说明了玩转UE4SS这类高级工具你需要的不仅仅是下载文件更需要对现代开发环境、脚本权限和游戏文件结构有一个清晰的认知。本指南的目的就是带你系统性地绕过这些坑从零开始直到你能亲手写出并运行一个属于自己的游戏脚本真正把UE4SS这个强大的工具用起来。2. UE4SS脚本系统核心原理与工作流拆解在深入动手之前理解UE4SS是如何工作的能让你在遇到问题时不再迷茫也能让你更安全、更高效地使用它。2.1 UE4SS的核心架构注入器与脚本引擎UE4SS的核心可以拆解为两部分注入器Injector和脚本运行时环境。注入器通常是一个名为xinput1_3.dll或类似名称的DLL文件。它的工作原理利用了Windows系统加载动态链接库的搜索顺序。当你启动一款游戏时系统会按特定路径顺序寻找游戏运行所需的DLL文件。UE4SS的注入器会伪装成一个系统DLL如xinput1_3这是手柄输入相关的库并被游戏优先加载。一旦加载这个注入器就会在游戏进程内部“安家”为后续操作搭建好舞台。脚本运行时环境则是注入器搭建好的舞台上的“导演和演员”。目前主流是Lua引擎。注入器会初始化一个Lua虚拟机然后从指定目录通常是游戏根目录下的UE4SS-scripts文件夹加载你编写的.lua脚本文件。这些脚本通过UE4SS暴露出的强大API能够直接调用游戏内部的对象、函数、读取和修改内存数据从而实现各种功能。注意这种DLL注入方式属于“外部修改”虽然UE4SS本身设计精良、相对稳定但它依然可能被游戏的反作弊系统如Easy Anti-Cheat, BattlEye检测并导致封号。绝对不要在任何启用反作弊的在线多人游戏中使用它仅限单人模式或官方支持Mod的服务器。2.2 标准工作流与热词问题解析一个标准的UE4SS工作流是这样的准备环境 - 获取UE4SS - 配置 - 编写脚本 - 测试调试。而我们开头提到的热词错误就发生在更前置的“环境准备”环节尤其是当你需要从源码构建UE4SS或者使用一些基于Node.js的社区工具链时。错误信息“npm : 无法加载文件 ... 因为在此系统上禁止运行脚本”其根源是Windows PowerShell的执行策略Execution Policy。出于安全考虑Windows默认禁止运行未签名的本地脚本。npm.ps1是Node.js包管理器npm的PowerShell启动脚本当执行策略为Restricted时它就无法运行导致后续所有npm命令如npm install失败。解决方案这也是你玩转任何现代脚本/开发工具的基础技能以管理员身份打开PowerShell。输入命令Get-ExecutionPolicy查看当前策略。输入命令Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser修改策略。RemoteSigned策略允许运行本地脚本只对来自远程的脚本要求签名对大多数开发场景是安全的。输入Y确认。完成这一步就为你后续可能遇到的、需要命令行工具辅助的Mod开发流程扫清了一个大障碍。3. 从零开始UE4SS的安装与基础配置现在我们进入实战的第一个关键步骤正确安装和配置UE4SS。这里以《幻兽帕鲁》为例但流程适用于绝大多数UE4/UE5游戏。3.1 获取UE4SS发布文件不建议新手直接从源码编译除非你有特定需求。最稳妥的方式是从GitHub Releases页面下载预编译的版本。访问UE4SS的官方GitHub仓库。进入“Releases”页面。寻找最新的稳定版Stable Release。通常文件名会包含版本号和对应的虚幻引擎版本如UE4SS_X.X.X_UE4-UE5。下载压缩包通常是.zip格式。3.2 部署到游戏目录这是最关键的一步路径错了就全盘失效。找到你的游戏安装根目录。例如《幻兽帕鲁》的Steam版通常位于Steam\steamapps\common\Palworld。将下载的UE4SS压缩包全部解压到游戏根目录。解压后你应该能看到UE4SS文件夹、xinput1_3.dll、dxgi.dll等文件直接位于游戏根目录下与Palworld.exe同级。重要选择UE4SS通常提供两种注入DLLxinput1_3.dll和dxgi.dll。前者兼容性更广后者在某些情况下可能更稳定。如果游戏本身不依赖这些DLL大多数独立游戏不依赖你可以任选其一。如果游戏启动失败尝试换用另一个。一个简单的重命名切换即可。3.3 初次启动与验证像平常一样启动游戏。如果安装成功游戏启动时你应该能在屏幕左上角看到UE4SS加载的日志信息通常是白色文字或者按Insert键可以呼出/隐藏UE4SS的图形界面如果有的话。首次运行后UE4SS会在其目录下生成配置文件如UE4SS-settings.ini和日志文件。检查日志文件是排查问题的第一手段。4. 脚本编写入门理解Lua与UE4SS API安装配置只是搭好了舞台真正的主角是你写的脚本。UE4SS主要使用Lua脚本语言它语法简单上手快。4.1 Lua脚本基础结构一个最简单的UE4SS Lua脚本看起来像这样-- 这是一个注释。脚本文件名可以是 my_first_mod.lua local mod {} -- 这是一个在游戏每帧都会调用的函数 function mod.Tick(delta_time) -- 在这里编写你每帧想执行的逻辑 -- 例如检查按键状态 end -- 这是一个在脚本被加载时执行一次的初始化函数 function mod.Initialize() -- 打印日志到控制台或文件 Log.Info([我的第一个Mod] 初始化成功) -- 注册一个按键事件 RegisterKeyBind(F1, function() Log.Info(你按下了F1键) -- 这里可以调用更强大的功能比如生成一个物品 end) end return mod你需要将这样的脚本文件保存到游戏根目录\UE4SS\scripts文件夹下。UE4SS会在游戏启动时自动加载该目录下所有的.lua文件。4.2 核心API与游戏对象交互UE4SS的强大在于它通过Lua暴露了游戏内部的对象。最核心的概念是UE4.FindObject和UE4.StaticFindObject。UE4.FindObject(“对象完整名称”)在游戏运行时查找一个对象如角色类、物品类、函数。UE4.StaticFindObject(...)功能类似但在某些查找场景下更常用。例如在《幻兽帕鲁》中你想获取玩家角色的生命值属性可能会经历这样的查找链先找到玩家的角色类。从类中找到生命值属性的定义UPropertyUE4SS中通常有对应封装。获取当前玩家实例UObject。从实例中读取属性的值。代码可能近似如下具体类名和属性名需要通过UE4SS自带的控制台或对象浏览器工具探查function mod.GetPlayerHealth() local PlayerControllerClass UE4.FindObject(“BlueprintGeneratedClass /Game/.../PlayerController.PlayerController_C”) if PlayerControllerClass then local PlayerController UE4.GetPlayerController(0) -- 获取第一个玩家控制器 if PlayerController and PlayerController.Pawn then local Character PlayerController.Pawn -- 假设生命值属性叫 “CurrentHP” local HealthProp Character:FindProperty(“CurrentHP”) if HealthProp then local HealthValue Character:GetPropertyValue(HealthProp) Log.Info(“当前生命值” .. tostring(HealthValue)) return HealthValue end end end return nil end探查游戏对象是核心技能。你需要熟练使用UE4SS内置的“控制台”或“对象转储”功能输入DumpObjects或FindObject等命令来搜索和确认类名、属性名。这个过程就像在黑暗中用声纳探测地形是Mod开发的必修课。5. 实战演练构建一个“物品生成器”脚本让我们结合一个具体案例将前面的知识串联起来。目标在《幻兽帕鲁》中按下一个快捷键比如F4在玩家面前生成10个木材。5.1 步骤一探查与确认首先我们需要知道物品的类名木材在游戏内部对应的物品类是什么比如可能是BP_Item_Wood_C。生成物品的函数游戏里哪个函数负责在世界中生成一个物品可能是SpawnActor或某个特定的物品管理器函数。玩家的位置和朝向我们需要在玩家面前一定距离的位置生成物品。使用UE4SS的控制台你可以输入Obj Dump /Game/Blueprints/Item/ -- 假设物品蓝图在这个路径下用于模糊搜索或者如果你知道大概名字FindObject Wood从输出的日志中仔细寻找可能的类名。同时你也可以查阅游戏社区的现有Mod或文档这是快速入门的好方法。5.2 步骤二编写脚本框架创建一个新文件SpawnWood.lua。local mod {} local bEnabled false -- 一个开关防止按键连发 function mod.Initialize() Log.Info(“[物品生成器] 脚本已加载”) RegisterKeyBind(“F4”, function() if not bEnabled then bEnabled true mod.SpawnWoodInFront() -- 简单防连发0.5秒后重置开关 CreateThread(function() Sleep(0.5) bEnabled false end) end end) end function mod.SpawnWoodInFront() -- 1. 获取玩家控制器和角色 local PlayerController UE4.GetPlayerController(0) if not PlayerController or not PlayerController.Pawn then return end local PlayerCharacter PlayerController.Pawn -- 2. 计算生成位置玩家位置 前方200单位 * 朝向 local PlayerLocation PlayerCharacter:GetActorLocation() local PlayerRotation PlayerCharacter:GetActorRotation() -- 将旋转角转换为方向向量前向量 local ForwardVector UE4.RotationToVector(PlayerRotation) local SpawnDistance 200.0 local SpawnLocation PlayerLocation (ForwardVector * SpawnDistance) -- 稍微抬高一点避免生成在地里 SpawnLocation.Z SpawnLocation.Z 50.0 -- 3. 查找木材的物品类 (这里需要替换为真实的类名) local WoodItemClass UE4.FindObject(“BlueprintGeneratedClass /Game/Blueprints/Item/BP_Item_Wood.BP_Item_Wood_C”) if not WoodItemClass then Log.Error(“找不到木材物品类”) return end -- 4. 生成物品 local SpawnParams UE4.FActorSpawnParameters() SpawnParams.SpawnCollisionHandlingOverride UE4.ESpawnActorCollisionHandlingMethod.AlwaysSpawn -- 假设使用 GameplayStatics.SpawnActor 这个静态函数 local World PlayerController:GetWorld() if World then for i 1, 10 do -- 每次生成位置略有随机偏移避免完全重叠 local FinalLocation SpawnLocation UE4.FVector( math.random(-20.0, 20.0), math.random(-20.0, 20.0), 0.0 ) local SpawnedActor World:SpawnActor(WoodItemClass, FinalLocation, UE4.FRotator(0,0,0), SpawnParams) if SpawnedActor then Log.Info(“已生成木材 #” .. i) end end end end return mod5.3 步骤三调试与优化将脚本放入scripts文件夹启动游戏。按F4测试。如果没反应首先检查UE4SS日志文件看脚本是否有语法错误加载失败。其次检查控制台是否有你写的Log信息输出。如果游戏崩溃最可能的原因是FindObject找不到类返回了nil或者调用了错误的函数。需要反复确认类名和函数名。务必在关键操作前添加nil判断这是保证脚本健壮性的关键。如果生成了但位置不对调整SpawnDistance和随机偏移量。可以先用Log输出位置坐标看看。这个例子涵盖了查找对象、调用函数、数学计算、线程控制等多个核心概念是一个非常好的综合练习。6. 高级技巧与社区资源利用当你掌握了基础以下技巧能让你如虎添翼。6.1 使用信号Signals与事件Hooks直接每帧检查Tick效率低下。UE4SS允许你“钩住”游戏的特定函数在其被调用时执行你的代码。这称为“信号”。例如你想在玩家每次攻击时触发效果可以查找游戏的攻击函数如ReceiveBeginAttack然后注册一个信号-- 假设找到了攻击函数 local AttackFunc UE4.FindObject(“Function /Game/.../Character.Attack”) if AttackFunc then RegisterSignal(AttackFunc, “Post”, function(self, ...) Log.Info(“玩家发动了攻击”) -- 在这里添加你的自定义效果 end) end“Post”表示在原函数执行之后调用你的函数。还有“Pre”之前。6.2 利用现有Mod与库不要重复造轮子。GitHub、Discord社区如Unreal Modding Community有大量开源UE4SS脚本。学习代码阅读别人的脚本是快速学习API用法和高级技巧的最佳途径。复用模块常见的功能如菜单UIImGui绑定、配置读写、内存操作等都有成熟的库。你可以直接引用这些库到你的脚本中。Mod管理器对于大型Mod考虑使用如“ModLoader”之类的框架来管理依赖和更新。6.3 性能与安全考量性能避免在Tick函数中进行复杂的查找或循环。尽量使用事件驱动Signals。昂贵的操作如遍历所有游戏对象可以放到单独的线程中并控制执行频率。安全再次强调离线使用。定期备份你的存档。复杂的脚本可能引发不可预见的游戏状态错误导致存档损坏。版本兼容游戏更新后内部对象地址和函数签名可能改变导致你的脚本失效。关注游戏更新日志和Mod社区动态。7. 故障排除与常见问题实录即使按照指南操作你也一定会遇到问题。这里记录一些典型场景和解决思路。问题1游戏启动崩溃或UE4SS日志不出现。排查检查DLL文件是否放对了位置游戏根目录。尝试切换xinput1_3.dll和dxgi.dll。查看Windows事件查看器或游戏自带的崩溃报告看是否有相关错误模块。可能原因游戏版本与UE4SS版本不兼容游戏有强反作弊与其他Mod如ReShade、其他注入器冲突。尝试纯净环境测试。问题2脚本文件已放置但游戏内无效果日志也无相关输出。排查首先检查UE4SS主日志文件看是否成功加载了你的脚本文件。可能有语法错误导致加载失败。在脚本开头加一句Log.Info(“脚本开始加载”)测试。可能原因脚本文件编码应为UTF-8 without BOM脚本文件名或路径有特殊字符脚本的mod.Initialize函数没有被正确定义或返回。问题3FindObject总是返回 nil找不到对象。排查这是最常遇到的问题。确认你使用的对象全名包括路径和后缀100%正确。使用控制台的DumpObjects命令配合通配符*进行模糊搜索。例如DumpObjects *Wood*。对象名可能随着游戏更新而改变。技巧有时对象在游戏加载到特定阶段后才存在。尝试将查找代码放在一个延迟执行的函数中或者监听游戏关卡加载完成的事件。问题4调用游戏函数导致崩溃。排查确认你获取到的函数指针是正确的。确认调用函数的“对象实例”self是正确的。游戏函数的参数数量和类型必须完全匹配Lua侧传递的参数类型要正确是UE4.FVector而不是普通的Lua table。方法先尝试调用无参数或参数简单的函数。使用Log.Info打印出每一步获取到的对象地址和类型逐步缩小问题范围。玩转UE4SS的过程本质上是一个“探索-实验-调试”的循环。它赋予你的不仅仅是修改游戏的能力更是一种深入理解软件如何运行、数据如何在内存中组织的思维方式。从解决“禁止运行脚本”这样的系统权限问题到成功让第一行自己的代码在游戏世界里产生效果每一步的突破都会带来巨大的成就感。记住社区是你最强的后盾多读、多问、多实验这片由代码构成的游戏模改天地等待着你来留下自己的创意。

相关新闻

模板驱动文档自动化:零代码实现业务文档工业化

模板驱动文档自动化:零代码实现业务文档工业化

1. 项目概述:当文档生产变成“填空题”,而不是“写作文”你有没有经历过这种场景:每周一早上,市场部同事准时把一份《月度客户反馈摘要》模板发到群里,要求销售、客服、产品三个部门各自填入数据,再汇总成P…

2026/10/15 7:31:32 阅读更多 →
虚幻4 HTTP服务器插件开发:实现游戏与外部系统的实时API交互

虚幻4 HTTP服务器插件开发:实现游戏与外部系统的实时API交互

1. 项目概述:为什么虚幻4项目需要一个HTTP服务器?如果你正在用虚幻引擎4开发一个项目,无论是游戏、模拟器还是数字孪生应用,你很可能遇到过这样的需求:需要从外部系统(比如一个Web管理后台、一个移动端App&…

2026/10/15 8:10:32 阅读更多 →
UE4卡通渲染全流程实战:从硬边阴影到轮廓描边的材质实现

UE4卡通渲染全流程实战:从硬边阴影到轮廓描边的材质实现

1. 项目概述:UE4卡通渲染材质全流程如果你也和我一样,被《原神》、《塞尔达传说:旷野之息》或者《崩坏3》那种干净利落、充满表现力的画面所吸引,并且琢磨着怎么在UE4里实现类似的效果,那这篇分享就是为你准备的。卡通…

2026/10/15 8:10:32 阅读更多 →

最新新闻

ponytail:把终端命令变成可复用技能的高效自动化工具

ponytail:把终端命令变成可复用技能的高效自动化工具

ponytail。第一次在同事的终端里看到这个词,我还以为是某个桌面对弈壁纸的花名。直到他现场敲了两行命令,把原本我得翻半天历史记录、拼接七八条命令才能完成的日志分析,变成了问候式的一行pt log --path access.log --top 5,我才…

2026/10/15 13:46:16 阅读更多 →
TileLang是什么?当前不存在的领域专用语言解析

TileLang是什么?当前不存在的领域专用语言解析

我无法根据当前输入生成符合要求的博文。原因如下:项目标题“tilelang”本身缺乏明确语义指向:它既不是广为人知的编程语言(如 Python、Rust)、也不是主流开源项目(如 Zig、Vlang、MoonScript)、更非已建立…

2026/10/15 13:46:16 阅读更多 →
Tilelang不存在:编程语言术语辨伪与技术查证方法

Tilelang不存在:编程语言术语辨伪与技术查证方法

我无法生成关于“tilelang”的博文内容。原因如下:根据当前公开可查的权威技术资料、主流编程语言官网(如Python、Rust、Haskell、OCaml等)、知名开源平台(GitHub、GitLab)、学术数据库(arXiv、ACM DL&…

2026/10/15 13:46:16 阅读更多 →
机器人动力学约束路径规划:从几何路径到物理可行轨迹

机器人动力学约束路径规划:从几何路径到物理可行轨迹

1. 为什么“能走通”的路径,在真实机器人上反而会翻车?“移动机器人运动规划(四)——动力学约束下的路径规划”,这个标题里藏着一个绝大多数初学者甚至不少工程实践者都曾踩过的深坑:把几何路径规划当成运动…

2026/10/15 13:46:16 阅读更多 →
双芯光纤SPR传感技术及COMSOL仿真优化

双芯光纤SPR传感技术及COMSOL仿真优化

1. 项目背景与核心价值双芯光纤表面等离子体共振(SPR)传感技术是近年来光纤传感领域的重要突破方向。这种将两个纤芯集成在单根光纤中的特殊结构,相比传统单芯光纤SPR传感器具有更高的灵敏度和更好的稳定性。我在实际研究中发现,当…

2026/10/15 13:46:16 阅读更多 →
第一次做 GEO 要几步?从注册到第一篇内容被收录的启动路径

第一次做 GEO 要几步?从注册到第一篇内容被收录的启动路径

结论先放这儿:6 步。注册 → 搭知识库 → 生成用户问题 → 攒标题 → 补正文 → 跑监测。前 4 步搭台子,第 5 步出第一篇成稿,第 6 步验证它有没有被 AI 读到。先说这篇是写给谁的 如果你刚注册完 GEOchat,打开后台看到「知识库、…

2026/10/15 13:45:15 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →