解密RimWorld环世界地形数据
这是来自粉丝的求助,其实这个问题应该求助那些参与多语言翻译和模组制作的人。
随着国力的不断强大,很多跨国的产品不管游戏、电影、机器还是软件系统,都越来越多的有中国人参与,这个也不例外。
我从来不喜欢直接告诉你那是什么,我更乐于告诉你我是怎么知道的,时间紧迫,本文将把几个小时的解密笔记搬上来了事~
首先,打开存档(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环世界地形数据相关推荐
- 【观察】星环科技重构数据云平台,持续释放数据红利和价值
申耀的科技观察 读懂科技,赢取未来! 众所周知,如今的世界正在以加速度进入到智能时代,特别是随着各项业务的云化深入以及万物互联,数据处理能力的进一步提升,智能算法一次又一次的突破,以及云计算在传统产业 ...
- Cesium中地形数据的加载
在cesium中为了看到更真实的世界,加载地形数据是必不可少的. 有地形数据和没有地形数据进行比较,就会一目了然了. 说明:1.地形数据是无法单独展示的,地形数据需要结合影像图或者普通瓦片来展示才能看 ...
- Unity中使用Real World Terrain插件下载Mapbox真实游戏地图场景的地形数据经验笔记
上文记录了在unity中使用WorldComposer下载,本文继续整理一篇Unity资源商店上比较优质的地形插件"Real World Terrain". 附上商店上官网链接: ...
- 基于星环科技大数据平台 辽宁城市建设职业技术学院打造智慧校园
当今世界,发展职业教育已经成为各国应对危机.促进就业.迎接新工业革命挑战的共同行动.同时数字化技术的快速发展,改变着学习和教育,将成为职业教育系统整体改革与创新发展的战略选择. 星环科技与北京点为信息 ...
- 世界机场数据(带位置坐标)
最近在一个航旅的项目上需要用到机场数据,网上搜了一圈,有一个开放.免费的世界机场数据网站:OurAirports. 同OpenStreetMap类似,是一个开放的可编辑的数据网站,截止目前拥有5460 ...
- cesium获取模型高度_Cesium中地形数据的加载
Cesium开发中,如果想要看到真实感,地形数据(DEM)不可或缺.但是很多非GIS专业的人,对地形数据的定位不清晰,不明白地形数据如何展示. 最近很多人问我这个问题,综合看下来,主要问题就集中在地形 ...
- MicroStation里CASS地形数据生成三维地形模型
将如下CASS地形数据文件稍作编辑,生成MicroStation输入命令脚本: place point; xy=362047.09,3254845.853,88.288; xy=362047.273, ...
- 30米分辨率的DEM地形数据——STRM高程数据
DEM地形数据是我们在各种研究和设计中经常使用的数据!之前我们分享过源于GEBCO组织的全球范围的500米分辨率的DEM地形数据(可查看之前的文章),这个数据的优点是数据很小,在大区域分析的时候也不会 ...
- 如何打造智能世界的数据底座?深耕华为云大数据,畅享价值最大化
随着信息的快速传递,掌控流量和数据成为企业进步的秘诀,想要获得更好的业务发展,当然需要及时掌握信息数据的核心.对于企业而言,如何才能够提升日常报表的处理效率,快速解决各种繁杂的数据呢?华为云大数据的出 ...
最新文章
- 手把手教你玩转ARP包(二)
- python两个类共用一个变量_python – 如何从一个类到另一个类访问变量?
- [(转)hystar整理]Entity Framework 教程
- 机器学习Tensorflow基础知识、张量与变量
- Linux系统编程15:进程控制之如何创建进程和写时拷贝技术
- 虚拟机linux搭建samba,搭建samba服务使在windows上使用虚拟机为linux
- 免费 | 开源操作系统年度盛会最新日程曝光,邀您一同开启烧脑模式!
- 进程切换与线程切换的区别
- c语言电机正反转,步进电机正反转(单片机C语言程序设计).doc
- Hackintosh-OpenCore系列篇-macOS install
- android wear 制作时钟界面,android wear开发之绘制表盘.doc
- Python 将 QQ 聊天记录生成词云(分手了如何欢度情人节?)
- HDU6357 Hills And Valleys
- [原创]WIA 学习笔记
- Android Hook 实战--替换第三方sdk的类
- 圣地亚哥911警用呼叫中心响应时间平均5秒
- 视频原理和FFmpeg
- 万分之二用百分之怎么表示_百分比表示什么 什么是百分之多少是怎么算的?...
- “spoolsv.exe应用程序错误”的解决方法
- 云计算基础及解决方案