2024-08-14 23:33:05 -06:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2024-08-15 20:08:23 -06:00
|
|
|
"io"
|
|
|
|
"log"
|
2024-09-26 19:49:59 -06:00
|
|
|
"log/slog"
|
|
|
|
"net"
|
2024-08-14 23:33:05 -06:00
|
|
|
"os"
|
2024-08-15 20:08:23 -06:00
|
|
|
"sshpong/internal/client"
|
2024-09-26 19:49:59 -06:00
|
|
|
"sshpong/internal/lobby"
|
2024-08-24 16:09:12 -06:00
|
|
|
"strings"
|
2024-08-15 20:08:23 -06:00
|
|
|
)
|
2024-08-14 23:33:05 -06:00
|
|
|
|
2024-09-26 19:49:59 -06:00
|
|
|
var username string
|
2024-08-14 23:33:05 -06:00
|
|
|
|
2024-08-15 20:08:23 -06:00
|
|
|
func main() {
|
2024-09-26 19:49:59 -06:00
|
|
|
slog.SetLogLoggerLevel(slog.LevelDebug)
|
|
|
|
slog.Debug("Debug logs active...")
|
|
|
|
|
2024-08-14 23:33:05 -06:00
|
|
|
fmt.Println("Welcome to sshpong!")
|
|
|
|
fmt.Println("Please enter your username")
|
|
|
|
|
2024-09-26 19:49:59 -06:00
|
|
|
egress := make(chan lobby.LobbyMessage)
|
|
|
|
ingress := make(chan lobby.LobbyMessage)
|
2024-08-24 16:09:12 -06:00
|
|
|
interrupter := make(chan client.InterrupterMessage, 100)
|
2024-09-26 19:49:59 -06:00
|
|
|
exit := make(chan string)
|
2024-08-14 23:33:05 -06:00
|
|
|
|
2024-08-15 20:08:23 -06:00
|
|
|
buf := make([]byte, 1024)
|
|
|
|
n, err := os.Stdin.Read(buf)
|
2024-08-14 23:33:05 -06:00
|
|
|
if err != nil {
|
2024-08-15 20:08:23 -06:00
|
|
|
log.Panic("Bro your input is no good...")
|
2024-08-14 23:33:05 -06:00
|
|
|
}
|
2024-09-26 19:49:59 -06:00
|
|
|
username = string(buf[:n-1])
|
2024-08-14 23:33:05 -06:00
|
|
|
|
2024-09-26 19:49:59 -06:00
|
|
|
fmt.Println("username is...", username)
|
|
|
|
conn, err := ConnectToLobby(username)
|
2024-08-15 20:08:23 -06:00
|
|
|
if err != nil {
|
|
|
|
log.Panic(err)
|
|
|
|
}
|
2024-08-14 23:33:05 -06:00
|
|
|
|
2024-08-15 20:08:23 -06:00
|
|
|
// User input handler
|
2024-09-26 19:49:59 -06:00
|
|
|
go func(egress chan lobby.LobbyMessage) {
|
2024-08-15 20:08:23 -06:00
|
|
|
buf := make([]byte, 1024)
|
|
|
|
for {
|
2024-08-14 23:33:05 -06:00
|
|
|
n, err := os.Stdin.Read(buf)
|
|
|
|
if err != nil {
|
2024-08-15 20:08:23 -06:00
|
|
|
log.Panic("Bro your input wack as fuck")
|
2024-08-14 23:33:05 -06:00
|
|
|
}
|
|
|
|
|
2024-08-24 16:09:12 -06:00
|
|
|
input := string(buf[:n-1])
|
|
|
|
args := strings.Fields(input)
|
|
|
|
|
2024-09-26 19:49:59 -06:00
|
|
|
userMessage := lobby.LobbyMessage{}
|
2024-08-24 16:09:12 -06:00
|
|
|
|
|
|
|
select {
|
|
|
|
case msg := <-interrupter:
|
2024-09-26 19:49:59 -06:00
|
|
|
userMessage, err := client.HandleInterruptInput(msg, args, username)
|
2024-08-24 16:09:12 -06:00
|
|
|
if err != nil {
|
2024-09-26 19:49:59 -06:00
|
|
|
userMessage, err = client.HandleUserInput(args, username)
|
2024-08-24 16:09:12 -06:00
|
|
|
if err == io.EOF {
|
2024-09-26 19:49:59 -06:00
|
|
|
exit <- ""
|
2024-08-24 16:09:12 -06:00
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
egress <- userMessage
|
2024-09-26 19:49:59 -06:00
|
|
|
if userMessage.MessageType == "accept" || userMessage.MessageType == "disconect" {
|
|
|
|
slog.Debug("Closing input handler with accept or disconnect message", slog.Any("message content", userMessage.Message))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if userMessage.MessageType == "start_game" {
|
|
|
|
slog.Debug("closing input handler with start_game message and sending exit signal")
|
|
|
|
|
|
|
|
// TODO: This is a wierd one...
|
|
|
|
sg, ok := userMessage.Message.(lobby.StartGame)
|
|
|
|
if !ok {
|
|
|
|
slog.Debug("Start game interrupt message was improperly formatted... Could be indicative of an error in the HandleinterruptInput method")
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
exit <- sg.GameID
|
|
|
|
return
|
|
|
|
}
|
2024-08-24 16:09:12 -06:00
|
|
|
|
|
|
|
default:
|
2024-09-26 19:49:59 -06:00
|
|
|
userMessage, err = client.HandleUserInput(args, username)
|
2024-08-24 16:09:12 -06:00
|
|
|
if err == io.EOF {
|
2024-09-26 19:49:59 -06:00
|
|
|
exit <- ""
|
2024-08-24 16:09:12 -06:00
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
egress <- userMessage
|
2024-08-14 23:33:05 -06:00
|
|
|
|
2024-08-24 16:09:12 -06:00
|
|
|
}
|
2024-09-26 19:49:59 -06:00
|
|
|
|
2024-08-14 23:33:05 -06:00
|
|
|
}
|
2024-08-15 20:08:23 -06:00
|
|
|
}(egress)
|
2024-08-14 23:33:05 -06:00
|
|
|
|
2024-08-15 20:08:23 -06:00
|
|
|
// Ingress Handler
|
2024-09-26 19:49:59 -06:00
|
|
|
go func(oc chan lobby.LobbyMessage) {
|
2024-08-15 20:08:23 -06:00
|
|
|
for {
|
|
|
|
msg := <-ingress
|
|
|
|
|
2024-08-24 16:09:12 -06:00
|
|
|
interrupterMsg, err := client.HandleServerMessage(msg)
|
|
|
|
if err != nil {
|
|
|
|
log.Panic("Error handling server message disconnecting...")
|
|
|
|
}
|
|
|
|
if interrupterMsg.InterruptType != "" {
|
|
|
|
interrupter <- interrupterMsg
|
|
|
|
}
|
2024-08-15 20:08:23 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
}(ingress)
|
|
|
|
|
|
|
|
// Network writer
|
2024-09-26 19:49:59 -06:00
|
|
|
go func(userMessages chan lobby.LobbyMessage) {
|
2024-08-15 20:08:23 -06:00
|
|
|
for {
|
|
|
|
msg := <-userMessages
|
2024-09-26 19:49:59 -06:00
|
|
|
bytes, err := lobby.Marshal(msg)
|
2024-08-15 20:08:23 -06:00
|
|
|
if err != nil {
|
|
|
|
log.Panic("Malformed proto message", err)
|
|
|
|
}
|
|
|
|
_, err = conn.Write(bytes)
|
|
|
|
if err == io.EOF {
|
|
|
|
log.Panic("Server disconnected sorry...")
|
|
|
|
} else if err != nil {
|
|
|
|
log.Panic("Error reading from server connection...")
|
|
|
|
}
|
2024-09-26 19:49:59 -06:00
|
|
|
if msg.MessageType == "start_game" || msg.MessageType == "disconnect" {
|
|
|
|
slog.Debug("closing network writer ")
|
|
|
|
return
|
|
|
|
}
|
2024-08-15 20:08:23 -06:00
|
|
|
}
|
|
|
|
}(egress)
|
|
|
|
|
|
|
|
// Network reader
|
2024-09-26 19:49:59 -06:00
|
|
|
go func(serverMessages chan lobby.LobbyMessage) {
|
2024-08-15 20:08:23 -06:00
|
|
|
buf := make([]byte, 1024)
|
|
|
|
for {
|
|
|
|
n, err := conn.Read(buf)
|
|
|
|
if err == io.EOF {
|
2024-09-26 19:49:59 -06:00
|
|
|
fmt.Println("disconnected from lobby")
|
2024-08-15 20:08:23 -06:00
|
|
|
} else if err != nil {
|
2024-08-23 11:59:19 -06:00
|
|
|
log.Panic("Error reading from server connection...", err)
|
2024-08-15 20:08:23 -06:00
|
|
|
}
|
|
|
|
|
2024-09-26 19:49:59 -06:00
|
|
|
message, err := lobby.Unmarshal(buf[:n])
|
2024-08-15 20:08:23 -06:00
|
|
|
if err != nil {
|
2024-09-26 19:49:59 -06:00
|
|
|
log.Panic("Error reading message from server", err)
|
2024-08-15 20:08:23 -06:00
|
|
|
}
|
|
|
|
serverMessages <- message
|
|
|
|
}
|
|
|
|
}(ingress)
|
2024-08-14 23:33:05 -06:00
|
|
|
|
2024-09-26 19:49:59 -06:00
|
|
|
fmt.Println("Waiting for an exit message")
|
|
|
|
isStartGame := <-exit
|
|
|
|
if isStartGame != "" {
|
|
|
|
fmt.Println("Connecting to game", isStartGame)
|
|
|
|
gameConn, err := ConnectToGame(username, isStartGame)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
log.Panic("Failed to connect to game server...", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
client.Game(gameConn)
|
|
|
|
|
|
|
|
} else {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func ConnectToLobby(username string) (net.Conn, error) {
|
|
|
|
conn, err := net.Dial("tcp", "127.0.0.1:12345")
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("Sorry, failed to connect to server...")
|
|
|
|
}
|
|
|
|
|
|
|
|
loginMsg, err := lobby.Marshal(lobby.LobbyMessage{MessageType: "name", Message: lobby.Name{Name: username}})
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("Sorry bro but your username is wack AF...")
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = conn.Write(loginMsg)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("Sorry, could not communicate with server...")
|
|
|
|
}
|
|
|
|
|
|
|
|
return conn, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func ConnectToGame(username, gameID string) (net.Conn, error) {
|
|
|
|
conn, err := net.Dial("tcp", "127.0.0.1:42069")
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = conn.Write([]byte(fmt.Sprintf("%s:%s", gameID, username)))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return conn, nil
|
2024-08-14 23:33:05 -06:00
|
|
|
}
|