sshpong/internal/netwrk/netwrk.go

188 lines
3.6 KiB
Go
Raw Normal View History

2024-08-02 13:04:41 -06:00
package netwrk
import (
2024-08-05 18:00:41 -06:00
"bufio"
2024-08-02 13:04:41 -06:00
"fmt"
"log"
"net"
"time"
"github.com/google/uuid"
)
type Client struct {
name string
conn net.Conn
}
type ClientPool struct {
clients map[string]Client
}
type GameClients struct {
client1 Client
client2 Client
}
type GameConnections struct {
games map[string]GameClients
}
var clientPool *ClientPool
var gameConnections *GameConnections
2024-08-05 18:00:41 -06:00
// Starts listening on port 12345 for TCP connections
// Also creates client pool and game connection singletons
2024-08-02 13:04:41 -06:00
func Listen() {
clientPool = &ClientPool{
clients: map[string]Client{},
}
gameConnections = &GameConnections{
games: map[string]GameClients{},
}
listener, err := net.Listen("tcp", ":12345")
if err != nil {
log.Fatal(err)
}
defer listener.Close()
go func() {
for {
conn, err := listener.Accept()
if err != nil {
log.Println(err)
continue
}
name := make([]byte, 1024)
n, err := conn.Read(name)
if err != nil {
log.Println(fmt.Sprintf("Failed to read from connection: %s", conn.LocalAddr()))
} else {
clientPool.clients[uuid.New().String()] = Client{
name: string(name[:n]),
conn: conn,
}
}
}
}()
}
2024-08-05 18:00:41 -06:00
func handleLobbyConnection(connID string, conn net.Conn) {
defer conn.Close()
reader := bufio.NewReader(conn)
for {
message, err := reader.ReadString('\n')
if err != nil {
log.Printf("Error reading message %v", err)
delete(clientPool.clients, connID)
return
}
handleLobbyMessage(message, conn)
}
}
func handleLobbyMessage(message string, conn net.Conn) {
key, data := decodeMessage(message)
switch message {
case "start":
break
case "waiting":
break
default:
clientPool.clients[message]
}
}
func decodeLobbyMessage(message string) (string, any) {
switch message {
case "start":
return "start", nil
case "waiting":
return "waiting", nil
default:
break
}
strings
}
}
2024-08-02 13:04:41 -06:00
func GetPool() (map[string]Client, bool) {
if clientPool.clients != nil {
return clientPool.clients, true
}
return clientPool.clients, false
}
func CreateGame(clientID1, clientID2 string) (string, error) {
client1, ok := clientPool.clients[clientID1]
if !ok {
return "", fmt.Errorf("Client 1 was not found in client pool :(")
}
if err := client1.conn.SetWriteDeadline(time.Time{}); err != nil {
return "", fmt.Errorf("Client 1 was not responsive")
}
client2, ok := clientPool.clients[clientID2]
if !ok {
return "", fmt.Errorf("Client 2 was not found in client pool :(")
}
if err := client2.conn.SetWriteDeadline(time.Time{}); err != nil {
return "", fmt.Errorf("Client 2 was not responsive")
}
gameID := uuid.New().String()
gameConnections.games[gameID] = GameClients{
client1: client1,
client2: client2,
}
return gameID, nil
}
func SendGameUpdateToClients(gameID string, bytes []byte) error {
clients, ok := gameConnections.games[gameID]
if !ok {
return fmt.Errorf("Could not find game clients record")
}
_, err := clients.client1.conn.Write(bytes)
if err != nil {
return fmt.Errorf("Could not write to client1 connection")
}
_, err = clients.client1.conn.Write(bytes)
if err != nil {
return fmt.Errorf("Could not write to client2 connection")
}
return nil
}
func PingAndCleanLobbyClients() {
ping := []byte("ping")
deadClients := []string{}
for id, client := range clientPool.clients {
client.conn.SetWriteDeadline(time.Now().Add(time.Second))
_, err := client.conn.Write(ping)
if err != nil {
log.Println("Could not write to client, deleting connection:", id)
deadClients = append(deadClients, id)
}
}
for _, id := range deadClients {
delete(clientPool.clients, id)
}
}