之前下了个红警尤里复仇是繁体的,看着很难受。所以趁着放假把它简体化一下。

语言文件存储在langmd.mix->ra2md.csf文件中,使用xcc mixer可以把它提取出来,放到游戏文件目录即可。

csf文件格式:CSF File Format on ModEnc, the Command & Conquer Modding Encyclopedia

这个文件可以用 红警文本csf编辑器去一条一条的编辑,但是效率有点低。

既然已经知道csf文件格式,直接用Python将其中的文字提取出来,然后保存到Word中,然后使用Word的繁体转简体,一键转换。最后再把简体字按csf文件格式重新保存就可以了。

以下是转换需要的Python代码:

# 解析红警2的csf文件
import os
import structdef read_dword(f):return struct.unpack('<I', f.read(4))[0]def write_dword(f, num):return f.write(struct.pack('<I', num))class CsfHeader(object):# 0x0    char[4]     " FSC"identifier = b' FSC'langMap = ['US', 'UK', 'German', 'French', 'Spanish', 'Italian','Japanese', 'Jabberwockie', 'Korean', 'Chinese', 'Unknown']def __init__(self) -> None:# 0x4    DWORD       CSF Versionself.version = 0# 0x8   DWORD       NumLabelsself.NumLabels = 0# 0xC   DWORD       NumStringsself.NumStrings = 0# 0x10    DWORD       (unused)# 0x14  DWORD       Languageself.Language = 0def __str__(self):s = 'NumLabels= %d, NumStrings= %d, Language= %s' % (self.NumLabels, self.NumStrings, CsfHeader.langMap[self.Language])return sdef save(self, f):f.write(CsfHeader.identifier)write_dword(f, self.version)write_dword(f, self.NumLabels)write_dword(f, self.NumStrings)# (unused)write_dword(f, 0)write_dword(f, self.Language)class LabelHeader(object):# 0x0    char[4]     " LBL"identifier = b' LBL'def __init__(self) -> None:# 0x4  DWORD       Number of string pairsself.Number_of_string_pairs = 0# 0x8 DWORD       LabelNameLengthself.LabelNameLength = 0# 0xC   char[LabelNameLength]   LabelNameself.LabelName = ''def save(self, f):f.write(LabelHeader.identifier)write_dword(f, self.Number_of_string_pairs)write_dword(f, self.LabelNameLength)f.write(self.LabelName)class LabelValue(object):# 0x0    char[4]         " RTS" or "WRTS"identifiers = [b' RTS', b'WRTS']def __init__(self) -> None:# 0x4    DWORD       ValueLengthself.ValueLength = 0# 0x8   byte[ValueLength*2]                         Valueself.Value = ''# 0x8+ValueLength*2 DWORD                           ExtraValueLengthself.ExtraValueLength = 0# 0x8+ValueLength*2+0x4 char[ExtraValueLength]      ExtraValueself.ExtraValue = ''self.text = ''def decode(self):self.Value = bytes([~x & 0xff for x in self.Value])self.text = self.Value.decode('utf16')return self.textdef encode(self):self.Value = bytes([~x & 0xff for x in self.Value])return self.Valuedef replace(self, text):self.text = text# 注意,这里需要指明编码大小端, 只写 'utf16' 会多出两个字节指示编码的大小端self.Value = text.encode('utf-16-le')self.ValueLength = len(text)def save(self, f):if self.ExtraValueLength == 0:f.write(LabelValue.identifiers[0])else:f.write(LabelValue.identifiers[1])write_dword(f, self.ValueLength)f.write(self.encode())if self.ExtraValueLength != 0:write_dword(f, self.ExtraValueLength)f.write(self.ExtraValue)class Label(object):def __init__(self) -> None:self.header = LabelHeader()self.values = []def save(self, f):self.header.save(f)for v in self.values:v.save(f)# Headerdef parse_csf_header(f):f.seek(0, 0)if f.read(4) != CsfHeader.identifier:print("Parse Csf Header Failed!")return Falseheader = CsfHeader()header.version = read_dword(f)header.NumLabels = read_dword(f)header.NumStrings = read_dword(f)f.read(4)header.Language = read_dword(f)return headerdef parse_label_header(f):if f.read(4) != LabelHeader.identifier:print("Parse Label Header Failed!")return Falseheader = LabelHeader()header.Number_of_string_pairs = read_dword(f)header.LabelNameLength = read_dword(f)header.LabelName = f.read(header.LabelNameLength)return headerdef parse_label_value(f):t = f.read(4)if t not in LabelValue.identifiers:print("Parse Value Failed!")return Falsevalue = LabelValue()value.ValueLength = read_dword(f)value.Value = f.read(value.ValueLength * 2)if t == LabelValue.identifiers[1]:value.ExtraValueLength = read_dword(f)value.ExtraValue = f.read(value.ExtraValueLength)value.decode()return value# Labeldef parse_label(f):header = parse_label_header(f)if not header:print("Parse Label Failed!")return Falselabel = Label()label.header = headerfor i in range(header.Number_of_string_pairs):value = parse_label_value(f)if not value:return labellabel.values.append(value)return labeldef parse_csf(filename):f = open(filename, 'rb')header = parse_csf_header(f)if not header:print("Parse Csf Failed!")return Falselabels = []for i in range(header.NumLabels):if i == 1270:print("break")label = parse_label(f)if not label:breaklabels.append(label)f.close()return (header, labels)def dump_texts(filename: str, labels: Label):f = open(filename, 'w', encoding='utf8')for l in labels:for v in l.values:s = '[%s]%s'%(l.header.LabelName.decode(), v.text)f.write(s + '\n')f.close()return Truedef read_translate(filename:str):translations = {}name = ''value = ''with open(filename, 'r', encoding='utf8') as f:while True:line = f.readline()if line == '':breakif line[0] != '[':translations[name] += '\n' + line[:-1]continuepos = line.index(']')name = line[1:pos]value = line[pos + 1:-1]translations[name] = valueprint("translations count: %d"%len(translations))return translationsdef replace_translation(labels, translations):for l in labels:for v in l.values:name = l.header.LabelName.decode()new_text = translations[name]v.replace(new_text)return labelsdef main():filename = r'G:\hongj2yuri\RA2YR\ra2md.csf'header, labels = parse_csf(filename)print(str(header))# 提取繁体字信息# df = os.path.splitext(filename)[0] + '.txt'# dump_texts(df, labels)# Word繁体到简体转换,然后新建一个txt文档,保存转换后的结果# 读取转换后的简体字信息translations = read_translate(r'G:\hongj2yuri\RA2YR\ra2md_sc.txt')# 转换所有Label中的繁体信息labels = replace_translation(labels, translations)# 保存新文件nf = os.path.splitext(filename)[0] + '_sc.csf'with open(nf, 'wb') as f:header.save(f)for l in labels:l.save(f)return Truemain()

