Save game load game to cloud

This commit is contained in:
giongto35 2019-05-04 04:03:08 +08:00
parent 681733ac75
commit 1d2dfbf554
4 changed files with 69 additions and 12 deletions

View file

@ -19,7 +19,9 @@ type Director struct {
Done chan struct{}
roomID string
hash string
// Hash represents a game state (roomID, gamePath).
// It is used for save file name
hash string
}
const FPS = 60
@ -126,3 +128,13 @@ func (d *Director) LoadGame() error {
return nil
}
}
// GetHash return hash
func (d *Director) GetHash() string {
return d.hash
}
// GetHashPath return the full path to hash file
func (d *Director) GetHashPath() string {
return savePath(d.hash)
}

View file

@ -10,6 +10,7 @@ import (
"cloud.google.com/go/storage"
)
// TODO: Add interface, abstract out Gstorage
type Client struct {
bucket *storage.BucketHandle
gclient *storage.Client

View file

@ -7,6 +7,7 @@ import (
"net/http"
"github.com/giongto35/cloud-game/cws"
storage "github.com/giongto35/cloud-game/handler/cloud-storage"
"github.com/giongto35/cloud-game/handler/gamelist"
"github.com/giongto35/cloud-game/handler/room"
"github.com/giongto35/cloud-game/webrtc"
@ -36,11 +37,14 @@ type Handler struct {
// All webrtc peerconnections are handled by the server
// ID -> peerconnections
peerconnections map[string]*webrtc.WebRTC
// onlineStorage is client accessing to online storage (GCP)
onlineStorage *storage.Client
}
// NewHandler returns a new server
func NewHandler(overlordConn *websocket.Conn, isDebug bool, gamePath string) *Handler {
log.Println("new OverlordClient")
return &Handler{
oClient: NewOverlordClient(overlordConn),
rooms: map[string]*room.Room{},
@ -48,6 +52,8 @@ func NewHandler(overlordConn *websocket.Conn, isDebug bool, gamePath string) *Ha
isDebug: isDebug,
gamePath: gamePath,
onlineStorage: storage.NewInitClient(),
}
}
@ -132,7 +138,7 @@ func (h *Handler) createNewRoom(gameName string, roomID string, playerIndex int)
// or the roomID doesn't have any running sessions (room was closed)
// we spawn a new room
if roomID == "" || !h.isRoomRunning(roomID) {
room := room.NewRoom(roomID, h.gamePath, gameName)
room := room.NewRoom(roomID, h.gamePath, gameName, h.onlineStorage)
// TODO: Might have race condition
h.rooms[room.ID] = room
return room

View file

@ -3,12 +3,15 @@ package room
import (
"fmt"
"image"
"io/ioutil"
"log"
"math/rand"
"strconv"
"sync"
"time"
emulator "github.com/giongto35/cloud-game/emulator"
storage "github.com/giongto35/cloud-game/handler/cloud-storage"
"github.com/giongto35/cloud-game/webrtc"
)
@ -27,10 +30,13 @@ type Room struct {
sessionsLock *sync.Mutex
director *emulator.Director
// Cloud storage to store room state online
onlineStorage *storage.Client
}
// NewRoom creates a new room
func NewRoom(roomID, gamepath, gameName string) *Room {
func NewRoom(roomID, gamepath, gameName string, onlineStorage *storage.Client) *Room {
// if no roomID is given, generate it
if roomID == "" {
roomID = generateRoomID()
@ -46,13 +52,14 @@ func NewRoom(roomID, gamepath, gameName string) *Room {
room := &Room{
ID: roomID,
imageChannel: imageChannel,
audioChannel: audioChannel,
inputChannel: inputChannel,
rtcSessions: []*webrtc.WebRTC{},
sessionsLock: &sync.Mutex{},
director: director,
Done: make(chan struct{}),
imageChannel: imageChannel,
audioChannel: audioChannel,
inputChannel: inputChannel,
rtcSessions: []*webrtc.WebRTC{},
sessionsLock: &sync.Mutex{},
director: director,
Done: make(chan struct{}),
onlineStorage: onlineStorage,
}
go room.startVideo()
@ -135,11 +142,42 @@ func (r *Room) Close() {
}
func (r *Room) SaveGame() error {
return r.director.SaveGame()
// TODO: Move to game view
if err := r.director.SaveGame(); err != nil {
return err
}
time.Sleep(1000 * time.Millisecond)
// Try to save the game to gCloud
// TODO: Add goroutine
if err := r.onlineStorage.SaveFile(r.director.GetHash(), r.director.GetHashPath()); err != nil {
return err
}
return nil
}
func (r *Room) LoadGame() error {
return r.director.LoadGame()
err := r.director.LoadGame()
time.Sleep(1000 * time.Millisecond)
if err != nil {
// TODO: Put in GoRoutine
// If the game is not on local server
// Try to load from gcloud
data, err := r.onlineStorage.LoadFile(r.director.GetHash())
if err != nil {
return err
}
// Save the data fetched from gcloud to local server
ioutil.WriteFile(r.director.GetHashPath(), data, 0644)
// Reload game again
err = r.director.LoadGame()
if err != nil {
return err
}
}
return err
}
func (r *Room) IsRunning() bool {