gamemaker吧 关注:13,627贴子:94,960

求助,字体是如何保存在内存里的?

只看楼主收藏回复

求会内存的大佬指点一下子


IP属地:河北1楼2024-10-06 20:20回复
    就……我有个点子!
    我打算通过内存读取的方式,来做一个gms游戏的汉化软件,不对data.wim动刀子,而是对内存进行操作来实现这一点。
    原理大概是可行的。
    我通过ce读取到了字符串,成功修改了字符串,让修改后的字符串在游戏里显示。
    我在游戏打开后删掉了data,wim文件,游戏已然能够正常运行,这证明游戏的数据已经保存在内存里了,在游戏关掉前不会删除。
    utmt里font可以随便塞,证明这玩意没有严格的大小限制。
    由于我之前啃了一段时间yy转csv,明白了原理,我现在能够直接使用代码生成图片字体了。
    原理可行。
    现在只差把这玩意塞进内存里了。


    IP属地:河北2楼2024-10-06 20:21
    回复
      本人代码渣渣,c语言和c#正在学,正在啃utmt的源代码。
      我感觉我这个点子挺有趣的,打算把这玩意当成消磨时间的娱乐项目。


      IP属地:河北3楼2024-10-06 20:23
      回复
        按咱掌握的信息,GM绘制文字的过程是
        首先要知道文字的内容A(字符串string,也就是draw text的最后一项参数),然后根据所用字体B,去内存(或者可能是显存)的对应区域提取纹理C。
        汉化呢,通常来说主要的努力方向是A,但这帖子里提到的问题似乎是在问B和C的事。还是不改data.win的情况下改变这部分……咱知道的是surface默认是RGBA各8bit存储,纹理页没有验证过但推测也是这个格式。字体里的每个文字都是色彩纯白调节alpha,但不太确定文字外完全透明区域的RGB信息是0还是255。


        IP属地:北京4楼2024-10-07 14:15
        收起回复
          图片字体,由png图片文件和csv文本文件组成。
          前者是由透明背景和白色字符组成的图片,后者csv是存储坐标的文本文件。
          举个例子,我的游戏里需要显示一个a字符,那么游戏会将其转化成unicode编码,然后从csv里面找到对应的unicode编码,并获得具体的坐标。
          比如说50.50xy坐标,wh分别是5,那就能够在这个xy坐标找到一个5x5像素的图片,这个图片会显示在游戏里,这就是a。
          根据这个原理,我可以整一个活。
          比如说我可以在图片字体里写一个“整活”,并将a对应的图片坐标篡改,那么游戏里面的文本“a”,在显示出来就会变成“整活”两个字。


          IP属地:河北来自Android客户端5楼2024-10-07 23:07
          回复
            我不是很了解内存,之前我瞎改过内存的汇编代码导致程序崩溃过N次,所以这次我准备了防数据溢出的策略。
            不知道用不用得上,我不是很清楚字符串会不会出现这种情况,不过还是先准备上。
            具体方法。
            缩减字符串,令一个文本可以显示出多个字符。
            例如原本文本是“来自王国的公主前往战场”,每一个字都对应的正确的单个字。
            我可以将文本篡改为“这”,单个字符,对应着一张长条的图片。
            图片里面写着“来自王国的公主前往战场”。
            给图片字体的数据进行一定程度的篡改,把压力转移到字体图片存储的区域。
            它必须受的住,因为它如果受不住,那我这整个想法、整个点子都是在扯淡。


            IP属地:河北来自Android客户端6楼2024-10-07 23:20
            回复
              这种做法初步判断为“不现实”,理由如下:
              0、中文要使用的字符数量本身就多于其他语言;
              1、将单个文字占据纹理改为整句话占用纹理无疑会加剧这个问题;
              2、原有纹理上的外文字符可能分散在各个角落,即可能不存在一个可以放下整句话的区域;
              3、综上,你可能需要给texture page上的元素重整顺序之后再专门划定个区域用来放各式各样的“整句话”且随用随替;
              4、而实际的运行过程是侦测到游戏准备显示一句话→拦截该显示→把原本的话替换为一个代表整句话的特殊字符→把这个特殊字符的显示指定到一个“整句话区域”→翻译原文并把结果输出到那个区域→重新允许这句话(已经变成一个字符)的显示;
              5、如果原游戏带有打字机效果(文字是一个一个增加的),甚至无法通过这种方法获取到要翻译的原文,实在不理解你绕开data.win,用挂的方式来做翻译的理由。
              最后呢,不知道题主自称的“代码渣渣”是谦虚还是事实,如果是后者的话,请在有一定的基础和实践后再尝试自己搭建架构。不然翻译界这么多年没产生出这个结构的东西,只是因为他们没想到/技术力不足/不够努力吗。


              IP属地:北京7楼2024-10-09 09:03
              收起回复
                通过ce查内存,找到了png的开始字节89 50 4E 47 0D 0A 1A 0A,结束49454e44,并成功提取出了一张png图片,遂发现这玩意只是ACSII那点字符。
                不是哥们,就这么点玩意,占我差不多0x3000这么大块地?


                IP属地:河北来自Android客户端8楼2024-10-09 21:07
                回复
                  在exe+里面的绿色地址,游戏程序保留了一张acsii字体的256x256的图像,通过开头和结尾我很轻松就将其提取出来了。
                  然后我在公共内存里找到了两张图,提取其中一张图,可以发现是font字体,我亲手搞进去的汉字版本。
                  至此我已经实现了内存图像的提取。
                  修改应该也不是问题,用ce写个程序,把我的png图像转化成字节,然后写入到内存里就行。
                  这很轻松,毕竟我已经能够将字节数组转化成png图片文件了,倒着来自然也不是问题,最多也就多了个写入的环节。
                  可惜python权限啥的懒得搞,用ai写的内存读写程序被拒绝访问了,只能继续用ce写个程序来替换字节了,这倒也不算是问题。
                  现在只差一个问题,找不到内存里的csv文件。


                  IP属地:河北来自Android客户端9楼2024-10-09 23:08
                  回复
                    进度稳步推进,现在只差最后一个问题,找不到内存里的csv文件。
                    原本想着顺藤摸瓜用csv数据找到png图像,没想到现在png已经找到了,csv却还没影


                    IP属地:河北来自Android客户端10楼2024-10-09 23:12
                    回复
                      你可以去找一下ut的反编译工具看看游戏是不是用yyc编译的,能反编译出代码的话方法就很多了


                      IP属地:吉林11楼2024-10-10 15:13
                      收起回复
                        有了点新方法的思路,关于寻找csv。
                        找个巨量的csv文件,打开游戏后导出内存数据。
                        然后换上量巨少的csv文件,配套的png文件则是不便,反正这么搞也崩不了,同样导出内存数据。
                        为了防止数据量过多,搞个几乎空白的datawin资源文件,只有字体当中的csv发生改变。
                        接下来就能够比对这两者的数据了。
                        由于gms游戏会有地址随机偏移,想要匹配相似的感觉会很困难,比对的方法要简单一点,不能比相似度。
                        比00和a0吧,内存的空白区域,这样能够反向推断出这片区域的数据量。
                        然后人工核对,算出一一对应的部分,剩下不和谐的部分就是csv发生改变的地方,能够据此找到csv的位置,进而找出特征,大概能成。
                        不知道能不能成,下次试试


                        IP属地:河北来自Android客户端13楼2024-10-11 14:30
                        回复
                          经过内存查看器,决定将搜索的内容改为??,也就是真正的ce里真正的空白,根据非空白的数据量找出数据的异常增量。
                          麻了,内存10000000导出了一部分,直接飙到1.5gb往上,太大了所以果断停止,先从小的开始。
                          从01000000开始试,前后有多处不一样的数据。
                          然后发现游戏的数据有的在02000000往后的部分,数据量实在太大,通过内存寻找异常增量的计划破产了。


                          IP属地:河北来自Android客户端14楼2024-10-17 11:10
                          回复
                            先继续学c#,下一步我打算通过读取datawin的chunk,通过里面关于字体中文本的数据来寻找内存里的csv。
                            就像png是那什么,我想gms应该不会对这个进行加密,应该是原封原样搞进内存里。
                            可惜我在内存方面完全是个小白,最多把常规的png转化成字节数组,不知道怎么把文本文件转化成字节数组,要不然就能省了这一步了。
                            感谢utmt,要不然我连拾人牙慧都没办法拾


                            IP属地:河北来自Android客户端15楼2024-10-17 11:17
                            回复
                              那个。。首先png是压缩格式 gm会在运行时会先把png解码成的纹理数据才能上传到gpu的 所以你改内存里的png肯定是行不通的(而且我怀疑内存中这个png压根没啥用)
                              然后你总是提什么“csv”我也没理解是什么意思
                              字体纹理是存在纹理页里的,字体中的每个字符都会对应一个glyph结构体,这个结构体包括字符的原点、宽高以及纹理页的索引、纹理宽高之类的东西。所以你要增加中文字符,应该考虑创建新的字符的glyph结构体


                              IP属地:山东来自Android客户端16楼2024-10-17 17:31
                              回复