更新抑制

此页面介绍的是使用异常跳过方块更新及其之后代码的做法。关于基岩版中可造成方块更新延迟的同名特性，请见百家号上的“**更新抑制（基岩版）**”。
关于游戏由于方块更新次数过多而跳过方块更新的现象，请见“**更新跳略**”。关于游戏由于光照更新过多而与主线程不同步，使得光照更新延缓很久的现象，请见“**光照更新抑制**”。关于其他含义，请见“**更新抑制（消歧义）**”。

* 这并不代表所有方法均已移除，新的方法正在等待玩家发现与公布。

**更新抑制（Update Suppression）**是指在方块更新传播过程中，迫使游戏停止当前方块更新过程，跳过所有未执行的方块更新，以及更新后的一系列其他游戏逻辑。**更新抑制器（Update Suppressor）**则是用于完成更新抑制的装置。

更新抑制允许玩家引起部分方块的方块更新，而避免其他方块更新，故可以用于进行切门、将方块放置在通常不可能存在的位置等；还由于可以取消后续的其他逻辑，可以用来复制方块、物品分身、方块实体替换。更新抑制器还可以用于制造可控的服务端崩溃。

**警告：**这些装置有较大的风险导致游戏崩溃甚至存档损坏，建造及使用时请小心。若你仅需要跳过方块更新但无法承担此风险，请使用更新跳略。

原理
--

正常情况下，游戏不会跳过所应该执行的逻辑。因此更新抑制都是通过游戏漏洞来完成的。更新抑通常制是使用特定方式触发程序抛出异常或错误，且该异常抛出后在特定位置被捕获，从而跳过本应执行的逻辑。如果触发了异常但游戏并未将其捕获，则会导致游戏崩溃甚至存档损坏。

一种常用的方式是由玩家操作来引发游戏抛出异常。游戏服务端在处理来自客户端的数据包时，发生的任何异常都会被及时捕获，在游戏日志中记录下**无法处理数据包（Failed to handle packet）**，而不会引发游戏崩溃。因此如果异常的抛出是由玩家的客户端操作直接引起的（俗称“玩家更新”或“玩家操作”，下文称“玩家操作”），且不是对着BUD链上的黏性活塞作出[需要测试]，则不会使游戏崩溃。但如果意外由其他方式引起异常，往往会使游戏崩溃，甚至存档损坏。

另外一种可能的方式是引起JVM错误，如内存溢出错误。在比较器产生的特定方块更新中，所有异常或错误都会被捕获，并抛出一个崩溃异常。该崩溃异常又可以通过上一种方式由玩家操作捕获，从而避免崩溃。但若使用内存溢出错误，还需要保证异常被捕获后已经释放足够的内存来使游戏继续运行。

举例来说，以下常见事件属于“玩家操作”：

* 玩家放置、破坏方块
* 玩家拉动拉杆
* 玩家按下按钮
* 玩家踩下压力板
* 玩家点火
* 玩家引爆末地水晶、重生锚等

以下事件**不**属于“玩家操作”：

* 活塞伸出/收回
* 侦测器反应
* 中继器，比较器的反应
* 按钮弹起
* 压力板弹起
* 箭射中按钮
* 火由于计划刻或随机刻改变状态或熄灭
* 非玩家实体激活压力板
* TNT实体的爆炸
* Carpet模组中的`/player <name> attack`、`/player <name> place`

### 与更新跳略的区别

        参见：切门

更新抑制与更新跳略有着本质上的不同，但许多玩家经常混淆它们。下面给出了更新抑制的一些特点。

* 更新抑制是利用漏洞进行的，属于BUG。

Template:Schematic

* 触发更新抑制后，该游戏刻的剩余代码将被跳过；触发更新跳略前已被规划的方块更新在更新跳略后仍会执行，但是它们造成的连锁方块更新将会被跳过。例如拆除图中的活塞，铁门将完整保留。

* 更新抑制是利用漏洞进行的，而更新跳略是故意为之的特性。

Template:Schematic

* 触发更新抑制后，该游戏刻的剩余代码将被跳过；触发更新跳略前已被规划的方块更新在更新跳略后仍会执行，但是它们造成的连锁方块更新将会被跳过。例如使用更新抑制切门中破碎的传送门方块毗邻的传送门方块在使用更新跳略切的门中也会破碎。若图中BUD链连接到更新抑制器，拆除活塞，铁门将完整保留；若连接到更新跳略器，拆除活塞，铁门只能保留上半部分。

## 内存溢出更新抑制

  “**OOM**”重定向至此。关于基于内存溢出的区块保存抑制，请见“**区块保存抑制**”。
