s2prot

package module
v1.5.1 Latest Latest
Warning

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

Go to latest
Published: Jan 15, 2024 License: Apache-2.0 Imports: 9 Imported by: 11

README

s2prot

Build Status Go Reference GoDoc Go Report Card codecov

Package s2prot is a decoder/parser of Blizzard's StarCraft II replay file format (*.SC2Replay).

s2prot processes the "raw" data that can be decoded from replay files using an MPQ parser such as github.com/icza/mpq.

The package is designed to be used by other packages or apps, and is safe for concurrent use. There is also an example CLI app that can be used standalone.

Parses all versions that were written with retail versions of StarCraft II (and some beta versions too).

Check out the sister project to parse StarCraft: Brood War replays: screp

Using the s2prot CLI app

There is a command line application in the cmd/s2prot folder which can be used to parse and display information about a single replay file.

The extracted data is displayed using JSON representation.

Usage is as simple as:

s2prot [FLAGS] repfile.SC2Replay

Run with -h to see a list of available flags.

Example to parse a file called sample.SC2Replay, and display replay header, game metadata (included by default) and replay details:

s2prot -details=true sample.SC2Relay

Or simply:

s2prot -details sample.SC2Relay

High-level Usage

GoDoc

The package s2prot/rep provides enumerations and types to model data structures of StarCraft II replays (*.SC2Replay) decoded by the s2prot package. These provide a higher level overview and much easier to use.

The below example code can be found in https://github.com/icza/s2prot/blob/master/_example/rep.go.

Install the latest version of the library:

go get -u github.com/icza/s2prot/rep@master

To open and parse a replay:

import "github.com/icza/s2prot/rep"

r, err := rep.NewFromFile("../../mpq/reps/lotv.SC2Replay")
if err != nil {
	fmt.Printf("Failed to open file: %v\n", err)
	return
}
defer r.Close()

And that's all! We now have all the info from the replay! Printing some of it:

fmt.Printf("Version:        %v\n", r.Header.VersionString())
fmt.Printf("Loops:          %d\n", r.Header.Loops())
fmt.Printf("Length:         %v\n", r.Header.Duration())
fmt.Printf("Map:            %s\n", r.Details.Title())
fmt.Printf("Game events:    %d\n", len(r.GameEvts))
fmt.Printf("Message events: %d\n", len(r.MessageEvts))
fmt.Printf("Tracker events: %d\n", len(r.TrackerEvts.Evts))

fmt.Println("Players:")
for _, p := range r.Details.Players() {
	fmt.Printf("\tName: %-20s, Race: %c, Team: %d, Result: %v\n",
		p.Name, p.Race().Letter, p.TeamId()+1, p.Result())
}

Output:

Version:        3.2.2.42253
Loops:          13804
Length:         14m22.75s
Map:            Magma Mines
Game events:    10461
Message events: 32
Tracker events: 1758
Players:
	Name: <NoGy>IMBarabba     , Race: P, Team: 1, Result: Defeat
	Name: <NoGy>Nova          , Race: T, Team: 1, Result: Defeat
	Name: <9KingS>BiC         , Race: T, Team: 2, Result: Victory
	Name: <9KingS>DakotaFannin, Race: P, Team: 2, Result: Victory

Tip: the Struct type defines a String() method which returns a nicely formatted JSON representation; this is what most type are "made of":

fmt.Printf("Full Header:\n%v\n", r.Header)

Output:

Full Header:
{
  "dataBuildNum": 42253,
  "elapsedGameLoops": 13804,
  "ngdpRootKey": {
    "data": "\ufffd \ufffd\ufffd\ufffd\ufffd]\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd"
  },
  "replayCompatibilityHash": {
    "data": "\ufffd\ufffd\ufffd'⌂\u001fv\ufffd%\rEĪѓX"
  },
  "signature": "StarCraft II replay\u001b11",
  "type": 2,
  "useScaledTime": true,
  "version": {
    "baseBuild": 42253,
    "build": 42253,
    "flags": 1,
    "major": 3,
    "minor": 2,
    "revision": 2
  }
}

Low-level Usage

GoDoc

The below example code can be found in https://github.com/icza/s2prot/blob/master/_example/s2prot.go.

To use s2prot, we need an MPQ parser to get content from a replay.

