getting somewhere with db and auth
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user