cloud-game/handler/browser.go
Nguyen Huu Thanh 81cdf27acc WIP
2019-04-30 17:33:35 +07:00

156 lines
3.9 KiB
Go

package handler
import (
"encoding/json"
"log"
"github.com/giongto35/cloud-game/config"
"github.com/giongto35/cloud-game/cws"
"github.com/giongto35/cloud-game/handler/gamelist"
"github.com/giongto35/cloud-game/webrtc"
"github.com/gorilla/websocket"
pionRTC "github.com/pion/webrtc"
uuid "github.com/satori/go.uuid"
)
type BrowserClient struct {
*cws.Client
session *Session
oclient *OverlordClient
gameName string
roomID string
playerIndex int
}
// NewOverlordClient returns a client connecting to browser. This connection exchanges information between clients and server
func NewBrowserClient(c *websocket.Conn, overlordClient *OverlordClient) *BrowserClient {
roomID := ""
gameName := ""
playerIndex := 0
// Create connection to overlord
browserClient := &BrowserClient{
Client: cws.NewClient(c),
gameName: "",
roomID: "",
playerIndex: 0,
}
//sessionID := strconv.Itoa(rand.Int())
sessionID := uuid.Must(uuid.NewV4()).String()
wssession := &Session{
BrowserClient: browserClient,
OverlordClient: overlordClient,
peerconnection: webrtc.NewWebRTC(),
// The server session is maintaining
}
browserClient.Send(cws.WSPacket{
ID: "gamelist",
Data: gamelist.GetEncodedGameList(),
}, nil)
browserClient.Receive("heartbeat", func(resp cws.WSPacket) cws.WSPacket {
return resp
})
browserClient.Receive("initwebrtc", func(resp cws.WSPacket) cws.WSPacket {
log.Println("Received user SDP")
localSession, err := wssession.peerconnection.StartClient(resp.Data, config.Width, config.Height)
if err != nil {
log.Fatalln(err)
}
return cws.WSPacket{
ID: "sdp",
Data: localSession,
SessionID: sessionID,
}
})
// TODO: Add save and load
//browserClient.Receive("save", func(resp cws.WSPacket) (req cws.WSPacket) {
//log.Println("Saving game state")
//req.ID = "save"
//req.Data = "ok"
//if roomID != "" {
////err := rooms[roomID].director.SaveGame()
//err := browserClient.room.director.SaveGame()
//if err != nil {
//log.Println("[!] Cannot save game state: ", err)
//req.Data = "error"
//}
//} else {
//req.Data = "error"
//}
//return req
//})
//browserClient.Receive("load", func(resp cws.WSPacket) (req cws.WSPacket) {
//log.Println("Loading game state")
//req.ID = "load"
//req.Data = "ok"
//if roomID != "" {
//err := rooms[roomID].director.LoadGame()
//if err != nil {
//log.Println("[!] Cannot load game state: ", err)
//req.Data = "error"
//}
//} else {
//req.Data = "error"
//}
//return req
//})
browserClient.Receive("start", func(resp cws.WSPacket) (req cws.WSPacket) {
gameName = resp.Data
roomID = resp.RoomID
playerIndex = resp.PlayerIndex
isNewRoom := false
log.Println("Starting game")
// If we are connecting to overlord, request serverID from roomID
if browserClient.oclient != nil {
session := browserClient.session
roomServerID := getServerIDOfRoom(session.OverlordClient, roomID)
log.Println("Server of RoomID ", roomID, " is ", roomServerID)
if roomServerID != "" && wssession.ServerID != roomServerID {
// TODO: Re -register
go bridgeConnection(wssession, roomServerID, gameName, roomID, playerIndex)
return
}
}
roomID, isNewRoom = startSession(wssession.peerconnection, gameName, roomID, playerIndex)
// Register room to overlord if we are connecting to overlord
if isNewRoom && browserClient.session.OverlordClient != nil {
browserClient.session.OverlordClient.Send(cws.WSPacket{
ID: "registerRoom",
Data: roomID,
}, nil)
}
req.ID = "start"
req.RoomID = roomID
req.SessionID = sessionID
return req
})
browserClient.Receive("candidate", func(resp cws.WSPacket) (req cws.WSPacket) {
// Unuse code
hi := pionRTC.ICECandidateInit{}
err := json.Unmarshal([]byte(resp.Data), &hi)
if err != nil {
log.Println("[!] Cannot parse candidate: ", err)
} else {
// webRTC.AddCandidate(hi)
}
req.ID = "candidate"
return req
})
return browserClient
}