Update patch_bp.py

This commit is contained in:
2025-04-20 23:15:33 +08:00
parent 94de090b93
commit 5e8d19824a

View File

@@ -38,6 +38,7 @@ class BPScript:
break break
pos += 1 pos += 1
data = self.data[start_pos:pos] data = self.data[start_pos:pos]
data_len = len(data)
try: try:
data = data.decode('cp932') data = data.decode('cp932')
except UnicodeDecodeError: except UnicodeDecodeError:
@@ -45,7 +46,7 @@ class BPScript:
data = "utf8:" + data data = "utf8:" + data
if not data: if not data:
return None return None
return start_pos, self.iPos - 2 return start_pos, self.iPos - 2, data_len
def extract_values(self): def extract_values(self):
str_pos = {} str_pos = {}
@@ -58,38 +59,19 @@ class BPScript:
t = self.extract_string() t = self.extract_string()
if t is not None: if t is not None:
if t[0] not in str_pos: if t[0] not in str_pos:
str_pos[t[0]] = [t[1]] str_pos[t[0]] = (t[2], [t[1]])
else: else:
str_pos[t[0]].append(t[1]) str_pos[t[0]][1].append(t[1])
except UnicodeDecodeError: except UnicodeDecodeError:
self.iPos -= 2 self.iPos -= 2
return str_pos return str_pos
def extract_strings(self):
self.iPos = self.last_pos + 1
while self.data[self.iPos] == 0:
self.iPos += 1
strings = []
start_pos = self.iPos
while self.iPos < self.len:
if self.data[self.iPos] == 0:
data = self.data[start_pos:self.iPos]
data_len = len(data)
try:
data = data.decode('cp932')
except UnicodeDecodeError:
data = data.decode('utf-8')
data = "utf8:" + data
if data:
strings.append((start_pos, data_len))
start_pos = self.iPos + 1
self.iPos += 1
return dict(strings)
def setup_values(self, values: dict): def setup_values(self, values: dict, append: bool = True):
data = bytearray(self.data) data = bytearray(self.data)
goffsets = self.extract_values() goffsets = self.extract_values()
offsets = self.extract_strings() offsets = {}
for k, v in goffsets.items():
offsets[k] = v[0]
print(offsets) print(offsets)
self.iPos = self.header_size self.iPos = self.header_size
all_keys = list(int(i) for i in values.keys()) all_keys = list(int(i) for i in values.keys())
@@ -99,6 +81,7 @@ class BPScript:
new_offsets[key] = key new_offsets[key] = key
last_len = 0 last_len = 0
last_key = all_keys[-1] last_key = all_keys[-1]
instr_size = self.instr_size
for i in range(len(all_keys)): for i in range(len(all_keys)):
key = all_keys[i] key = all_keys[i]
ori_len = offsets[key] + 1 ori_len = offsets[key] + 1
@@ -113,16 +96,30 @@ class BPScript:
last_len = new_len last_len = new_len
if new_len == ori_len: if new_len == ori_len:
continue continue
for j in range(i + 1, len(all_keys)): if append:
off = all_keys[j] new_offsets[key] = instr_size + self.header_size
new_offsets[off] += new_len - ori_len instr_size += new_len
else:
for j in range(i + 1, len(all_keys)):
off = all_keys[j]
new_offsets[off] += new_len - ori_len
print(new_offsets) print(new_offsets)
old_len = last_key + last_len old_len = last_key + last_len
new_len = new_offsets[last_key] + last_len if append:
new_len = self.header_size + instr_size
else:
new_len = new_offsets[last_key] + last_len
# 对齐到16字节 # 对齐到16字节
new_len = new_len + (16 - new_len % 16) # new_len = new_len + (16 - new_len % 16)
data = bytearray(data + b'\0' * (new_len - self.len)) print(old_len, new_len, self.len)
self.len = new_len if old_len == self.len:
data = bytearray(data + b'\0' * (new_len - self.len))
else:
if append:
data = bytearray(data + b'\0' * (new_len - self.len))
else:
data = bytearray(data[0:all_keys[0]] + b'\0' * (new_len - self.len) + data[all_keys[0]:])
self.len = len(data)
data[4:8] = struct.pack('<L', self.len - self.header_size) data[4:8] = struct.pack('<L', self.len - self.header_size)
for i in all_keys: for i in all_keys:
start = new_offsets[i] start = new_offsets[i]
@@ -137,15 +134,20 @@ class BPScript:
data[start:end] = v data[start:end] = v
print(data[start:end]) print(data[start:end])
for k, v in goffsets.items(): for k, v in goffsets.items():
for i in v: for i in v[1]:
data[i:i+2] = struct.pack('<H', new_offsets[k] - i + 1) data[i:i+2] = struct.pack('<H', new_offsets[k] - i + 1)
self.data = data self.data = data
print(len(data))
def save_as(self, path: str): def save_as(self, path: str):
with open(path, 'wb') as f: with open(path, 'wb') as f:
f.write(self.data) f.write(self.data)
append = True
if '--no-append' in sys.argv:
append = False
sys.argv.remove('--no-append')
base = sys.argv[1] base = sys.argv[1]
json_f = f"{base}.json" json_f = f"{base}.json"
if len(sys.argv) >= 3: if len(sys.argv) >= 3:
@@ -159,5 +161,5 @@ print(scr.iPos)
print(scr.last_pos) print(scr.last_pos)
with open(json_f, "r", encoding="utf-8") as f: with open(json_f, "r", encoding="utf-8") as f:
data = json.load(f) data = json.load(f)
scr.setup_values(data) scr.setup_values(data, append)
scr.save_as(output) scr.save_as(output)