Skip to content

Commit

Permalink
Further updates
Browse files Browse the repository at this point in the history
  • Loading branch information
1lann committed Mar 26, 2016
1 parent f757b15 commit 66c5800
Show file tree
Hide file tree
Showing 16 changed files with 969 additions and 255 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2015 Jason Chu (1lann)
Copyright (c) 2016 Jason Chu (1lann)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
51 changes: 25 additions & 26 deletions record/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
package record

import (
"bytes"
"github.com/1lann/lol-replay/recording"
"io"
"time"
)

Expand All @@ -30,33 +30,30 @@ type recorder struct {
gameId string
}

// Record starts a new recording that writes into the io.ReadWriteSeeker
// (such as an *os.File) and blocks until the recording ends or an
// error occurs. It is the caller's responsibility to close
// the writer when the recording is complete. Note that partial data may be
// written to the writer, even if the recording was unsuccessful. This partial
// data can probably be played back. ErrNotFound enclosed in a *RecordingError
// is returned if there is no game that can be recorded from the provided
// parameters.
func Record(platform, gameId, encryptionKey string,
file io.ReadWriteSeeker) error {
// Record starts a new recording that writes into a *recording.Recording
// and blocks until the recording ends or an error occurs. Note that partial
// data may be written to the recording, even if the recording was
// unsuccessful. This partial data can probably be played back. ErrNotFound
// enclosed in a *RecordingError is returned if there is no game that can be
// recorded from the provided parameters.
func Record(platform, gameId, encryptionKey string, userMetadata interface{},
rec *recording.Recording) error {
url, found := platformURLs[platform]
if !found {
return newError("", ErrUnknownPlatform)
}

thisRecording, err := recording.NewRecording(file)
if err != nil {
return newError("", err)
}

thisRecorder := &recorder{
platformURL: url,
recording: thisRecording,
recording: rec,
platform: platform,
gameId: gameId,
}

if err := thisRecorder.recording.StoreUserMetadata(userMetadata); err != nil {
return err
}

version, err := GetPlatformVersion(platform)
if err != nil {
return err
Expand Down Expand Up @@ -107,12 +104,14 @@ func (r *recorder) waitForFirstChunk() error {
return err
}

if err := r.recording.StoreGameMetadata(data); err != nil {
return err
if !r.recording.HasMetadata() {
if err := r.recording.StoreGameMetadata(bytes.NewReader(data)); err != nil {
return err
}
}

// Get the startup frames
for i := 1; i <= metadata.StartupChunk+1; i++ {
for i := 1; i <= metadata.StartupChunk; i++ {
for {
chunk, err := r.retrieveLastChunkInfo()
if err != nil {
Expand All @@ -125,7 +124,7 @@ func (r *recorder) waitForFirstChunk() error {
continue
}

if err := r.storeChunkFrame(i); err != nil {
if err := r.storeChunk(i); err != nil {
return err
}
break
Expand Down Expand Up @@ -165,7 +164,7 @@ func (r *recorder) recordFrames() error {
lastChunk = chunk.CurrentChunk
lastKeyFrame = chunk.CurrentKeyFrame

if err := r.storeChunkFrame(chunk.CurrentChunk); err != nil {
if err := r.storeChunk(chunk.CurrentChunk); err != nil {
return err
}
if err := r.storeKeyFrame(chunk.CurrentKeyFrame); err != nil {
Expand All @@ -180,14 +179,14 @@ func (r *recorder) recordFrames() error {

if chunk.CurrentChunk > lastChunk {
for i := lastChunk + 1; i <= chunk.CurrentChunk; i++ {
if err := r.storeChunkFrame(i); err != nil {
if err := r.storeChunk(i); err != nil {
return err
}
}
}

if chunk.NextChunk < chunk.CurrentChunk && chunk.NextChunk > 0 {
if err := r.storeChunkFrame(chunk.NextChunk); err != nil {
if err := r.storeChunk(chunk.NextChunk); err != nil {
return err
}
}
Expand Down Expand Up @@ -222,12 +221,12 @@ func (r *recorder) storeChunkInfo(firstChunkID, firstKeyFrame int,
chunkInfo := recording.ChunkInfo{
NextChunk: firstChunkID,
CurrentChunk: firstChunkID,
NextUpdate: 3000,
NextUpdate: 0,
StartGameChunk: chunk.StartGameChunk,
CurrentKeyFrame: firstKeyFrame,
EndGameChunk: chunk.CurrentChunk,
AvailableSince: 0,
Duration: 3000,
Duration: 30000,
EndStartupChunk: chunk.EndStartupChunk,
}

Expand Down
62 changes: 42 additions & 20 deletions record/retrieve.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"github.com/1lann/lol-replay/recording"
"io"
"io/ioutil"
"net/http"
"strconv"
Expand All @@ -15,14 +16,12 @@ const retryWaitDuration = time.Second * 5
var ErrNotFound = errors.New("not found")
var ErrUnknownPlatform = errors.New("unknown platform")

func requestOnceURL(url string) ([]byte, error) {
func requestOnceURL(url string) (io.ReadCloser, error) {
resp, err := http.Get(url)
if err != nil {
return nil, err
}

defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
if resp.StatusCode == http.StatusNotFound {
return nil, ErrNotFound
Expand All @@ -31,46 +30,69 @@ func requestOnceURL(url string) ([]byte, error) {
return nil, errors.New(resp.Status)
}

contents, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}

return contents, nil
return resp.Body, nil
}

func requestURL(url string) ([]byte, error) {
func requestURL(url string) (io.ReadCloser, error) {
var lastError error

for i := 0; i < 3; i++ {
var data []byte
data, lastError = requestOnceURL(url)
var reader io.ReadCloser
reader, lastError = requestOnceURL(url)
if lastError == ErrNotFound {
return nil, newError("request URL", ErrNotFound)
return nil, ErrNotFound
} else if lastError != nil {
time.Sleep(retryWaitDuration)
continue
}

return data, nil
return reader, nil
}

return nil, newError("request URL", lastError)
}

func requestURLWriteTo(url string, w io.Writer) (int, error) {
reader, err := requestURL(url)
if err != nil {
return 0, err
}

defer reader.Close()
num, err := io.Copy(w, reader)
return int(num), err
}

func requestURLBytes(url string) ([]byte, error) {
reader, err := requestURL(url)
if err != nil {
return nil, err
}

defer reader.Close()
return ioutil.ReadAll(reader)
}

type metadata struct {
StartupChunk int `json:"endStartupChunkId"`
LastChunk int `json:"lastChunkId"`
}

// IsValidPlatform returns whether or not a platform is valid (i.e. has an
// entry in the map of platforms and platform URLs).
func IsValidPlatform(platform string) bool {
_, found := platformURLs[platform]
return found
}

// GetPlatformVersion returns the current version of the specified platform.
func GetPlatformVersion(platform string) (string, error) {
url, found := platformURLs[platform]
if !found {
return "", newError("get platform version", ErrUnknownPlatform)
}

resp, err := requestURL(url + "/observer-mode/rest/consumer/version")
resp, err := requestURLBytes(url + "/observer-mode/rest/consumer/version")
if err != nil {
return "", newError("get platform version", err)
}
Expand All @@ -79,7 +101,7 @@ func GetPlatformVersion(platform string) (string, error) {
}

func (r *recorder) retrieveMetadata() (metadata, []byte, error) {
resp, err := requestURL(r.platformURL +
resp, err := requestURLBytes(r.platformURL +
"/observer-mode/rest/consumer/getGameMetaData/" + r.platform +
"/" + r.gameId + "/0/token")
if err != nil {
Expand All @@ -95,7 +117,7 @@ func (r *recorder) retrieveMetadata() (metadata, []byte, error) {
return result, resp, nil
}

func (r *recorder) storeChunkFrame(frame int) error {
func (r *recorder) storeChunk(frame int) error {
if frame <= 0 {
return nil
}
Expand All @@ -108,11 +130,11 @@ func (r *recorder) storeChunkFrame(frame int) error {
"/observer-mode/rest/consumer/getGameDataChunk/" + r.platform + "/" +
r.gameId + "/" + strconv.Itoa(frame) + "/token")
if err != nil {
return newError("chunk frame", err)
return newError("chunk", err)
}

if err := r.recording.StoreChunk(frame, resp); err != nil {
return newError("chunk frame", err)
return newError("chunk", err)
}
return nil
}
Expand Down Expand Up @@ -140,7 +162,7 @@ func (r *recorder) storeKeyFrame(frame int) error {
}

func (r *recorder) retrieveLastChunkInfo() (recording.ChunkInfo, error) {
resp, err := requestURL(r.platformURL +
resp, err := requestURLBytes(r.platformURL +
"/observer-mode/rest/consumer/getLastChunkInfo/" + r.platform + "/" +
r.gameId + "/0/token")
if err != nil {
Expand Down
Loading

0 comments on commit 66c5800

Please sign in to comment.