**内存溢出（Out of Memory，简称OOM）更新抑制**，又称**更新冻结（Update Freezing）**，是通过填满内存，让游戏抛出内存溢出异常的更新抑制方式。

原作者的机器是为4395MB的内存设计的，但实际需要的内存可能会有浮动。该机器需要在服务端上运行。

### 原理

进行这种抑制需要玩家恰到好处地填充游戏内存，这样在需要更新抑制时，游戏内存就会溢出。为了填满内存，可以使用位于未加载区块中的乱码书和填充方块事件列表。

填充方块事件列表有几种方法：使用活塞阵列填充和使用飞行器填充。使用活塞阵列需要约37万个活塞，使用飞行器可以省去大量活塞，但需要挂机较长时间。

使用内存溢出错误，还需要保证异常被捕获后已经释放足够的内存来使游戏继续运行。

### 结构

更新冻结器是一个很庞大的机器（活塞阵列版本约856×10×2830，飞行器版本约732×100×3936），由很多部分构成。

结构

#### 活塞阵列

为填充足够的内存，活塞阵列版更新冻结器需要28×192=5376个**活塞阵列**单元，由192列的无延迟信号传输链传输信号，总大小约为640×8×576。

#### 飞行器

为填充足够的内存，飞行器版更新冻结器需要25个**飞行器**单元飞行[需要更多信息]m，飞行器本身总大小约为3×100×11。

#### 安全网

**提示**：本段落的主题不是**#铁轨更新抑制器**。
**安全网（Safety Buffer）**是用于释放少量内存，预防游戏崩溃的部分，大小为130×5×29。

 File:Update Freezer-Safefy Buffer(Redstone part).png
左侧图片是安全网的俯视图，使用了混凝土标记数据。在中继器旁突出的混凝土下方是机器铁轨下凹的部分，样式如右侧图片。

#### 防崩BUD音符盒

 File:Update Freezer-BUD NoteBlock.png
右侧图片展示了适用于活塞阵列版的BUD音符盒阵列。从图中的调试屏幕可知，音符盒未激活。它们可用于防止方块事件列表一直尝试扩容，从而预防一些问题以减少崩溃。

 File:Update Freezer-BUD NoteBlock(Fly Tec).png
右侧图片展示了适用于飞行器版的BUD音符盒阵列。从图中的调试屏幕可知，音符盒已激活。这种阵列更易于机器复位，只需要拉一下拉杆即可。

#### BUD活塞

这些BUD活塞会在接收到BUD链的信号后几乎同时加入方块事件列表，由于之前加入列表的内容过多，此时该列表会扩容，从而占满内存。

 File:Update Freezer-BUD Pistons.png
这是飞行器版本的BUD活塞，对于活塞阵列版本，需要去掉左侧的2个BUD活塞以及连接它们的比较器。

在原视频所用版本，连接它们的比较器需要在活板门关闭时放置，全部放置完毕后打开活板门。在最晚可用版本中，连接它们的比较器需要使用其他跳过方块更新的手段（如更新跳略）放置。

#### BUD链

        参见：BUD链

BUD链可以将需要抑制的更新信号引导到安全网和BUD活塞处。

## 强转抑制

        参见：关于强转抑制器的笔记

“

这可不是一台更新跳略器，这是一台货真价实的更新抑制器！

”
——**Void0**
**强转抑制（Cast Suppression）**，或**CCE更新抑制（CCE Suppression）**，是通过玩家操作引起游戏抛出`ClassCastException`类型转换异常的更新抑制方式。

该方法需要将特定的方块实体替换为潜影盒，这一过程需要通过更新抑制进行。成功制造这样一个潜影盒之后，放置一个检测它的比较器，这个比较器就具有更新抑制的能力。

### 原理

**类型转换异常（ClassCastException，简称CCE）**是Java的一个运行时异常，当一个对象的类型被强制转换到一个它不符合的类型的时被抛出。更新抑制可以通过方块实体替换抛出CCE实现。

潜影盒计算自己的比较器输出时，会先获取自己的方块实体，并强制类型转换为物品栏。其他容器类方块都没有这类不加判断的类型转换，所以这类更新抑制装置必须用潜影盒建造。

如果让一个潜影盒拥有非物品栏的方块实体，那么每当要计算它应有的比较器输出时，就会抛出CCE。这可以通过方块实体替换来实现。

将一个比较器背对这样的潜影盒放置，每次更新这个比较器时，就会重新计算一次该输出的能量以判断是否应该更新其状态，于是引发异常。这个潜影盒和比较器两者就构成了一个没有状态、不需要重置的强转抑制器。

### 建造

        主条目：方块实体替换

