getting somewhere with db and auth

This commit is contained in:
2025-01-19 21:17:07 +01:00
parent be32dec202
commit 52ab45fe53
7 changed files with 326 additions and 69 deletions
+107 -31
View File
@@ -11,6 +11,7 @@ import (
"time"
pb "gitea.boner.be/bdnugget/goonserver/actions"
"gitea.boner.be/bdnugget/goonserver/db"
"google.golang.org/protobuf/proto"
)
@@ -27,15 +28,20 @@ type Player struct {
}
var (
players = make(map[int]*Player)
actionQueue = make(map[int][]*pb.Action) // Queue to store actions for each player
playerConns = make(map[int]net.Conn) // Map to store player connections
mu sync.RWMutex // Add mutex for protecting shared maps
chatHistory = make([]*pb.ChatMessage, 0, 100)
chatMutex sync.RWMutex
players = make(map[int]*Player)
actionQueue = make(map[int][]*pb.Action) // Queue to store actions for each player
playerConns = make(map[int]net.Conn) // Map to store player connections
mu sync.RWMutex // Add mutex for protecting shared maps
chatHistory = make([]*pb.ChatMessage, 0, 100)
chatMutex sync.RWMutex
nextPlayerID = 1 // Assuming player IDs start from 1
)
func main() {
if err := db.InitDB("goonserver.db"); err != nil {
log.Fatalf("Failed to initialize database: %v", err)
}
ln, err := net.Listen("tcp", port)
if err != nil {
log.Fatalf("Failed to listen on port %s: %v", port, err)
@@ -68,34 +74,110 @@ func main() {
func handleConnection(conn net.Conn) {
defer conn.Close()
mu.Lock()
playerID := len(players) + 1
newPlayer := &Player{ID: playerID, X: 5, Y: 5}
players[playerID] = newPlayer
playerConns[playerID] = conn
mu.Unlock()
fmt.Printf("Player %d connected\n", playerID)
// Read initial message for player ID
reader := bufio.NewReader(conn)
// Send player ID to the client
serverMsg := &pb.ServerMessage{
PlayerId: int32(playerID),
CurrentTick: 0,
// Wait for authentication
lengthBuf := make([]byte, 4)
if _, err := io.ReadFull(reader, lengthBuf); err != nil {
log.Printf("Failed to read auth message length: %v", err)
return
}
if err := writeMessage(conn, serverMsg); err != nil {
log.Printf("Failed to send player ID to player %d: %v", playerID, err)
messageLength := binary.BigEndian.Uint32(lengthBuf)
messageBuf := make([]byte, messageLength)
if _, err := io.ReadFull(reader, messageBuf); err != nil {
log.Printf("Failed to read auth message: %v", err)
return
}
batch := &pb.ActionBatch{}
if err := proto.Unmarshal(messageBuf, batch); err != nil {
log.Printf("Failed to unmarshal auth message: %v", err)
return
}
if len(batch.Actions) == 0 {
log.Printf("No auth action received")
return
}
action := batch.Actions[0]
var playerID int
var authErr error
switch action.Type {
case pb.Action_REGISTER:
playerID, authErr = db.RegisterPlayer(action.Username, action.Password)
case pb.Action_LOGIN:
playerID, authErr = db.AuthenticatePlayer(action.Username, action.Password)
default:
log.Printf("Invalid initial action type: %v", action.Type)
return
}
// Send auth response
response := &pb.ServerMessage{
PlayerId: int32(playerID),
AuthSuccess: authErr == nil,
}
if authErr != nil {
response.ErrorMessage = authErr.Error()
if err := writeMessage(conn, response); err != nil {
log.Printf("Failed to send auth response: %v", err)
}
return
}
// Load last known position
x, y, err := db.LoadPlayerState(playerID)
if err != nil {
log.Printf("Error loading state for player %d: %v", playerID, err)
x, y = 5, 5 // Default position
}
player := &Player{
ID: playerID,
X: x,
Y: y,
}
mu.Lock()
players[playerID] = player
playerConns[playerID] = conn
mu.Unlock()
// Ensure player state is saved on any kind of disconnect
defer func() {
if err := db.SavePlayerState(playerID, player.X, player.Y); err != nil {
log.Printf("Error saving state for player %d: %v", playerID, err)
}
mu.Lock()
delete(players, playerID)
delete(playerConns, playerID)
delete(actionQueue, playerID)
mu.Unlock()
log.Printf("Player %d disconnected", playerID)
}()
// Send player ID to client
if err := writeMessage(conn, response); err != nil {
log.Printf("Failed to send player ID: %v", err)
return
}
fmt.Printf("Player %d connected\n", playerID)
// Listen for incoming actions from this player
reader := bufio.NewReader(conn)
for {
// Read message length
lengthBuf := make([]byte, 4)
if _, err := io.ReadFull(reader, lengthBuf); err != nil {
log.Printf("Error reading message length from player %d: %v", playerID, err)
delete(players, playerID)
delete(playerConns, playerID)
delete(actionQueue, playerID)
if err == io.EOF {
log.Printf("Player %d disconnected gracefully", playerID)
} else {
log.Printf("Error reading message length from player %d: %v", playerID, err)
}
return
}
messageLength := binary.BigEndian.Uint32(lengthBuf)
@@ -104,9 +186,6 @@ func handleConnection(conn net.Conn) {
messageBuf := make([]byte, messageLength)
if _, err := io.ReadFull(reader, messageBuf); err != nil {
log.Printf("Error reading message from player %d: %v", playerID, err)
delete(players, playerID)
delete(playerConns, playerID)
delete(actionQueue, playerID)
return
}
@@ -120,10 +199,7 @@ func handleConnection(conn net.Conn) {
if batch.PlayerId == int32(playerID) {
for _, action := range batch.Actions {
if action.Type == pb.Action_DISCONNECT {
log.Printf("Player %d disconnected gracefully", playerID)
delete(players, playerID)
delete(playerConns, playerID)
delete(actionQueue, playerID)
log.Printf("Player %d requested disconnect", playerID)
return
}
}