Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
                }
            }
        }