Skip to content
Improved patching engine that also supports legacy formats such as IPS, PPF and FireFlower
PHP
Branch: master
Clone or download
Latest commit dbc1849 Jul 13, 2015
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
LICENSE Cleaned up the output and removed all the messages about it being "be… Oct 22, 2012
README Cleaned up the output and removed all the messages about it being "be… Oct 22, 2012
ninja2.php Merging update. Jul 13, 2015

README

NINJA 2.0 (cli)
Copyright (c) 2006, 2012 Derrick Sobodash


FEATURES

 * Capable of creating and applying patches between both directories and
   single files

 * XOR patches allows a NINJA patch to both patch a file and restore its
   original form

 * Support for International Patching Standard (IPS) with the LunarCut
   format extension.

 * Support for PlayStation Patch Format (PPF) 1.0, 2.0 and 3.0

 * Support for Generic Diff Format (GDIFF) binary patches

 * Support for FireFlower Patcher (FFP/PAT) textual patches. Can use as
   both a patcher an unpatcher

 * Support for Microsoft File Compare output; can use as both a patcher
   and unpatcher (Example: fc /b FILE1 FILE2 >output.pat)

 * Format supports addressing in files up to 32,317,006*10^600 bytes;
   sadly, this implementation only supports up to 9,223,372,036,854,775,807.

 * NINJA patches support a struct of internal patch info so you can store
   the author, version number, game title, game genre, patch language,
   release date, patch homepage and a 1074 character summary

 * Nintendo 8-bit: Supports patching around NES headers; support for all
   NES formats except Pasofami (interNES, Famtasia and UNIF); one patch
   will work on NES, FAM and UNF ROMs

 * Super Nintendo: Supports patching around SNES headers; deinterleaving of
   Game Doctor SF3, Professor SF2, Super UFO and Multi Game Doctor formats;
   can preserve NSRT headers; one patch will work on SMC, SWC, FIG, 048, 
   058, 078, SFC, MGD, UFO, GD3 and GD7 ROMs

 * Nintendo 64: Supports deinterleaving of Doctor V64 ROMS; one patch will
   work on both Z64 and V64 ROMs

 * Game Boy: Supports removal of SmartCart Game Boy headers

 * Sega Master System: Supports deinterleaving of Super Magic Drive ROMs;
   one patch will work on both SMS and SMD ROMs

 * Sega Genesis: Supports deinterleaving of Super Magic Drive ROMs; one
   patch will work on both BIN and SMD ROMs

 * PC-Engine: Supports removal of Magic Super Griffin headers

 * Atari Lynx: Supports patching around Atari Lynx headers; one patch will
   work on LNX/RAW and LYX ROMs


REQUIREMENTS

 * PHP5 and the GMP module (php5-cli and php5-gmp on Debian)


COMMAND-LINE USEAGE

NINJA does two things: makes patches and applies them. This version can apply
NINJA 2.0, PPF, IPS, FFP, PAT and GDIFF patches. In the case of PPF, PAT, FFP
and NINJA, the internal patch info will be displayed in the console for you
to read.

The command lines are:

 * Create - ninja2.bat SOURCE MODIFIED FILE TYPE INFO
                          |       |     |    |    |
                          |       |     |    |    +- Text info file
                          |       |     |    +------ Format of data
                          |       |     +----------- File to create
                          |       +----------------- Modified file/folder
                          +------------------------- Original file/folder
 * Apply  - ninja2.bat PATCH TARGET
                         |     |
                         |     +-------------------- File/Folder to patch
                         +-------------------------- Patch file

The text info file must be a plain text file of 8 lines. The data expected on
each line is:

 1: Author      (  84 characters max)
 2: Version     (  11 characters max)
 3: Title       ( 256 characters max)
 4: Genre       (  48 characters max)
 5: Language    (  48 characters max)
 6: Date        (   8 characters max) (YYYYMMDD)
 7: Website     ( 512 characters max)
 8: Description (1074 characters max)

Data exceeding the limit for each line will be ignored. If no file is
specified, blank bytes will be entered for the file info.

