Support chat messages

This commit is contained in:
Trevor Slocum 2020-08-19 17:05:17 -07:00
parent b37807f82f
commit 407bacce7d
3 changed files with 114 additions and 20 deletions

View File

@ -60,7 +60,9 @@ func handleRead(c *websocket.Conn, done chan struct{}) {
return
}
statusBuf.Write([]byte(fmt.Sprintf("recv: %s\n", message)))
if debug {
statusMessage(fmt.Sprintf("recv: %s\n", message))
}
if messageType == websocket.PingMessage || messageType == websocket.PongMessage {
continue
@ -70,12 +72,24 @@ func handleRead(c *websocket.Conn, done chan struct{}) {
gameState = &GameState{}
err = json.Unmarshal(message, gameState)
if err != nil {
// TODO currently skipping, should show error
statusBuf.Write(append([]byte(message), byte('\n')))
statusMessage(string(message))
continue
}
if gameState.Turn == 0 {
var gameCommand *GameCommand
gameCommand = &GameCommand{}
err = json.Unmarshal(message, gameCommand)
if err != nil {
// TODO currently skipping, should show error
continue
}
if gameCommand.Command == CommandMessage {
statusMessage(fmt.Sprintf("<%s> %s", "Opponent", gameCommand.Value))
}
}
currentGameState = gameState
if gameState.Player > 0 {
@ -173,7 +187,9 @@ func handleRead(c *websocket.Conn, done chan struct{}) {
updateGameText()
statusBuf.Write([]byte(fmt.Sprintf("decode: %+v\n", gameState)))
if debug {
statusMessage(fmt.Sprintf("read: %+v\n", gameState))
}
app.Draw()
}
@ -181,7 +197,9 @@ func handleRead(c *websocket.Conn, done chan struct{}) {
func handleWrite(c *websocket.Conn) {
for msg := range writeBuffer {
statusBuf.Write([]byte(fmt.Sprintf("write: %+v\n", msg)))
if debug {
statusMessage(fmt.Sprintf("write: %+v\n", msg))
}
w, err := c.NextWriter(websocket.TextMessage)
if err != nil {

View File

@ -7,6 +7,7 @@ const CommandRaw = 0
const CommandContinue = 1
const CommandThrow = 2
const CommandCut = 3
const CommandMessage = 4
type GameCommand struct {
Player int
@ -19,17 +20,16 @@ func (gc GameCommand) ToStr() string {
switch gc.Command {
case CommandEnd:
commandprinted = "End"
break
case CommandRaw:
commandprinted = "Raw"
case CommandContinue:
commandprinted = "Continue"
break
case CommandCut:
commandprinted = "Cut"
break
case CommandThrow:
commandprinted = "Throw"
case CommandMessage:
commandprinted = "Message"
}
return fmt.Sprintf("Player %d - %s - %s", gc.Player, commandprinted, gc.Value)
}

98
main.go
View File

@ -7,6 +7,10 @@ import (
"strings"
"time"
"sync"
"github.com/gdamore/tcell"
"gitlab.com/tslocum/cbind"
"gitlab.com/tslocum/cview"
@ -14,15 +18,22 @@ import (
cribbage "gitlab.com/tslocum/joker-cribbage"
)
const (
DefaultStatusText = "Press Enter to chat, 1-6 to throw a card, Space to continue"
LogFormat = "2006-01-02 15:04:05"
)
var (
debug bool
app *cview.Application
inputConfig *cbind.Configuration
statusText *cview.TextView
gameText *cview.TextView
statusButton *cview.Button
statusText *cview.TextView
gameText *cview.TextView
statusBuf *cview.TextView
inputField *cview.InputField
statusBuf *cview.TextView
statusGrid *cview.Grid
@ -38,6 +49,11 @@ var (
writeBuffer = make(chan string)
exit = make(chan bool)
inputFocused bool
wroteFirstLogMessage bool
logMutex sync.Mutex
)
func setupThrowGrid() {
@ -149,11 +165,51 @@ func updateGameText() {
gameText.SetText(newGameText)
}
func toggleFocus() {
if inputFocused && inputField.GetText() != "" {
writeBuffer <- "msg " + inputField.GetText()
statusMessage(fmt.Sprintf("<%s> %s", "You", inputField.GetText()))
}
inputFocused = !inputFocused
inputField.SetText("")
focusUpdated()
}
func focusUpdated() {
if inputFocused {
app.SetFocus(inputField)
} else {
app.SetFocus(nil)
}
}
func statusMessage(message string) {
logMutex.Lock()
defer logMutex.Unlock()
var prefix string
if !wroteFirstLogMessage {
wroteFirstLogMessage = true
} else {
prefix = "\n"
}
if len(message) > 0 && message[0:1] != "<" {
message = "* " + message
}
statusBuf.Write([]byte(prefix + time.Now().Format(LogFormat) + " " + message))
app.Draw()
}
func main() {
cview.Styles.PrimaryTextColor = tcell.ColorDefault
cview.Styles.PrimitiveBackgroundColor = tcell.ColorDefault
var connectAddress string
flag.BoolVar(&debug, "debug", false, "print debug information")
flag.StringVar(&connectAddress, "server", "wss://play.cribbage.world/crib", "Server address")
flag.Parse()
@ -162,11 +218,15 @@ func main() {
inputConfig = cbind.NewConfiguration()
inputConfig.SetKey(tcell.ModNone, tcell.KeyEnter, func(ev *tcell.EventKey) *tcell.EventKey {
doAction()
toggleFocus()
return nil
})
inputConfig.SetRune(tcell.ModNone, ' ', func(ev *tcell.EventKey) *tcell.EventKey {
if inputFocused {
return ev
}
doAction()
return nil
})
@ -174,6 +234,10 @@ func main() {
for i := 1; i <= 6; i++ {
i := i // Capture
inputConfig.SetRune(tcell.ModNone, '0'+rune(i), func(ev *tcell.EventKey) *tcell.EventKey {
if inputFocused {
return ev
}
selectCardIndex(i)
app.Draw()
return nil
@ -182,10 +246,6 @@ func main() {
app.SetInputCapture(inputConfig.Capture)
app.SetBeforeFocusFunc(func(p cview.Primitive) bool {
return false
})
starterWidget = NewCardWidget(joker.Card{}, nil)
mainHandStack = NewCardStackWidget()
mainCribStack = NewCardStackWidget()
@ -202,7 +262,7 @@ func main() {
g := cview.NewGrid().
SetColumns(cardWidth, 1, (cardBufferX*5)+cardWidth, 2, -1).
SetRows(cardHeight, 1, 1, cardHeight+1, -1)
SetRows(cardHeight, 1, 1, cardHeight+1, 2, -1)
gameText = cview.NewTextView()
gameText.SetTextAlign(cview.AlignCenter)
@ -217,6 +277,13 @@ func main() {
statusText = cview.NewTextView()
inputField = cview.NewInputField().
SetText("").
SetLabel("> ").
SetFieldWidth(0).
SetFieldBackgroundColor(tcell.ColorDefault).
SetFieldTextColor(tcell.ColorDefault)
statusBuf = cview.NewTextView().SetWrap(true).SetWordWrap(true)
setupThrowGrid()
@ -235,10 +302,19 @@ func main() {
g.AddItem(cview.NewTextView(), 3, 3, 1, 1, 0, 0, false)
g.AddItem(mainCribStack, 3, 4, 1, 1, 0, 0, false)
g.AddItem(statusBuf, 4, 0, 1, 5, 0, 0, false)
g.AddItem(inputField, 4, 0, 1, 5, 0, 0, false)
g.AddItem(statusBuf, 5, 0, 1, 5, 0, 0, false)
app.SetRoot(g, true)
app.SetBeforeFocusFunc(func(p cview.Primitive) bool {
return p == nil || p == inputField
})
focusUpdated()
statusMessage(DefaultStatusText)
go connect(connectAddress)
go func() {