建造强转抑制器需要先进行方块实体替换。合适的带有方块实体且无物品栏的方块包括讲台（1.14及以上）和唱片机（1.11-1.13），它们被破坏时，在删除自己的方块实体之前会先发出一次方块更新。玩家可以用别的更新抑制方法打断逻辑，跳过删除方块实体这一步。

 File:Make CCE Suppressor before 1.17.gif
正在发出红石信号的讲台被破坏的时候，会在删除方块实体之前更新自己下方的毗邻，此时触发更新抑制就可以保留方块实体。讲台发出红石信号的时长只有2游戏刻，但是也可以通过额外的一次更新抑制来使讲台保持激活状态，因为在1.17以下，栈溢出更新抑制仍然适用，额外一次更新抑制成本不高。玩家翻书时，讲台发出信号，激活动力铁轨，并触发更新抑制。由于讲台发出信号早于讲台计划解除激活状态的计划刻，所以计划刻没有产生，讲台保持激活状态。这种制作方法也适用于1.17及以上，但由于需要多次触发更新抑制，这种方法略显麻烦。

 File:Make CCE Suppressor in 1.17.png
在1.17及之后的版本，放有书的讲台被破坏时，会在删除自己的方块实体之前发出一次比较器更新。因此，还可以直接破坏对着更新抑制器的浮空比较器后面的有书的讲台，如右图。

保留了讲台的方块实体后，在其位置放置一个潜影盒，由于该位置已经存在方块实体，潜影盒不会产生新的方块实体，这就实现了方块实体替换。这就是强转抑制器的核心，更新一个从它这里取输出的比较器，就会触发强转抑制。

### 应用

        参见：物品分身

 File:Usage of CCE Suppression.png

将物品放入投掷器时，投掷器物品栏发生变化，发出比较器更新，抑制器中的比较器重新计算自己的输入信号，并触发更新抑制。这样就完成了一次物品分身。连续这样操作就可以很快地制作物品分身，这是目前已知的最好的物品分身的制作方法。

强转抑制器是无状态的，每次更新比较器时，一般都会抛出异常，但也可能不会抛出。异常的触发是在计算潜影盒输出的时候发生的，如果收到的更新不会使比较器重新计算输入，就不会抛出异常。

强转抑制器是在比较器从潜影盒取输出时发生的，所以如果没有比较器，就不会触发更新抑制。你也可以在比较器和潜影盒之间放置一个红石导体，其被充能到15信号强度时，会屏蔽后面的容器，比较器就不会计算容器的输出，这样可以关闭强转抑制器。

按本教程做出的强转抑制器的比较器输出为15，这个输出也可用于更新抑制。

#### 连接BUD链

 File:CCE Suppressor (simple BUD line).png
右图展示了强转抑制器连接水平连续式BUD链的方式。钻石块上方的结构方块上方的方块及对应的结构分别对应左侧结构方块及结构。

### 错误报告

下面是强转抑制的服务端错误报告和崩溃报告，可供技术玩家参考。

* 未崩溃的错误报告
* 崩溃后的崩溃报告

## 栈溢出更新抑制

**栈溢出（Stack Overflow）更新抑制**是利用方块更新的大量传播填满栈，让游戏抛出栈溢出异常来实现更新抑制的方法。

### 原理

这种更新抑制器会引起足够的方块更新，向栈中添加大量数据来导致栈溢出，此时游戏会抛出栈溢出异常。根据不同操作系统中JVM默认的栈的大小不同，所需要的方块更新数量不同，抑制器所需的大小也就不同。

### 极简更新抑制器

        参见：更新跳略#极简更新跳略器

此装置使得在1.16（20w18a）至1.17.1进行更新抑制的成本大大降低。但在1.17至1.17.1中有可能造成未知原因的崩溃，1.18至1.18.2中该机器会由于未知原因会导致崩溃[需要更多信息]，但这些版本中重新进入后都会成功更新抑制；1.20-pre2及以后，红石线会连接四周开启的活板门上的红石线，导致该装置彻底失效。

活板门应使用木质活板门，且其在关闭时应在方块的上半部分。在活板门上要放置红石线。

使用这个机器前建议打开游戏声音。使用机器需要先打开活板门，之后敲击音符盒B。若敲击音符盒时机器**未**发出活板门声，则可关闭活板门，此时更新抑制完成就位。否则需要先打开活板门，敲击音符盒A，此时活板门会关闭。之后即可再次尝试。也可以通过使用红石信号强/弱充能音符盒A再取消充能完成一次复位。

右侧是上方更新抑制器的连接侦测器式BUD链的方法。图中侦测器用于复位这个更新抑制器。

