Skip to content

Commit

Permalink
feat: be undo
Browse files Browse the repository at this point in the history
  • Loading branch information
zly2006 committed Aug 12, 2023
1 parent 8ef50ae commit aa30c20
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 4 deletions.
14 changes: 13 additions & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,21 @@
- [ ] RVCHub,通用的机器分享平台,以及自动识别机器是否进行了正确的版权标注
- [ ] RVCSign,签名您的机器,通用简单的步骤保证您的机器不被篡改或伪造
- [ ] 微时序分析和模拟:方块更新断点(NC, PP, CU, BE)、BED调试器、逐更新、逐tick、更新重置
- [x] Ctrl+Z立刻回退上一步操作,机器研发不再需要备份!(等待更多测试)
- [x] Ctrl+Z立刻回退上一步操作,机器研发不怕误操作!(仅方块和计划刻)
- [ ] 机器的自动化单元测试,将您的机器分成一个个模块并独立测试,保证每一个模块都正确运行

## 其他功能

1. 命令快捷键,可以使用masa快捷键依次执行多条指令
2. 实体真实位置显示,以动画不流畅为代价换取碰撞箱实时更新(调试中:有可能造成运动抽搐)
3. 珍珠炮计算(WIP)
4. 聊天框右键工具(SuperRight)已完成
5. 物品栏右键工具(SuperRight),计划
6. 方块右键工具(SuperRight),计划
7. 实体右键数据修改工具(SuperRight),计划
8. RVC原理图右键工具(SuperRight),等待rvc完成
9. RVC导出原理图,完成

## 著作权保护

RVC可以帮助您保护您的著作权,通过定时或手动记录您的更改,保留您的每一点创作痕迹,以便您在需要的时候证明您的著作权。
Expand Down
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ dependencies {
modImplementation "curse.maven:carpet-349239:4573334"
// Game test
testImplementation "net.fabricmc:fabric-loader-junit:${project.loader_version}"
include(implementation("org.bouncycastle:bcprov-jdk18on:1.76"))
include(implementation("org.bouncycastle:bcpg-jdk18on:1.76"))
}

