A Python package for manipulating IPS patches
Project description
# ips-util
## Summary
This is a Python package for manipulating binary patches encoded in the International Patching System (IPS) format, as documented [here](http://fileformats.archiveteam.org/wiki/IPS_(binary_patch_format)) and [here](http://old.smwiki.net/wiki/IPS_file_format). IPS is a format that historically has been widely used for the distribution of ROM hacks for classic game consoles; as far as I know it remains a standard format today, despite its known limitations, and tools for using it are still helpful.
While the ips-util package does provide a command-line interface for creating and applying patches analagous to the GUI provided by [Lunar IPS](https://fusoya.eludevisibility.org/lips/) and similar tools, I created it mainly to assist in writing Python scripts that generate ROM hacks and output IPS patches. Thus it may not be as full-featured as other programs... but given how bare-bones the IPS format is, I'm not sure how "full-featured" such a tool could really be.
I've included a suite of tests to verify that ips-util handles the known pitfalls of the IPS format as best I can, but there may still be some edge cases I haven't thought of. I also haven't put too much thought into optimizing the creation of patches from a source and target file... the results seem pretty good based on limited testing, but I know that [Flips](https://github.com/Alcaro/Flips), for example, still has some optimizations I haven't bothered to implement. I'm not too worried about it; we don't live in a world where the difference between a 2Kb and a 3Kb patch matters to anyone that much anymore.
## Command line usage
The package provides a command-line interface which can be accessed independently of the Python shell (although `python -m ips_util` will still work if you really want it...).
To create a patch, using existing source and target binary files:
```bash
> ips_util create "Super Mario World.smc" "Super Mario World [1337357_h4x_3v4r].smc" -o 1337_p47ch.ips
```
To apply a patch to a binary file:
```bash
> ips_util apply 1337_p47ch.ips "Super Mario World.smc" -o w00t.smc
```
Note that in both cases, if an output file is not specified using the `-o` flag, the result will be written to stdout, for use in whatever complicated `bash` shenanigans you Linux kids get up to these days.
You can also dump the contents of a patch, to preview it or to debug your patch creation scripts:
```bash
> ips_util trace 1337_p47ch.ips
```
(However, for the moment, a proper visual tool like [ips-peek](https://github.com/vector-man/IPS-Peek) is probably better in every way for that purpose.)
## Usage in scripts
Very simple:
```python
from ips_util import Patch
def this_is_my_patch():
patch = Patch()
patch.add_record(0x1234, 999.to_bytes(2, byteorder='little')) # Max out some stat
patch.add_rle_record(0x5678, b'\xea', 0x10) # NOP out a bunch of code
with open('gavroche.ips', 'w+b') as f:
f.write(patch.encode())
```
Or:
```python
from ips_util import Patch
def dude_wheres_my_patch():
patch = Patch.load('gavroche.ips')
with open('some_data.smc', 'rb') as f_in:
with open('some_patched_data.smc', 'w+b') as f_out:
f_out.write(patch.apply(f_in.read()))
```
## License
Copy[right|left] is dumb and oppressive. So just do whatevs; I don't care.
## Summary
This is a Python package for manipulating binary patches encoded in the International Patching System (IPS) format, as documented [here](http://fileformats.archiveteam.org/wiki/IPS_(binary_patch_format)) and [here](http://old.smwiki.net/wiki/IPS_file_format). IPS is a format that historically has been widely used for the distribution of ROM hacks for classic game consoles; as far as I know it remains a standard format today, despite its known limitations, and tools for using it are still helpful.
While the ips-util package does provide a command-line interface for creating and applying patches analagous to the GUI provided by [Lunar IPS](https://fusoya.eludevisibility.org/lips/) and similar tools, I created it mainly to assist in writing Python scripts that generate ROM hacks and output IPS patches. Thus it may not be as full-featured as other programs... but given how bare-bones the IPS format is, I'm not sure how "full-featured" such a tool could really be.
I've included a suite of tests to verify that ips-util handles the known pitfalls of the IPS format as best I can, but there may still be some edge cases I haven't thought of. I also haven't put too much thought into optimizing the creation of patches from a source and target file... the results seem pretty good based on limited testing, but I know that [Flips](https://github.com/Alcaro/Flips), for example, still has some optimizations I haven't bothered to implement. I'm not too worried about it; we don't live in a world where the difference between a 2Kb and a 3Kb patch matters to anyone that much anymore.
## Command line usage
The package provides a command-line interface which can be accessed independently of the Python shell (although `python -m ips_util` will still work if you really want it...).
To create a patch, using existing source and target binary files:
```bash
> ips_util create "Super Mario World.smc" "Super Mario World [1337357_h4x_3v4r].smc" -o 1337_p47ch.ips
```
To apply a patch to a binary file:
```bash
> ips_util apply 1337_p47ch.ips "Super Mario World.smc" -o w00t.smc
```
Note that in both cases, if an output file is not specified using the `-o` flag, the result will be written to stdout, for use in whatever complicated `bash` shenanigans you Linux kids get up to these days.
You can also dump the contents of a patch, to preview it or to debug your patch creation scripts:
```bash
> ips_util trace 1337_p47ch.ips
```
(However, for the moment, a proper visual tool like [ips-peek](https://github.com/vector-man/IPS-Peek) is probably better in every way for that purpose.)
## Usage in scripts
Very simple:
```python
from ips_util import Patch
def this_is_my_patch():
patch = Patch()
patch.add_record(0x1234, 999.to_bytes(2, byteorder='little')) # Max out some stat
patch.add_rle_record(0x5678, b'\xea', 0x10) # NOP out a bunch of code
with open('gavroche.ips', 'w+b') as f:
f.write(patch.encode())
```
Or:
```python
from ips_util import Patch
def dude_wheres_my_patch():
patch = Patch.load('gavroche.ips')
with open('some_data.smc', 'rb') as f_in:
with open('some_patched_data.smc', 'w+b') as f_out:
f_out.write(patch.apply(f_in.read()))
```
## License
Copy[right|left] is dumb and oppressive. So just do whatevs; I don't care.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
ips_util-1.0.tar.gz
(5.9 kB
view details)
Built Distribution
File details
Details for the file ips_util-1.0.tar.gz
.
File metadata
- Download URL: ips_util-1.0.tar.gz
- Upload date:
- Size: 5.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.13.0 setuptools/40.6.3 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.6.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 478502f573f2b92f6409ae9efb129025b9e2cd2d71b2c9b6f1fd1796cb311933 |
|
MD5 | 6b7d8f2cad92519b5480054b082a04ce |
|
BLAKE2b-256 | e3684250a1ca49778ec7bd00ac408c0cf8a56d09ab8adbfa59f63f14c84d089e |
File details
Details for the file ips_util-1.0-py3-none-any.whl
.
File metadata
- Download URL: ips_util-1.0-py3-none-any.whl
- Upload date:
- Size: 7.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.13.0 setuptools/40.6.3 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.6.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 7862e9fbf09d7a9cdfdac05062755a1bad2d64bd54737046b497852b84d98f2b |
|
MD5 | dee8023eb5d8be96426d3bcfa9d44e38 |
|
BLAKE2b-256 | c488472d4c77ec23a6ba1fa824800d39b0917010bdb25cc9574c4bb13547e894 |