这是3gt自复位更新抑制器，装置需要朝向南方。该机器用于更新跳略时无法自复位，但可以手动复位。在使用此机器触发一次更新抑制后，在音符盒B上方放置朝上的活塞即可完成制作。

### 铁轨更新抑制器

**提示**：本段落的主题不是**#安全网**。
**铁轨更新抑制器**是1.18.2及以下版本中玩家最常使用的更新抑制器，也是研究最为成熟的更新抑制器。这种更新抑制器从上往下可以看到大量铁轨。

 File:Stack Overflow Suppressor.png

### 错误报告

下面是栈溢出更新抑制的服务端错误报告和崩溃报告，可供技术玩家参考。

* 未崩溃的错误报告
* 崩溃后的崩溃报告

历史
--

在22w11a中，更新的存储从栈更改为队列[需要更多信息]，更新顺序不再颠倒，因此栈溢出更新抑制被修复，这在MC-249082中被认为是按预期工作。然而，这个更新在22w12a中修复，取而代之的是更新跳略。

 1.17 | ?
 1.18 | ?
 2023年4月17日
 2023年6月14日
 ?

画廊
--

Update Freezer (vert view).png内存溢出更新抑制器（活塞阵列版）的主要部分CCE Suppressor (simple BUD line).png带普通连续式BUD链的强转抑制器的概览图和分层图。钻石块上方的结构方块上方的方块及对应的结构分别对应左侧结构方块CCE Suppressor (vert BUD line).png带垂直BUD链的强转抑制器的概览图。强转抑制器及BUD链在结构方块的白线内Stack Overflow Suppressor.png普通栈溢出更新抑制器，带一小段BUD链Stack Overflow Suppressor (vert BUD line).png带垂直BUD链的栈溢出更新抑制器
视频
--

* 栈溢出更新抑制、BUD链
* 内存溢出更新抑制
* 强转抑制

栈溢出更新抑制、BUD链
Template:Yt
Template:Bv
Template:Bv
Template:Bv
Template:Bv

极简更新抑制器
Template:Bv

内存溢出更新抑制
Template:Bv

Template:Bv

强转抑制
Template:Bv
Template:Bv
Template:Bv

Template:Bv
## 外部链接

* #强转抑制的来源：关于强转抑制器的笔记 —— Void0
* #极简更新抑制器中自复位版本的来源：3gt自复位更新抑制器 —— MC-cubes
* 6gt自复位更新抑制器 —— Bot\_City
* [Minecraft生电漫游指南]更新抑制专题:都2023年了还不会玩更新抑制? —— 猪哥Bro\_Pig
* 浅谈更新抑制器与注意事项 —— xingjiFIUG
* Minecraft失效特性Wiki：Java版:更新抑制（英文）
* 红石电路原理/方块更新与延迟理论的拓展#更新抑制 —— Xiaoyuan-xyz
* 深度剖析Minecraft #2 方块更新（2.7 更新抑制） —— Fallen\_Breath

参见
--

* 方块更新
* 中文Minecraft Wiki上的崩溃
* 更新抑制（消歧义）
* BUD链
* 更新跳略
* 光照更新抑制
* 切门

参考
--

1. ↑ 玩家可能会选择保密一段时间以增加可用版本区间
2. ↑ MC-249181 — “动力铁轨和激活铁轨的更新顺序被颠倒了。” — 漏洞状态为“已修复”。
3. ↑ “Update Suppression, Block Duplication, Skull Converter and More” – Panda4994。YouTube，2016年6月11日。（Bilibili搬运 BV1Ws411v7d2 Bilibili搬运）
4. ↑ “[1.19+] Update Suppression is back to stay” – FX - PR0CESS。YouTube，2023年4月17日。（Bilibili搬运）
5. ↑ “Minecraft Update Suppression is Back: The OOM Method that Bypasses Mojang's Patch” – Igna778。YouTube，2023年4月17日。（Bilibili搬运）
6. ↑ HackerRouter的动态 — 哔哩哔哩
7. ↑ “Shulker Suppression - The Ultimate Update Bug That Cant Be Patched!” – Igna778。YouTube，2023年6月15日。（Bilibili搬运）

注释
--

1. ↑ 1.0 1.1 原存档中使用的是该方块
2. ↑ 2.0 2.1 原存档中（9290，-50，-12515）和（9290，-50，-12810）处向东看可看到部分活塞阵列不完整
3. ↑ 部分视频中两个内容都有讲解

## 许可协议

此页面的内容来源于Minecraft Wiki上的MCW:沙盒/教程/更新抑制页面，且对原内容进行了更改。

因此这些内容在CC BY-NC-SA许可协议下提供。（中文原文）