test {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.github.zly2006.reden.mixin.undo;

import com.github.zly2006.reden.access.ScheduledTickAccess;
import net.minecraft.server.world.BlockEvent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;

@SuppressWarnings("AddedMixinMembersNamePattern")
@Mixin(BlockEvent.class)
public class MixinBlockEvent implements ScheduledTickAccess {
@Unique
long undoId;

@Override
public long getUndoId() {
return undoId;
}

@Override
public void setUndoId(long l) {
undoId = l;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;

@SuppressWarnings("AddedMixinMembersNamePattern")
@Mixin(OrderedTick.class)
public class MixinScheduledTick implements ScheduledTickAccess {
@Unique
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.github.zly2006.reden.mixin.undo;

import com.github.zly2006.reden.access.PlayerData;
import com.github.zly2006.reden.access.ScheduledTickAccess;
import com.github.zly2006.reden.mixinhelper.UpdateMonitorHelper;
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
import net.minecraft.server.world.BlockEvent;
import net.minecraft.server.world.ServerWorld;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

@Mixin(ServerWorld.class)
public class MixinServerWorld {
@Redirect(
method = "addSyncedBlockEvent",
at = @At(
value = "INVOKE",
target = "Lit/unimi/dsi/fastutil/objects/ObjectLinkedOpenHashSet;add(Ljava/lang/Object;)Z",
remap = false
)
)
private boolean onAddBlockEvent(ObjectLinkedOpenHashSet<BlockEvent> instance, Object curr) {
if (curr instanceof ScheduledTickAccess access) {
PlayerData.UndoRecord recording = UpdateMonitorHelper.INSTANCE.getRecording();
if (recording != null) {
access.setUndoId(recording.getId());
}
}
return instance.add((BlockEvent) curr);
}
@Inject(
method = "processBlockEvent",
at = @At(
value = "INVOKE",
shift = At.Shift.BEFORE,
target = "Lnet/minecraft/block/BlockState;onSyncedBlockEvent(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;II)Z"
)
)
private void beforeProcessBlockEvent(BlockEvent event, CallbackInfoReturnable<Boolean> cir) {
UpdateMonitorHelper.INSTANCE.setRecording(
UpdateMonitorHelper.INSTANCE.getUndoRecordsMap().get(((ScheduledTickAccess) event).getUndoId())
);
}
@Inject(
method = "processBlockEvent",
at = @At(
value = "INVOKE",
shift = At.Shift.AFTER,
target = "Lnet/minecraft/block/BlockState;onSyncedBlockEvent(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;II)Z"
)
)
private void afterProcessBlockEvent(BlockEvent event, CallbackInfoReturnable<Boolean> cir) {
UpdateMonitorHelper.INSTANCE.setRecording(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ object UpdateMonitorHelper {
return recording!!
}

private fun removeRecord(id: Long) = undoRecordsMap.remove(id)
internal fun removeRecord(id: Long) = undoRecordsMap.remove(id)
@JvmStatic
fun playerStartRecord(player: ServerPlayerEntity) {
val playerView = player.data()
Expand All @@ -111,7 +111,7 @@ object UpdateMonitorHelper {
if (playerView.isRecording) {
playerView.isRecording = false
recording = null
playerView.redo.clear()
playerView.redo.onEach { removeRecord(it.id) }.clear()
if (playerView.undo.lastOrNull() != null) {
if (playerView.undo.last().data.isEmpty()) {
removeRecord(playerView.undo.last().id)
Expand Down
1 change: 1 addition & 0 deletions src/main/java/com/github/zly2006/reden/network/Rollback.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class Rollback(
val view = player.data()
UpdateMonitorHelper.playerStopRecording(player)
fun operate(record: PlayerData.UndoRecord): PlayerData.UndoRecord {
UpdateMonitorHelper.removeRecord(record.id) // no longer monitoring rollbacked record
val ret = PlayerData.UndoRecord(record.id, record.data.keys.associateWith {
PlayerData.Entry.fromWorld(
player.world,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class TntSyncPacket(
syncedTntPos.clear()
}
if (isClient) {
ClientPlayNetworking.registerGlobalReceiver(pType) { packet, client, sender ->
ClientPlayNetworking.registerGlobalReceiver(pType) { packet, client, _ ->
pearlTask?.onTntSyncPacket(packet)
if (DEBUG_LOGGER.booleanValue) {
client.sendMessage("TntSyncPacket: TNT${packet.tntPower} @ ${packet.tntPos}")
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/com/github/zly2006/reden/utils/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import net.minecraft.util.Identifier
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Vec3d
import net.minecraft.world.World
import kotlin.io.path.exists
import kotlin.io.path.readBytes
import kotlin.io.path.toPath

lateinit var server: MinecraftServer

Expand Down Expand Up @@ -53,6 +56,14 @@ object ResourceLoader {
return stream.readAllBytes()
}
else {
val e = this::class.java.classLoader.resources(".").map {
it.toURI().resolve(path)
}.filter {
it.toPath().exists()
}.findFirst().map {
it.toPath().readBytes()
}
if (e.isPresent) return e.get()
throw RuntimeException("The specified resource $path was not found!")
}
}
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/reden.accesswidener
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ accessible field net/minecraft/entity/vehicle/AbstractMinecartEntity clientX D
accessible field net/minecraft/entity/vehicle/AbstractMinecartEntity clientY D
accessible field net/minecraft/entity/vehicle/AbstractMinecartEntity clientZ D
extendable class net/minecraft/world/tick/OrderedTick
extendable class net/minecraft/server/world/BlockEvent
2 changes: 2 additions & 0 deletions src/main/resources/reden.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
"pearl.MixinExplosion",
"tick.MixinTick",
"tick.MixinWatchdog",
"undo.MixinBlockEvent",
"undo.MixinCommands",
"undo.MixinPlayerMode",
"undo.MixinSchedule",
"undo.MixinScheduledTick",
"undo.MixinServerWorld",
"undo.MixinServerWorldChunk",
"undo.MixinUpdater"
],
Expand Down

0 comments on commit aa30c20

Please sign in to comment.