goonscape/network/network.go

122 lines
2.9 KiB
Go
Raw Permalink Normal View History

2025-01-13 11:10:48 +01:00
package network
2024-10-31 01:06:39 +01:00
import (
"log"
"net"
"time"
2025-01-13 13:23:52 +01:00
"gitea.boner.be/bdnugget/goonscape/game"
2025-01-13 11:10:48 +01:00
"gitea.boner.be/bdnugget/goonscape/types"
2024-10-31 01:06:39 +01:00
pb "gitea.boner.be/bdnugget/goonserver/actions"
"google.golang.org/protobuf/proto"
)
func ConnectToServer() (net.Conn, int32, error) {
2025-01-13 11:10:48 +01:00
conn, err := net.Dial("tcp", types.ServerAddr)
2024-10-31 01:06:39 +01:00
if err != nil {
log.Printf("Failed to dial server: %v", err)
return nil, 0, err
}
log.Println("Connected to server. Waiting for player ID...")
buf := make([]byte, 1024)
n, err := conn.Read(buf)
if err != nil {
log.Printf("Error reading player ID from server: %v", err)
return nil, 0, err
}
var response pb.ServerMessage
if err := proto.Unmarshal(buf[:n], &response); err != nil {
log.Printf("Failed to unmarshal server response: %v", err)
return nil, 0, err
}
playerID := response.GetPlayerId()
log.Printf("Successfully connected with player ID: %d", playerID)
return conn, playerID, nil
}
2025-01-13 11:10:48 +01:00
func HandleServerCommunication(conn net.Conn, playerID int32, player *types.Player, otherPlayers map[int32]*types.Player) {
2025-01-13 10:00:23 +01:00
buf := make([]byte, 4096)
2025-01-13 11:10:48 +01:00
actionTicker := time.NewTicker(types.ClientTickRate)
2025-01-13 10:00:23 +01:00
defer actionTicker.Stop()
2025-01-13 00:31:15 +01:00
2024-10-31 01:06:39 +01:00
go func() {
2025-01-13 10:00:23 +01:00
for range actionTicker.C {
player.Lock()
2024-10-31 01:06:39 +01:00
if len(player.ActionQueue) > 0 {
2025-01-13 10:00:23 +01:00
actions := make([]*pb.Action, len(player.ActionQueue))
2025-01-13 11:10:48 +01:00
copy(actions, player.ActionQueue)
2025-01-13 00:31:15 +01:00
batch := &pb.ActionBatch{
2024-10-31 01:06:39 +01:00
PlayerId: playerID,
2025-01-13 00:31:15 +01:00
Actions: actions,
Tick: player.CurrentTick,
2024-10-31 01:06:39 +01:00
}
2025-01-13 10:00:23 +01:00
player.ActionQueue = player.ActionQueue[:0]
player.Unlock()
2025-01-13 00:31:15 +01:00
data, err := proto.Marshal(batch)
2024-10-31 01:06:39 +01:00
if err != nil {
2025-01-13 00:31:15 +01:00
log.Printf("Failed to marshal action batch: %v", err)
2024-10-31 01:06:39 +01:00
continue
}
2025-01-13 10:00:23 +01:00
if _, err = conn.Write(data); err != nil {
2025-01-13 00:31:15 +01:00
log.Printf("Failed to send actions to server: %v", err)
2024-10-31 01:06:39 +01:00
return
}
2025-01-13 10:00:23 +01:00
} else {
player.Unlock()
2024-10-31 01:06:39 +01:00
}
}
}()
for {
n, err := conn.Read(buf)
if err != nil {
log.Printf("Failed to read from server: %v", err)
return
}
var serverMessage pb.ServerMessage
if err := proto.Unmarshal(buf[:n], &serverMessage); err != nil {
log.Printf("Failed to unmarshal server message: %v", err)
continue
}
2025-01-13 10:00:23 +01:00
player.Lock()
player.CurrentTick = serverMessage.CurrentTick
2025-01-13 00:31:15 +01:00
tickDiff := serverMessage.CurrentTick - player.CurrentTick
2025-01-13 11:10:48 +01:00
if tickDiff > types.MaxTickDesync {
2025-01-13 10:00:23 +01:00
for _, state := range serverMessage.Players {
if state.PlayerId == playerID {
player.ForceResync(state)
break
}
}
2025-01-13 00:31:15 +01:00
}
2025-01-13 10:00:23 +01:00
player.Unlock()
2025-01-13 00:31:15 +01:00
2024-10-31 01:06:39 +01:00
for _, state := range serverMessage.Players {
2025-01-13 10:00:23 +01:00
if state.PlayerId == playerID {
2025-01-13 11:10:48 +01:00
continue
2025-01-13 10:00:23 +01:00
}
if otherPlayer, exists := otherPlayers[state.PlayerId]; exists {
2025-01-13 11:10:48 +01:00
otherPlayer.UpdatePosition(state, types.ServerTickRate)
2025-01-13 10:00:23 +01:00
} else {
2025-01-13 11:10:48 +01:00
otherPlayers[state.PlayerId] = types.NewPlayer(state)
2024-10-31 01:06:39 +01:00
}
}
2025-01-13 13:23:52 +01:00
if g, ok := player.UserData.(*game.Game); ok && len(serverMessage.ChatMessages) > 0 {
g.Chat.HandleServerMessages(serverMessage.ChatMessages)
}
2024-10-31 01:06:39 +01:00
}
}