sshpong/cmd/client/main.go

203 lines
4.1 KiB
Go
Raw Permalink Normal View History

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-10-03 22:41:33 -06:00
"sshpong/internal/config"
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-10-03 22:41:33 -06:00
if len(os.Args) == 1 {
config.LoadConfig("")
} else {
config.LoadConfig(os.Args[1])
}
slog.SetLogLoggerLevel(slog.Level(config.Config.LogLevel))
2024-09-26 19:49:59 -06:00
2024-08-14 23:33:05 -06:00
fmt.Println("Welcome to sshpong!")
2024-09-28 23:26:06 -06:00
egress := make(chan []byte)
ingress := make(chan []byte)
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-10-03 22:41:33 -06:00
var usernameOk = false
// In the future make a DB call as well?
isUsernameOk := func(un string) bool {
if strings.Contains(un, ":") || len(strings.Split(un, " ")) > 1 || len(un) < 1 {
fmt.Println(client.Red, "Sorry, please pick a username that has no special characters or spaces.", client.Normal)
return false
}
return true
}
for !usernameOk {
fmt.Println("Please enter your username")
buf := make([]byte, 1024)
n, err := os.Stdin.Read(buf)
if err != nil {
log.Panic("Bro your input is no good...")
}
username = string(buf[:n-1])
usernameOk = isUsernameOk(username)
2024-08-14 23:33:05 -06:00
}
2024-09-26 19:49:59 -06:00
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-28 23:26:06 -06:00
go func() {
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-28 23:26:06 -06:00
userMessage := []byte{}
2024-08-24 16:09:12 -06:00
select {
case msg := <-interrupter:
2024-10-03 22:41:33 -06:00
if msg.InterruptType == "start_game" {
slog.Debug("closing input handler with start_game message and sending exit signal")
exit <- msg.Content
return
}
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
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-09-28 23:26:06 -06:00
}()
2024-08-14 23:33:05 -06:00
2024-08-15 20:08:23 -06:00
// Ingress Handler
2024-09-28 23:26:06 -06:00
go func() {
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...")
}
2024-10-03 22:41:33 -06:00
if interrupterMsg.InterruptType == "start_game" {
exit <- interrupterMsg.Content
}
2024-08-24 16:09:12 -06:00
if interrupterMsg.InterruptType != "" {
interrupter <- interrupterMsg
}
2024-08-15 20:08:23 -06:00
}
2024-09-28 23:26:06 -06:00
}()
2024-08-15 20:08:23 -06:00
// Network writer
2024-09-28 23:26:06 -06:00
go func() {
2024-08-15 20:08:23 -06:00
for {
2024-09-28 23:26:06 -06:00
msg := <-egress
slog.Debug("writing egress message to server", "message", msg)
_, err = conn.Write(msg)
2024-08-15 20:08:23 -06:00
if err == io.EOF {
2024-09-28 23:26:06 -06:00
log.Panic("Server disconnected, sorry...")
2024-08-15 20:08:23 -06:00
}
}
2024-09-28 23:26:06 -06:00
}()
2024-08-15 20:08:23 -06:00
// Network reader
2024-09-28 23:26:06 -06:00
go func() {
2024-08-15 20:08:23 -06:00
buf := make([]byte, 1024)
for {
n, err := conn.Read(buf)
if err == io.EOF {
2024-09-28 23:26:06 -06:00
log.Panic("disconnected from lobby")
2024-08-15 20:08:23 -06:00
}
2024-09-28 23:26:06 -06:00
ingress <- buf[:n]
2024-08-15 20:08:23 -06:00
}
2024-09-28 23:26:06 -06:00
}()
2024-08-14 23:33:05 -06:00
2024-09-26 19:49:59 -06:00
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) {
2024-10-03 22:41:33 -06:00
slog.Debug("connecting to server...")
2024-09-26 19:49:59 -06:00
conn, err := net.Dial("tcp", "127.0.0.1:12345")
if err != nil {
return nil, fmt.Errorf("Sorry, failed to connect to server...")
}
2024-09-28 23:26:06 -06:00
loginMsg, err := lobby.Marshal(lobby.NameData{Name: username}, lobby.Name)
2024-09-26 19:49:59 -06:00
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
}