Documentation
¶
Index ¶
- Constants
- type DM2Parser
- func (d *DM2Parser) ApplyPacket(packet *pb.Packet) error
- func (demo *DM2Parser) GetTextProto() *pb.DM2Demo
- func (demo *DM2Parser) Marshal() ([]byte, error)
- func (demo *DM2Parser) NextPacket() (message.Buffer, int, error)
- func (p *DM2Parser) RegisterCallback(event int, dofunc func(any))
- func (p *DM2Parser) Unmarshal() error
- func (p *DM2Parser) UnregisterCallback(msgtype int)
- func (demo *DM2Parser) WriteTextProto(filename string) error
- type MVD2Parser
- func (p *MVD2Parser) GetDebug() bool
- func (p *MVD2Parser) GetDemos() []*pb.MvdDemo
- func (p *MVD2Parser) GetRawData() []byte
- func (p *MVD2Parser) GetRawPosition() int
- func (p *MVD2Parser) IsZipped() bool
- func (p *MVD2Parser) NextPacket() (message.Buffer, error)
- func (p *MVD2Parser) ParseConfigString(msg *message.Buffer, remap *pb.MvdConfigStringRemap) (*pb.ConfigString, error)
- func (p *MVD2Parser) ParseConfigStrings(msg *message.Buffer, remap *pb.MvdConfigStringRemap) map[int32]*pb.ConfigString
- func (p *MVD2Parser) ParseDeltaEntities(msg *message.Buffer) (map[int32]*pb.PackedEntity, error)
- func (p *MVD2Parser) ParseDeltaEntity(msg *message.Buffer, bits int64, from *pb.PackedEntity) (*pb.PackedEntity, error)
- func (p *MVD2Parser) ParseDeltaPlayer(msg *message.Buffer, bits uint32, flags int32) (*pb.PackedPlayer, error)
- func (p *MVD2Parser) ParseEntityBits(msg *message.Buffer) (int32, int64)
- func (p *MVD2Parser) ParseFrame(msg *message.Buffer) (*pb.MvdFrame, error)
- func (p *MVD2Parser) ParseMulticast(msg *message.Buffer, to int, extra int) *pb.MvdMulticast
- func (p *MVD2Parser) ParsePacket(msg *message.Buffer) (*pb.MvdPacket, error)
- func (p *MVD2Parser) ParsePacketPlayers(msg *message.Buffer) (map[int32]*pb.PackedPlayer, error)
- func (p *MVD2Parser) ParsePlayerStats(msg *message.Buffer, flags int32) map[uint32]int32
- func (p *MVD2Parser) ParseServerData(msg *message.Buffer, extra int) (*pb.MvdServerData, error)
- func (p *MVD2Parser) ParseSound(msg *message.Buffer, extra int) *pb.PackedSound
- func (p *MVD2Parser) ParseUnicast(msg *message.Buffer, reliable bool, extra int) (*pb.MvdUnicast, error)
- func (p *MVD2Parser) RegisterCallback(event int, dofunc func(any))
- func (p *MVD2Parser) Unmarshal() ([]*pb.MvdDemo, error)
- func (p *MVD2Parser) UnregisterCallback(msgtype int)
- type MVD2Writer
- func (w *MVD2Writer) Finalize(name string) error
- func (w *MVD2Writer) Marshal() error
- func (w *MVD2Writer) MarshalConfigstring(data *pb.ConfigString) message.Buffer
- func (w *MVD2Writer) MarshalConfigstrings(data map[int32]*pb.ConfigString) message.Buffer
- func (w *MVD2Writer) MarshalEntities(ents map[int32]*pb.PackedEntity) message.Buffer
- func (w *MVD2Writer) MarshalFrame(frame *pb.MvdFrame) message.Buffer
- func (w *MVD2Writer) MarshalMulticast(mc *pb.MvdMulticast) (*message.Buffer, error)
- func (w *MVD2Writer) MarshalPlayer(num int32, player *pb.PackedPlayer) message.Buffer
- func (w *MVD2Writer) MarshalPlayers(players map[int32]*pb.PackedPlayer) message.Buffer
- func (w *MVD2Writer) MarshalServerData() message.Buffer
- func (w *MVD2Writer) MarshalSound(sound *pb.PackedSound) (message.Buffer, error)
Constants ¶
const ( MVDMagic = 843339341 // {'M','V','D','2'} GZIPMagic = 35615 // {0x8b, 0x1f} MaxStats = 32 // playerstate stats uint32 bitmask MaxStatsExt = 64 // extended playerstates supported MaxConfigStrings = 2080 // CS_MAX MaxClients = 256 // hard limit MaxEdicts = 1024 // hard limit ProtocolMinimum = 2009 // minor proto version required ProtocolCurrent = 2010 // minor proto version ProtocolPlus = 2011 // not sure this is used ProtocolPlusPlus = 2012 // same ProtocolPlayerFog = 2013 CommandBits = 5 CommandMask = ((1 << CommandBits) - 1) ClientNumNone = MaxClients - 1 FlagExtLimits = 1 << 2 // multiview flags extended limits FlagExtLimits2 = 1 << 3 // even more extended!! )
const ( MVDSvcBad = iota MVDSvcNop MVDSvcDisconnect MVDSvcReconnect MVDSvcServerData MVDSvcConfigString MVDSvcFrame MVDSvcFrameNoDelta MVDSvcUnicast MVDSvcUnicastReliable MVDSvcMulticastAll MVDSvcMulticastPHS MVDSvcMulticastPVS MVDSvcMulticastAllR MVDSvcMulticastPHSR MVDSvcMulticastPVSR MVDSvcSound MVDSvcPrint MVDSvcStuffText MVDSvcMax )
Multi-view message types
const ( SvcBad = iota SvcMuzzleFlash SvcMuzzleFlash2 SvcTemporaryEntity SvcLayout SvcInventory SvcNoOperation SvcDisconnect SvcReconnect SvcSound SvcPrint SvcStuffText SvcServerData SvcConfigString SvcSpawnBaseline SvcCenterprint SvcDownload SvcPlayerInfo SvcPacketEntities SvcDeltaPacketEntities SvcFrame SvcMax )
Regular demo message types
const ( MvdPlayerType = 1 << 0 MvdPlayerOrigin = 1 << 1 MvdPlayerOrigin2 = 1 << 2 MvdPlayerViewOffset = 1 << 3 MvdPlayerViewAngles = 1 << 4 MvdPlayerViewAngles2 = 1 << 5 MvdPlayerKickAngles = 1 << 6 MvdPlayerBlend = 1 << 7 MvdPlayerFov = 1 << 8 MvdPlayerWeaponIndex = 1 << 9 MvdPlayerWeaponFrame = 1 << 10 MvdPlayerGunOffset = 1 << 11 MvdPlayerGunAngles = 1 << 12 MvdPlayerRdFlags = 1 << 13 MvdPlayerStats = 1 << 14 MvdPlayerRemove = 1 << 15 MvdPlayerMoreBits = 1 << 8 MvdPlayerBits = 16 MvdPlayerMask = (1 << MvdPlayerBits) - 1 )
Multi-view playerstate bit values
const ( MvdPlayerFlagIgnoreGunIndex = 1 << 0 MvdPlayerFlagIgnoreGunFrames = 1 << 1 MvdPlayerFlagIgnoreBlend = 1 << 2 MvdPlayerFlagIgnoreViewAngles = 1 << 3 MvdPlayerFlagIgnoreDeltaAngles = 1 << 4 MvdPlayerFlagIgnorePrediction = 1 << 5 MvdPlayerFlagExtensions = 1 << 6 MvdPlayerFlagExtensions2 = 1 << 7 MvdPlayerFlagForce = 1 << 8 MvdPlayerFlagRemove = 1 << 9 )
Multi-view playerstate flags
const ( FlagNoMessages = 1 << 0 FlagReverved1 = 1 << 1 FlagReverved2 = 1 << 2 )
Multi-view stream flags (3 bits)
const ( EntityStateLongSolid = 1 << 3 EntityStateUMask = 1 << 4 EntityStateBeamOrigin = 1 << 5 EntityStateShortAngles = 1 << 6 EntityStateExtensions = 1 << 7 EntityStateExtensions2 = 1 << 8 PlayerStateExtensions = 1 << 6 PlayerStateExtensions2 = 1 << 7 )
Multi-view entity bits
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type DM2Parser ¶ added in v1.0.233
type DM2Parser struct {
// contains filtered or unexported fields
}
func NewDM2Demo ¶ added in v1.0.233
Read the entire binary demo file into memory
func (*DM2Parser) ApplyPacket ¶ added in v1.0.233
ApplyPacket will add all the messages from the packet to the current demo.
func (*DM2Parser) GetTextProto ¶ added in v1.0.233
func (*DM2Parser) Marshal ¶ added in v1.0.233
Convert the textproto demo back into a quake 2 playable binary demo. The returned byte slice just needs to be written to a file as is.
func (*DM2Parser) NextPacket ¶ added in v1.0.233
Demos are organized by "lumps" of data that are essentially packets. Even though all the data is already known, each lump represents a server packet's worth of game data. Each packet is prefixed with a 32 bit integer of the size of the packet and then a bunch of individual messages.
The default packet size for protocol 34 is 1390 bytes. Demos created by modern clients using protocols 35/36 will still write demos for protocol 34 to maximize compatability. Although it is possible to force these clients to record in their native protocol version.
func (*DM2Parser) RegisterCallback ¶ added in v1.0.233
RegisterCallback allows for a custom function to be called at specific points while a demo is being parsed.
`event` is an index corresponding to what you want your callback to be associated with. These match up with the SVC* server messages.
`dofunc` is the function definition to be called at that event. The argument is set to `any` to accept any type, but this arg should be the parsed server message proto. Inside the dofunc, the arg will need to be casted to the appropriate type. Something like:
printMsg := argname.(*pb.Print)
func (*DM2Parser) UnregisterCallback ¶ added in v1.0.233
Dynamically remove a particular callback
func (*DM2Parser) WriteTextProto ¶ added in v1.0.233
Turn a parsed demo structure back into a binary file
type MVD2Parser ¶ added in v1.0.262
type MVD2Parser struct {
// contains filtered or unexported fields
}
This struct is the receiver used for parsing demo data.
func NewMVD2Parser ¶ added in v1.0.262
func NewMVD2Parser(f string) (*MVD2Parser, error)
Read the contents of the multi-view demo file and setup a receiver for parsing the data into textproto. The data is checked to make sure it's a valid demo file and the internal pointer set to just after the magic value.
Multi-view demo files can be deflated using GZIP (rfc1952) compression on the fly. Compression is detected using the file header and automatically uncompressed if utilized.
func (*MVD2Parser) GetDebug ¶ added in v1.0.274
func (p *MVD2Parser) GetDebug() bool
Private member accessor
func (*MVD2Parser) GetDemos ¶ added in v1.0.274
func (p *MVD2Parser) GetDemos() []*pb.MvdDemo
Private member accessor
func (*MVD2Parser) GetRawData ¶ added in v1.0.274
func (p *MVD2Parser) GetRawData() []byte
Private member accessor
func (*MVD2Parser) GetRawPosition ¶ added in v1.0.274
func (p *MVD2Parser) GetRawPosition() int
Private member accessor
func (*MVD2Parser) IsZipped ¶ added in v1.0.274
func (p *MVD2Parser) IsZipped() bool
Private member accessor
func (*MVD2Parser) NextPacket ¶ added in v1.0.262
func (p *MVD2Parser) NextPacket() (message.Buffer, error)
Demos are organized by shards of data that are essentially packets. Even though all the data is already known, each shard represents a server packet's worth of game data. Each packet is prefixed with a 16 bit integer of the size of the packet and then a bunch of individual messages in any particular order. Regular DM2 demos use 4 bytes for this value instead of 2.
There is no ending delimiter to the packet, the end of the last message is right up against the size value for the next packet. When the size value is 0 (0x0000), there are no more packets and the end of the demo has been reached. This is different from regular DM2 demos where a value of -1 (signed 0xffff) is the end of the demo.
func (*MVD2Parser) ParseConfigString ¶ added in v1.0.262
func (p *MVD2Parser) ParseConfigString(msg *message.Buffer, remap *pb.MvdConfigStringRemap) (*pb.ConfigString, error)
Parse a single configstring from MVD data
func (*MVD2Parser) ParseConfigStrings ¶ added in v1.0.262
func (p *MVD2Parser) ParseConfigStrings(msg *message.Buffer, remap *pb.MvdConfigStringRemap) map[int32]*pb.ConfigString
This parses the blob of configstrings that directly follow the serverdata at the beginning of the demo file.
The list of players in the demo is built using configstrings for skins. The cs_index - skin offset == the player number (0-maxclients), and the player name is the prefix of the skin string.
func (*MVD2Parser) ParseDeltaEntities ¶ added in v1.0.262
func (p *MVD2Parser) ParseDeltaEntities(msg *message.Buffer) (map[int32]*pb.PackedEntity, error)
Parse all the entities from a frame. These come directly after all the playerstates.
func (*MVD2Parser) ParseDeltaEntity ¶ added in v1.0.262
func (p *MVD2Parser) ParseDeltaEntity(msg *message.Buffer, bits int64, from *pb.PackedEntity) (*pb.PackedEntity, error)
Parse an individual edict_t. These are delta compressed (only changes from the last update are emitted); the PackedEntity proto returned merged with the previos version of this entity.
func (*MVD2Parser) ParseDeltaPlayer ¶ added in v1.0.262
func (p *MVD2Parser) ParseDeltaPlayer(msg *message.Buffer, bits uint32, flags int32) (*pb.PackedPlayer, error)
Parse a compressed player. Parsing delta players from regular DM2 demos is similar but not identical, so a separate func is needed.
func (*MVD2Parser) ParseEntityBits ¶ added in v1.0.262
func (p *MVD2Parser) ParseEntityBits(msg *message.Buffer) (int32, int64)
Each entity is prefixed with up to 5 bytes of bitmask followed by the entity number (up to 2 bytes) and then the actual data.
func (*MVD2Parser) ParseFrame ¶ added in v1.0.262
Each frame contains portal data, then all the player POVs (delta compressed), and then all the compressed entities.
func (*MVD2Parser) ParseMulticast ¶ added in v1.0.262
func (p *MVD2Parser) ParseMulticast(msg *message.Buffer, to int, extra int) *pb.MvdMulticast
ParseMulticast is used to parse all 6 multicast cmd types
func (*MVD2Parser) ParsePacket ¶ added in v1.0.262
Loop through all the messages included in this shard of data.
func (*MVD2Parser) ParsePacketPlayers ¶ added in v1.0.262
func (p *MVD2Parser) ParsePacketPlayers(msg *message.Buffer) (map[int32]*pb.PackedPlayer, error)
Read all the player info from a frame.
func (*MVD2Parser) ParsePlayerStats ¶ added in v1.0.262
Stats are a set of integer values at the end of each playerstate. They are are used to transfer rapidly changing values from server to client for displaying in the HUD. Score, health value, armor value, etc. These are transfered every server frame.
Some stats numbers are direct values (health, armor), and some are indexes to things like config string values.
func (*MVD2Parser) ParseServerData ¶ added in v1.0.262
func (p *MVD2Parser) ParseServerData(msg *message.Buffer, extra int) (*pb.MvdServerData, error)
ServerData is the first message in a demo, it contains info about what protocol versions were used at the time of the capture, the game directory, the client number of the dummy spec, and more.
func (*MVD2Parser) ParseSound ¶ added in v1.0.262
func (p *MVD2Parser) ParseSound(msg *message.Buffer, extra int) *pb.PackedSound
func (*MVD2Parser) ParseUnicast ¶ added in v1.0.262
func (p *MVD2Parser) ParseUnicast(msg *message.Buffer, reliable bool, extra int) (*pb.MvdUnicast, error)
func (*MVD2Parser) RegisterCallback ¶ added in v1.0.262
func (p *MVD2Parser) RegisterCallback(event int, dofunc func(any))
RegisterCallback allows for a custom function to be called at specific points while a demo is being parsed.
`event` is an index corresponding to what you want your callback to be associated with. These match up with the SVC* server messages.
`dofunc` is the function definition to be called at that event. The argument is set to `any` to accept any type, but this arg should be the parsed server message proto. Inside the dofunc, the arg will need to be casted to the appropriate type. Something like:
printMsg := argname.(*pb.Print)
func (*MVD2Parser) Unmarshal ¶ added in v1.0.262
func (p *MVD2Parser) Unmarshal() ([]*pb.MvdDemo, error)
Parse a demo file into one or more protobufs.
Each .mvd2 file can contain multiple "demos", each usually being a unique map. Recording a multi-view demo can survive a map change on the server, the demo will just contain another MvdServerData message with configstrings, playerstates and entity baselines.
Unmarshal will return a list of demo protos in event a .mvd2 file contains more than a single demo.
func (*MVD2Parser) UnregisterCallback ¶ added in v1.0.262
func (p *MVD2Parser) UnregisterCallback(msgtype int)
Dynamically remove a particular callback
type MVD2Writer ¶ added in v1.0.262
type MVD2Writer struct {
// contains filtered or unexported fields
}
func NewMVD2Writer ¶ added in v1.0.262
func NewMVD2Writer(mvd *pb.MvdDemo) *MVD2Writer
Creates a new writer struct. All the proto-to-binary writing funcs use this struct as a receiver.
func (*MVD2Writer) Finalize ¶ added in v1.0.262
func (w *MVD2Writer) Finalize(name string) error
This is the final step when writing a demo. It will write all the binary data generated to a file named from the argument.
func (*MVD2Writer) Marshal ¶ added in v1.0.262
func (w *MVD2Writer) Marshal() error
This is the top level function for converting a textproto-based multi-view demo to it's proper binary format.
func (*MVD2Writer) MarshalConfigstring ¶ added in v1.0.262
func (w *MVD2Writer) MarshalConfigstring(data *pb.ConfigString) message.Buffer
func (*MVD2Writer) MarshalConfigstrings ¶ added in v1.0.262
func (w *MVD2Writer) MarshalConfigstrings(data map[int32]*pb.ConfigString) message.Buffer
func (*MVD2Writer) MarshalEntities ¶ added in v1.0.262
func (w *MVD2Writer) MarshalEntities(ents map[int32]*pb.PackedEntity) message.Buffer
func (*MVD2Writer) MarshalFrame ¶ added in v1.0.262
func (w *MVD2Writer) MarshalFrame(frame *pb.MvdFrame) message.Buffer
func (*MVD2Writer) MarshalMulticast ¶ added in v1.0.262
func (w *MVD2Writer) MarshalMulticast(mc *pb.MvdMulticast) (*message.Buffer, error)
Generate a binary buffer from a Multicast proto
func (*MVD2Writer) MarshalPlayer ¶ added in v1.0.262
func (w *MVD2Writer) MarshalPlayer(num int32, player *pb.PackedPlayer) message.Buffer
func (*MVD2Writer) MarshalPlayers ¶ added in v1.0.262
func (w *MVD2Writer) MarshalPlayers(players map[int32]*pb.PackedPlayer) message.Buffer
func (*MVD2Writer) MarshalServerData ¶ added in v1.0.262
func (w *MVD2Writer) MarshalServerData() message.Buffer
func (*MVD2Writer) MarshalSound ¶ added in v1.0.262
func (w *MVD2Writer) MarshalSound(sound *pb.PackedSound) (message.Buffer, error)
Generate a binary buffer from a PackedSound proto