"""Run the game's actual x86 layout/measurement code without Direct3D. Requires unicorn. --exe is a locally generated executable, never redistributed. The draw boundary is intercepted to inspect the exact strings/positions that the engine submits. All wrapping and measuring instructions execute unchanged. """ import argparse import struct import unittest from pathlib import Path from unicorn import Uc, UC_ARCH_X86, UC_MODE_32, UC_HOOK_CODE from unicorn.x86_const import UC_X86_REG_ESP, UC_X86_REG_ECX, UC_X86_REG_EIP DEFAULT_EXE = r"F:\steam\steamapps\common\The I of the Dragon\TheIOfTheDragon.exe" EXE_PATH = DEFAULT_EXE def make_machine(): data = Path(EXE_PATH).read_bytes() pe = struct.unpack_from(' 1024: raise AssertionError('unterminated output line') lines.append((bytes(buf), *ints(pos, 2))) machine.reg_write(UC_X86_REG_ESP, sp + 24) machine.reg_write(UC_X86_REG_EIP, ret) uc.hook_add(UC_HOOK_CODE, draw, begin=0x4eab70, end=0x4eab70) uc.emu_start(0x4ed380, stop, count=1000000) if uc.reg_read(UC_X86_REG_EIP) != stop: raise AssertionError('layout did not terminate') return lines, ints(0x2000020, 1)[0] class LayoutTests(unittest.TestCase): def test_chinese_label_does_not_overlap_shortcut(self): lines, _ = layout('停止\nS') self.assertEqual(lines, [('停止'.encode('gb2312'), 12, 0), (b'S', 20, 17)]) def test_two_chinese_lines_and_shortcut(self): lines, _ = layout('建造城镇\nCtrl+B', width=48) self.assertEqual(lines, [('建造城镇'.encode('gb2312'), 0, 0), (b'Ctrl+B', 0, 17)]) def test_wrap_never_splits_a_chinese_character(self): lines, _ = layout('开始新游戏', width=24) self.assertEqual(lines, [('开始'.encode('gb2312'), 0, 0), ('新游'.encode('gb2312'), 0, 17), ('戏'.encode('gb2312'), 6, 34)]) def test_mixed_ascii_chinese_width(self): lines, _ = layout('A龙B\nS', width=48) self.assertEqual(lines, [('A龙B'.encode('gb2312'), 10, 0), (b'S', 20, 17)]) def test_ascii_layout_unchanged(self): lines, _ = layout('Stop\nS') self.assertEqual(lines, [(b'Stop', 8, 0), (b'S', 20, 17)]) def test_measure_only_height_matches_rendered_lines(self): _, height = layout('停止\nS', measure_only=True) self.assertEqual(height, 34) def test_alignment_control_codes_preserve_flags(self): for prefix, initial, x, shortcut_x in [('\a', 0, 12, 20), ('\b', 2, 0, 0), ('\v', 0, 24, 40)]: with self.subTest(prefix=repr(prefix)): lines, _ = layout(prefix + '停止\nS', alignment=initial) self.assertEqual(lines, [('停止'.encode('gb2312'), x, 0), (b'S', shortcut_x, 17)]) def test_space_wrap_preserves_chinese_and_shortcut(self): lines, _ = layout('停止 停止\nS', width=24) self.assertEqual(lines, [('停止'.encode('gb2312'), 0, 0), ('停止'.encode('gb2312'), 0, 17), (b'S', 8, 34)]) def test_mixed_word_wrap_retries_complete_character(self): lines, _ = layout('A龙B龙C', width=24) self.assertEqual(lines, [('A龙'.encode('gb2312'), 2, 0), ('B龙'.encode('gb2312'), 2, 17), (b'C', 8, 34)]) def test_one_character_wide_box(self): lines, _ = layout('龙龙龙龙', width=12) self.assertEqual(lines, [(b'\xc1\xfa', 0, 0), (b'\xc1\xfa', 0, 17), (b'\xc1\xfa', 0, 34), (b'\xc1\xfa', 0, 51)]) def test_oversize_character_remains_intact(self): lines, _ = layout('龙A', width=8, alignment=0) self.assertEqual(lines, [(b'\xc1\xfa', 0, 0), (b'A', 0, 17)]) def test_first_mixed_wrap_has_real_height(self): lines, _ = layout('AB龙', width=24) self.assertEqual(lines, [(b'AB', 4, 0), (b'\xc1\xfa', 6, 17)]) def test_world_map_tooltip_from_user_screenshot(self): lines, _ = layout('\a世界地图', width=96) self.assertEqual(lines, [('世界地图'.encode('gb2312'), 24, 0)]) def test_minimap_tooltip_from_user_screenshot(self): text = '\a小地图\n切换小地图显示开/关。\n\v(Enter)' lines, _ = layout(text, width=160) self.assertEqual(lines, [('小地图'.encode('gb2312'), 62, 0), ('切换小地图显示开/关。'.encode('gb2312'), 16, 17), (b'(Enter)', 104, 34)]) if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--exe', default=DEFAULT_EXE) args, remaining = parser.parse_known_args() EXE_PATH = args.exe unittest.main(argv=[__file__] + remaining)