最近又开始玩MC了,自己弄了个整合包,以AE2、Mek和沉浸工程为主。自从玩过了东方女仆mod和TACZ枪械mod了,我就再也离不开这两个mod了——女仆能拿枪,这就无敌了啊。可是这个整合包玩着玩着,我突然发现我女仆没了?用卷轴定位说是在未加载区块上,可是我tp到了对应的座标,就是不见我的女仆。于是一场惊心动魄的救援行动就此展开——
背景
因为有和朋友联机的需求,所以开了个服务器。因为当时正在搞乙烯发电厂,打算开创造找个远一点(指7万方块之外)的地方设计一下怎么搞。结果忘记让女仆待在家里,就跟着传送了过来,她在旁边突突突打怪,我也没管她。我记得当天夜里一路玩到凌晨两点,虽然设计出了16个燃气发电机、发电容量为1MFE/t的设计,但现实中我都困的不行了,于是就tp回家,改成生存就下线了。下线之后NAS有个更新,需要重启服务器,自然也有需要重启容器中的游戏服务端,我不知道这是否是女仆丢失的原因。但我查阅了github上的issue区,只找到一篇相关的问题报告,但模组作者没有回应,大哥自己把issue关了。
救援计划
发现女仆消失后,我立刻放下手中的任务,开始思索如何把女仆带回来。目前来看,仆人铃和小号都无法召回女仆,因为模组认为女仆在未加载区块上。如果生成新的女仆,那么原来的女仆还是会存在,并且一直处于这种幽灵状态。由于仆人铃在绑定时会显示uuid,于是我推断模组应该是给每个女仆都设定了uuid作为id,如果我能让模组重新生成一个具有相同uuid的女仆,就算不能把原来的女仆带回来,至少也能顶掉原来的女仆进而修正这个幽灵状态。索性这个mod是开源的,而我正好略懂一些kotlin/jvm的编程技巧,于是我便冲到GitHub上查阅源码。
根据源码可知,女仆的数据是存储在nbt标签中的,所以只要我们能够提取到女仆的UUID,然后把它移花接木到魂符上就行了。
实施救援
由于不想把事情搞得太麻烦,所以我是根据我自己的情况进行的修复。如果大家也遇到了类似的情况,可以发动自己的脑筋,再不济去解析一下游戏的存档,总能找到uuid的。
由于我先前绑定过仆人铃,而仆人铃刚好就是把女仆的uuid存在nbt里的,所以主手拿着仆人铃,执行以下命令:
/data get entity @p SelectedItem
这个命令会在聊天窗口显示nbt数据,但游戏内不好复制,于是我从启动器的控制台日志里面复制出了结果:
{
id: "touhou_little_maid:servant_bell",
tag: {
ServantBellTip: "女仆名称",
ServantBellUuid: [I; -1136390084, -1170784113, -1271669764, -260320852]
},
Count: 1b
}
虽然长得很像json,但实际不是。总之,可以看到里面有个ServantBellUuid
,后面虽然不是uuid的常见形式,但熟悉uuid的话应该能看出,这是把字节数据当成整数给表示出来了。
下面我们就可以找一个魂符来移花接木了。其实理论上用胶片也行,但是你得手动复活。
退出服务器,我创建了一个单人的存档,召唤了一个女仆,然后把它收进魂符里面,使用上面的命令查看nbt数据:
{id: "touhou_little_maid:smart_slab_has_maid", tag: {MaidInfo: {CanUpdate: 1b, MaidExperience: 0, SoundPackId: "littlemaid_peco", MaidBackpackData: {}, LeftHanded: 0b, MaidAIChatData: {ChatTemperature: -1.0d, ChatModel: "", CustomSetting: "", TtsModel: "", TtsSiteName: "", ChatSiteName: "", OwnerName: "", TtsLanguage: ""}, AbsorptionAmount: 0.0f, MaidHunger: 0, Invulnerable: 0b, IsYsmModel: 0b, ForgeCaps: {"tacz:synced_entity_data": [], "mekanism:radiation": {radiation: 1.0E-7d}, "curios:inventory": {Curios: []}}, MaidSchedulePos: {Work: {Z: -1374, X: -320, Y: 63}, Dimension: "minecraft:overworld", Configured: 0b, Idle: {Z: -1374, X: -320, Y: 63}, Sleep: {Z: -1374, X: -320, Y: 63}}, ModelId: "geckolib:foxmaid", ArmorDropChances: [0.085f, 0.085f, 0.085f, 0.085f], MaidBackpackType: "touhou_little_maid:middle_backpack", HandDropChances: [0.085f, 0.085f], MaidBaubleInventory: {Size: 9, Items: []}, ForcedAge: 0, MaidIsRideable: 1b, MaidScriptBook: [], MaidScheduleMode: "DAY", ArmorItems: [{id: "minecraft:iron_boots", Count: 1b, tag: {Damage: 59}}, {id: "minecraft:iron_leggings", Count: 1b, tag: {Damage: 59}}, {id: "minecraft:iron_chestplate", Count: 1b, tag: {Damage: 59}}, {id: "minecraft:iron_helmet", Count: 1b, tag: {Damage: 59}}], FavorabilityManagerCounter: {WorkMeal: 2352, Sleep: 8780, Death: 0}, StructureSpawn: 0b, MaidTaskInventory: {Size: 9, Items: []}, MaidInventory: {Size: 36, Items: [{Slot: 0, Count: 22b, id: "minecraft:bread"}, {Slot: 5, Count: 1b, tag: {AllTypeCreative: 1b, AmmoCount: 2147483614}, id: "tacz:ammo_box"}]}, MaidIsPickup: 0b, YsmRoamingVars: {}, UUID: [I; -1136390084, -1170784113, -1271669764, -260320852], ForgeData: {}, StruckByLightning: 0b, YsmRoamingUpdateFlag: 0, Motion: [0.0d, -0.0784000015258789d, 0.0d], MaidGameSkillData: {}, CanPickUpLoot: 0b, Fire: -1s, MaidFavorability: 384, PersistenceRequired: 0b, DeathTime: 0s, MaidTaskDataMaps: {}, OnGround: 1b, YsmModelId: "", MaidHideInventory: {Size: 1, Items: []}, KillRecord: {Slime: 0, Wither: 2, KillRecord: 2, EnderDragon: 0}, Attributes: [{Name: "gunsmithlib:bullet_speed", Base: 0.0d}, {Name: "minecraft:generic.max_health", Base: 80.0d}, {Name: "gunsmithlib:bullet_damage", Base: 0.0d}, {Name: "forge:entity_gravity", Base: 0.08d}, {Name: "tacz:tacz.bullet_resistance", Base: 0.0d}, {Name: "minecraft:generic.armor", Base: 0.0d}, {Name: "minecraft:generic.armor_toughness", Base: 0.0d}, {Name: "forge:step_height_addition", Base: 0.0d}, {Name: "minecraft:generic.attack_damage", Base: 6.0d}, {Name: "forge:swim_speed", Base: 1.0d}, {Name: "minecraft:generic.movement_speed", Base: 0.699999988079071d}], Brain: {memories: {}}, Owner: [I; 玩家uuid], Age: 0, Sitting: 0b, YsmModelTexture: "", Rotation: [-100.0f, 0.0f], HurtByTimestamp: 104992, CitadelData: {}, MaidSubConfig: {SoundFreq: 0.19999993f, PickupType: 2, BackpackShow: 0b, OpenDoor: 1b, ChatBubbleShow: 1b, ActiveClimbing: 1b, OpenFenceGate: 1b, BackItemShow: 1b}, MaidTask: "touhou_little_maid:gun_attack", HandItems: [{id: "tacz:modern_kinetic_gun", Count: 1b, tag: {AttachmentEXTENDED_MAG: {id: "tacz:attachment", tag: {AttachmentId: "tacz:light_extended_mag_3"}, Count: 1b}, HasBulletInBarrel: 1b, GunCurrentAmmoCount: 3, GunFireMode: "SEMI", GunId: "classicr:tti_g34"}}, {id: "mekanismadditions:light_blue_balloon", Count: 1b}], Air: 300s, YsmModelName: '{"text":""}', FallDistance: 0.0f, YsmRouletteAnim: "empty", MaidIsHome: 0b, Pos: [-324.85620222628216d, 63.0d, -1372.3034760980975d], Health: 80.0f, HurtTime: 0s, FallFlying: 0b, InLove: 0, PortalCooldown: 0}}, Count: 1b}
眼尖的读者可能看出来了,你这魂符的uuid怎么和之前女仆的一样啊?那当然了,因为我这篇文章是事后复盘,既然没办法复现bug,那就只能力图还原一下当时的情景了。
这怎么这么多一大坨?当我试图移花接木的时候,我发现无论是rcon还是游戏内的聊天框,都说命令太长。那就只能精简掉一些不必要的字段了,可是哪些字段不必要呢?我看了看代码,觉得有点麻烦,于是以实践检验真理。在我的不断尝试下,发现大部分字段都可以精简,只留下女仆uuid和玩家的uuid即可。
于是我使用如下命令,将我工具栏的第二格覆盖为一个有女仆数据的魂符:
/item replace entity @p hotbar.1 with touhou_little_maid:smart_slab_has_maid{MaidInfo: {CanUpdate: 1b, MaidIsPickup: 1b, UUID: [I; 463257288, 837635870, -1609583147, 1128655388], Owner: [I; 玩家uuid]}}
这个命令足够短,可以直接在游戏的聊天框内输入。只要把其中UUID的部分换成你女仆的uuid即可。关于Owner,由于我是正版玩家,而且服务器也开了正版验证,因此无论是单机还是服务器,uuid都是不变的,复制出来直接拿来用就好了。但如果你是离线模式,或者服务器没开正版验证,你就得自己想办法去确定自己的uuid了,好在也不难。
万事具备,就差一个右键了。
对着地面使用魂符,虽然数据全都没了,但我的女仆又回来了!于是接下来就是创造模式的理赔时间了——好感度丢了?直接创造往上加!物品没了?创造模式丢什么拿什么,没丢的也能拿,就算是精神损失费了!这就是1967年冬天,平帐的好机会啊(不是)!
后记
虽然一开始女仆丢了很着急,但好在最后有惊无险地救回来了。不过这种方法是否会有后遗症或者副作用,我暂且不得而知。从目前来看,似乎一切正常,因此我和朋友就继续搭建乙烯发电厂去了。
-全文完-

