rompatcher

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 4, 2026 License: MIT Imports: 25 Imported by: 0

README

RomPatcher.go

A native Go library and command-line ROM patcher, rewritten from RomPatcher.js by Marc Robledo. This repository contains the patching engine and CLI only; it has no web frontend. Building from source requires Go 1.21 or newer. Prebuilt binaries are self-contained and do not require a Go installation.

AI-assisted development

This Go rewrite was developed with substantial assistance from OpenAI Codex. Although it has been reviewed and tested, AI-assisted code can contain mistakes. Users should independently evaluate and test it for their use case.

Format support

Format Apply Create Source/target validation
IPS / IPS32 / EBP Yes Yes
UPS Yes, forward or reverse Yes Size + source/target CRC32
BPS Yes Yes Size + source/target CRC32
APS (N64) Yes Yes N64 cart ID + stored header CRC
APS (GBA) Yes No Source size + per-block CRC16
RUP / NINJA2 Yes, forward or reverse Yes Source/target MD5
PPF 1–3 Yes, including undo when present Yes Size, block check, and undo records when present
BSDIFF40 (.bdf / .bspatch) Yes No
Paper Mario Star Rod (.mod) Yes No Fixed source size + CRC32
VCDIFF / xdelta Yes, including xdelta3 LZMA No Optional per-window Adler-32

Validation refers to checks enabled by ApplyOptions.Validate or CLI -v. Invalid headers, payloads, and embedded patch checksums are rejected as they are decoded. PPF creation cannot represent an output smaller than its input.

VCDIFF supports RFC 3284 default and custom code tables, source/target windows, configurable address caches, Adler-32 validation, and xdelta3's common LZMA secondary compression through the pure-Go github.com/ulikunitz/xz package. DJW and FGK secondary compression are detected and reported as unsupported.

Installation

Download a platform archive from GitHub Releases, or install the latest version with Go:

go install github.com/olsonb97/RomPatcher.go/cmd/rompatcher@latest

Library

output, err := rompatcher.Apply(sourceBytes, patchBytes,
    rompatcher.ApplyOptions{Validate: true})

created, err := rompatcher.Create(original, modified, rompatcher.FormatBPS, nil)
patchBytes, err := created.MarshalBinary()

// Cancellable, bounded-memory patching and creation.
size, err := rompatcher.ApplyReaderAt(ctx, source, sourceSize, patchFile,
    patchSize, output, options)
size, err = rompatcher.CreateReaderAt(ctx, originalFile, originalSize,
    modifiedFile, modifiedSize, patchOutput, rompatcher.FormatBPS, nil)

ApplyOptions supports cancellation, progress callbacks, an output-size limit, temporary iNES, FDS, Lynx, or SNES copier-header handling, and Game Boy or Mega Drive/Genesis internal checksum repair. The default output limit is 64 MiB plus twice the source size.

ApplyReaderAt and ApplyFile keep the source and output file-backed for every supported format and decode patch records incrementally. CreateReaderAt and CreateFile also keep both input files out of memory unless BPS delta matching is explicitly enabled. VCDIFF retains only the current target window. Header and checksum compatibility transformations use the memory-backed path. ApplyFileChain uses temporary files between patches. Inspect, DryRun, and ApplyChain provide their in-memory counterparts.

CLI

rompatcher apply game.sfc translation.bps -v -o game-patched.sfc
rompatcher apply --dry-run --json game.sfc translation.bps
rompatcher apply games.zip patch.bps -s "region/game.sfc" -o game.sfc
rompatcher apply game.sfc base.bps addon.ips -v -o final.sfc
rompatcher archive games.zip
rompatcher create original.sfc modified.sfc -f bps -o patch.bps
rompatcher inspect --json patch.bps
rompatcher hash game.sfc
rompatcher batch jobs.json
rompatcher version
Applying patches

rompatcher apply SOURCE PATCH [PATCH...] applies patches from left to right. Useful options are -o for output, -v to validate, -n for a dry run, -j for JSON, and -p for progress. Run rompatcher apply --help for the rest.

ZIP files are supported, but 7z files are not. If a ZIP contains multiple choices, run rompatcher archive FILE.zip, then select one with -s for the source or -e for a patch. Use - for stdin or stdout where applicable. Existing output files are never overwritten.

Batch manifests

rompatcher batch jobs.json accepts this structure:

