tome_client/client2/backend.go

260 lines
6.6 KiB
Go
Raw Normal View History

2021-10-01 12:53:36 -04:00
package main
import (
"flag"
"log"
"os"
"os/signal"
"strconv"
"strings"
"time"
"unicode/utf8"
2021-10-01 13:10:55 -04:00
"git.saintnet.tech/tomecraft/tome_lib"
2021-10-01 12:53:36 -04:00
"github.com/google/uuid"
"github.com/gorilla/websocket"
)
var done chan interface{}
var interrupt chan os.Signal
var pid int
var matchID uuid.UUID
func receiveHandler(connection *websocket.Conn, container *UIContainer) {
defer close(done)
for {
2021-10-01 13:10:55 -04:00
var resp tome_lib.SessionCommandResult
2021-10-01 12:53:36 -04:00
err := connection.ReadJSON(&resp)
if err != nil {
log.Println("Error in receive:", err)
break
}
switch resp.Result {
2021-10-01 13:10:55 -04:00
case tome_lib.SessionRespJoined1:
pid = tome_lib.SentinalID
2021-10-01 12:53:36 -04:00
container.Output <- "joined as sentinal"
2021-10-01 13:10:55 -04:00
case tome_lib.SessionRespJoined2:
pid = tome_lib.ScourgeID
2021-10-01 12:53:36 -04:00
container.Output <- "joined as scourge"
2021-10-01 13:10:55 -04:00
case tome_lib.SessionRespFound:
2021-10-01 12:53:36 -04:00
matchID = resp.MatchID
2021-10-02 13:29:33 -04:00
container.Output <- "game found"
2021-10-01 13:10:55 -04:00
case tome_lib.SessionRespPlayed:
2021-10-01 12:53:36 -04:00
if resp.GameResult != nil {
switch resp.GameResult.ResultType {
2021-10-01 13:10:55 -04:00
case tome_lib.ActCmd:
2021-10-01 12:53:36 -04:00
container.Output <- resp.GameResult.ActionResult.String()
2021-10-01 13:10:55 -04:00
case tome_lib.StateCmd:
2021-10-01 12:53:36 -04:00
container.State = resp.GameResult.StateResult
container.Updated <- true
2021-10-01 13:10:55 -04:00
case tome_lib.DebugCmd:
container.Output <- "debug response"
2021-10-01 12:53:36 -04:00
}
} else {
container.Output <- "error playing"
}
2021-10-01 13:10:55 -04:00
case tome_lib.SessionRespLeft:
2021-10-02 13:29:33 -04:00
container.Output <- "game left"
2021-10-01 12:53:36 -04:00
matchID = uuid.Nil
return
2021-10-01 13:10:55 -04:00
case tome_lib.SessionRespBroadcastSenTurn:
2021-10-01 12:53:36 -04:00
container.Output <- "Sentinal may take their turn"
2021-10-01 13:10:55 -04:00
case tome_lib.SessionRespBroadcastScoTrun:
2021-10-01 12:53:36 -04:00
container.Output <- "Scourge may take their turn"
2021-10-01 13:10:55 -04:00
case tome_lib.SessionRespBroadcastSenWin:
2021-10-01 12:53:36 -04:00
container.Output <- "Sentinal wins!"
2021-10-01 13:10:55 -04:00
case tome_lib.SessionRespBroadcastScoWin:
2021-10-01 12:53:36 -04:00
container.Output <- "Scourge wins!"
2021-10-01 13:10:55 -04:00
case tome_lib.SessionRespBroadcastUpdate:
2021-10-01 12:53:36 -04:00
container.GetUpdate <- true
2021-10-01 13:10:55 -04:00
case tome_lib.SessionRespBroadcastScoJoin:
2021-10-02 13:29:33 -04:00
container.Output <- "Scourge has joined the game"
2021-10-01 13:10:55 -04:00
case tome_lib.SessionRespBroadcastSenJoin:
2021-10-02 13:29:33 -04:00
container.Output <- "Sentinal has joined the game"
2021-10-01 13:10:55 -04:00
case tome_lib.SessionRespBroadcastScoLeft:
2021-10-02 13:29:33 -04:00
container.Output <- "Scourge has left the game"
2021-10-01 13:10:55 -04:00
case tome_lib.SessionRespBroadcastSenLeft:
2021-10-02 13:29:33 -04:00
container.Output <- "Sentinal has left the game"
2021-10-01 13:10:55 -04:00
case tome_lib.SessionRespBroadcastSenReady:
2021-10-01 12:53:36 -04:00
container.Output <- "Sentinal is ready"
2021-10-01 13:10:55 -04:00
case tome_lib.SessionRespBroadcastScoReady:
2021-10-01 12:53:36 -04:00
container.Output <- "scourge is ready"
2021-10-01 13:10:55 -04:00
case tome_lib.SessionRespBroadcastNone:
2021-10-01 12:53:36 -04:00
2021-10-01 13:10:55 -04:00
case tome_lib.SessionRespError:
2021-10-01 12:53:36 -04:00
container.Output <- "generic error"
default:
container.Output <- "Received a server response we don't know how to handle"
}
}
}
func backend(container *UIContainer) {
done = make(chan interface{}) // Channel to indicate that the receiverHandler is done
interrupt = make(chan os.Signal) // Channel to listen for interrupt signal to terminate gracefully
2021-10-01 13:10:55 -04:00
cmd := make(chan tome_lib.SessionCommand)
2021-10-01 12:53:36 -04:00
signal.Notify(interrupt, os.Interrupt) // Notify the interrupt channel for SIGINT
hostname := flag.String("host", "localhost", "server hostname to connect to")
port := flag.Int("port", 7636, "port to connect to")
flag.Parse()
port_s := strconv.Itoa(*port)
socketUrl := "ws://" + *hostname + ":" + port_s + "/ws"
id := uuid.New()
conn, _, err := websocket.DefaultDialer.Dial(socketUrl, nil)
if err != nil {
log.Fatal("Error connecting to Websocket Server:", err)
}
defer conn.Close()
go receiveHandler(conn, container)
go GetCommand(id, cmd, container)
ticker := time.NewTicker(2 * time.Second)
// Our main loop for the client
// We send our relevant packets here
for {
2021-10-01 13:10:55 -04:00
var c tome_lib.SessionCommand
2021-10-01 12:53:36 -04:00
select {
case c = <-cmd:
err := conn.WriteJSON(c)
if err != nil {
log.Println("Error during writing to websocket:", err)
return
}
2021-10-01 13:10:55 -04:00
if c.Command == tome_lib.SessionCmdLeave {
2021-10-01 12:53:36 -04:00
break
}
case <-container.GetUpdate:
if container.State != nil {
2021-10-01 13:10:55 -04:00
err = conn.WriteJSON(&tome_lib.SessionCommand{
2021-10-01 12:53:36 -04:00
ID: id,
MatchID: matchID,
2021-10-01 13:10:55 -04:00
Command: tome_lib.SessionCmdPlay,
GameCommand: &tome_lib.Command{
2021-10-01 12:53:36 -04:00
PlayerID: pid,
2021-10-01 13:10:55 -04:00
Type: tome_lib.StateCmd,
2021-10-01 12:53:36 -04:00
Cmd: "g",
},
})
if err != nil {
log.Println("Error during writing to websocker:", err)
return
}
container.Updated <- true
}
case <-interrupt:
// We received a SIGINT (Ctrl + C). Terminate gracefully...
log.Println("Received SIGINT interrupt signal. Closing all pending connections")
// Close our websocket connection
2021-10-01 13:10:55 -04:00
err := conn.WriteJSON(tome_lib.SessionCommand{
2021-10-01 12:53:36 -04:00
ID: id,
2021-10-01 13:10:55 -04:00
Command: tome_lib.SessionCmdLeave,
2021-10-01 12:53:36 -04:00
})
if err != nil {
log.Println("Error during closing websocket:", err)
return
}
select {
case <-done:
log.Println("Receiver Channel Closed! Exiting....")
case <-time.After(time.Duration(1) * time.Second):
log.Println("Timeout in closing receiving channel. Exiting....")
}
return
case <-ticker.C:
select {
case <-done:
return
default:
if matchID != uuid.Nil {
2021-10-01 13:10:55 -04:00
err := conn.WriteJSON(tome_lib.SessionCommand{
2021-10-01 12:53:36 -04:00
ID: id,
MatchID: matchID,
2021-10-01 13:10:55 -04:00
Command: tome_lib.SessionCmdPoll,
2021-10-01 12:53:36 -04:00
})
if err != nil {
log.Println("Error writing to websocket:", err)
return
}
}
}
}
}
}
2021-10-01 13:10:55 -04:00
func GetCommand(uid uuid.UUID, resp chan tome_lib.SessionCommand, container *UIContainer) {
2021-10-01 12:53:36 -04:00
for {
var cmd string
var t int
input := <-container.Input
input_s := strings.Split(input, " ")
t, err := strconv.Atoi(input_s[0])
if err != nil {
continue
}
cmd = trimFirstRune(input)
cmd = strings.TrimSpace(cmd)
switch t {
case 0:
//session
2021-10-01 13:10:55 -04:00
switch tome_lib.SessionCmd(cmd) {
case tome_lib.SessionCmdQuery:
resp <- tome_lib.SessionCommand{
2021-10-01 12:53:36 -04:00
ID: uid,
2021-10-01 13:10:55 -04:00
Command: tome_lib.SessionCmdQuery,
2021-10-01 12:53:36 -04:00
}
2021-10-01 13:10:55 -04:00
case tome_lib.SessionCmdJoin:
resp <- tome_lib.SessionCommand{
2021-10-01 12:53:36 -04:00
ID: uid,
MatchID: matchID,
2021-10-01 13:10:55 -04:00
Command: tome_lib.SessionCmdJoin,
2021-10-01 12:53:36 -04:00
}
2021-10-01 13:10:55 -04:00
case tome_lib.SessionCmdLeave:
resp <- tome_lib.SessionCommand{
2021-10-01 12:53:36 -04:00
ID: uid,
MatchID: matchID,
2021-10-01 13:10:55 -04:00
Command: tome_lib.SessionCmdLeave,
2021-10-01 12:53:36 -04:00
}
default:
break
}
case 1:
//state
2021-10-01 13:10:55 -04:00
resp <- tome_lib.SessionCommand{
2021-10-01 12:53:36 -04:00
ID: uid,
MatchID: matchID,
2021-10-01 13:10:55 -04:00
Command: tome_lib.SessionCmdPlay,
GameCommand: &tome_lib.Command{
2021-10-01 12:53:36 -04:00
PlayerID: pid,
2021-10-01 13:10:55 -04:00
Type: tome_lib.StateCmd,
2021-10-01 12:53:36 -04:00
Cmd: cmd,
},
}
case 2:
//action
2021-10-01 13:10:55 -04:00
resp <- tome_lib.SessionCommand{
2021-10-01 12:53:36 -04:00
ID: uid,
MatchID: matchID,
2021-10-01 13:10:55 -04:00
Command: tome_lib.SessionCmdPlay,
GameCommand: &tome_lib.Command{
2021-10-01 12:53:36 -04:00
PlayerID: pid,
2021-10-01 13:10:55 -04:00
Type: tome_lib.ActCmd,
2021-10-01 12:53:36 -04:00
Cmd: cmd,
},
}
}
}
}
func trimFirstRune(s string) string {
_, i := utf8.DecodeRuneInString(s)
return s[i:]
}