make server authoritative on time of day
This commit is contained in:
parent
aec43c0bcf
commit
c39715b84c
@ -228,8 +228,13 @@ private:
|
||||
return;
|
||||
}
|
||||
|
||||
// Update sky
|
||||
// Update sky with server time if connected, otherwise use local time
|
||||
if (network.isConnected()) {
|
||||
float serverTime = network.getServerTimeOfDay();
|
||||
sky->updateFromServerTime(serverTime);
|
||||
} else {
|
||||
sky->update(GetFrameTime());
|
||||
}
|
||||
|
||||
// Time of day controls (for testing)
|
||||
if (IsKeyPressed(KEY_T)) {
|
||||
|
||||
@ -56,11 +56,24 @@ void NetworkManager::processMessage(const uint8_t* data, std::size_t size) {
|
||||
case MessageType::LoginResponse:
|
||||
handleLoginResponse(data, size);
|
||||
break;
|
||||
case MessageType::TimeSync:
|
||||
handleTimeSync(data, size);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkManager::handleTimeSync(const uint8_t* data, std::size_t size) {
|
||||
// Message format: [type(1)][timeOfDay(4)]
|
||||
if (size < 5) return;
|
||||
|
||||
float timeOfDay;
|
||||
std::memcpy(&timeOfDay, &data[1], sizeof(timeOfDay));
|
||||
|
||||
serverTimeOfDay.store(timeOfDay);
|
||||
}
|
||||
|
||||
void NetworkManager::handleSpawn(const uint8_t* data, std::size_t size) {
|
||||
// Message format: [type(1)][id(4)][x(4)][y(4)][z(4)][colorLen(1)][color(colorLen)]
|
||||
if (size < 18) return;
|
||||
|
||||
@ -25,7 +25,8 @@ enum class MessageType : uint8_t {
|
||||
ColorChanged = 0x0A,
|
||||
LoginResponse = 0x0B,
|
||||
Logout = 0x0C,
|
||||
Heartbeat = 0x0D
|
||||
Heartbeat = 0x0D,
|
||||
TimeSync = 0x0E
|
||||
};
|
||||
|
||||
struct RemotePlayer {
|
||||
@ -55,6 +56,7 @@ public:
|
||||
std::string getPlayerColor() const { return playerColor; }
|
||||
|
||||
std::unordered_map<uint32_t, RemotePlayer> getRemotePlayers();
|
||||
float getServerTimeOfDay() const { return serverTimeOfDay.load(); }
|
||||
|
||||
// Available colors for cycling
|
||||
static const std::vector<std::string> AVAILABLE_COLORS;
|
||||
@ -76,6 +78,7 @@ private:
|
||||
|
||||
std::mutex remotePlayersMutex;
|
||||
std::unordered_map<uint32_t, RemotePlayer> remotePlayers;
|
||||
std::atomic<float> serverTimeOfDay{0.0f};
|
||||
|
||||
void startReceive();
|
||||
void processMessage(const uint8_t* data, std::size_t size);
|
||||
@ -86,4 +89,5 @@ private:
|
||||
void handlePlayerList(const uint8_t* data, std::size_t size);
|
||||
void handleColorChanged(const uint8_t* data, std::size_t size);
|
||||
void handleLoginResponse(const uint8_t* data, std::size_t size);
|
||||
void handleTimeSync(const uint8_t* data, std::size_t size);
|
||||
};
|
||||
|
||||
@ -75,6 +75,13 @@ void Sky::update(float) {
|
||||
moon.updatePosition(timeOfDay);
|
||||
}
|
||||
|
||||
void Sky::updateFromServerTime(float serverTimeOfDay) {
|
||||
timeOfDay = serverTimeOfDay;
|
||||
updateColors();
|
||||
sun.updatePosition(timeOfDay);
|
||||
moon.updatePosition(timeOfDay);
|
||||
}
|
||||
|
||||
void Sky::Sun::updatePosition(float timeOfDay) {
|
||||
// Convert time of day to angle (0.25 = sunrise at 6am, 0.75 = sunset at 6pm)
|
||||
// Adjust so that 0.25 (6am) = 0 degrees, 0.75 (6pm) = 180 degrees
|
||||
|
||||
@ -57,6 +57,7 @@ public:
|
||||
~Sky();
|
||||
|
||||
void update(float deltaTime);
|
||||
void updateFromServerTime(float serverTimeOfDay);
|
||||
void render(const Camera3D& camera);
|
||||
void renderSkybox(const Camera3D& camera); // Render skybox that follows camera
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ const (
|
||||
MSG_LOGIN_RESPONSE = 0x0B
|
||||
MSG_LOGOUT = 0x0C
|
||||
MSG_HEARTBEAT = 0x0D
|
||||
MSG_TIME_SYNC = 0x0E
|
||||
)
|
||||
|
||||
// Vec3 represents a 3D vector
|
||||
@ -195,3 +196,11 @@ func DecodeHeartbeatPacket(data []byte) (playerID uint32, ok bool) {
|
||||
playerID = binary.LittleEndian.Uint32(data[1:5])
|
||||
return playerID, true
|
||||
}
|
||||
|
||||
// EncodeTimeSyncPacket creates a time sync packet
|
||||
func EncodeTimeSyncPacket(timeOfDay float32) []byte {
|
||||
msg := make([]byte, 5)
|
||||
msg[0] = MSG_TIME_SYNC
|
||||
binary.LittleEndian.PutUint32(msg[1:5], math.Float32bits(timeOfDay))
|
||||
return msg
|
||||
}
|
||||
@ -40,6 +40,8 @@ type Server struct {
|
||||
heightmap [][]float32
|
||||
mutex sync.RWMutex
|
||||
nextID uint32
|
||||
timeOfDay float32
|
||||
startTime time.Time
|
||||
}
|
||||
|
||||
// NewServer creates a new game server
|
||||
@ -61,6 +63,8 @@ func NewServer(port string, heightmap [][]float32) (*Server, error) {
|
||||
userData: make(map[string]*UserData),
|
||||
heightmap: heightmap,
|
||||
nextID: 0,
|
||||
timeOfDay: 0.0,
|
||||
startTime: time.Now(),
|
||||
}
|
||||
|
||||
server.loadUserData()
|
||||
@ -90,6 +94,15 @@ func (s *Server) Run() error {
|
||||
}
|
||||
}()
|
||||
|
||||
// Start time of day updater and broadcaster
|
||||
go func() {
|
||||
ticker := time.NewTicker(100 * time.Millisecond) // Update time 10 times per second
|
||||
defer ticker.Stop()
|
||||
for range ticker.C {
|
||||
s.updateAndBroadcastTime()
|
||||
}
|
||||
}()
|
||||
|
||||
buffer := make([]byte, 1024)
|
||||
log.Println("Server running...")
|
||||
|
||||
@ -121,6 +134,29 @@ func (s *Server) Run() error {
|
||||
}
|
||||
}
|
||||
|
||||
// updateAndBroadcastTime updates the server time and broadcasts it to all clients
|
||||
func (s *Server) updateAndBroadcastTime() {
|
||||
// Calculate elapsed time since server start
|
||||
elapsed := time.Since(s.startTime).Seconds()
|
||||
|
||||
// Day cycle duration in seconds (e.g., 10 minutes = 600 seconds)
|
||||
dayDuration := 600.0
|
||||
|
||||
// Calculate time of day (0.0 to 1.0, where 0.5 is noon)
|
||||
s.timeOfDay = float32(math.Mod(elapsed/dayDuration, 1.0))
|
||||
|
||||
// Broadcast to all connected players
|
||||
msg := EncodeTimeSyncPacket(s.timeOfDay)
|
||||
|
||||
s.mutex.RLock()
|
||||
for _, p := range s.players {
|
||||
if p.Address != nil {
|
||||
s.conn.WriteToUDP(msg, p.Address)
|
||||
}
|
||||
}
|
||||
s.mutex.RUnlock()
|
||||
}
|
||||
|
||||
func (s *Server) handleLogin(data []byte, addr *net.UDPAddr) {
|
||||
username, ok := DecodeLoginPacket(data)
|
||||
if !ok || username == "" {
|
||||
@ -203,6 +239,10 @@ func (s *Server) handleLogin(data []byte, addr *net.UDPAddr) {
|
||||
s.conn.WriteToUDP(listMsg, addr)
|
||||
}
|
||||
|
||||
// Send current time of day to new player
|
||||
timeMsg := EncodeTimeSyncPacket(s.timeOfDay)
|
||||
s.conn.WriteToUDP(timeMsg, addr)
|
||||
|
||||
// Notify other players about new player
|
||||
s.broadcastPlayerJoined(player)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user