import "github.com/icza/mpq"

m, err := mpq.NewFromFile("../../mpq/reps/automm.SC2Replay")
if err != nil {
	panic(err)
}
defer m.Close()

Replay header (which is the MPQ User Data) can be decoded by s2prot.DecodeHeader(). Printing replay version:

header := s2prot.DecodeHeader(m.UserData())
ver := header.Structv("version")
fmt.Printf("Version: %d.%d.%d.%d\n",
	ver.Int("major"), ver.Int("minor"), ver.Int("revision"), ver.Int("build"))
// Output: "Version: 2.1.9.34644"

Base build is part of the replay header:

baseBuild := int(ver.Int("baseBuild"))
fmt.Printf("Base build: %d\n", baseBuild)
// Output: "Base build: 32283"

Which can be used to obtain the proper instance of Protocol:

p := s2prot.GetProtocol(baseBuild)
if p == nil {
	panic("Unknown base build!")
}

Which can now be used to decode all other info in the replay. To decode the Details and print the map name:

detailsData, err := m.FileByName("replay.details")
if err != nil {
	panic(err)
}
details := p.DecodeDetails(detailsData)
fmt.Println("Map name:", details.Stringv("title"))
// Output: "Map name: Hills of Peshkov"

Tip: We can of course print the whole decoded header which is a Struct:

fmt.Printf("Full Header:\n%v\n", header)

Which yields a JSON text similar to the one posted above (at High-level Usage).

Information sources

License

Open-sourced under the Apache License 2.0.

Documentation

Overview

Package s2prot is a decoder/parser of Blizzard's StarCraft II replay file format (*.SC2Replay).

s2prot processes the "raw" data that can be decoded from replay files using an MPQ parser such as https://github.com/icza/mpq.

The package is safe for concurrent use.

High-level Usage

The package s2prot/rep provides enumerations and types to model data structures of StarCraft II replays (*.SC2Replay) decoded by the s2prot package. These provide a higher level overview and much easier to use.

The below example code can be found in https://github.com/icza/s2prot/blob/master/_example/rep.go.

To open and parse a replay:

import "github.com/icza/s2prot/rep"

r, err := rep.NewFromFile("../../mpq/reps/lotv.SC2Replay")
if err != nil {
	fmt.Printf("Failed to open file: %v\n", err)
	return
}
defer r.Close()

And that's all! We now have all the info from the replay! Printing some of it:

fmt.Printf("Version:        %v\n", r.Header.VersionString())
fmt.Printf("Loops:          %d\n", r.Header.Loops())
fmt.Printf("Length:         %v\n", r.Header.Duration())
fmt.Printf("Map:            %s\n", r.Details.Title())
fmt.Printf("Game events:    %d\n", len(r.GameEvts))
fmt.Printf("Message events: %d\n", len(r.MessageEvts))
fmt.Printf("Tracker events: %d\n", len(r.TrackerEvts.Evts))

fmt.Println("Players:")
for _, p := range r.Details.Players() {
	fmt.Printf("\tName: %-20s, Race: %c, Team: %d, Result: %v\n",
		p.Name, p.Race().Letter, p.TeamId()+1, p.Result())
}

Output:

Version:        3.2.2.42253
Loops:          13804
Length:         14m22.75s
Map:            Magma Mines
Game events:    10461
Message events: 32
Tracker events: 1758
Players:
	Name: <NoGy>IMBarabba     , Race: P, Team: 1, Result: Defeat
	Name: <NoGy>Nova          , Race: T, Team: 1, Result: Defeat
	Name: <9KingS>BiC         , Race: T, Team: 2, Result: Victory
	Name: <9KingS>DakotaFannin, Race: P, Team: 2, Result: Victory

Tip: the Struct type defines a String() method which returns a nicely formatted JSON representation; this is what most type are "made of":

fmt.Printf("Full Header:\n%v\n", r.Header)

Output:

Full Header:
{
  "dataBuildNum": 42253,
  "elapsedGameLoops": 13804,
  "ngdpRootKey": {
    "data": "\ufffd \ufffd\ufffd\ufffd\ufffd]\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd..."
  },
  "replayCompatibilityHash": {
    "data": "\ufffd\ufffd\ufffd'⌂\u001fv\ufffd%\rEĪѓX"
  },
  "signature": "StarCraft II replay\u001b11",
  "type": 2,
  "useScaledTime": true,
  "version": {
    "baseBuild": 42253,
    "build": 42253,
    "flags": 1,
    "major": 3,
    "minor": 2,
    "revision": 2
  }
}

