这是来自粉丝的求助,其实这个问题应该求助那些参与多语言翻译和模组制作的人。

随着国力的不断强大,很多跨国的产品不管游戏、电影、机器还是软件系统,都越来越多的有中国人参与,这个也不例外。

我从来不喜欢直接告诉你那是什么,我更乐于告诉你我是怎么知道的,时间紧迫,本文将把几个小时的解密笔记搬上来了事~

首先,打开存档(RimWorld.Ideology.v1.3.3066.rev1166

C:\Users\Administrator\AppData\LocalLow\Ludeon Studios\RimWorld by Ludeon Studios\Saves

这是个xml文件,文件较大,可能需要一些有内存映射技术的专业文本编辑器来提高速度;

接着是英语水平了,搜索地形的英文:terrain

最后反复F3几次“查找下一个”锁定terrainGrid节点,因为前后有roof屋顶设置

这个topGridDeflate节点应该就是地表数据了,从“乱码”风格看,应该就是base64编码

开始敲C++代码进行解码,代码略,解密出来看不出什么,为什么?

因为地形经常一大块地方是一样的,这里看不到大量重复的数值~

所以,要么是加密,要么是压缩(压缩其实也是加密),从节点名称Deflate猜测:是压缩

开发者模式看到大量的C#堆栈调用信息,开发语言应该就是C#,因此用C#解压缩

private void button1_Click(object sender, EventArgs e){byte[] buf = Convert.FromBase64String(this.textBox1.Text);using (System.IO.MemoryStream ms = new System.IO.MemoryStream()){ms.Write(buf, 0, buf.Length);ms.Position = 0;using (System.IO.Compression.DeflateStream ds = new System.IO.Compression.DeflateStream(ms, System.IO.Compression.CompressionMode.Decompress)){ds.Flush();byte[] data = new byte[65536 * 2];int len = ds.Read(data, 0, data.Length);ds.Close();// view key pointint size = (int)System.Math.Sqrt((double)(len / 2));for (int y = 8; y <= 11; y++){for (int x = 33; x < 36; x++){int idx = GetByteOffset(x, y, size, 2);ushort w_10_10 = (ushort)(data[idx] + data[idx + 1] * 256);System.Diagnostics.Debug.Print("(" + x.ToString() + "," + y.ToString() + ")=" + w_10_10.ToString());}}// displaythis.textBox2.Text = System.Text.Encoding.UTF8.GetString(data, 0, len);}}}

最后解出来101250字节,地图是225x225=50625个格子,因此是每个格子2个字节数据

(代码后面加上转为2字节16位整数查看)

用开发者模式修改左上角一个格子的数据,存档,再次解密,在对比:

只有100800和100801两字节改变,说明x是水平向右,而y是从下向上

继续开发者模式,连续设置不同的地形,列出对应的16位数值:

左下角连续土地块:0x86A1=34465(-31071)
下一行第一格土地:0x86A1=34465(-31071)已确认沼泽:0x8606=34310(-31226)浅水:0x2CB5=11445浅海水:0xFF89=65417(-119)流动的浅水:0x66D4=26324深水:0x798C=31116深海水:0xA790=42896(-22640)流动的深水:0x8015=32789(-32747)粗糙的砂岩地面:0x?=?

数值上看不出高度或类型,猜测为地形定义的ID值,不管是哪种,只要这个值一样即可

至少对当前存档有效,新建一个地图,再次试验:

确定该值对不同存档有效(相同游戏版本)

那么解析一个图片,然后根据图像颜色生成地形数据的代码,很自然的就有了

        private void button2_Click(object sender, EventArgs e){ushort[] w_vectorTab = new ushort[8];w_vectorTab[0] = 0x86A1;    // 土地w_vectorTab[1] = 0x8606;    // 沼泽w_vectorTab[2] = 0x2CB5;    // 浅水w_vectorTab[3] = 0xFF89;    // 浅海水w_vectorTab[4] = 0x66D4;    // 流动的浅水w_vectorTab[5] = 0x798C;    // 深水w_vectorTab[6] = 0xA790;    // 深海水w_vectorTab[7] = 0x8015;    // 流动的深水System.Drawing.Color[] s_colorTab = new Color[8];s_colorTab[0] = Color.FromArgb(255, 255, 255);      // 白色=土地s_colorTab[1] = Color.FromArgb(  0, 128,   0);      // 墨绿=沼泽s_colorTab[2] = Color.FromArgb(  0, 255,   0);      // 绿色=浅水s_colorTab[3] = Color.FromArgb(255,   0, 255);      // 紫色=浅海水s_colorTab[4] = Color.FromArgb(  0, 255, 255);      // 青色=流动的浅水s_colorTab[5] = Color.FromArgb(  0,   0,   0);      // 黑色=深水()s_colorTab[6] = Color.FromArgb(128,   0, 128);      // 深蓝=深海水()s_colorTab[7] = Color.FromArgb(255, 255,   0);      // 黄色=流动的深水System.Drawing.Bitmap bmp = new Bitmap("C:\\Users\\Administrator\\Desktop\\terrain.bmp");//ushort[] data = new ushort[bmp.Width * bmp.Width];byte[] data = new byte[bmp.Width * bmp.Width * 2];// tryfor (int y = 0; y < bmp.Height; y++){for (int x = 0; x < bmp.Width; x++){System.Drawing.Color c = bmp.GetPixel(x, y);// 0 if not foundint k = 0;// findfor (int i = 0; i < s_colorTab.Length; i++){if (s_colorTab[i] == c){k = i;break;}}//System.Diagnostics.Debug.Assert(k >= 0);int idx = (bmp.Height - 1 - y) * bmp.Width + x;// x86 little endianushort key = w_vectorTab[k];data[idx * 2] = (byte)(key & 0x00FF);data[idx * 2 + 1] = (byte)((key >> 8) & 0x00FF);}}// bmp will auto-disposeusing (System.IO.MemoryStream ms = new System.IO.MemoryStream()){using (System.IO.Compression.DeflateStream ds = new System.IO.Compression.DeflateStream(ms, System.IO.Compression.CompressionMode.Compress, true)){ds.Write(data, 0, data.Length);ds.Close();byte[] buf = ms.ToArray();ms.Close();string str = Convert.ToBase64String(buf);this.textBox1.Text = InsertCrLf(str, 100, "\r\n");}}// ret}

读取的文件固定放在桌面的terrain.bmp位图,兼顾原有100字节换行风格

粘贴到存档位置覆盖,保存,进去重新加载即可

同样的,屋顶的解析也是类似:

    无:0
山岩顶:0x2A44=10820

那么根据图片来生成山岩顶的代码,依小姐姐的葫芦曲线画瓢

private void button3_Click(object sender, EventArgs e){ushort[] w_vectorTab = new ushort[3];w_vectorTab[0] = 0x0000;    // 无w_vectorTab[1] = 0;    // 建筑屋顶w_vectorTab[2] = 0x2A44;    // 山岩顶System.Drawing.Color[] s_colorTab = new Color[8];s_colorTab[0] = Color.FromArgb(255, 255, 255);      // 白色=无s_colorTab[1] = Color.FromArgb(  0, 128,   0);      // 墨绿=建筑屋顶s_colorTab[2] = Color.FromArgb(  0,   0,   0);      // 黑色=山岩顶System.Drawing.Bitmap bmp = new Bitmap("C:\\Users\\Administrator\\Desktop\\roof.bmp");//ushort[] data = new ushort[bmp.Width * bmp.Width];byte[] data = new byte[bmp.Width * bmp.Width * 2];// tryfor (int y = 0; y < bmp.Height; y++){for (int x = 0; x < bmp.Width; x++){System.Drawing.Color c = bmp.GetPixel(x, y);// 0 if not foundint k = 0;// findfor (int i = 0; i < s_colorTab.Length; i++){if (s_colorTab[i] == c){k = i;break;}}//System.Diagnostics.Debug.Assert(k >= 0);int idx = (bmp.Height - 1 - y) * bmp.Width + x;// x86 little endianushort key = w_vectorTab[k];data[idx * 2] = (byte)(key & 0x00FF);data[idx * 2 + 1] = (byte)((key >> 8) & 0x00FF);}}// bmp will auto-disposeusing (System.IO.MemoryStream ms = new System.IO.MemoryStream()){using (System.IO.Compression.DeflateStream ds = new System.IO.Compression.DeflateStream(ms, System.IO.Compression.CompressionMode.Compress, true)){ds.Write(data, 0, data.Length);ds.Close();byte[] buf = ms.ToArray();ms.Close();string str = Convert.ToBase64String(buf);this.textBox1.Text = InsertCrLf(str, 100, "\r\n");}}// ret}

无图但有真相

解密RimWorld环世界地形数据相关推荐

  1. 【观察】星环科技重构数据云平台,持续释放数据红利和价值

    申耀的科技观察 读懂科技,赢取未来! 众所周知,如今的世界正在以加速度进入到智能时代,特别是随着各项业务的云化深入以及万物互联,数据处理能力的进一步提升,智能算法一次又一次的突破,以及云计算在传统产业 ...

  2. Cesium中地形数据的加载

    在cesium中为了看到更真实的世界,加载地形数据是必不可少的. 有地形数据和没有地形数据进行比较,就会一目了然了. 说明:1.地形数据是无法单独展示的,地形数据需要结合影像图或者普通瓦片来展示才能看 ...

  3. Unity中使用Real World Terrain插件下载Mapbox真实游戏地图场景的地形数据经验笔记

    上文记录了在unity中使用WorldComposer下载,本文继续整理一篇Unity资源商店上比较优质的地形插件"Real World Terrain". 附上商店上官网链接: ...

  4. 基于星环科技大数据平台 辽宁城市建设职业技术学院打造智慧校园

    当今世界,发展职业教育已经成为各国应对危机.促进就业.迎接新工业革命挑战的共同行动.同时数字化技术的快速发展,改变着学习和教育,将成为职业教育系统整体改革与创新发展的战略选择. 星环科技与北京点为信息 ...

  5. 世界机场数据(带位置坐标)

    最近在一个航旅的项目上需要用到机场数据,网上搜了一圈,有一个开放.免费的世界机场数据网站:OurAirports. 同OpenStreetMap类似,是一个开放的可编辑的数据网站,截止目前拥有5460 ...

  6. cesium获取模型高度_Cesium中地形数据的加载

    Cesium开发中,如果想要看到真实感,地形数据(DEM)不可或缺.但是很多非GIS专业的人,对地形数据的定位不清晰,不明白地形数据如何展示. 最近很多人问我这个问题,综合看下来,主要问题就集中在地形 ...

  7. MicroStation里CASS地形数据生成三维地形模型

    将如下CASS地形数据文件稍作编辑,生成MicroStation输入命令脚本: place point; xy=362047.09,3254845.853,88.288; xy=362047.273, ...

  8. 30米分辨率的DEM地形数据——STRM高程数据

    DEM地形数据是我们在各种研究和设计中经常使用的数据!之前我们分享过源于GEBCO组织的全球范围的500米分辨率的DEM地形数据(可查看之前的文章),这个数据的优点是数据很小,在大区域分析的时候也不会 ...

  9. 如何打造智能世界的数据底座?深耕华为云大数据,畅享价值最大化

    随着信息的快速传递,掌控流量和数据成为企业进步的秘诀,想要获得更好的业务发展,当然需要及时掌握信息数据的核心.对于企业而言,如何才能够提升日常报表的处理效率,快速解决各种繁杂的数据呢?华为云大数据的出 ...

最新文章

  1. 手把手教你玩转ARP包(二)
  2. python两个类共用一个变量_python – 如何从一个类到另一个类访问变量?
  3. [(转)hystar整理]Entity Framework 教程
  4. 机器学习Tensorflow基础知识、张量与变量
  5. Linux系统编程15:进程控制之如何创建进程和写时拷贝技术
  6. 虚拟机linux搭建samba,搭建samba服务使在windows上使用虚拟机为linux
  7. 免费 | 开源操作系统年度盛会最新日程曝光,邀您一同开启烧脑模式!
  8. 进程切换与线程切换的区别
  9. c语言电机正反转,步进电机正反转(单片机C语言程序设计).doc
  10. Hackintosh-OpenCore系列篇-macOS install
  11. android wear 制作时钟界面,android wear开发之绘制表盘.doc
  12. Python 将 QQ 聊天记录生成词云(分手了如何欢度情人节?)
  13. HDU6357 Hills And Valleys
  14. [原创]WIA 学习笔记
  15. Android Hook 实战--替换第三方sdk的类
  16. 圣地亚哥911警用呼叫中心响应时间平均5秒
  17. 视频原理和FFmpeg
  18. 万分之二用百分之怎么表示_百分比表示什么 什么是百分之多少是怎么算的?...
  19. “spoolsv.exe应用程序错误”的解决方法
  20. 云计算基础及解决方案

热门文章

  1. Flutter写第一个跨平台薅羊毛APP(一)
  2. 【HTML入门】记第一次写关于《尼尔机械纪元》网页
  3. 做一个互联网时代的有心人
  4. Java第二次pta大作业总结
  5. Leetcode929.Unique Email Addresses独特的电子邮件地址
  6. 重庆市教育发展现状可视化分析报告(Python)
  7. 单县职业中等专业学校计算机专业,单县职业中专有哪些专业?
  8. jquery实现全屏
  9. python实现滑动验证码_使用python实现滑动验证码
  10. 审计报告是公司每年都要做的吗?哪些企业需要做审计报告?