{
  "jobs": [{
    "source": "games.zip",
    "sourceEntry": "region/game.sfc",
    "patches": [{"path": "translation.bps"}, {"path": "fix.ips"}],
    "output": "game-patched.sfc",
    "validate": true,
    "removeHeader": false,
    "addHeader": false,
    "fixChecksum": true
  }]
}

Each job requires source, patches, and output; output is optional with batch -n. Optional fields are sourceEntry, validate, removeHeader, addHeader, fixChecksum, and maxOutput. Each patch requires path and may include entry for ZIP selection.

Building release archives

The build script requires Python 3 and Go. With no -t options it builds all nine targets:

python build_release.py 1.0.1

Use -t to select one or more targets:

python build_release.py 1.0.1 -t windows/amd64
python build_release.py 1.0.1 -t windows/amd64,linux/amd64
python build_release.py --list-targets

Use -o DIR to change the output directory. Archives include the license files, and their SHA-256 hashes are written to checksums.txt.

License

RomPatcher.go is MIT-licensed and retains the original RomPatcher.js copyright and license notice. Its pure-Go XZ dependency and the Go standard library are BSD-3-Clause; the exact required attributions are tracked in THIRD_PARTY_NOTICES.md and bundled in every release archive alongside LICENSE.

Verification

go test ./...
go vet ./...
go test -bench . -benchmem

The tests cover every supported apply format and every supported creator, malformed-input safety, resizing, cancellation, atomic output, ZIP ambiguity, chains, custom VCDIFF tables, LZMA secondary compression, reversible UPS and RUP, header handling, and known patch checksums. An optional real-world corpus harness provides broader compatibility coverage without redistributing third-party patches or game data.

Documentation

Overview

Package rompatcher parses, inspects, creates, and applies common ROM patch formats. It provides memory-backed helpers, cancellable random-access file patching, validation, ordered patch chains, ZIP input selection, and ROM header/checksum compatibility operations.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrUnknownFormat means the patch signature is not recognized.
	ErrUnknownFormat = errors.New("rompatcher: unknown patch format")
	// ErrInvalidPatch means the patch structure or values are malformed.
	ErrInvalidPatch = errors.New("rompatcher: invalid patch")
	// ErrSourceMismatch means source validation failed.
	ErrSourceMismatch = errors.New("rompatcher: source does not match patch")
	// ErrTargetMismatch means generated output validation failed.
	ErrTargetMismatch = errors.New("rompatcher: patched output does not match patch")
	// ErrPatchMismatch means the patch's own checksum failed.
	ErrPatchMismatch = errors.New("rompatcher: patch checksum mismatch")
	// ErrOutputTooLarge means a configured or default size limit was exceeded.
	ErrOutputTooLarge = errors.New("rompatcher: size limit exceeded")
	// ErrUnsupported means the requested operation is unavailable for the format.
	ErrUnsupported = errors.New("rompatcher: operation is not supported by this format")
	// ErrUnexpectedEnd means the patch ended before a complete value was read.
	ErrUnexpectedEnd = errors.New("rompatcher: unexpected end of patch")
	// ErrAmbiguousArchive means an archive entry must be selected explicitly.
	ErrAmbiguousArchive = errors.New("rompatcher: archive contains multiple candidate entries")
)

Functions

func AdditionalChecksum

func AdditionalChecksum(data []byte, name string) string

AdditionalChecksum returns format-specific source identification when available.

func Adler32

func Adler32(data []byte) uint32

Adler32 returns the Adler-32 checksum of data.

func Apply

func Apply(source, patchData []byte, options ApplyOptions) ([]byte, error)

Apply parses patchData and applies it to source in memory.

Example
package main

import (
	"fmt"

	rompatcher "github.com/olsonb97/RomPatcher.go"
)

func main() {
	original := []byte("original data")
	modified := []byte("patched! data")
	patch, _ := rompatcher.Create(original, modified, rompatcher.FormatBPS, nil)
	encoded, _ := patch.MarshalBinary()

	output, _ := rompatcher.Apply(original, encoded, rompatcher.ApplyOptions{Validate: true})
	fmt.Println(string(output))
}
Output:
patched! data

func ApplyFile

func ApplyFile(sourcePath, patchPath, outputPath string, opts ApplyOptions) error

ApplyFile applies one patch using file-backed I/O and atomic output.

func ApplyFileContext

func ApplyFileContext(ctx context.Context, sourcePath, patchPath, outputPath string, opts ApplyOptions) error

