之前下了个红警尤里复仇是繁体的,看着很难受。所以趁着放假把它简体化一下。
语言文件存储在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 struct def 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 Version self.version = 0 # 0x8 DWORD NumLabels self.NumLabels = 0 # 0xC DWORD NumStrings self.NumStrings = 0 # 0x10 DWORD (unused) # 0x14 DWORD Language self.Language = 0 def __str__(self): s = 'NumLabels= %d, NumStrings= %d, Language= %s' % ( self.NumLabels, self.NumStrings, CsfHeader.langMap[self.Language]) return s def 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 pairs self.Number_of_string_pairs = 0 # 0x8 DWORD LabelNameLength self.LabelNameLength = 0 # 0xC char[LabelNameLength] LabelName self.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 ValueLength self.ValueLength = 0 # 0x8 byte[ValueLength*2] Value self.Value = '' # 0x8+ValueLength*2 DWORD ExtraValueLength self.ExtraValueLength = 0 # 0x8+ValueLength*2+0x4 char[ExtraValueLength] ExtraValue self.ExtraValue = '' self.text = '' def decode(self): self.Value = bytes([~x & 0xff for x in self.Value]) self.text = self.Value.decode('utf16') return self.text def encode(self): self.Value = bytes([~x & 0xff for x in self.Value]) return self.Value def 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) # Header def parse_csf_header(f): f.seek(0, 0) if f.read(4) != CsfHeader.identifier: print("Parse Csf Header Failed!") return False header = 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 header def parse_label_header(f): if f.read(4) != LabelHeader.identifier: print("Parse Label Header Failed!") return False header = LabelHeader() header.Number_of_string_pairs = read_dword(f) header.LabelNameLength = read_dword(f) header.LabelName = f.read(header.LabelNameLength) return header def parse_label_value(f): t = f.read(4) if t not in LabelValue.identifiers: print("Parse Value Failed!") return False value = 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 # Label def parse_label(f): header = parse_label_header(f) if not header: print("Parse Label Failed!") return False label = Label() label.header = header for i in range(header.Number_of_string_pairs): value = parse_label_value(f) if not value: return label label.values.append(value) return label def parse_csf(filename): f = open(filename, 'rb') header = parse_csf_header(f) if not header: print("Parse Csf Failed!") return False labels = [] for i in range(header.NumLabels): if i == 1270: print("break") label = parse_label(f) if not label: break labels.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 True def read_translate(filename:str): translations = {} name = '' value = '' with open(filename, 'r', encoding='utf8') as f: while True: line = f.readline() if line == '': break if line[0] != '[': translations[name] += '\n' + line[:-1] continue pos = line.index(']') name = line[1:pos] value = line[pos + 1:-1] translations[name] = value print("translations count: %d"%len(translations)) return translations def 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 labels def 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 True main()
讯享网
转换后的效果:



版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/126949.html