Allowed data types are as follows:

 raw - Raw Binary (0)               gb  - Nintendo Game Boy (5)
 nes - Nintendo/Famicom (1)         sms - Sega Master System/Game Gear (6)
 fds - Famicom Disk System (2)      mega- Sega Genesis/Megadrive (7)
 snes- Super Nintendo/Famicom (3)   pce - NEC TurboGrafx-16/PC-Engine (8)
 n64 - Nintendo 64 (4)              lynx- Atari Lynx (9)

If no data type is specified, raw is assumed.

If your original data is a folder, the modified data must be a folder with the
same structure. To decrease patch creation time, it is recommended you include
only modified files in the modified folder, otherwise NINJA will be forced to
scan every single file.

NINJA will fail if you attempt to create a patch between a file and a folder.


FILE FORMAT

NINJA 2.0 follows a much simpler file format than its predecessor. Each patch
consists of 3 regions: HEADER, INFO and DATA. HEADER and INFO make up the first
sector of the patch (1024 bytes).

@HEADER@
{
  NINJA_MAGIC - string "NINJA" (5 bytes)
  NINJA_VER   - char "2"       (1 byte )
}

@INFO@
{
  PATCH_ENC   - int ENC      (   1 byte ) // Info text encoding
                                          // 0: System codepage / 1: UTF-8
  PATCH_AUTH  - string AUTH  (  84 bytes) // Author
  PATCH_VER   - string VER   (  11 bytes) // Version
  PATCH_TITLE - string TITLE ( 256 bytes) // Title
  PATCH_GENRE - string GENRE (  48 bytes) // Genre
  PATCH_LANG  - string LANG  (  48 bytes) // Language
  PATCH_DATE  - string DATE  (   8 bytes) // Date as YYYYMMDD
  PATCH_WEB   - string WEB   ( 512 bytes) // Website
  PATCH_DESC  - string DESC  (1074 bytes) // Info (New line marked by "\n")
}

@DATA@
{
  COMMAND     - int COMMAND  (  1 byte )
  if COMMAND == 0x1     // Open File|Close Current
  {
    FILE_N_MUL    - int N_MUL     (        1 byte ) // 0 Signals single-file
    FILE_N_LEN    - int N_LEN     (    N_MUL bytes) // Length of file name
    FILE_NAME     - string NAME   (    N_LEN bytes) // File name
    FILE_TYPE     - int TYPE      (        1 byte ) // File format
    FILE_SSIZE_MUL- int SSIZE_MUL (        1 byte )
    FILE_SSIZE    - int SIZE      (SSIZE_MUL bytes) // Source file size
    FILE_MSIZE_MUL- int MSIZE_MUL (        1 byte )
    FILE_MSIZE    - int MIZE      (MSIZE_MUL bytes) // Modified file size
    FILE_SMD5     - string SMD5   (       16 bytes) // Source MD5sum
    FILE_MMD5     - string MMD5   (       16 bytes) // Modified MD5sum
    if SSIZE > MSIZE
    {
      FILE_MAGIC   - char "M"        (       1 byte ) // Source overflow
      FILE_OVER_MUL- int OVER_MUL    (       1 byte )
      FILE_OVER    - int OVER        (OVER_MUL bytes) // Overflow length
      FILE_OVERFLOW- string OVERFLOW (    OVER bytes) // Lost from modified
    }
    else if MSIZE > SSIZE
    {
      FILE_MAGIC   - char "A"        (       1 byte ) // Modified overflow
      FILE_OVER_MUL- int OVER_MUL    (       1 byte )
      FILE_OVER    - int OVER        (OVER_MUL bytes) // Overflow length
      FILE_OVERFLOW- string OVERFLOW (    OVER bytes) // Gained in modified
    }
  }
  else if COMMAND == 02 // XOR Patch
  {
    PATCH_OFF_MUL- int OFF_MUL (      1 byte )
    PATCH_OFF    - int OFF     (OFF_MUL bytes) // Patch offset
    PATCH_LEN_MUL- int LEN_MUL (      1 byte )
    PATCH_LEN    - int LEN     (LEN_MUL bytes) // Patch length
    PATCH_XOR    - string XOR  (    LEN bytes) // XOR string
  }
  else if COMMAND == 0x0
    // Terminate patch
}


You can’t perform that action at this time.