ApplyFileContext is ApplyFile with explicit cancellation.

func ApplyParsedWithOptions

func ApplyParsedWithOptions(source []byte, p Patch, opts ApplyOptions) ([]byte, error)

ApplyParsedWithOptions applies an already parsed patch in memory.

func ApplyReaderAt

func ApplyReaderAt(ctx context.Context, source io.ReaderAt, sourceSize int64, patch io.ReaderAt, patchSize int64, output io.WriterAt, opts ApplyOptions) (int64, error)

ApplyReaderAt normally applies a patch without loading either input into memory. Header conversion and checksum repair use the compatibility memory path. The returned size is the exact output length. Output must also implement io.ReaderAt for formats that copy from already-produced output; *os.File and the package's in-memory adapter both satisfy that requirement.

Example
package main

import (
	"bytes"
	"context"
	"fmt"
	"os"

	rompatcher "github.com/olsonb97/RomPatcher.go"
)

func main() {
	original := []byte("before")
	modified := []byte("after!")
	patch, _ := rompatcher.Create(original, modified, rompatcher.FormatBPS, nil)
	encoded, _ := patch.MarshalBinary()
	output, _ := os.CreateTemp("", "rompatcher-example-*")
	defer os.Remove(output.Name())
	defer output.Close()

	size, _ := rompatcher.ApplyReaderAt(
		context.Background(),
		bytes.NewReader(original), int64(len(original)),
		bytes.NewReader(encoded), int64(len(encoded)),
		output, rompatcher.ApplyOptions{Validate: true},
	)
	data := make([]byte, size)
	_, _ = output.ReadAt(data, 0)
	fmt.Println(string(data))
}
Output:
after!

func ApplyWithOptions

func ApplyWithOptions(source, patchData []byte, opts ApplyOptions) ([]byte, error)

ApplyWithOptions is an explicit-name alias for Apply.

func CRC16

func CRC16(data []byte) uint16

CRC16 returns CRC-16/CCITT-FALSE, used by APS (GBA).

func CRC32

func CRC32(data []byte) uint32

CRC32 returns the IEEE CRC-32 checksum of data.

func CreateFile

func CreateFile(originalPath, modifiedPath, outputPath string, format Format, opts *CreateOptions) error

CreateFile creates a patch using file-backed I/O and atomic output.

func CreateFileContext

func CreateFileContext(ctx context.Context, originalPath, modifiedPath, outputPath string, format Format, opts *CreateOptions) error

CreateFileContext creates a patch from two files and atomically publishes it. Inputs stay file-backed unless BPS delta matching is explicitly enabled.

func CreateReaderAt

func CreateReaderAt(ctx context.Context, original io.ReaderAt, originalSize int64, modified io.ReaderAt, modifiedSize int64, output io.Writer, format Format, options *CreateOptions) (int64, error)

CreateReaderAt creates a patch without loading either input into memory. BPS creation uses memory only when CreateOptions.BPSDelta is explicitly enabled. The output is written sequentially and is not closed by this function.

Example
package main

import (
	"bytes"
	"context"
	"fmt"

	rompatcher "github.com/olsonb97/RomPatcher.go"
)

func main() {
	original := []byte("before")
	modified := []byte("after!")
	var encoded bytes.Buffer

	size, _ := rompatcher.CreateReaderAt(
		context.Background(),
		bytes.NewReader(original), int64(len(original)),
		bytes.NewReader(modified), int64(len(modified)),
		&encoded, rompatcher.FormatIPS, nil,
	)
	fmt.Println(size == int64(encoded.Len()))
}
Output:
true

func DefaultPatchedPath

func DefaultPatchedPath(sourcePath string) string

DefaultPatchedPath inserts " (patched)" before a source file's extension.

func ExtractZIP

func ExtractZIP(path, entry string, kind InputKind, maxSize uint64, dst io.Writer) (string, error)

ExtractZIP selects one ZIP entry and streams it to dst without buffering the entry in memory.

func FixROMChecksum

func FixROMChecksum(data []byte, name string) bool

FixROMChecksum repairs a recognized internal ROM checksum in place.

func MD5

func MD5(data []byte) string

MD5 returns the lowercase hexadecimal MD5 digest of data.

func ReadZIP

func ReadZIP(path, entry string, kind InputKind, maxSize uint64) ([]byte, string, error)

ReadZIP selects and reads one ZIP entry. A zero maxSize means unlimited.

func ReadZIPBytes