Low-level Usage

The below example code can be found in https://github.com/icza/s2prot/blob/master/_example/s2prot.go.

To use s2prot, we need an MPQ parser to get content from a replay.

import "github.com/icza/mpq"

m, err := mpq.NewFromFile("../../mpq/reps/automm.SC2Replay")
if err != nil {
	panic(err)
}
defer m.Close()

Replay header (which is the MPQ User Data) can be decoded by s2prot.DecodeHeader(). Printing replay version:

header := s2prot.DecodeHeader(m.UserData())
ver := header.Structv("version")
fmt.Printf("Version: %d.%d.%d.%d\n",
	ver.Int("major"), ver.Int("minor"), ver.Int("revision"), ver.Int("build"))
// Output: "Version: 2.1.9.34644"

Base build is part of the replay header:

baseBuild := int(ver.Int("baseBuild"))
fmt.Printf("Base build: %d\n", baseBuild)
// Output: "Base build: 32283"

Which can be used to obtain the proper instance of Protocol:

p := s2prot.GetProtocol(baseBuild)
if p == nil {
	panic("Unknown base build!")
}

Which can now be used to decode all other info in the replay. To decode the Details and print the map name:

detailsData, err := m.FileByName("replay.details")
if err != nil {
	panic(err)
}
details := p.DecodeDetails(detailsData)
fmt.Println("Map name:", details.Stringv("title"))
// Output: "Map name: Hills of Peshkov"

Tip: We can of course print the whole decoded header which is a Struct:

fmt.Printf("Full Header:\n%v\n", header)

Which yields a JSON text similar to the one posted above (at High-level Usage).

Information sources

- s2protocol: Blizzard's reference implementation in python: https://github.com/Blizzard/s2protocol

- s2protocol implementation of the Scelight project: https://github.com/icza/scelight/tree/master/src-app/hu/scelight/sc2/rep/s2prot

- Replay model of the Scelight project: https://github.com/icza/scelight/tree/master/src-app/hu/scelight/sc2/rep/model

Index

Constants

This section is empty.

Variables

View Source
var (
	// MinBaseBuild is the min supported base build
	MinBaseBuild int

	// MaxBaseBuild is the max supported base build
	MaxBaseBuild int
)

Functions

This section is empty.

Types

type BitArr

type BitArr struct {
	Count int    // Bits count
	Data  []byte // Data holding the bits
}

BitArr is a bit array which stores the bits in a byte slice.

func (*BitArr) Bit

func (b *BitArr) Bit(n int) bool

Bit tells if the bit at the specified position (zero-based) is 1.

func (BitArr) MarshalJSON

func (b BitArr) MarshalJSON() ([]byte, error)

MarshalJSON produces a custom JSON string for a more informative and more compact representation of the bitarray. The essence is that the Data slice is presented in hex format (instead of the default Base64 encoding).

func (*BitArr) Ones

func (b *BitArr) Ones() (c int)

Ones returns the number of 1 bits in the bit array.

func (BitArr) String

func (b BitArr) String() string

String returns the string representation of the bit array in hexadecimal form. Using value receiver so printing a BitArr value will call this method.

type Event

type Event struct {
	Struct
	*EvtType // Pointer only to avoid copying
}

Event descriptor

func (*Event) Loop

func (e *Event) Loop() int64

Loop returns the loop (time) of the event.

func (*Event) UserID

func (e *Event) UserID() int64

UserID returns the ID of the user that issued the event.

type EvtType

type EvtType struct {
	ID   int    // Id of the event
	Name string // Name of the event
	// contains filtered or unexported fields
}

EvtType describes a named event data structure type.

type Protocol

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

The Protocol type which implements the data structures and their decoding from SC2Replay files defined by s2protocol.

func GetProtocol

func GetProtocol(baseBuild int) *Protocol

GetProtocol returns the Protocol for the specified base build. nil return value indicates unknown/unsupported base build.

func (*Protocol) DecodeAttributesEvts

func (p *Protocol) DecodeAttributesEvts(contents []byte) Struct