转换后的效果:

红警2 csf文件解析 简体化相关推荐

  1. python实现红警三录像文件读取与自动分析生成流程图信息——一、简介

    之前做了一个红警三的建造出兵流程图绘制工具 有评论建议说能不能够自动读取录像. 同时自己使用的时候,也感觉确实一点点手动绘制太过麻烦. 所以专门为该工具做了个自动录像读取分析工具. 技术路线:pyth ...

  2. python实现红警三录像文件读取与自动分析生成流程图信息——二、项目结构与代码初步介绍

    总目录 一.简介 二.项目结构与代码初步介绍 三.拓展给mod使用 ======================= 大爽歌作,made by big shuang ================== ...

  3. jquery实现流程图绘制工具——展现红警三建造出兵操作 ——二、代码初步介绍,项目结构与文件介绍

    目录 一.简介 二.代码初步介绍 拓展.实现红警三录像文件读取与自动分析生成流程图信息 ======================= 大爽歌作,made by big shuang ======== ...

  4. 红警2单位属性汇总_20201009_

    将红警的规则文件 rules.ini 放置在工作目录,运行如下代码,便可以将红警中的士兵,战车和建筑单位相关属性信息汇总在excel表格中 相关文件都放置于资源文件中 #红警单位属性信息汇总 impo ...

  5. 解决win10红警卡顿

    打开红警所在的文件夹,找到Ra2.ini(有的版本是Ra2md.ini),双击打开,出现一个文档,都是英文字母,找到[Video],找到后,里边有三行,不需要管,只要在第一行上边添加VideoBack ...

  6. jquery实现流程图绘制工具——展现红警三建造出兵操作 ——一 简介

    作为一名红警三玩家,为了提高自己的技术,我会时不时的看一些别人的录像来学习,所以想要对录像的信息进行一定的记录. 单纯用文字是很麻烦的,且不够直观,容易啰嗦. 故而我有这样一个想法: 能否用图表比较详 ...

  7. 远程连接寝室linux,求救啊。。。一个寝室怎么连网打红警?。。急急啊!

    chinesedragon 于 2009-10-02 22:49:29发表: 安装IPX/SPX/NetBIOS协议就行了 yuanwenhuitykk 于 2009-10-02 18:59:38发表 ...

  8. 惊艳于红警开源代码?赏心悦目的代码注释,我们也可以 !

    文章目录 1.前言 2. 我们惊叹它的什么? 2.1 清晰的代码注释 2.2 语义化的编码规范 2.3 小而精的逻辑实现 3. 依葫芦画瓢 3.1 添加文档级注释 3.2 添加类级注释 3.3 添加方 ...

  9. 红蓝对抗-红队攻防全流程解析

    红队攻防全流程解析 文章目录 红队攻防全流程解析 基础设施架构设计部署 选择域名 邮件钓鱼之前期信息收集与侦查 钓鱼样本制作 内网横向移动 文件感染与横向移动 基础设施架构设计部署 普通架构:红队人员 ...

  10. Json文件解析(下

    Json文件解析(下) 代码地址:https://github.com/nlohmann/json 从STL容器转换 任何序列容器(std::array,std::vector,std::deque, ...

最新文章

  1. 4.IT-解决方案-4-Cluster-Win2K3
  2. PHP程序员上相亲节目,结果遭女嘉宾瞬间全灭灯
  3. github上开箱即用的app之TODO app
  4. Matplotlib常用库方法
  5. centos下resin4启动一会儿自动关闭处理
  6. [收藏学习]Linux的实时监测命令
  7. AndroidStudio_安卓原生开发_Json解析报错_要注意这点---Android原生开发工作笔记141
  8. java 异常捕捉 ( try catch finally ) 清晰解释
  9. mysql 触发器存储过程的区别_MySQL触发器、存储过程实现
  10. Adobe Acrobat如何快速将PDF文档的书签修改为“承前缩放”——PDF增效插件AutoBookmark
  11. 30分钟了解DNS及搭建方法
  12. python捕获屏幕的标准库_Python标准库urllib2的使用和获取网站状态举例
  13. 电压电流的超前与滞后
  14. 前端怎么画三角形_css如何画三角形?
  15. IMX6ULL与IMX6UL异同(主要是优化了其成本:安全功能减低,优化功耗EMC SIM模块删除等与但和I.MX6UltraLite芯片是PIN-2-PIN兼容的)
  16. bootstrap——模态框
  17. 计算方法 差商与牛顿插值
  18. 类名不是抽象的,并且未覆盖XX类中的抽象方法jjjj
  19. py中lambda和apply的使用总结
  20. 面试高频算法题补充系列:如何判断一个点是否在三角形内?

热门文章

  1. CAD二次开发 C# .net dwg批量转dxf
  2. 简单的http客户端
  3. 水经注万能地图下载器功能大全
  4. 多功能雨伞项目计划书_多功能的雨伞创业项目计划书
  5. Dubbo源码解析-Dubbo协议解析
  6. 为什么算法工程师也叫调参狗?
  7. C# 监控字段_资产运营专业线升级公告(资源、物业、运维监控)
  8. react 创建组件的两种方式
  9. OCR电子发票批量自动合成软件
  10. Matlab读nc文件