Skip to content

Instantly share code, notes, and snippets.

@Darksecond
Last active May 23, 2017 08:00
Show Gist options
  • Save Darksecond/3706842f74ba04ceecebd5f10e89b0ec to your computer and use it in GitHub Desktop.
Save Darksecond/3706842f74ba04ceecebd5f10e89b0ec to your computer and use it in GitHub Desktop.

Revisions

  1. Darksecond revised this gist May 23, 2017. 1 changed file with 169 additions and 0 deletions.
    169 changes: 169 additions & 0 deletions patch_v3.ksy
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,169 @@
    meta:
    id: patch_v3
    file-extension: lvl
    endian: le
    instances:
    header:
    type: header
    pos: 0
    maps:
    type: map
    pos: 8
    repeat: expr
    repeat-expr: header.map_count
    size: 185344
    types:
    max_teams:
    seq:
    - id: none
    type: u1
    - id: ctf
    type: u1
    - id: slayer
    type: u1
    - id: oddball
    type: u1
    - id: koth
    type: u1
    - id: race
    type: u1
    - id: headhunter
    type: u1
    - id: juggernaught
    type: u1
    - id: territories
    type: u1
    - id: assault
    type: u1
    - id: stub_10
    type: u1
    - id: stub_11
    type: u1
    - id: stub_12
    type: u1
    - id: stub_13
    type: u1
    - id: stub_14
    type: u1
    - id: stub_15
    type: u1
    header:
    seq:
    - id: version
    type: u4
    - id: map_count
    type: u4
    map:
    seq:
    - id: version
    type: u4
    - id: patch_checksum
    type: u4
    doc: >
    Inverted CRC32 of the chunk, patch_checksum field should be zero.
    A chunk is 185344 bytes long.
    It does not include the 8 byte file header.
    - id: unknown2
    type: u4
    doc: always seems to be '1'
    - id: scenario
    type: str
    encoding: UTF-8
    size: 256
    - id: map_checksum
    type: u4
    - id: map_end
    type: u4
    doc: offering_id?
    - id: unknown5
    type: u4
    doc: always seems to be '0xFFFFFFFF'
    - id: name_en
    type: str
    encoding: UTF-16
    size: 64
    - id: name2
    type: str
    encoding: UTF-16
    size: 64
    - id: name_de
    type: str
    encoding: UTF-16
    size: 64
    - id: name_fr
    type: str
    encoding: UTF-16
    size: 64
    - id: name5
    type: str
    encoding: UTF-16
    size: 64
    - id: name6
    type: str
    encoding: UTF-16
    size: 64
    - id: name_ch
    type: str
    encoding: UTF-16
    size: 64
    - id: name8
    type: str
    encoding: UTF-16
    size: 64
    - id: name9
    type: str
    encoding: UTF-16
    size: 64
    - id: description_en
    type: str
    encoding: UTF-16
    size: 256
    - id: description2
    type: str
    encoding: UTF-16
    size: 256
    - id: description_de
    type: str
    encoding: UTF-16
    size: 256
    - id: description_fr
    type: str
    encoding: UTF-16
    size: 256
    - id: description5
    type: str
    encoding: UTF-16
    size: 256
    - id: description6
    type: str
    encoding: UTF-16
    size: 256
    - id: description_ch
    type: str
    encoding: UTF-16
    size: 256
    - id: description8
    type: str
    encoding: UTF-16
    size: 256
    - id: description9
    type: str
    encoding: UTF-16
    size: 256
    - id: map_start
    type: u4
    - id: unknown6
    type: u4
    doc: >
    always seems be '0'.
    Possibly flags or sort order?
    - id: max_teams
    type: max_teams
    - id: raw_dxt1
    size: 0x2C790
    doc: >
    This is DDS file with DXT1.
    Width is 220.
    Height is 207.
    Size is 0x2C790.
    This is the raw dxt1 bitmap, it just needs a header.
  2. Darksecond revised this gist Apr 7, 2017. 1 changed file with 1 addition and 2 deletions.
    3 changes: 1 addition & 2 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,6 @@
    # Halo 2 patch_v3.lvl signer/checker.

    The chunk checksum is just a CRC32. It seems to be a slighty weird one in that there seems to be signed/unsigned difficulties.
    This is fixed in the javascript for all my test cases.
    The chunk checksum is just a CRC32. It seems to be inverted though.
    Right now it does nothing except check the signatures of each chunk.

    It is easy to add json serialization/unserialization later.
  3. Darksecond revised this gist Apr 7, 2017. 1 changed file with 3 additions and 2 deletions.
    5 changes: 3 additions & 2 deletions patch.js
    Original file line number Diff line number Diff line change
    @@ -14,7 +14,8 @@ for(let index = 0; index < maps; index++) {
    chunk[6] = 0;
    chunk[7] = 0;

    // Weirdities to make CRC32 behave. It matches all my test cases.
    let crc = (CRC32.buf(chunk)*-1 >>> 0) - 1;
    // checksum seems to be inverted.
    // So invert & treat as unsigned.
    let crc = ~CRC32.buf(chunk) >>> 0;
    console.log(checksum.toString(16), crc.toString(16));
    }
  4. Darksecond revised this gist Apr 7, 2017. 1 changed file with 2 additions and 4 deletions.
    6 changes: 2 additions & 4 deletions package.json
    Original file line number Diff line number Diff line change
    @@ -4,14 +4,12 @@
    "description": "",
    "main": "patch.js",
    "dependencies": {
    "crc": "^3.4.4",
    "crc-32": "^1.0.1",
    "crc32": "^0.2.2"
    "crc-32": "^1.0.1"
    },
    "devDependencies": {},
    "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "",
    "author": "Tim Peters",
    "license": "ISC"
    }
  5. Darksecond revised this gist Apr 7, 2017. 1 changed file with 7 additions and 0 deletions.
    7 changes: 7 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    # Halo 2 patch_v3.lvl signer/checker.

    The chunk checksum is just a CRC32. It seems to be a slighty weird one in that there seems to be signed/unsigned difficulties.
    This is fixed in the javascript for all my test cases.
    Right now it does nothing except check the signatures of each chunk.

    It is easy to add json serialization/unserialization later.
  6. Darksecond created this gist Apr 7, 2017.
    17 changes: 17 additions & 0 deletions package.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,17 @@
    {
    "name": "patchnode-19232",
    "version": "1.0.0",
    "description": "",
    "main": "patch.js",
    "dependencies": {
    "crc": "^3.4.4",
    "crc-32": "^1.0.1",
    "crc32": "^0.2.2"
    },
    "devDependencies": {},
    "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "",
    "license": "ISC"
    }
    20 changes: 20 additions & 0 deletions patch.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,20 @@
    const CRC32 = require('crc-32');

    const fs = require('fs');

    const buffer = fs.readFileSync('./patch_v3.lvl.3');
    const header = buffer.slice(0,8);
    const maps = buffer.readUInt32LE(4);
    console.log(maps);
    for(let index = 0; index < maps; index++) {
    let chunk = buffer.slice(8+185344*index,8+185344*(index+1));
    let checksum = chunk.readUInt32LE(4);
    chunk[4] = 0;
    chunk[5] = 0;
    chunk[6] = 0;
    chunk[7] = 0;

    // Weirdities to make CRC32 behave. It matches all my test cases.
    let crc = (CRC32.buf(chunk)*-1 >>> 0) - 1;
    console.log(checksum.toString(16), crc.toString(16));
    }