internal void ResendUnoccupiedPacket(VehicleData fullPacket, Client exception) { if (fullPacket.NetHandle == null) { return; } var vehicleEntity = new NetHandle(fullPacket.NetHandle.Value); var full = PacketOptimization.WriteUnOccupiedVehicleSync(fullPacket); var basic = PacketOptimization.WriteBasicUnOccupiedVehicleSync(fullPacket); var msgNear = Server.CreateMessage(); msgNear.Write((byte)PacketType.UnoccupiedVehSync); msgNear.Write(full.Length); msgNear.Write(full); var msgFar = Server.CreateMessage(); msgFar.Write((byte)PacketType.BasicUnoccupiedVehSync); msgFar.Write(basic.Length); msgFar.Write(basic); List <NetConnection> connectionsNear = new List <NetConnection>(); List <NetConnection> connectionsFar = new List <NetConnection>(); foreach (var client in exception.Streamer.GetNearClients()) { // skip sending a sync packet for a trailer to it's owner. if (CheckUnoccupiedTrailerDriver(client, vehicleEntity)) { continue; } if (client.NetConnection.Status == NetConnectionStatus.Disconnected) { continue; } if (client.NetConnection.RemoteUniqueIdentifier == exception.NetConnection.RemoteUniqueIdentifier) { continue; } if (client.Position == null) { continue; } if (client.Position.DistanceToSquared(fullPacket.Position) < 20000) { connectionsNear.Add(client.NetConnection); } else { connectionsFar.Add(client.NetConnection); } } Server.SendMessage(msgNear, connectionsNear, NetDeliveryMethod.UnreliableSequenced, (int)ConnectionChannel.UnoccupiedVeh); foreach (var client in exception.Streamer.GetFarClients()) { connectionsFar.Add(client.NetConnection); } Server.SendMessage(msgFar, connectionsFar, NetDeliveryMethod.UnreliableSequenced, (int)ConnectionChannel.UnoccupiedVeh); }
internal void Pulse() { if (Util.Util.TickCount - _lastUpdate > UNOCCUPIED_VEH_RATE) { _lastUpdate = Util.Util.TickCount; if (SyncedVehicles.Count > 0) { var vehicleCount = 0; var buffer = new List <byte>(); lock (SyncedVehicles) { foreach (var vehicle in SyncedVehicles) { var ent = Main.NetEntityHandler.NetToEntity(vehicle); if (ent == null || !vehicle.StreamedIn) { continue; } var dist = ent.Model.IsBoat ? ent.Position.DistanceToSquared2D(vehicle.Position.ToVector()) : ent.Position.DistanceToSquared(vehicle.Position.ToVector()); var veh = new Vehicle(ent.Handle); byte BrokenDoors = 0; byte BrokenWindows = 0; for (var i = 0; i < 8; i++) { if (veh.Doors[(VehicleDoorIndex)i].IsBroken) { BrokenDoors |= (byte)(1 << i); } if (!veh.Windows[(VehicleWindowIndex)i].IsIntact) { BrokenWindows |= (byte)(1 << i); } } var syncUnocVeh = dist > 2f || ent.Rotation.DistanceToSquared(vehicle.Rotation.ToVector()) > 2f || Math.Abs(new Vehicle(ent.Handle).EngineHealth - vehicle.Health) > 1f || Util.Util.BuildTyreFlag(new Vehicle(ent.Handle)) != vehicle.Tires || vehicle.DamageModel == null || vehicle.DamageModel.BrokenWindows != BrokenWindows || vehicle.DamageModel.BrokenDoors != BrokenDoors; if (!syncUnocVeh) { continue; } { vehicle.Position = ent.Position.ToLVector(); vehicle.Rotation = ent.Rotation.ToLVector(); vehicle.Health = veh.EngineHealth; vehicle.Tires = (byte)Util.Util.BuildTyreFlag(veh); if (vehicle.DamageModel == null) { vehicle.DamageModel = new VehicleDamageModel(); } vehicle.DamageModel.BrokenWindows = BrokenWindows; vehicle.DamageModel.BrokenDoors = BrokenDoors; var data = new VehicleData { VehicleHandle = vehicle.RemoteHandle, Position = vehicle.Position, Quaternion = vehicle.Rotation, Velocity = ent.Velocity.ToLVector(), VehicleHealth = vehicle.Health, DamageModel = new VehicleDamageModel() { BrokenWindows = BrokenWindows, BrokenDoors = BrokenDoors, } }; if (ent.IsDead) { data.Flag = (short)VehicleDataFlags.VehicleDead; } else { data.Flag = 0; } byte tyreFlag = 0; for (int i = 0; i < 8; i++) { if (veh.IsTireBurst(i)) { tyreFlag |= (byte)(1 << i); } } data.PlayerHealth = tyreFlag; var bin = PacketOptimization.WriteUnOccupiedVehicleSync(data); buffer.AddRange(bin); vehicleCount++; } } } if (vehicleCount > 0) { buffer.Insert(0, (byte)vehicleCount); var msg = Main.Client.CreateMessage(); msg.Write((byte)PacketType.UnoccupiedVehSync); msg.Write(buffer.Count); msg.Write(buffer.ToArray()); Main.Client.SendMessage(msg, NetDeliveryMethod.Unreliable, (int)ConnectionChannel.UnoccupiedVeh); Main._bytesSent += buffer.Count; Main._messagesSent++; } } } for (int i = 0; i < Interpolations.Count; i++) { var pair = Interpolations.ElementAt(i); pair.Value.Pulse(); if (pair.Value.HasFinished) { Interpolations.Remove(pair.Key); } } }