154 lines
3.9 KiB
Go
154 lines
3.9 KiB
Go
package netwrk
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"net"
|
|
"strings"
|
|
|
|
"google.golang.org/protobuf/proto"
|
|
)
|
|
|
|
type LobbyPlayerStatus struct {
|
|
Username string
|
|
Status string
|
|
}
|
|
|
|
type Interrupter struct {
|
|
MessageType string
|
|
Message string
|
|
ReplyChan chan string
|
|
}
|
|
|
|
var username string
|
|
var lobby chan LobbyPlayerStatus
|
|
var interruptChan chan Interrupter
|
|
|
|
func ConnectToLobby(playerUsername string, messageOutputChan chan *LobbyMessage, lobbyMessageChan chan LobbyPlayerStatus, interruptChannel chan Interrupter) {
|
|
username = playerUsername
|
|
lobby = lobbyMessageChan
|
|
interruptChan = interruptChannel
|
|
|
|
conn, err := net.Dial("tcp", "127.0.0.1:12345")
|
|
if err != nil {
|
|
fmt.Println("Sorry, failed to connect to server...")
|
|
return
|
|
}
|
|
|
|
loginMsg, err := proto.Marshal(&LobbyMessage{Type: "name", Content: username})
|
|
if err != nil {
|
|
fmt.Println("Sorry bro but your username is wack AF...")
|
|
}
|
|
|
|
_, err = conn.Write(loginMsg)
|
|
if err != nil {
|
|
fmt.Println("Sorry, could not communicate with server...")
|
|
}
|
|
|
|
fmt.Println("Starting client loop")
|
|
messageInputChan := make(chan *LobbyMessage)
|
|
go func() {
|
|
for {
|
|
messageBytes := make([]byte, 1024)
|
|
|
|
n, err := conn.Read(messageBytes)
|
|
if err != nil {
|
|
fmt.Println("Sorry, failed to read message from server...", err)
|
|
}
|
|
|
|
message := &LobbyMessage{}
|
|
|
|
err = proto.Unmarshal(messageBytes[:n], message)
|
|
if err != nil {
|
|
fmt.Println("Sorry, the server sent something weird back...")
|
|
}
|
|
|
|
messageInputChan <- message
|
|
}
|
|
}()
|
|
for {
|
|
select {
|
|
case msg := <-messageInputChan:
|
|
if isDone, gameID := handleLobbyMessage(conn, msg); isDone {
|
|
if gameID != "" {
|
|
interruptChan <- Interrupter{
|
|
MessageType: "game",
|
|
Message: gameID,
|
|
ReplyChan: make(chan string),
|
|
}
|
|
return
|
|
} else {
|
|
return
|
|
}
|
|
}
|
|
case msg := <-messageOutputChan:
|
|
fmt.Println("Sending message out", msg)
|
|
err := SendMessageToServer(conn, msg)
|
|
if err != nil {
|
|
fmt.Println("Error!", err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func handleLobbyMessage(serverConn net.Conn, message *LobbyMessage) (bool, string) {
|
|
switch message.Type {
|
|
case "text":
|
|
fmt.Println(message.Content)
|
|
return false, ""
|
|
case "error":
|
|
fmt.Println("Error:", message.Content)
|
|
return false, ""
|
|
case "invite":
|
|
fmt.Println("GOT INVITE!")
|
|
replyChan := make(chan string)
|
|
interruptChan <- Interrupter{
|
|
MessageType: "invite",
|
|
Message: fmt.Sprintf("Invite from player %s\nAccept: Y Decline: N", message.Content),
|
|
ReplyChan: replyChan,
|
|
}
|
|
input := <-replyChan
|
|
if strings.ToLower(input) == "yes" || strings.ToLower(input) == "y" {
|
|
SendMessageToServer(serverConn, &LobbyMessage{Type: "accept_game", Content: username})
|
|
SendMessageToServer(serverConn, &LobbyMessage{Type: "quit", Content: username})
|
|
return true, message.Content
|
|
} else {
|
|
SendMessageToServer(serverConn, &LobbyMessage{Type: "decline_game", Content: username})
|
|
}
|
|
return false, ""
|
|
case "accept":
|
|
fmt.Println(message.Content, "accepted your invite. Game starting...")
|
|
SendMessageToServer(serverConn, &LobbyMessage{Type: "quit", Content: username})
|
|
return true, message.Content
|
|
case "decline_game":
|
|
fmt.Println("Sorry,", message.Content, "declined your game invite...")
|
|
return false, ""
|
|
case "connect":
|
|
lobby <- LobbyPlayerStatus{Username: message.Content, Status: "connected"}
|
|
fmt.Println(message.Content, "connected!")
|
|
return false, ""
|
|
case "disconnect":
|
|
lobby <- LobbyPlayerStatus{Username: message.Content, Status: "disconnected"}
|
|
fmt.Println(message.Content, "disconnected!")
|
|
return false, ""
|
|
case "pong":
|
|
log.Println("PoNg!")
|
|
return false, ""
|
|
default:
|
|
log.Println("Got message", message)
|
|
}
|
|
return false, ""
|
|
}
|
|
|
|
func SendMessageToServer(connection net.Conn, message *LobbyMessage) error {
|
|
bytes, err := proto.Marshal(message)
|
|
if err != nil {
|
|
return fmt.Errorf("Error marshalling message. Your protobuf is wack yo.")
|
|
}
|
|
_, err = connection.Write(bytes)
|
|
if err != nil {
|
|
return fmt.Errorf("Error writing to client connection")
|
|
}
|
|
return nil
|
|
}
|