From 4523d50407c5609053cda789026ef73126340345 Mon Sep 17 00:00:00 2001 From: giongto35 Date: Sat, 13 Apr 2019 03:03:27 +0800 Subject: [PATCH 01/39] Maintain connection --- static/js/const.js | 1 + static/js/ws.js | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/static/js/const.js b/static/js/const.js index 2899c46f..11f49ae0 100644 --- a/static/js/const.js +++ b/static/js/const.js @@ -99,4 +99,5 @@ KEY_BIT = ["a", "b", "select", "start", "up", "down", "left", "right"]; INPUT_FPS = 100; +PINGPONGPS = 5; INPUT_STATE_PACKET = 5; diff --git a/static/js/ws.js b/static/js/ws.js index eedbb3b0..9b7e5c7a 100644 --- a/static/js/ws.js +++ b/static/js/ws.js @@ -18,7 +18,9 @@ function startGame() { // Clear old roomID conn.onopen = () => { log("WebSocket is opened. Send ping"); - conn.send(JSON.stringify({"id": "ping", "data": GAME_LIST[gameIdx].nes, "room_id": roomID.value, "player_index": parseInt(playerIndex.value, 10)})); + conn.send(JSON.stringify({"id": "ping", "data": GAME_LIST[gameIdx].nes, "room_id": roomID.value, "player_index": parseInt(playerIndex.value, 10)}));inputTimer + log("Send ping pong frequently") + pingpongTimer = setInterval(sendPing, 1000 / PINGPONGPS) } conn.onerror = error => { @@ -33,9 +35,13 @@ function startGame() { d = JSON.parse(e.data); switch (d["id"]) { case "pong": + // TODO: Change name use one session log("Recv pong. Start webrtc"); startWebRTC(); break; + case "pingpong": + // TODO: Calc time + break; case "sdp": log("Got remote sdp"); pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(atob(d["data"])))); @@ -54,6 +60,11 @@ function startGame() { } } + function sendPing() { + // TODO: format the package with time + conn.send(JSON.stringify({"id": "pingpong", "data": "pingpong"})); + } + // webrtc pc = new RTCPeerConnection({iceServers: [{urls: 'stun:stun.l.google.com:19302'}]}) // input channel From 5c37b6b114202e8bcf41652cd26230ad63d7dc49 Mon Sep 17 00:00:00 2001 From: giongto35 Date: Sat, 13 Apr 2019 12:32:33 +0800 Subject: [PATCH 02/39] Fix save load race condition by event queue --- ui/director.go | 10 ++++++---- ui/gameview.go | 27 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/ui/director.go b/ui/director.go index a8d73bc9..592db041 100644 --- a/ui/director.go +++ b/ui/director.go @@ -16,7 +16,7 @@ type Director struct { inputChannel chan int closedChannel chan bool roomID string - hash string + hash string } const FPS = 60 @@ -94,7 +94,8 @@ func (d *Director) PlayGame(path string) { func (d *Director) SaveGame() error { if d.hash != "" { - return d.view.console.SaveState(savePath(d.hash)) + d.view.Save(d.hash) + return nil } else { return nil } @@ -102,8 +103,9 @@ func (d *Director) SaveGame() error { func (d *Director) LoadGame() error { if d.hash != "" { - return d.view.console.LoadState(savePath(d.hash)) + d.view.Load(d.hash) + return nil } else { return nil } -} \ No newline at end of file +} diff --git a/ui/gameview.go b/ui/gameview.go index 4380379c..805bc8c5 100644 --- a/ui/gameview.go +++ b/ui/gameview.go @@ -36,6 +36,9 @@ type GameView struct { // equivalent to the list key pressed const above keyPressed [NumKeys * 2]bool + savingPath string + loadingPath string + imageChannel chan *image.RGBA inputChannel chan int } @@ -108,12 +111,36 @@ func (view *GameView) Update(t, dt float64) { } console := view.console view.updateControllers() + view.UpdateEvents() console.StepSeconds(dt) // fps to set frame view.imageChannel <- console.Buffer() } +func (view *GameView) Save(hash string) { + // put saving event to queue, process in updateEvent + view.savingPath = savePath(view.hash) +} + +func (view *GameView) Load(path string) { + // put saving event to queue, process in updateEvent + view.loadingPath = savePath(view.hash) +} + +func (view *GameView) UpdateEvents() { + // If there is saving event, save and discard the save event + if view.savingPath != "" { + view.console.SaveState(view.savingPath) + view.savingPath = "" + } + // If there is loading event, save and discard the load event + if view.loadingPath != "" { + view.console.LoadState(view.loadingPath) + view.loadingPath = "" + } +} + func (view *GameView) updateControllers() { // Divide keyPressed to player 1 and player 2 // First 8 keys are player 1 From 211f94731a842b5fe09660d2816171b6915c23e1 Mon Sep 17 00:00:00 2001 From: giongto35 Date: Sun, 14 Apr 2019 00:08:27 +0800 Subject: [PATCH 03/39] Init ws once --- main.go | 54 +++++----- static/js/gameboy_controller.js | 28 ++--- static/js/ws.js | 176 ++++++++++++++++---------------- 3 files changed, 130 insertions(+), 128 deletions(-) diff --git a/main.go b/main.go index 376a2ab7..abb0810f 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,6 @@ package main import ( - "os" "encoding/json" "fmt" "image" @@ -10,6 +9,7 @@ import ( "math/rand" "net/http" _ "net/http/pprof" + "os" "strconv" "time" @@ -21,15 +21,15 @@ import ( ) const ( - width = 256 - height = 240 - scale = 3 - title = "NES" + width = 256 + height = 240 + scale = 3 + title = "NES" gameboyIndex = "./static/gameboy.html" - debugIndex = "./static/index_ws.html" + debugIndex = "./static/index_ws.html" ) -var indexFN = gameboyIndex +var indexFN = debugIndex // Time allowed to write a message to the peer. var readWait = 30 * time.Second @@ -61,7 +61,7 @@ var rooms map[string]*Room func main() { fmt.Println("Usage: ./game [debug]") - if len(os.Args) > 1 { + if len(os.Args) > 1 { // debug indexFN = debugIndex fmt.Println("Use debug version") @@ -80,7 +80,6 @@ func main() { http.ListenAndServe(":8000", nil) } - func getWeb(w http.ResponseWriter, r *http.Request) { bs, err := ioutil.ReadFile(indexFN) if err != nil { @@ -101,13 +100,13 @@ func initRoom(roomID, gameName string) string { // create director director := ui.NewDirector(roomID, imageChannel, inputChannel, closedChannel) - + rooms[roomID] = &Room{ imageChannel: imageChannel, inputChannel: inputChannel, closedChannel: closedChannel, rtcSessions: []*webrtc.WebRTC{}, - director: director, + director: director, } go fanoutScreen(imageChannel, roomID) @@ -163,13 +162,13 @@ func ws(w http.ResponseWriter, r *http.Request) { // streaming game // start new games and webrtc stuff? - isDone := false + //isDone := false var gameName string var roomID string var playerIndex int - for !isDone { + for { c.SetReadDeadline(time.Now().Add(readWait)) mt, message, err := c.ReadMessage() if err != nil { @@ -189,14 +188,14 @@ func ws(w http.ResponseWriter, r *http.Request) { // SDP connection initializations follows WebRTC convention // https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Protocols switch req.ID { - case "ping": - gameName = req.Data - roomID = req.RoomID - playerIndex = req.PlayerIndex - log.Println("Ping from server with game:", gameName) - res.ID = "pong" + //case "ping": + //gameName = req.Data + //roomID = req.RoomID + //playerIndex = req.PlayerIndex + //log.Println("Ping from server with game:", gameName) + //res.ID = "pong" - case "sdp": + case "initwebrtc": log.Println("Received user SDP") localSession, err := webRTC.StartClient(req.Data, width, height) if err != nil { @@ -218,6 +217,11 @@ func ws(w http.ResponseWriter, r *http.Request) { res.ID = "candidate" case "start": + gameName = req.Data + roomID = req.RoomID + playerIndex = req.PlayerIndex + //log.Println("Ping from server with game:", gameName) + //res.ID = "pong" log.Println("Starting game") roomID = startSession(webRTC, gameName, roomID, playerIndex) res.ID = "start" @@ -225,7 +229,7 @@ func ws(w http.ResponseWriter, r *http.Request) { // maybe we wont close websocket // isDone = true - + case "save": log.Println("Saving game state") res.ID = "save" @@ -262,10 +266,10 @@ func ws(w http.ResponseWriter, r *http.Request) { c.SetWriteDeadline(time.Now().Add(writeWait)) err = c.WriteMessage(mt, []byte(stRes)) - if err != nil { - log.Println("write:", err) - break - } + //if err != nil { + //log.Println("write:", err) + //break + //} } } diff --git a/static/js/gameboy_controller.js b/static/js/gameboy_controller.js index f4aa65b5..d87872d5 100644 --- a/static/js/gameboy_controller.js +++ b/static/js/gameboy_controller.js @@ -3,23 +3,17 @@ function showMenuScreen() { log("Clean up connection / frame"); // clean up before / after menu - try { - inputChannel.close(); - } catch (err) { - log(`> [Warning] input channel: ${err}`); - } + //try { + //inputChannel.gameboyIndeoclose(); + //} catch (err) { + //log(`> [Warning] peer connection: ${err}`); + //} - try { - pc.close(); - } catch (err) { - log(`> [Warning] peer connection: ${err}`); - } - - try { - conn.close(); - } catch (err) { - log(`> [Warning] Websocket connection: ${err}`); - } + //try { + //conn.close(); + //} catch (err) { + //log(`> [Warning] Websocket connection: ${err}`); + //} $("#game-screen").hide(); if (!DEBUG) { @@ -90,7 +84,7 @@ document.body.onkeyup = function (e) { } } else if (screenState === "game") { setState(e, false); - + switch (KEY_MAP[e.keyCode]) { case "save": conn.send(JSON.stringify({"id": "save", "data": ""})); diff --git a/static/js/ws.js b/static/js/ws.js index 9b7e5c7a..1aba878c 100644 --- a/static/js/ws.js +++ b/static/js/ws.js @@ -1,93 +1,68 @@ +var pc; // web socket -function startGame() { - log("Starting game screen"); +conn = new WebSocket(`ws://${location.host}/ws`); - // clear - endInput(); - document.getElementById('div').innerHTML = ""; - if (!DEBUG) { - $("#menu-screen").fadeOut(400, function() { - $("#game-screen").show(); - }); +// Clear old roomID +conn.onopen = () => { + log("WebSocket is opened. Send ping"); + log("Send ping pong frequently") + pingpongTimer = setInterval(sendPing, 1000 / PINGPONGPS) + + startWebRTC(); +} + +conn.onerror = error => { + log(`Websocket error: ${error}`); +} + +conn.onclose = () => { + log("Websocket closed"); +} + +conn.onmessage = e => { + d = JSON.parse(e.data); + switch (d["id"]) { + case "sdp": + log("Got remote sdp"); + pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(atob(d["data"])))); + break; + case "pong": + // TODO: Change name use one session + log("Recv pong. Start webrtc"); + //startWebRTC(); + break; + case "pingpong": + // TODO: Calc time + break; + case "start": + log("Got start"); + roomID.value = "" + currentRoomID.innerText = d["room_id"] + break; + case "save": + log(`Got save response: ${d["data"]}`); + break; + case "load": + log(`Got load response: ${d["data"]}`); + break; } - // end clear +} - conn = new WebSocket(`ws://${location.host}/ws`); - - // Clear old roomID - conn.onopen = () => { - log("WebSocket is opened. Send ping"); - conn.send(JSON.stringify({"id": "ping", "data": GAME_LIST[gameIdx].nes, "room_id": roomID.value, "player_index": parseInt(playerIndex.value, 10)}));inputTimer - log("Send ping pong frequently") - pingpongTimer = setInterval(sendPing, 1000 / PINGPONGPS) - } - - conn.onerror = error => { - log(`Websocket error: ${error}`); - } - - conn.onclose = () => { - log("Websocket closed"); - } - - conn.onmessage = e => { - d = JSON.parse(e.data); - switch (d["id"]) { - case "pong": - // TODO: Change name use one session - log("Recv pong. Start webrtc"); - startWebRTC(); - break; - case "pingpong": - // TODO: Calc time - break; - case "sdp": - log("Got remote sdp"); - pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(atob(d["data"])))); - break; - case "start": - log("Got start"); - roomID.value = "" - currentRoomID.innerText = d["room_id"] - break; - case "save": - log(`Got save response: ${d["data"]}`); - break; - case "load": - log(`Got load response: ${d["data"]}`); - break; - } - } - - function sendPing() { - // TODO: format the package with time - conn.send(JSON.stringify({"id": "pingpong", "data": "pingpong"})); - } +function sendPing() { + // TODO: format the package with time + //conn.send(JSON.stringify({"id": "pingpong", "data": "pingpong"})); +} +function startWebRTC() { // webrtc pc = new RTCPeerConnection({iceServers: [{urls: 'stun:stun.l.google.com:19302'}]}) - // input channel - inputChannel = pc.createDataChannel('foo') - inputChannel.onclose = () => { - log('inputChannel has closed'); - } - - inputChannel.onopen = () => { - log('inputChannel has opened'); - } - - inputChannel.onmessage = e => { - log(`Message from DataChannel '${inputChannel.label}' payload '${e.data}'`); - } - pc.oniceconnectionstatechange = e => { log(`iceConnectionState: ${pc.iceConnectionState}`); if (pc.iceConnectionState === "connected") { - conn.send(JSON.stringify({"id": "start", "data": ""})); - startInput(); + //conn.send(JSON.stringify({"id": "start", "data": ""})); screenState = "game"; } else if (pc.iceConnectionState === "disconnected") { @@ -110,19 +85,48 @@ function startGame() { session = btoa(JSON.stringify(pc.localDescription)); localSessionDescription = session; log("Send SDP to remote peer"); - conn.send(JSON.stringify({"id": "sdp", "data": session})); + conn.send(JSON.stringify({"id": "initwebrtc", "data": session})); } else { console.log(JSON.stringify(event.candidate)); } } - function startWebRTC() { - // receiver only tracks - pc.addTransceiver('video', {'direction': 'recvonly'}); + // receiver only tracks + pc.addTransceiver('video', {'direction': 'recvonly'}); - // create SDP - pc.createOffer({offerToReceiveVideo: true, offerToReceiveAudio: false}).then(d => { - pc.setLocalDescription(d).catch(log); - }) - } + // create SDP + pc.createOffer({offerToReceiveVideo: true, offerToReceiveAudio: false}).then(d => { + pc.setLocalDescription(d).catch(log); + }) +} + +function startGame() { + log("Starting game screen"); + conn.send(JSON.stringify({"id": "start", "data": GAME_LIST[gameIdx].nes, "room_id": roomID.value, "player_index": parseInt(playerIndex.value, 10)}));inputTimer + + // clear menu screen + //endInput(); + document.getElementById('div').innerHTML = ""; + if (!DEBUG) { + $("#menu-screen").fadeOut(400, function() { + $("#game-screen").show(); + }); + } + // end clear + + // input channel + inputChannel = pc.createDataChannel('foo') + inputChannel.onclose = () => { + log('inputChannel has closed'); + } + + inputChannel.onopen = () => { + log('inputChannel has opened'); + } + + inputChannel.onmessage = e => { + log(`Message from DataChannel '${inputChannel.label}' payload '${e.data}'`); + } + + startInput(); } From ac87ceb5d1c601b5b1d5b2d69d3049b774a39f6b Mon Sep 17 00:00:00 2001 From: giongto35 Date: Sun, 14 Apr 2019 01:21:14 +0800 Subject: [PATCH 04/39] WIP --- static/js/gameboy_controller.js | 4 +--- static/js/global.js | 3 +-- static/js/ws.js | 29 +++++++++++++++-------------- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/static/js/gameboy_controller.js b/static/js/gameboy_controller.js index d87872d5..ce12dee2 100644 --- a/static/js/gameboy_controller.js +++ b/static/js/gameboy_controller.js @@ -63,7 +63,6 @@ function chooseGame(idx, force=false) { function setState(e, bo) { if (e.keyCode in KEY_MAP) { keyState[KEY_MAP[e.keyCode]] = bo; - stateUnchange = false; unchangePacket = INPUT_STATE_PACKET; } } @@ -149,7 +148,7 @@ document.body.onkeydown = function (e) { function sendInput() { // prepare key - if (stateUnchange || unchangePacket > 0) { + if (unchangePacket > 0) { st = ""; KEY_BIT.slice().reverse().forEach(elem => { st += keyState[elem] ? 1 : 0; @@ -162,7 +161,6 @@ function sendInput() { a[0] = ss; inputChannel.send(a); - stateUnchange = false; unchangePacket--; } } diff --git a/static/js/global.js b/static/js/global.js index 0bc060be..0ddec381 100644 --- a/static/js/global.js +++ b/static/js/global.js @@ -32,7 +32,6 @@ keyState = { quit: false } -stateUnchange = true; unchangePacket = INPUT_STATE_PACKET; inputTimer = null; @@ -53,4 +52,4 @@ function log(msg) { document.getElementById('div').innerHTML += msg + '
' console.log(msg); } -} \ No newline at end of file +} diff --git a/static/js/ws.js b/static/js/ws.js index 1aba878c..ee8429cd 100644 --- a/static/js/ws.js +++ b/static/js/ws.js @@ -98,6 +98,21 @@ function startWebRTC() { pc.createOffer({offerToReceiveVideo: true, offerToReceiveAudio: false}).then(d => { pc.setLocalDescription(d).catch(log); }) + + // input channel + inputChannel = pc.createDataChannel('foo') + inputChannel.onclose = () => { + log('inputChannel has closed'); + } + + inputChannel.onopen = () => { + log('inputChannel has opened'); + } + + inputChannel.onmessage = e => { + log(`Message from DataChannel '${inputChannel.label}' payload '${e.data}'`); + } + } function startGame() { @@ -114,19 +129,5 @@ function startGame() { } // end clear - // input channel - inputChannel = pc.createDataChannel('foo') - inputChannel.onclose = () => { - log('inputChannel has closed'); - } - - inputChannel.onopen = () => { - log('inputChannel has opened'); - } - - inputChannel.onmessage = e => { - log(`Message from DataChannel '${inputChannel.label}' payload '${e.data}'`); - } - startInput(); } From 4fcf67e05e7a9e24c45f6c7dc7711052e5b5e969 Mon Sep 17 00:00:00 2001 From: giongto35 Date: Sun, 14 Apr 2019 12:54:58 +0800 Subject: [PATCH 05/39] Clean old session --- main.go | 19 ++++++++++++++++++- static/js/ws.js | 28 ++++++++++++++-------------- webrtc/webrtc.go | 8 +++++++- 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/main.go b/main.go index abb0810f..b49db9c7 100644 --- a/main.go +++ b/main.go @@ -57,7 +57,7 @@ type Room struct { director *ui.Director } -var rooms map[string]*Room +var rooms = map[string]*Room{} func main() { fmt.Println("Usage: ./game [debug]") @@ -132,8 +132,24 @@ func isRoomRunning(roomID string) bool { return false } +// startSession cleans all of the dependencies of old game to current webRTC session +func cleanSession(webrtc *webrtc.WebRTC) { + roomID := webrtc.RoomID + if !isRoomRunning(roomID) { + return + } + + for id, session := range rooms[roomID].rtcSessions { + if session == webrtc { + rooms[roomID].rtcSessions = append(rooms[roomID].rtcSessions[:id], rooms[roomID].rtcSessions[id+1:]...) + break + } + } +} + // startSession handles one session call func startSession(webRTC *webrtc.WebRTC, gameName string, roomID string, playerIndex int) string { + cleanSession(webRTC) // If the roomID is empty, // or the roomID doesn't have any running sessions (room was closed) // we spawn a new room @@ -143,6 +159,7 @@ func startSession(webRTC *webrtc.WebRTC, gameName string, roomID string, playerI // TODO: Might have race condition rooms[roomID].rtcSessions = append(rooms[roomID].rtcSessions, webRTC) + webRTC.AttachRoomID(roomID) faninInput(rooms[roomID].inputChannel, webRTC, playerIndex) return roomID diff --git a/static/js/ws.js b/static/js/ws.js index ee8429cd..047d0c28 100644 --- a/static/js/ws.js +++ b/static/js/ws.js @@ -58,6 +58,20 @@ function startWebRTC() { // webrtc pc = new RTCPeerConnection({iceServers: [{urls: 'stun:stun.l.google.com:19302'}]}) + // input channel + inputChannel = pc.createDataChannel('foo') + inputChannel.onclose = () => { + log('inputChannel has closed'); + } + + inputChannel.onopen = () => { + log('inputChannel has opened'); + } + + inputChannel.onmessage = e => { + log(`Message from DataChannel '${inputChannel.label}' payload '${e.data}'`); + } + pc.oniceconnectionstatechange = e => { log(`iceConnectionState: ${pc.iceConnectionState}`); @@ -99,20 +113,6 @@ function startWebRTC() { pc.setLocalDescription(d).catch(log); }) - // input channel - inputChannel = pc.createDataChannel('foo') - inputChannel.onclose = () => { - log('inputChannel has closed'); - } - - inputChannel.onopen = () => { - log('inputChannel has opened'); - } - - inputChannel.onmessage = e => { - log(`Message from DataChannel '${inputChannel.label}' payload '${e.data}'`); - } - } function startGame() { diff --git a/webrtc/webrtc.go b/webrtc/webrtc.go index 03e279d7..dcead7f0 100644 --- a/webrtc/webrtc.go +++ b/webrtc/webrtc.go @@ -6,8 +6,8 @@ import ( "compress/gzip" "encoding/base64" "encoding/json" - "log" "io/ioutil" + "log" "math/rand" "time" @@ -107,6 +107,8 @@ type WebRTC struct { // for yuvI420 image ImageChannel chan []byte InputChannel chan int + + RoomID string } // StartClient start webrtc @@ -204,6 +206,10 @@ func (w *WebRTC) StartClient(remoteSession string, width, height int) (string, e return localSession, nil } +func (w *WebRTC) AttachRoomID(roomID string) { + w.RoomID = roomID +} + // TODO: Take a look at this func (w *WebRTC) AddCandidate(candidate webrtc.ICECandidateInit) { err := w.connection.AddICECandidate(candidate) From ebf1d93e4cbb4394b169c7fa87e06f8e22334f5c Mon Sep 17 00:00:00 2001 From: giongto35 Date: Sun, 14 Apr 2019 15:08:13 +0800 Subject: [PATCH 06/39] Fix gameboy screen not change state --- main.go | 2 +- static/gameboy.html | 6 +++--- static/js/ws.js | 5 +++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/main.go b/main.go index b49db9c7..5b4e5846 100644 --- a/main.go +++ b/main.go @@ -29,7 +29,7 @@ const ( debugIndex = "./static/index_ws.html" ) -var indexFN = debugIndex +var indexFN = gameboyIndex // Time allowed to write a message to the peer. var readWait = 30 * time.Second diff --git a/static/gameboy.html b/static/gameboy.html index 5f7684a7..685d608d 100644 --- a/static/gameboy.html +++ b/static/gameboy.html @@ -88,9 +88,9 @@
Game:
Use Up, Down, Left, Right to Move
- Z to jump (A)
- X to sprint (B)
- C is start (in game)
+ Z (A butotn)
+ X (B button)
+ C is start (or pause in some games)
V is select game
Q is super quit
S to save
diff --git a/static/js/ws.js b/static/js/ws.js index 047d0c28..8e8d6053 100644 --- a/static/js/ws.js +++ b/static/js/ws.js @@ -51,7 +51,7 @@ conn.onmessage = e => { function sendPing() { // TODO: format the package with time - //conn.send(JSON.stringify({"id": "pingpong", "data": "pingpong"})); + conn.send(JSON.stringify({"id": "pingpong", "data": "pingpong"})); } function startWebRTC() { @@ -77,7 +77,6 @@ function startWebRTC() { if (pc.iceConnectionState === "connected") { //conn.send(JSON.stringify({"id": "start", "data": ""})); - screenState = "game"; } else if (pc.iceConnectionState === "disconnected") { endInput(); @@ -117,6 +116,8 @@ function startWebRTC() { function startGame() { log("Starting game screen"); + screenState = "game"; + conn.send(JSON.stringify({"id": "start", "data": GAME_LIST[gameIdx].nes, "room_id": roomID.value, "player_index": parseInt(playerIndex.value, 10)}));inputTimer // clear menu screen From 57beefd531632f0ec25bba05d654d8a9b187f0bc Mon Sep 17 00:00:00 2001 From: giongto35 Date: Sun, 14 Apr 2019 15:20:15 +0800 Subject: [PATCH 07/39] WS handle whole connections --- static/gameboy.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/static/gameboy.html b/static/gameboy.html index 685d608d..3aff8ee2 100644 --- a/static/gameboy.html +++ b/static/gameboy.html @@ -37,7 +37,8 @@
GAME BOY
C
-