【歪门邪道】拯救消失的东方女仆 由 天空 Blond 采用 知识共享 署名 - 非商业性使用 - 相同方式共享 4.0 国际 许可协议进行许可。
本许可协议授权之外的使用权限可以从 https://skyblond.info/about.html 处获得。
2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
新车首发,新的一年,只带想赚米的人coinsrore.com
新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
新车上路,只带前10个人coinsrore.com
新盘首开 新盘首开 征召客户!!!coinsrore.com
新项目准备上线,寻找志同道合的合作伙伴coinsrore.com
新车即将上线 真正的项目,期待你的参与coinsrore.com
新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com
2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
新车首发,新的一年,只带想赚米的人coinsrore.com
新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
新车上路,只带前10个人coinsrore.com
新盘首开 新盘首开 征召客户!!!coinsrore.com
新项目准备上线,寻找志同道合的合作伙伴coinsrore.com
新车即将上线 真正的项目,期待你的参与coinsrore.com
新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com
2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
新车首发,新的一年,只带想赚米的人coinsrore.com
新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
新车上路,只带前10个人coinsrore.com
新盘首开 新盘首开 征召客户!!!coinsrore.com
新项目准备上线,寻找志同道合的合作伙伴coinsrore.com
新车即将上线 真正的项目,期待你的参与coinsrore.com
新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com
2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
新车首发,新的一年,只带想赚米的人coinsrore.com
新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
新车上路,只带前10个人coinsrore.com
新盘首开 新盘首开 征召客户!!!coinsrore.com
新项目准备上线,寻找志同道合的合作伙伴coinsrore.com
新车即将上线 真正的项目,期待你的参与coinsrore.com
新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com
2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
新车首发,新的一年,只带想赚米的人coinsrore.com
新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
新车上路,只带前10个人coinsrore.com
新盘首开 新盘首开 征召客户!!!coinsrore.com
新项目准备上线,寻找志同道合的合作伙伴coinsrore.com
新车即将上线 真正的项目,期待你的参与coinsrore.com
新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com
新车即将上线 真正的项目,期待你的参与
2025年10月新盘 做第一批吃螃蟹的人