mbEditorPro2.0 release

This commit is contained in:
2022-12-25 08:47:00 -05:00
parent 30375c8413
commit 942b33a252
110 changed files with 3543 additions and 1089 deletions
+116
View File
@@ -0,0 +1,116 @@
# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
# Magicbane Emulator Project © 2013 - 2022
# www.magicbane.com
import struct
import zlib
def read_dword(cache_file):
data = cache_file.read(4)
return struct.unpack('<I', data)[0]
def read_qword(cache_file):
dwords = struct.unpack('<II', cache_file.read(8))
buffer = struct.pack('<II', dwords[1], dwords[0])
return struct.unpack('<Q', buffer)[0]
def read_resource_data(cache_file, start, length):
current_position = cache_file.tell()
cache_file.seek(start)
data = cache_file.read(length)
cache_file.seek(current_position)
return data
def load_cache_file(filename):
cache_file = open(filename, 'rb')
num_resources = read_dword(cache_file)
read_dword(cache_file)
read_dword(cache_file)
read_dword(cache_file)
resources = []
for _ in range(num_resources):
resource_id = read_qword(cache_file)
resource_offset = read_dword(cache_file)
resource_decompressed_len = read_dword(cache_file)
resource_compressed_len = read_dword(cache_file)
resource_data = read_resource_data(
cache_file,
resource_offset,
resource_compressed_len
)
if resource_decompressed_len > resource_compressed_len:
resource_data = zlib.decompress(resource_data)
resources.append([
resource_id,
resource_data
])
return resources
def write_dword(cache_file, value):
data = struct.pack('<I', value)
cache_file.write(data)
def write_qword(cache_file, value):
qword = struct.pack('<Q', value)
dwords = [
struct.unpack('<I', qword[:4])[0],
struct.unpack('<I', qword[4:])[0],
]
data = struct.pack('<II', dwords[1], dwords[0])
cache_file.write(data)
def write_bytes(cache_file, value):
cache_file.write(value)
def save_cache_file(filename, resources, compress=True):
cache_file = open(filename, 'wb')
num_resources = len(resources)
last_offset = 0
last_offset += 0x10 # header
last_offset += num_resources * 0x14 # resource_headers
data_start = last_offset
for resource in resources:
resource.append(last_offset)
resource.append(len(resource[1]))
if compress:
resource[1] = zlib.compress(resource[1])
resource.append(len(resource[1]))
last_offset += resource[4]
data_end = last_offset
write_dword(cache_file, num_resources)
write_dword(cache_file, data_start)
write_dword(cache_file, data_end)
write_dword(cache_file, 0xffffffff)
for resource in resources:
write_qword(cache_file, resource[0])
write_dword(cache_file, resource[2])
write_dword(cache_file, resource[3])
write_dword(cache_file, resource[4])
for resource in resources:
write_bytes(cache_file, resource[1])
+108
View File
@@ -0,0 +1,108 @@
# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
# Magicbane Emulator Project © 2013 - 2022
# www.magicbane.com
import struct
from io import BytesIO
class ResStream:
def __init__(self, initial_bytes=b''):
self.buffer = BytesIO(initial_bytes)
def read_byte(self):
data = self.buffer.read(1)
return struct.unpack('<B', data)[0]
def read_bytes(self, n):
data = self.buffer.read(n)
return data
def read_word(self):
data = self.buffer.read(2)
return struct.unpack('<H', data)[0]
def read_dword(self):
data = self.buffer.read(4)
return struct.unpack('<I', data)[0]
def read_qword(self):
dwords = struct.unpack('<II', self.buffer.read(8))
buffer = struct.pack('<II', dwords[1], dwords[0])
return struct.unpack('<Q', buffer)[0]
def read_float(self):
data = self.buffer.read(4)
return struct.unpack('<f', data)[0]
def read_tuple(self):
data = self.buffer.read(12)
return struct.unpack('<fff', data)
def read_bool(self):
data = self.buffer.read(1)
return True if struct.unpack('<B', data)[0] else False
def read_wchar(self):
data = self.buffer.read(2)
return chr(struct.unpack('<H', data)[0])
def read_string(self):
length = self.read_dword()
data = [self.read_wchar() for _ in range(length)]
return ''.join(data)
def write_byte(self, value):
data = struct.pack('<B', value)
self.buffer.write(data)
def write_bytes(self, value):
data = value
self.buffer.write(data)
def write_word(self, value):
data = struct.pack('<H', value)
self.buffer.write(data)
def write_dword(self, value):
data = struct.pack('<I', value)
self.buffer.write(data)
def write_qword(self, value):
qword = struct.pack('<Q', value)
dwords = [
struct.unpack('<I', qword[:4])[0],
struct.unpack('<I', qword[4:])[0],
]
data = struct.pack('<II', dwords[1], dwords[0])
self.buffer.write(data)
def write_float(self, value):
data = struct.pack('<f', value)
self.buffer.write(data)
def write_tuple(self, value):
data = struct.pack('<fff', *value)
self.buffer.write(data)
def write_bool(self, value):
data = struct.pack('<B', 1 if value else 0)
self.buffer.write(data)
def write_wchar(self, value):
data = struct.pack('<H', value)
self.buffer.write(data)
def write_string(self, value):
length = len(value)
self.write_dword(length)
for char in value.encode('utf-16-le'):
self.write_byte(char)
def get_bytes(self):
self.buffer.seek(0)
return self.buffer.read()
+10
View File
@@ -0,0 +1,10 @@
# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
# Magicbane Emulator Project © 2013 - 2022
# www.magicbane.com
from .ArcFileCache import load_cache_file, save_cache_file
from .ResStream import ResStream
+47
View File
@@ -0,0 +1,47 @@
# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
# Magicbane Emulator Project © 2013 - 2022
# www.magicbane.com
def _hash_string_short(array):
v04 = (8 * array[7]) & 0xffffffff
v05 = v04 ^ array[4]
v06 = (16 * v05) & 0xffffffff
v07 = array[5] ^ v06
v08 = (16 * v07) & 0xffffffff
v09 = array[6] ^ v08
v10 = (32 * v09) & 0xffffffff
v11 = array[2] ^ v10
v12 = (32 * v11) & 0xffffffff
v13 = (array[1] ^ v12)
v14 = (32 * v13) & 0xffffffff
v15 = (array[7] ^ 0x5A0) >> 2
return array[0] ^ (v15) ^ (v14)
def _hash_string_long(array):
i = 0
result = 0
for c in array:
v = c - 32
result ^= (v << (i)) & 0xffffffff
if i > 0x18:
result ^= v >> (32 - i)
if i >= 0x1b:
i -= 32
i += 5
return result & 0xffffffff
def hash_string(string):
array = bytearray(string.encode())
length = len(string)
if (length == 7 or length == 8) and string[3] == '-':
array += bytearray(b'\x00')
return _hash_string_short(array)
else:
return _hash_string_long(array)
+19
View File
@@ -0,0 +1,19 @@
# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
# Magicbane Emulator Project © 2013 - 2022
# www.magicbane.com
#
def int32(x):
if x > 0xFFFFFFFF:
raise OverflowError
if x > 0x7FFFFFFF:
x = int(0x100000000 - x)
if x < 2147483648:
return -x
else:
return -2147483648
return x