func ReadZIPBytes(data []byte, entry string, kind InputKind, maxSize uint64) ([]byte, string, error)

ReadZIPBytes selects and reads one entry from an in-memory ZIP archive.

func SHA1

func SHA1(data []byte) string

SHA1 returns the lowercase hexadecimal SHA-1 digest of data.

func WriteFileAtomic

func WriteFileAtomic(path string, data []byte) error

WriteFileAtomic writes data atomically without replacing an existing file.

Types

type APSGBAPatch

type APSGBAPatch struct {
	SourceSize, TargetSize uint32
	// contains filtered or unexported fields
}

APSGBAPatch is a parsed APS patch for Game Boy Advance images.

func (*APSGBAPatch) Apply

func (p *APSGBAPatch) Apply(source []byte, options ApplyOptions) ([]byte, error)

Apply implements Patch.

func (APSGBAPatch) Description

func (APSGBAPatch) Description() string

Description returns an empty string when a format has no description field.

func (*APSGBAPatch) Format

func (*APSGBAPatch) Format() Format

Format implements Patch.

func (*APSGBAPatch) MarshalBinary

func (p *APSGBAPatch) MarshalBinary() ([]byte, error)

MarshalBinary implements Patch.

func (*APSGBAPatch) ValidateSource

func (p *APSGBAPatch) ValidateSource(source []byte) bool

ValidateSource implements Patch.

func (*APSGBAPatch) ValidationInfo

func (p *APSGBAPatch) ValidationInfo() *ValidationInfo

ValidationInfo implements Patch.

type APSN64Patch

type APSN64Patch struct {
	HeaderType, Encoding byte
	PatchDescription     string
	OriginalFormat       byte
	CartID               string
	CartCRC              [8]byte
	Pad                  [5]byte
	TargetSize           uint32
	// contains filtered or unexported fields
}

APSN64Patch is a parsed APS patch for Nintendo 64 images.

func (*APSN64Patch) Apply

func (p *APSN64Patch) Apply(source []byte, options ApplyOptions) ([]byte, error)

Apply implements Patch.

func (*APSN64Patch) Description

func (p *APSN64Patch) Description() string

Description implements Patch.

func (*APSN64Patch) Format

func (*APSN64Patch) Format() Format

Format implements Patch.

func (*APSN64Patch) MarshalBinary

func (p *APSN64Patch) MarshalBinary() ([]byte, error)

MarshalBinary implements Patch.

func (*APSN64Patch) ValidateSource

func (p *APSN64Patch) ValidateSource(source []byte) bool

ValidateSource implements Patch.

func (*APSN64Patch) ValidationInfo

func (p *APSN64Patch) ValidationInfo() *ValidationInfo

ValidationInfo implements Patch.

type ApplyOptions

type ApplyOptions struct {
	// Validate enables source and generated-output checks supported by the format.
	Validate bool
	// RemoveHeader temporarily removes a recognized copier or container header.
	RemoveHeader bool
	// AddHeader temporarily adds a recognized copier or container header.
	AddHeader bool
	// FixChecksum repairs a recognized internal ROM checksum after patching.
	FixChecksum bool
	// SourceName supplies the filename extension used for ROM-specific handling.
	SourceName string
	// Context cancels long-running patch operations. Nil means context.Background.
	Context context.Context
	// Progress receives coarse progress updates. Callbacks must return quickly;
	// they run synchronously with patching.
	Progress func(Progress)
	// MaxOutputSize caps allocations from untrusted patches. Zero chooses a
	// source-relative default (64 MiB plus twice the source size).
	MaxOutputSize uint64
}

ApplyOptions controls validation, ROM transforms, limits, and progress.

type ArchiveEntry

type ArchiveEntry struct {
	Name            string `json:"name"`
	Size            uint64 `json:"size"`
	CompressedSize  uint64 `json:"compressedSize"`
	PatchCandidate  bool   `json:"patchCandidate"`
	SourceCandidate bool   `json:"sourceCandidate"`
}

ArchiveEntry describes a selectable file inside a ZIP archive.

func ListZIP

func ListZIP(path string) ([]ArchiveEntry, error)

ListZIP lists regular entries and their candidate classifications.

func ListZIPBytes

func ListZIPBytes(data []byte) ([]ArchiveEntry, error)

ListZIPBytes lists entries in an in-memory ZIP archive.

type ArtifactInfo

type ArtifactInfo struct {
	Size   *uint64           `json:"size,omitempty"`
	Hashes map[string]string `json:"hashes,omitempty"`
}

ArtifactInfo describes an input or output by size and hashes.

type BDFPatch

type BDFPatch struct {
	TargetSize uint64
	// contains filtered or unexported fields
}

BDFPatch is a parsed BSDIFF40 patch.

func (*BDFPatch) Apply

func (p *BDFPatch) Apply(source []byte, options ApplyOptions) ([]byte, error)

Apply implements Patch.

func (BDFPatch) Description

func (BDFPatch) Description() string

Description returns an empty string when a format has no description field.

func (*BDFPatch) Format

func (*BDFPatch) Format() Format

Format implements Patch.

func (*BDFPatch) MarshalBinary

func (*BDFPatch) MarshalBinary() ([]byte, error)

MarshalBinary reports that BSDIFF creation is unsupported.

func (BDFPatch) ValidateSource

func (BDFPatch) ValidateSource([]byte) bool

ValidateSource accepts any source when a format has no source signature.

func (BDFPatch) ValidationInfo

func (BDFPatch) ValidationInfo() *ValidationInfo

ValidationInfo returns nil when a format has no source signature.

type BPSPatch

type BPSPatch struct {
	SourceSize, TargetSize uint64
	Metadata               string

	SourceCRC, TargetCRC, PatchCRC uint32
	// contains filtered or unexported fields
}

BPSPatch is a parsed BPS patch.

func (*BPSPatch) Apply

func (p *BPSPatch) Apply(source []byte, options ApplyOptions) ([]byte, error)

Apply implements Patch.

func (*BPSPatch) Description

func (p *BPSPatch) Description() string

Description implements Patch.

func (*BPSPatch) Format

func (*BPSPatch) Format() Format

Format implements Patch.

func (*BPSPatch) MarshalBinary

func (p *BPSPatch) MarshalBinary() ([]byte, error)

MarshalBinary implements Patch.

func (*BPSPatch) ValidateSource

func (p *BPSPatch) ValidateSource(source []byte) bool

ValidateSource implements Patch.

func (*BPSPatch) ValidationInfo

func (p *BPSPatch) ValidationInfo() *ValidationInfo

ValidationInfo implements Patch.

type ChainResult

type ChainResult struct {
	Output []byte      `json:"-"`
	Steps  []ChainStep `json:"steps"`
}

ChainResult contains ordered step reports and, for ApplyChain, output bytes.

func ApplyChain

func ApplyChain(source []byte, patches [][]byte, opts ApplyOptions) (ChainResult, error)

ApplyChain applies patches in order. Each patch receives the exact output of the previous patch, so validation catches an incorrectly ordered chain.

func ApplyFileChain

func ApplyFileChain(sourcePath string, patchPaths []string, outputPath string, opts ApplyOptions) (ChainResult, error)

ApplyFileChain applies patch files in order using temporary files for every intermediate result. The final output is published atomically and is never allowed to replace an existing file. Result.Output is intentionally nil.

func ApplyFileChainContext

func ApplyFileChainContext(ctx context.Context, sourcePath string, patchPaths []string, outputPath string, opts ApplyOptions) (result ChainResult, err error)

ApplyFileChainContext is ApplyFileChain with explicit cancellation.

type ChainStep

type ChainStep struct {
	Index      int          `json:"index"`
	Inspection Inspection   `json:"inspection"`
	Output     ArtifactInfo `json:"output"`
}

ChainStep reports the result of one patch in an ordered chain.

type CreateOptions

type CreateOptions struct {
	// Metadata supplies EBP metadata fields.
	Metadata map[string]string
	// Description supplies the description or metadata field where supported.
	Description string
	// SourceName supplies the filename extension used for format metadata.
	SourceName string
	// BPSDelta forces the memory-intensive delta matcher. Create uses it by
	// default for inputs up to 4 MiB; CreateReaderAt uses it only when requested.
	BPSDelta bool
	// Context cancels creation. Nil means context.Background.
	Context context.Context
	// Progress receives coarse creation updates.
	Progress func(Progress)
	// MaxPatchSize limits patch output. Zero chooses a default of
	// 64 MiB plus twice the larger input size.
	MaxPatchSize uint64
}

CreateOptions controls patch metadata, limits, and progress during creation.

type DryRunResult

type DryRunResult struct {
	Inspection  Inspection   `json:"inspection"`
	SourceValid *bool        `json:"sourceValid,omitempty"`
	Output      ArtifactInfo `json:"output"`
}

