Skip to content

Commit 6e2feee

Browse files
feat(ui): Add simple dialog for quick access to string hashes
1 parent c40f829 commit 6e2feee

File tree

2 files changed

+66
-2
lines changed

2 files changed

+66
-2
lines changed

src/bw_save_game/hash.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
def frostbite_fnv1(data: bytes):
2+
assert isinstance(data, bytes)
3+
h = 5381
4+
for byte in data:
5+
h = (((33 * h) & 0xFFFFFFFF) ^ byte) & 0xFFFFFFFF
6+
return h
7+
8+
9+
def frostbite_fnv1_lowercase(data: bytes):
10+
"""Return the FNV1 32bit hash for data.
11+
12+
>>> frostbite_fnv1_lowercase(b"Characters/Generic/Universal/Makeup/Blush_Makeup/HF_MAK_Blush_12A_Mask")
13+
3828825916
14+
"""
15+
assert isinstance(data, bytes)
16+
h = 5381
17+
for byte in data:
18+
v = (byte + 32 * ((byte - 65) & 0xFF <= 0x19)) & 0xFF
19+
h = (((33 * h) & 0xFFFFFFFF) ^ v) & 0xFFFFFFFF
20+
return h

src/bw_save_game/ui/__init__.py

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
from bw_save_game import __version__
3131
from bw_save_game.db_object import Long, to_native
32+
from bw_save_game.hash import frostbite_fnv1, frostbite_fnv1_lowercase
3233
from bw_save_game.persistence import (
3334
PersistenceKey,
3435
PersistencePropertyDefinition,
@@ -198,6 +199,7 @@ def __init__(self):
198199
self.selected_collectible_set_index = 0
199200
self.selected_definition_index = 0
200201
self.selected_instance_index = 0
202+
self.hash_input = ""
201203

202204
self.default_save_path = detect_save_game_path()
203205

@@ -296,10 +298,45 @@ def show_app_about(state: State):
296298
imgui.end_popup()
297299

298300

301+
def show_hash_popup(state: State):
302+
imgui.set_next_window_pos(imgui.get_main_viewport().get_center(), imgui.Cond_.appearing, (0.5, 0.5))
303+
imgui.set_next_window_size((500, 120))
304+
if imgui.begin_popup("Frostbite Hashes"):
305+
imgui.text_disabled("Input:")
306+
imgui.set_next_item_width(-1)
307+
_, state.hash_input = imgui.input_text("##hash_in", state.hash_input)
308+
309+
input_to_hash = state.hash_input.encode("utf-8")
310+
311+
imgui.text_disabled("FNV1:")
312+
imgui.same_line()
313+
imgui.set_next_item_width(-1)
314+
_, _ = imgui.input_text(
315+
"##fnv1",
316+
str(frostbite_fnv1(input_to_hash)),
317+
flags=imgui.InputTextFlags_.read_only | imgui.InputTextFlags_.no_undo_redo,
318+
)
319+
320+
imgui.text_disabled("FNV1 (lowercase):")
321+
imgui.same_line()
322+
imgui.set_next_item_width(-1)
323+
_, _ = imgui.input_text(
324+
"##fnv1_lower",
325+
str(frostbite_fnv1_lowercase(input_to_hash)),
326+
flags=imgui.InputTextFlags_.read_only | imgui.InputTextFlags_.no_undo_redo,
327+
)
328+
329+
imgui.end_popup()
330+
331+
299332
def show_main_menu_bar(state: State):
300333
if not imgui.begin_main_menu_bar():
301334
return
302335

336+
# https://github.com/ocornut/imgui/issues/331
337+
need_hash_open = False
338+
need_about_open = False
339+
303340
if imgui.begin_menu("File", True):
304341
clicked, selected = imgui.menu_item(label="Open", shortcut="Ctrl+O", p_selected=False)
305342
if clicked:
@@ -345,8 +382,12 @@ def show_main_menu_bar(state: State):
345382

346383
imgui.end_menu()
347384

348-
# https://github.com/ocornut/imgui/issues/331
349-
need_about_open = False
385+
if imgui.begin_menu("Tools", True):
386+
clicked, selected = imgui.menu_item(label="Frostbite String Hashes", shortcut="", p_selected=False)
387+
if clicked:
388+
need_hash_open = True
389+
imgui.end_menu()
390+
350391
if imgui.begin_menu("Help", True):
351392
clicked, selected = imgui.menu_item(label="About BWSaveGameEditor", shortcut="", p_selected=False)
352393
if clicked:
@@ -355,6 +396,8 @@ def show_main_menu_bar(state: State):
355396

356397
imgui.end_main_menu_bar()
357398

399+
if need_hash_open:
400+
imgui.open_popup("Frostbite Hashes")
358401
if need_about_open:
359402
imgui.open_popup("About")
360403

@@ -1359,6 +1402,7 @@ def show_editor_window(state: State):
13591402
def show_ui(state: State):
13601403
show_main_menu_bar(state)
13611404
show_app_about(state)
1405+
show_hash_popup(state)
13621406
show_editor_window(state)
13631407

13641408
clear_unused_retained_data()

0 commit comments

Comments
 (0)