DecodeAttributesEvts decodes and returns the attributes events. Panics if decoding fails.

func (*Protocol) DecodeDetails

func (p *Protocol) DecodeDetails(contents []byte) Struct

DecodeDetails decodes and returns the game details. Panics if decoding fails.

func (*Protocol) DecodeGameEvts

func (p *Protocol) DecodeGameEvts(contents []byte) ([]Event, error)

DecodeGameEvts decodes and returns the game events. In case of a decoding error, successfully decoded events are still returned along with an error.

func (*Protocol) DecodeInitData

func (p *Protocol) DecodeInitData(contents []byte) Struct

DecodeInitData decodes and returns the replay init data. Panics if decoding fails.

func (*Protocol) DecodeMessageEvts

func (p *Protocol) DecodeMessageEvts(contents []byte) ([]Event, error)

DecodeMessageEvts decodes and returns the message events. In case of a decoding error, successfully decoded events are still returned along with an error.

func (*Protocol) DecodeTrackerEvts

func (p *Protocol) DecodeTrackerEvts(contents []byte) ([]Event, error)

DecodeTrackerEvts decodes and returns the tracker events. In case of a decoding error, successfully decoded events are still returned along with an error.

type Struct

type Struct map[string]interface{}

Struct represents a decoded struct. It is a dynamic struct modelled with a general map with helper methods to access its content.

Tip: the Struct type defines a String() method which returns a nicely formatted JSON representation, so simply printing a Struct results in a nice JSON text.

func DecodeHeader

func DecodeHeader(contents []byte) Struct

DecodeHeader decodes and returns the replay header. Panics if decoding fails.

func (*Struct) Array

func (s *Struct) Array(path ...string) (v []interface{})

Array returns the array (of empty interfaces) specified by the path. zero value is returned if path is invalid.

func (*Struct) BitArr

func (s *Struct) BitArr(path ...string) (v BitArr)

BitArr returns the bit array specified by the path. zero value is returned if path is invalid.

func (*Struct) Bool

func (s *Struct) Bool(path ...string) (v bool)

Bool returns the bool specified by the path. zero value is returned if path is invalid.

func (*Struct) Bytes

func (s *Struct) Bytes(path ...string) (v []byte)

Bytes returns the []byte specified by the path. zero value is returned if path is invalid.

func (*Struct) Float

func (s *Struct) Float(path ...string) (v float64)

Float returns the floating point number specified by the path. zero value is returned if path is invalid.

func (*Struct) Int

func (s *Struct) Int(path ...string) (v int64)

Int returns the integer specified by the path. zero value is returned if path is invalid.

func (Struct) String

func (s Struct) String() string

String returns the indented JSON string representation of the Struct. Defined with value receiver so this gets called even if a non-pointer is printed.

func (*Struct) Stringv

func (s *Struct) Stringv(path ...string) (v string)

Stringv returns the string specified by the path. zero value is returned if path is invalid.

func (*Struct) Structv

func (s *Struct) Structv(path ...string) (v Struct)

Structv returns the (sub) Struct specified by the path. zero value is returned if path is invalid.

func (*Struct) Text

func (s *Struct) Text(path ...string) string

Text returns the []byte specified by the path converted to string. zero value is returned if path is invalid.

func (*Struct) Value

func (s *Struct) Value(path ...string) interface{}

Value returns the value specified by the path. zero value is returned if path is invalid.

Directories

Path Synopsis
This example shows how to use the rep package to easily extract information from a StarCraft II (*.SC2Replay) file.
This example shows how to use the rep package to easily extract information from a StarCraft II (*.SC2Replay) file.
Package build contains the python source codes of different builds of s2protocol emedded in Go.
Package build contains the python source codes of different builds of s2protocol emedded in Go.
cmd
s2prot
Package main is a simple CLI app to parse and display information about a StarCraft II replay passed as a CLI argument.
Package main is a simple CLI app to parse and display information about a StarCraft II replay passed as a CLI argument.
Package rep provides enumerations and types to model data structures of StarCraft II replays (*.SC2Replay) decoded by the s2prot package.
Package rep provides enumerations and types to model data structures of StarCraft II replays (*.SC2Replay) decoded by the s2prot package.

Jump to

Keyboard shortcuts

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