DryRunResult combines patch inspection with calculated output details.

func DryRun

func DryRun(source, patchData []byte, opts ApplyOptions) (DryRunResult, error)

DryRun applies a patch in memory without writing a file and reports the result.

type Format

type Format string

Format identifies a supported patch encoding.

const (
	// FormatIPS identifies classic IPS patches.
	FormatIPS Format = "ips"
	// FormatIPS32 identifies 32-bit IPS patches.
	FormatIPS32 Format = "ips32"
	// FormatEBP identifies EarthBound Patch format files.
	FormatEBP Format = "ebp"
	// FormatUPS identifies UPS patches.
	FormatUPS Format = "ups"
	// FormatAPSN64 identifies APS patches for Nintendo 64 images.
	FormatAPSN64 Format = "aps"
	// FormatAPSGBA identifies APS patches for Game Boy Advance images.
	FormatAPSGBA Format = "aps-gba"
	// FormatBPS identifies BPS patches.
	FormatBPS Format = "bps"
	// FormatRUP identifies NINJA2 RUP patches.
	FormatRUP Format = "rup"
	// FormatPPF identifies PPF patches.
	FormatPPF Format = "ppf"
	// FormatBDF identifies BSDIFF40 patches.
	FormatBDF Format = "bdf"
	// FormatPMSR identifies Star Rod PMSR mod patches.
	FormatPMSR Format = "mod"
	// FormatVCDIFF identifies VCDIFF/xdelta patches.
	FormatVCDIFF Format = "vcdiff"
)

type HashInfo

type HashInfo struct {
	Size  int64  `json:"size"`
	CRC32 string `json:"crc32"`
	MD5   string `json:"md5"`
	SHA1  string `json:"sha1"`
}

HashInfo contains common identifiers calculated in one pass.

func HashBytes

func HashBytes(data []byte) HashInfo

HashBytes calculates all supported hashes for in-memory data.

func HashReader

func HashReader(ctx context.Context, r io.Reader) (HashInfo, error)

HashReader calculates all supported hashes in one read pass.

type HeaderInfo

type HeaderInfo struct {
	Name string
	Size int
}

HeaderInfo describes a recognized copier or container header.

func AddHeader

func AddHeader(data []byte, name string) ([]byte, *HeaderInfo)

AddHeader prepends a suitable temporary header when the format is recognized.

func CanAddHeader

func CanAddHeader(data []byte, name string) *HeaderInfo

CanAddHeader reports whether a temporary header can be added for name.

func DetectHeader

func DetectHeader(data []byte, name string) *HeaderInfo

DetectHeader reports a recognized header already present in data.

func RemoveHeader

func RemoveHeader(data []byte, name string) (header, rom []byte, info *HeaderInfo)

RemoveHeader separates a recognized header from ROM data.

type IPS32Patch

type IPS32Patch struct {
	Truncate    uint32
	HasTruncate bool
	// contains filtered or unexported fields
}

IPS32Patch is the 32-bit-offset extension of IPS. It uses an IPS32 header, EEOF terminator, and an optional four-byte truncate size. Use InspectParsed for record details.

func (*IPS32Patch) Apply

func (p *IPS32Patch) Apply(source []byte, options ApplyOptions) ([]byte, error)

Apply implements Patch.

func (IPS32Patch) Description

func (IPS32Patch) Description() string

Description returns an empty string when a format has no description field.

func (*IPS32Patch) Format

func (*IPS32Patch) Format() Format

Format implements Patch.

func (*IPS32Patch) MarshalBinary

func (p *IPS32Patch) MarshalBinary() ([]byte, error)

MarshalBinary implements Patch.

func (IPS32Patch) ValidateSource

func (IPS32Patch) ValidateSource([]byte) bool

ValidateSource accepts any source when a format has no source signature.

func (IPS32Patch) ValidationInfo

func (IPS32Patch) ValidationInfo() *ValidationInfo

ValidationInfo returns nil when a format has no source signature.

type IPSPatch

type IPSPatch struct {
	Truncate    int
	HasTruncate bool
	Metadata    map[string]string
	// contains filtered or unexported fields
}

IPSPatch is a parsed IPS or EBP patch. Use InspectParsed for record details.

func (*IPSPatch) Apply

func (p *IPSPatch) Apply(source []byte, options ApplyOptions) ([]byte, error)

Apply implements Patch.

