Last active
January 15, 2025 02:57
-
-
Save doeyed/1ca1c4c6cbe3df5f6e1f1969c222d44d to your computer and use it in GitHub Desktop.
a JS unpacker for an odd container format used in google snake & minesweeper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {readFile, writeFile} from "fs" | |
function read_bin(index, block_size = 314, file_buffer) { | |
const use_u16 = !file_buffer[0] | |
const track_buffers = {}, odd_block_idxs = {}, even_block_idxs = {} | |
let total_odd_idxs = 0 | |
// track block indices table | |
Object.entries(index).forEach(([key, idx]) => { | |
let num_odd_idxs = file_buffer[idx] | |
if (use_u16) num_odd_idxs |= file_buffer[++idx] << 8 | |
total_odd_idxs += num_odd_idxs | |
odd_block_idxs[key] = [] | |
for (var _ = 0; _ < num_odd_idxs; _++) { | |
let block_idx = file_buffer[++idx] | |
if (use_u16) block_idx |= file_buffer[++idx] << 8 | |
odd_block_idxs[key].push(block_idx) | |
} | |
even_block_idxs[key] = [] | |
for (_ = 0; _ < num_odd_idxs; _++) { | |
let block_idx = file_buffer[++idx] | |
if (use_u16) block_idx |= file_buffer[++idx] << 8 | |
even_block_idxs[key].push(block_idx) | |
} | |
}) | |
let index_table_end = total_odd_idxs * 2 + Object.keys(index).length | |
if (use_u16) index_table_end *= 2, index_table_end += 2 | |
let last_block_idx = file_buffer[index_table_end++] | |
if (use_u16) last_block_idx |= file_buffer[index_table_end++] << 8 | |
// track data blocks | |
Object.keys(index).forEach(key => { | |
let buffer_size = 0 | |
odd_block_idxs[key].forEach(block_idx => { | |
const block_align_offset = ~(file_buffer[index_table_end + block_idx * 32 + 2] & 2) | |
buffer_size += block_size - block_align_offset | |
}) | |
track_buffers[key] = new ArrayBuffer(buffer_size) | |
const track_buffer = new Uint8Array(track_buffers[key]) | |
let track_buffer_idx = 0 | |
for (let idx = 0; idx < odd_block_idxs[key].length; idx++) { | |
const odd_block_idx = index_table_end + odd_block_idxs[key][idx] * 32, | |
even_block_idx = index_table_end + last_block_idx * 32 + even_block_idxs[key][idx] * (block_size - 32), | |
corr_block_size = block_size - !(file_buffer[odd_block_idx + 2] & 2) | |
const odd_block = file_buffer.subarray(odd_block_idx, odd_block_idx + 32) | |
const even_block = file_buffer.subarray(even_block_idx, even_block_idx + corr_block_size - 32) | |
track_buffer.set(odd_block, track_buffer_idx) | |
track_buffer.set(even_block, track_buffer_idx + 32) | |
track_buffer_idx += corr_block_size | |
} | |
}) | |
return track_buffers | |
} | |
readFile("./in/game_audio.bin", (err, file_buffer) => { | |
if (err) throw err | |
const final_obj = read_bin({ | |
BIG_DIG: 2, | |
DIG_REVEAL_1: 116, | |
DIG_REVEAL_2: 170, | |
DIG_REVEAL_3: 224, | |
DIG_REVEAL_4: 282, | |
DIG_REVEAL_5: 352, | |
DIG_REVEAL_6: 422, | |
DIG_REVEAL_7: 496, | |
DIG_REVEAL_8: 574, | |
MINE_1: 656, | |
MINE_2: 802, | |
MINE_3: 940, | |
MINE_4: 1074, | |
MINE_5: 1200, | |
PLANT_FLAG: 1370, | |
UNPLANT_FLAG: 1444 | |
}, 385, file_buffer) | |
Object.keys(final_obj).forEach(key => { | |
writeFile(`./out/${key}.bin`, new Uint8Array(final_obj[key]), err => { | |
if (err) throw err | |
}) | |
}) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment