Example #1
0
        protected override void OnNewSession(MsgSessionInfo msg)
        {
            PluginManager.EnableRealtimeReport(100);
            PluginManager.Log("===============================");
            PluginManager.Log("===============================");
            PluginManager.Log("OnNewSession: " + msg.Name + "@" + msg.ServerName);
            PluginManager.Log("===============================");
            PluginManager.Log("===============================");

            var server_config_ini = GatherServerConfigIni();
            var trackId           = msg.Track + "[" + msg.TrackConfig + "]";

            MRBackend.NewSessionWithConfigAsync(msg.ServerName, trackId
                                                , msg.SessionType, msg.Laps, msg.WaitTime, msg.SessionDuration, msg.AmbientTemp, msg.RoadTemp, msg.ElapsedMS
                                                , TrustToken, _fingerprint, PluginVersion, -1, -1, -1, server_config_ini);

            var maxDrivers = TryParseMaxDrivers(server_config_ini);

            PluginManager.Log($"Max drivers: {maxDrivers}");

            for (byte i = 0; i < maxDrivers; i++)
            {
                PluginManager.RequestCarInfo(i);
            }

            CurrentSessionStartTime = msg.CreationDate.AddMilliseconds(msg.ElapsedMS * -1);

            _distancesToReport.Clear();

            if (trackId != CurrentTrackDefinition?.TrackName)
            {
                ReloadTrackDefinition(trackId);
            }
        }
Example #2
0
        protected override void OnCollision(MsgClientEvent msg)
        {
            // Contact handling is now done by the backend completely - that is we just report any
            // collision with another car
            if (msg.Subtype == (byte)ACSProtocol.MessageType.ACSP_CE_COLLISION_WITH_CAR)
            {
                DriverInfo driver = null;
                if (!PluginManager.TryGetDriverInfo(Convert.ToByte(msg.CarId), out driver))
                {
                    throw new Exception("Driver not found: " + msg.CarId);
                }

                DriverInfo otherDriver = null;
                if (!PluginManager.TryGetDriverInfo(Convert.ToByte(msg.OtherCarId), out otherDriver))
                {
                    throw new Exception("(Other) Driver not found: " + msg.OtherCarId);
                }

                var driversCache      = GetDriversCache(driver, 980);
                var otherDriversCache = GetDriversCache(otherDriver, 980);

                var driversDistance = _distancesToReport[driver];
                _distancesToReport[driver] = new MRDistanceHelper();

                TrySendDistance(driver, true);
                MRBackend.CollisionAsyncV22(msg.CreationDate, msg.CarId, msg.OtherCarId, msg.RelativeVelocity, driver.LastSplinePosition, msg.RelativePosition.X, msg.RelativePosition.Z, msg.WorldPosition.X, msg.WorldPosition.Z, driversCache.ToArray(), otherDriversCache.ToArray(), driversDistance);
            }
        }
Example #3
0
        private void TrySendDistance(DriverInfo di, bool forced = false)
        {
            if (!_distancesToReport.ContainsKey(di))
            {
                _distancesToReport.Add(di, new MRDistanceHelper());
            }

            // New approach: We'll send the distance set as soon as a driver crosses a TrackDefinition.Split
            #region legacy approach: fixed distance
            if (CurrentTrackDefinition == null || CurrentTrackDefinition.Splits == null)
            {
                var distanceCached = _distancesToReport[di];
                // Then we'll do it in different resolutions; the first meters are more important than the later ones
                if (di.Distance > REGULAR_DISTANCE && distanceCached.MetersDriven > 2000 || forced) // After 2km, we'll just report in big chunks - or if forced
                {
                    MRBackend.DistanceDrivenAsync(di.CarId, distanceCached);
                    _distancesToReport[di] = new MRDistanceHelper();
                }
                else if (di.Distance < REGULAR_DISTANCE && distanceCached.MetersDriven > 200) // 200m is about "left pits", so we'll report this until
                {
                    MRBackend.DistanceDrivenAsync(di.CarId, distanceCached);
                    _distancesToReport[di] = new MRDistanceHelper();
                }
            }
            #endregion
            else
            {
                try
                {
                    if (di.LastCarUpdate != null && di.LastCarUpdate.List.Count > 1)
                    {
                        var lastPos = di.LastCarUpdate.Previous.Value;
                        var thisPos = di.LastCarUpdate.Value;

                        foreach (var split in CurrentTrackDefinition.Splits)
                        {
                            if (lastPos.NormalizedSplinePosition < split && thisPos.NormalizedSplinePosition > split)
                            {
                                // Gotcha!
                                var distanceCached = _distancesToReport[di];
                                _distancesToReport[di] = new MRDistanceHelper();

                                distanceCached.SplinePosCurrent     = thisPos.NormalizedSplinePosition;
                                distanceCached.SplinePosTimeCurrent = Convert.ToInt32(thisPos.CreationDate.Subtract(di.CurrentLapStart).TotalMilliseconds);
                                distanceCached.SplinePosLast        = lastPos.NormalizedSplinePosition;
                                distanceCached.SplinePosTimeLast    = Convert.ToInt32(lastPos.CreationDate.Subtract(di.CurrentLapStart).TotalMilliseconds);
                                MRBackend.DistanceDrivenAsync(di.CarId, distanceCached);
                                break;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    PluginManager.Log(ex);
                }
            }
        }
Example #4
0
        protected override void OnCarInfo(MsgCarInfo msg)
        {
            PluginManager.Log(DateTime.Now.TimeOfDay.ToString() + "- CarInfo: " + msg.CarId + ", " + msg.DriverName + "@" + msg.CarModel + ", Connected=" + msg.IsConnected);

            // To prevent a bug in communication we will only send when the Car IsConnected - discos only via the corresponding event please.
            if (msg.IsConnected)
            {
                MRBackend.RandomCarInfoAsync(msg.CarId, msg.CarModel, msg.DriverName, msg.DriverGuid, msg.IsConnected, GetCurrentRaceTimeMS(msg));
            }
        }
Example #5
0
        protected override void OnLapCompleted(MsgLapCompleted msg)
        {
            DriverInfo driver;

            if (!PluginManager.TryGetDriverInfo(msg.CarId, out driver))
            {
                PluginManager.Log("Error; car_id " + msg.CarId + " was not known by the PluginManager :(");
            }
            else
            {
                driver.IsOnOutlap = false;
                TrySendDistance(driver, true);
                MRBackend.LapCompletedAsync(msg.CreationDate, msg.CarId, driver.DriverGuid, msg.Laptime, msg.Cuts, msg.GripLevel, ConvertLB(msg.Leaderboard));
            }
        }
Example #6
0
        private void ReloadTrackDefinition(string trackId = null)
        {
            if (trackId == null)
            {
                trackId = CurrentTrackDefinition?.TrackName;
            }

            if (trackId != null)
            {
                CurrentTrackDefinition = MRBackend.GetTrackDefinition(trackId);
                CreatePitExitRectangle();
                PluginManager.Log($"Pit exit rectangle created: {PitExitRectangle}");
                PluginManager.Log($"Track Lines parsed: {CurrentTrackDefinition?.Lines?.Length ?? 0}");
            }
        }
Example #7
0
 protected override void OnAcServerAlive()
 {
     MRBackend.SendAlive(GetConnectedDriversHash());
 }
Example #8
0
        protected override void OnCarUpdate(DriverInfo di)
        {
            #region Distance
            if (!_distancesToReport.ContainsKey(di))
            {
                _distancesToReport.Add(di, new MRDistanceHelper());
            }

            var dh = _distancesToReport[di];
            // Generally, the meters driven are stored
            dh.MetersDriven += di.LastDistanceTraveled;

            // To protect this from some simple 1st gear driving together in combat range to grind stuff, we'll only allow Attack & Combat range
            // recording if there is acceleration. 3 or 5 are quite little values, even for slow cars like the GT86
            if (Math.Abs(di.CurrentAcceleration) > 2.0f && di.CurrentDistanceToClosestCar != 0)
            {
                // Then we'll check this interval (we're talking about a second or similar)
                // for driving in attack range (let's say.. inside 20m) or even combating (maybe 8m)
                if (di.CurrentDistanceToClosestCar < 8)
                {
                    dh.MetersCombatRange += di.LastDistanceTraveled;
                }
                else if (di.CurrentDistanceToClosestCar < 20)
                {
                    dh.MetersAttackRange += di.LastDistanceTraveled;
                }
            }
            #endregion

            #region Outlap detection

            if (!di.IsOnOutlap && PitExitRectangle.HasValue)
            {
                di.IsOnOutlap = PitExitRectangle.Value.Contains(new System.Windows.Point(di.LastPosition.X, di.LastPosition.Z));
                if (di.IsOnOutlap)
                {
                    MRBackend.DriverBackToPitsAsync(di.CarId, DateTime.Now);
                }
            }

            #endregion

            #region teleported to pits detection

            if (TeleportedToPits(di))
            {
                // Special trick: If we assume a teleport, we set the outlap to false
                // so the outlap detection above can trigger again
                di.IsOnOutlap = false;
            }

            #endregion

            #region Line crossing

            try
            {
                if (CurrentTrackDefinition?.Lines != null && di.LastCarUpdate?.Previous != null)
                {
                    // For performance we'll just calc the lines that are between the corresponding SplinePosition frame
                    foreach (var l in CurrentTrackDefinition.Lines.Where(x => x.FromSpline <= di.LastSplinePosition && x.ToSpline >= di.LastSplinePosition))
                    {
                        var isIntersecting = IsIntersecting(l, di.LastCarUpdate);
                        //PluginManager.BroadcastChatMessage($"{l.LineId}: {isIntersecting}");

                        // We are between the focus zone for this (l)ine. Did we cross it?
                        if (isIntersecting)
                        {
                            // That's worth a message to the backend then!
                            // Just need the min and max velocity of the latest entries
                            var driversCache      = GetDriversCache(di, 98);
                            var driversVelocities = driversCache.Select(x => new Vector3f(x.Velocity[0], 0, x.Velocity[1]).Length() * 3.6f);

                            var worldPositions = new List <float>();
                            foreach (var item in driversCache.Select(x => x.WorldPosition))
                            {
                                worldPositions.AddRange(item);
                            }

                            var distanceToNextCar = di.CurrentDistanceToClosestCar;
                            if (distanceToNextCar == 0) // = no other cars around
                            {
                                distanceToNextCar = 99999;
                            }
                            MRBackend.LineCrossedAsync(di.CarId, l.LineId, di.CurrentSpeed, di.CurrentAcceleration, driversVelocities.Min(), driversVelocities.Max(), distanceToNextCar, worldPositions.ToArray());
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                PluginManager.Log(ex);
            }

            #endregion
        }
Example #9
0
 protected override void OnAcServerTimeout()
 {
     PluginManager.Log("OnAcServerTimeout()");
     MRBackend.EndSessionAsync();
 }
Example #10
0
 protected override void OnClientLoaded(MsgClientLoaded msg)
 {
     MRBackend.RequestDriverLoadedAsync(msg.CarId);
 }
Example #11
0
        protected override void OnChatMessage(MsgChat msg)
        {
            if (!msg.IsCommand)
            {
                return;
            }

            var split = msg.Message.Split(' ');

            if (split.Length > 0)
            {
                switch (split[0].ToLower())
                {
                case "/mr":
                case "/minorating":
                {
                    if (split.Length == 1)         // only /mr
                    {
                        MRBackend.RequestDriverRatingAsync(msg.CarId);
                    }
                    else
                    {
                        MRBackend.RequestMRCommandAdminInfoAsync(msg.CarId, PluginManager.GetDriverInfo(msg.CarId).IsAdmin, split);
                    }
                }
                break;

                case "/mrpoint":
                {
                    string     text;
                    DriverInfo driver = null;
                    if (!PluginManager.TryGetDriverInfo(Convert.ToByte(msg.CarId), out driver))
                    {
                        text = "Driver not found: " + msg.CarId;
                    }
                    else if (driver?.LastCarUpdate?.Value == null)
                    {
                        text = "Something's wrong";
                    }
                    else
                    {
                        var upd = driver?.LastCarUpdate?.Value;

                        text = $"Spl:{upd.NormalizedSplinePosition:F5}|X={upd.WorldPosition.X:F5}|Z={upd.WorldPosition.Z:F5}";
                    }

                    PluginManager.SendChatMessage(msg.CarId, text);
                }
                break;

                case "/mrinfo":
                {
                    PluginManager.SendChatMessage(msg.CarId, $"Track id: {CurrentTrackDefinition?.TrackName}, length ={CurrentTrackDefinition?.Length:N0}");
                    PluginManager.SendChatMessage(msg.CarId, $"Pit exit: {PitExitRectangle?.X}");
                }
                break;

                case "/mrtrackreload":
                {
                    CurrentTrackDefinition = MRBackend.GetTrackDefinition(CurrentTrackDefinition.TrackName);
                    CreatePitExitRectangle();
                    PluginManager.SendChatMessage(msg.CarId, $"Track reloaded");
                }
                break;

                case "/mrtl1":
                {
                    string     text;
                    DriverInfo driver = null;
                    if (!PluginManager.TryGetDriverInfo(Convert.ToByte(msg.CarId), out driver))
                    {
                        text = "Driver not found: " + msg.CarId;
                    }
                    else if (driver?.LastCarUpdate?.Value == null)
                    {
                        text = "Something's wrong";
                    }
                    else
                    {
                        _AdminAddTrackLineStart = driver?.LastCarUpdate?.Value;
                        text = $"Start set: {_AdminAddTrackLineStart}";
                    }

                    PluginManager.SendChatMessage(msg.CarId, text);
                }
                break;

                case "/mrtl2":
                {
                    Console.WriteLine("TrackLine 2");
                    string     text   = null;
                    int        type   = 2; // pit exit = 1, default is line = 2
                    DriverInfo driver = null;
                    if (_AdminAddTrackLineStart == null)
                    {
                        text = "No start set";
                    }
                    else if (!PluginManager.TryGetDriverInfo(Convert.ToByte(msg.CarId), out driver))
                    {
                        text = "Driver not found: " + msg.CarId;
                    }
                    else if (driver?.LastCarUpdate?.Value == null)
                    {
                        text = "Something's wrong";
                    }
                    else if (split.Length < 2 || string.IsNullOrEmpty(split[1]))
                    {
                        text = "No hint set";
                    }
                    else
                    {
                        if (split.Length == 3)
                        {
                            type = int.Parse(split[2]);
                        }

                        try
                        {
                            var startPoint = _AdminAddTrackLineStart;
                            var endPoint   = driver?.LastCarUpdate?.Value;
                            MRBackend.CreateTrackLine(msg.CarId,
                                                      startPoint.NormalizedSplinePosition,
                                                      endPoint.NormalizedSplinePosition,
                                                      startPoint.WorldPosition.X,
                                                      startPoint.WorldPosition.Z,
                                                      endPoint.WorldPosition.X,
                                                      endPoint.WorldPosition.Z,
                                                      split[1],
                                                      type);
                            Console.WriteLine($"Message sent, type {type}");
                            ReloadTrackDefinition();
                            PluginManager.SendChatMessage(msg.CarId, "Track reloaded");
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine($"Exception in TrackLine2: {ex.ToString()}");
                        }
                    }

                    if (!string.IsNullOrEmpty(text))
                    {
                        PluginManager.SendChatMessage(msg.CarId, text);
                    }
                }
                break;

                default:
                    break;
                }
            }
        }
Example #12
0
 protected override void OnConnectionClosed(MsgConnectionClosed msg)
 {
     MRBackend.RandomCarInfoAsync(msg.CarId, "", "", "", false, GetCurrentRaceTimeMS(msg));
 }
Example #13
0
 protected override void OnSessionEnded(MsgSessionEnded msg)
 {
     PluginManager.Log("Session ended");
     MRBackend.EndSessionAsync();
 }
Example #14
0
 protected override void OnNewConnection(MsgNewConnection msg)
 {
     MRBackend.RandomCarInfoAsync(msg.CarId, msg.CarModel, msg.DriverName, msg.DriverGuid, true, GetCurrentRaceTimeMS(msg));
 }