func (*IPSPatch) Description

func (p *IPSPatch) Description() string

Description implements Patch.

func (*IPSPatch) Format

func (p *IPSPatch) Format() Format

Format implements Patch.

func (*IPSPatch) MarshalBinary

func (p *IPSPatch) MarshalBinary() ([]byte, error)

MarshalBinary implements Patch.

func (IPSPatch) ValidateSource

func (IPSPatch) ValidateSource([]byte) bool

ValidateSource accepts any source when a format has no source signature.

func (IPSPatch) ValidationInfo

func (IPSPatch) ValidationInfo() *ValidationInfo

ValidationInfo returns nil when a format has no source signature.

type InputKind

type InputKind string

InputKind controls which ZIP entries are considered candidates.

const (
	// InputSource selects likely source-ROM entries.
	InputSource InputKind = "source"
	// InputPatch selects recognized patch entries.
	InputPatch InputKind = "patch"
	// InputAny permits any regular ZIP entry.
	InputAny InputKind = "file"
)

type Inspection

type Inspection struct {
	Format      Format          `json:"format"`
	Description string          `json:"description,omitempty"`
	Source      ArtifactInfo    `json:"source,omitempty"`
	Target      ArtifactInfo    `json:"target,omitempty"`
	Validation  *ValidationInfo `json:"validation,omitempty"`
	Reversible  bool            `json:"reversible"`
	CanCreate   bool            `json:"canCreate"`
	RecordCount int             `json:"recordCount,omitempty"`
	// RecordCountKnown distinguishes a valid empty patch from a lazily decoded
	// format whose record count is unavailable without applying it.
	RecordCountKnown bool              `json:"recordCountKnown"`
	Metadata         map[string]string `json:"metadata,omitempty"`
	Limitations      []string          `json:"limitations,omitempty"`
}

Inspection reports a patch's format, requirements, and capabilities.

func Inspect

func Inspect(data []byte) (Inspection, error)

Inspect parses patch data and returns its metadata without applying it.

func InspectParsed

func InspectParsed(p Patch) Inspection

InspectParsed returns metadata for an already parsed patch. A nil patch returns a zero-value inspection.

type PMSRPatch

type PMSRPatch struct {
	TargetSize int
	// contains filtered or unexported fields
}

PMSRPatch is a parsed Star Rod PMSR mod patch.

func (*PMSRPatch) Apply

func (p *PMSRPatch) Apply(source []byte, options ApplyOptions) ([]byte, error)

Apply implements Patch.

func (PMSRPatch) Description

func (PMSRPatch) Description() string

Description returns an empty string when a format has no description field.

func (*PMSRPatch) Format

func (*PMSRPatch) Format() Format

Format implements Patch.

func (*PMSRPatch) MarshalBinary

func (*PMSRPatch) MarshalBinary() ([]byte, error)

MarshalBinary reports that PMSR creation is unsupported.

func (*PMSRPatch) ValidateSource

func (*PMSRPatch) ValidateSource(source []byte) bool

ValidateSource implements Patch.

func (*PMSRPatch) ValidationInfo

func (*PMSRPatch) ValidationInfo() *ValidationInfo

ValidationInfo implements Patch.

type PPFPatch

type PPFPatch struct {
	Version          int
	PatchDescription string
	ImageType        byte
	BlockCheck       []byte
	Undo             bool
	InputSize        uint32

	FileID string
	// contains filtered or unexported fields
}

PPFPatch is a parsed PPF patch.

func (*PPFPatch) Apply

func (p *PPFPatch) Apply(source []byte, options ApplyOptions) ([]byte, error)

Apply implements Patch.

func (*PPFPatch) Description

func (p *PPFPatch) Description() string

Description implements Patch.

func (*PPFPatch) Format

func (*PPFPatch) Format() Format

Format implements Patch.

func (*PPFPatch) MarshalBinary

func (p *PPFPatch) MarshalBinary() ([]byte, error)

MarshalBinary implements Patch.

func (*PPFPatch) ValidateSource

func (p *PPFPatch) ValidateSource(source []byte) bool

ValidateSource implements Patch.

func (*PPFPatch) ValidationInfo

func (p *PPFPatch) ValidationInfo() *ValidationInfo

ValidationInfo implements Patch.

type Patch

type Patch interface {
	Format() Format
	Apply(source []byte, options ApplyOptions) ([]byte, error)
	ValidateSource(source []byte) bool
	ValidationInfo() *ValidationInfo
	Description() string
	MarshalBinary() ([]byte, error)
}

