Skip to content

Commit

Permalink
Add gecko parsing
Browse files Browse the repository at this point in the history
hohav#40

commit ed7b525
Author: Nicolas Merz <[email protected]>
Date:   Sun Jun 12 20:43:15 2022 -0400

    Add gecko parsing

Co-authored-by: Nicolas Merz <[email protected]>
  • Loading branch information
davisdude and nicolasrmerz committed Jul 4, 2023
1 parent b8110ca commit bf66f22
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 2 deletions.
22 changes: 22 additions & 0 deletions slippi/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class EventType(IntEnum):
FRAME_START = 0x3A
ITEM = 0x3B
FRAME_END = 0x3C
GECKO_LIST = 0x3D


class Start(Base):
Expand Down Expand Up @@ -238,6 +239,27 @@ class ShieldDrop(IntEnum):
ARDUINO = 2


class Gecko(Base):
"""Gecko code that should be applied to the replay."""

b: Gecko.b #: `added(3.3.0)` Bytes of gecko code

def __init__(self, b: bytes):
self.b = b


@classmethod
def _parse(cls, stream):
# does this need a try/except block?
b = stream.getvalue()
return cls(b)

def __eq__(self, other):
if not isinstance(other, self.__class__):
return NotImplemented
return self.b is other.b


class End(Base):
"""Information about the end of the game."""

Expand Down
5 changes: 4 additions & 1 deletion slippi/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from logging import debug
from typing import BinaryIO, List, Optional, Union

from .event import FIRST_FRAME_INDEX, End, Frame, Start
from .event import FIRST_FRAME_INDEX, End, Frame, Start, Gecko
from .metadata import Metadata
from .parse import ParseEvent, parse
from .util import *
Expand All @@ -12,6 +12,7 @@ class Game(Base):
"""Replay data from a game of Super Smash Brothers Melee."""

start: Optional[Start] #: Information about the start of the game
gecko: Optional[Gecko] #: Bytes of gecko code (if there is one)
frames: List[Frame] #: Every frame of the game, indexed by frame number
end: Optional[End] #: Information about the end of the game
metadata: Optional[Metadata] #: Miscellaneous data not directly provided by Melee
Expand All @@ -22,13 +23,15 @@ def __init__(self, input: Union[BinaryIO, str, os.PathLike], skip_frames: bool =
:param input: replay file object or path"""
self.start = None
self.gecko = None
self.frames = []
self.end = None
self.metadata = None
self.metadata_raw = None

parse(input, {
ParseEvent.START: lambda x: setattr(self, 'start', x),
ParseEvent.GECKO: lambda x: setattr(self, 'gecko', x),
ParseEvent.FRAME: self._add_frame,
ParseEvent.END: lambda x: setattr(self, 'end', x),
ParseEvent.METADATA: lambda x: setattr(self, 'metadata', x),
Expand Down
9 changes: 8 additions & 1 deletion slippi/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import ubjson

from .event import End, EventType, Frame, Start
from .event import End, EventType, Frame, Start, Gecko
from .log import log
from .metadata import Metadata
from .util import *
Expand All @@ -22,6 +22,7 @@ class ParseEvent(Enum):
FRAME_START = 'frame_start' #: :py:class:`slippi.event.Frame.Start`:
ITEM = 'item' #: :py:class:`slippi.event.Frame.Item`:
FRAME_END = 'frame_end' #: :py:class:`slippi.event.Frame.End`:
GECKO = 'gecko' #: :py:class:`slippi.event.Gecko`:


class ParseError(IOError):
Expand Down Expand Up @@ -101,6 +102,8 @@ def _parse_event(event_stream, payload_sizes):
stream)
elif event_type is EventType.GAME_END:
event = End._parse(stream)
elif event_type is EventType.GECKO_LIST:
event = Gecko._parse(stream)
else:
event = None
return (1 + size, event)
Expand Down Expand Up @@ -133,6 +136,10 @@ def _parse_events(stream, payload_sizes, total_size, handlers, skip_frames):
stream.seek(skip, os.SEEK_CUR)
bytes_read += skip
continue
elif isinstance(event, Gecko):
handler = handlers.get(ParseEvent.GECKO)
if handler:
handler(event)
elif isinstance(event, End):
handler = handlers.get(ParseEvent.END)
if handler:
Expand Down

0 comments on commit bf66f22

Please sign in to comment.