Patch is a parsed patch that can be inspected, applied, or serialized.

func Create

func Create(original, modified []byte, format Format, opts *CreateOptions) (Patch, error)

Create builds an in-memory patch from original and modified data.

func Parse

func Parse(data []byte) (Patch, error)

Parse detects and decodes a patch held in memory.

type Progress

type Progress struct {
	Phase     string `json:"phase"`
	Format    Format `json:"format,omitempty"`
	Completed int64  `json:"completed"`
	Total     int64  `json:"total,omitempty"`
}

Progress describes a synchronous operation progress update.

type RUPPatch

type RUPPatch struct {
	TextEncoding                                                         byte
	Author, Version, Title, Genre, Language, Date, Web, PatchDescription string
	// contains filtered or unexported fields
}

RUPPatch is a parsed reversible NINJA2 RUP patch.

func (*RUPPatch) Apply

func (p *RUPPatch) Apply(source []byte, options ApplyOptions) ([]byte, error)

Apply implements Patch and automatically selects the reversible direction.

func (*RUPPatch) Description

func (p *RUPPatch) Description() string

Description implements Patch.

func (*RUPPatch) Format

func (*RUPPatch) Format() Format

Format implements Patch.

func (*RUPPatch) MarshalBinary

func (p *RUPPatch) MarshalBinary() ([]byte, error)

MarshalBinary implements Patch.

func (*RUPPatch) ValidateSource

func (p *RUPPatch) ValidateSource(source []byte) bool

ValidateSource implements Patch and accepts either reversible endpoint.

func (*RUPPatch) ValidationInfo

func (p *RUPPatch) ValidationInfo() *ValidationInfo

ValidationInfo implements Patch.

type UPSPatch

type UPSPatch struct {
	SourceSize, TargetSize uint64
	SourceCRC, TargetCRC   uint32
	// contains filtered or unexported fields
}

UPSPatch is a parsed reversible UPS patch.

func (*UPSPatch) Apply

func (p *UPSPatch) Apply(source []byte, options ApplyOptions) ([]byte, error)

Apply implements Patch and automatically selects the reversible direction.

func (UPSPatch) Description

func (UPSPatch) Description() string

Description returns an empty string when a format has no description field.

func (*UPSPatch) Format

func (*UPSPatch) Format() Format

Format implements Patch.

func (*UPSPatch) MarshalBinary

func (p *UPSPatch) MarshalBinary() ([]byte, error)

MarshalBinary implements Patch.

func (*UPSPatch) ValidateSource

func (p *UPSPatch) ValidateSource(source []byte) bool

ValidateSource implements Patch and accepts either reversible endpoint.

func (*UPSPatch) ValidationInfo

func (p *UPSPatch) ValidationInfo() *ValidationInfo

ValidationInfo implements Patch.

type VCDIFFPatch

type VCDIFFPatch struct {
	// contains filtered or unexported fields
}

VCDIFFPatch is a parsed VCDIFF/xdelta patch.

func (*VCDIFFPatch) Apply

func (p *VCDIFFPatch) Apply(source []byte, options ApplyOptions) ([]byte, error)

Apply implements Patch.

func (VCDIFFPatch) Description

func (VCDIFFPatch) Description() string

Description returns an empty string when a format has no description field.

func (*VCDIFFPatch) Format

func (*VCDIFFPatch) Format() Format

Format implements Patch.

func (*VCDIFFPatch) MarshalBinary

func (*VCDIFFPatch) MarshalBinary() ([]byte, error)

MarshalBinary reports that VCDIFF creation is unsupported.

func (VCDIFFPatch) ValidateSource

func (VCDIFFPatch) ValidateSource([]byte) bool

ValidateSource accepts any source when a format has no source signature.

func (VCDIFFPatch) ValidationInfo

func (VCDIFFPatch) ValidationInfo() *ValidationInfo

ValidationInfo returns nil when a format has no source signature.

type ValidationInfo

type ValidationInfo struct {
	Type   string   `json:"type"`
	Values []string `json:"values"`
}

ValidationInfo describes checksums accepted as source validation.

Directories

Path Synopsis
cmd
releasepack command
Command releasepack creates a deterministic release archive and SHA-256 checksum for one binary.
Command releasepack creates a deterministic release archive and SHA-256 checksum for one binary.
rompatcher command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL