void sectorClick(object sender, RoutedEventArgs e) { CheckBox fe2 = (CheckBox)e.Source; int index = Int32.Parse(fe2.Name.Substring(1, fe2.Name.Length - 1)); if ((Boolean)fe2.IsChecked) { SharedData.SelectedSectors.Add(SharedData.Sectors[index]); } else { SharedData.SelectedSectors.Remove(SharedData.Sectors[index]); } SharedData.SelectedSectors.Sort(); CfgFile sectorsIni = new CfgFile(Directory.GetCurrentDirectory() + "\\sectors.ini"); sectorsIni.setValue("Sectors", SharedData.Track.Id.ToString(), String.Join(";", SharedData.SelectedSectors), false); sectorsIni.Save(); }
private void parser(string yaml) { int start = 0; int end = 0; int length = 0; length = yaml.Length; start = yaml.IndexOf("WeekendInfo:\n", 0, length); end = yaml.IndexOf("\n\n", start, length - start); string WeekendInfo = yaml.Substring(start, end - start); SharedData.Track.Length = (Single)parseDoubleValue(WeekendInfo, "TrackLength", "km") * 1000; SharedData.Track.Id = parseIntValue(WeekendInfo, "TrackID"); SharedData.Track.Turns = parseIntValue(WeekendInfo, "TrackNumTurns"); SharedData.Track.City = parseStringValue(WeekendInfo, "TrackCity"); SharedData.Track.Country = parseStringValue(WeekendInfo, "TrackCountry"); SharedData.Track.Altitude = (Single)parseDoubleValue(WeekendInfo, "TrackAltitude", "m"); SharedData.Track.Sky = parseStringValue(WeekendInfo, "TrackSkies"); SharedData.Track.TrackTemperature = (Single)parseDoubleValue(WeekendInfo, "TrackSurfaceTemp", "C"); SharedData.Track.AirTemperature = (Single)parseDoubleValue(WeekendInfo, "TrackAirTemp", "C"); SharedData.Track.AirPressure = (Single)parseDoubleValue(WeekendInfo, "TrackAirPressure", "Hg"); SharedData.Track.WindSpeed = (Single)parseDoubleValue(WeekendInfo, "TrackWindVel", "m/s"); SharedData.Track.WindDirection = (Single)parseDoubleValue(WeekendInfo, "TrackWindDir", "rad"); SharedData.Track.Humidity = parseIntValue(WeekendInfo, "TrackRelativeHumidity", "%"); SharedData.Track.Fog = parseIntValue(WeekendInfo, "TrackFogLevel", "%"); if (parseIntValue(WeekendInfo, "Official") == 0 && parseIntValue(WeekendInfo, "SeasonID") == 0 && parseIntValue(WeekendInfo, "SeriesID") == 0) SharedData.Sessions.Hosted = true; else SharedData.Sessions.Hosted = false; if ( SharedData.theme != null ) SharedData.Track.Name = SharedData.theme.TrackNames.getValue("Tracks", SharedData.Track.Id.ToString(),false,"Unknown Track",false); SharedData.Sessions.SessionId = parseIntValue(WeekendInfo, "SessionID"); SharedData.Sessions.SubSessionId = parseIntValue(WeekendInfo, "SubSessionID"); length = yaml.Length; start = yaml.IndexOf("DriverInfo:\n", 0, length); end = yaml.IndexOf("\n\n", start, length - start); string DriverInfo = yaml.Substring(start, end - start); length = DriverInfo.Length; start = DriverInfo.IndexOf(" Drivers:\n", 0, length); end = length; string Drivers = DriverInfo.Substring(start, end - start - 1); string[] driverList = Drivers.Split(new string[] { "\n - " }, StringSplitOptions.RemoveEmptyEntries); foreach (string driver in driverList) { // KJ: fix // let's see if car is already in list ... int carIdx = parseIntValue(driver, "CarIdx"); var driverCarIdx = SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)); if (driverCarIdx != null) { // car already in list, check if driver changed var newUserId = parseIntValue(driver, "UserID"); if (driverCarIdx.UserId != newUserId) { logger.Info("driverChange detected - new driver ({0})", parseStringValue(driver,"UserName")); // driver changed - update driver details SharedData.updateControls = true; SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).Name = parseStringValue(driver, "UserName"); SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).Initials = parseStringValue(driver, "Initials"); if (parseStringValue(driver, "AbbrevName") != null) { string[] splitName = parseStringValue(driver, "AbbrevName").Split(','); if (splitName.Length > 1) SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).Shortname = splitName[1] + " " + splitName[0]; else SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).Shortname = parseStringValue(driver, "AbbrevName"); } else SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).Shortname = ""; SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).Club = parseStringValue(driver, "Club"); SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).SR = parseStringValue(driver, "SR"); SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).iRating = parseIntValue(driver, "iRating"); SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).UserId = newUserId; logger.Info("driverChange - looking for external data", ""); string[] external_driver; if ( SharedData.externalData.TryGetValue(newUserId, out external_driver) ) { logger.Info("driverChange - external data found", ""); int ed_idx; if ( ( ed_idx = Int32.Parse(SharedData.theme.getIniValue("General", "dataFullName") ) ) >= 0 && external_driver.Length > ed_idx ) { SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).Name = external_driver[ed_idx]; } if ( ( ed_idx = Int32.Parse(SharedData.theme.getIniValue("General", "dataShortName") ) ) >= 0 && external_driver.Length > ed_idx ) { SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).Shortname = external_driver[ed_idx]; } if ( ( ed_idx = Int32.Parse(SharedData.theme.getIniValue("General", "dataInitials") ) ) >= 0 && external_driver.Length > ed_idx ) { SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).Initials = external_driver[ed_idx]; } } logger.Info("driverChange - data ready", ""); } } int userId = parseIntValue(driver, "UserID"); if (userId < Int32.MaxValue && userId > 0) { int index = SharedData.Drivers.FindIndex(d => d.UserId.Equals(userId)); if (index < 0 && parseStringValue(driver, "CarPath") != "safety pcfr500s" && parseStringValue(driver, "AbbrevName") != "Pace Car") { if (SharedData.settings.IncludeMe || (!SharedData.settings.IncludeMe && parseIntValue(driver, "CarIdx") != 63)) { DriverInfo driverItem = new DriverInfo(); char[] charsToTrim = {'"'}; driverItem.Name = parseStringValue(driver, "UserName"); if (parseStringValue(driver, "AbbrevName") != null) { string[] splitName = parseStringValue(driver, "AbbrevName").Split(','); if (splitName.Length > 1) driverItem.Shortname = splitName[1] + " " + splitName[0]; else driverItem.Shortname = parseStringValue(driver, "AbbrevName"); } driverItem.Initials = parseStringValue(driver, "Initials"); driverItem.Club = parseStringValue(driver, "ClubName"); driverItem.NumberPlate = parseStringValue(driver, "CarNumber").Trim(charsToTrim); driverItem.CarId = parseIntValue(driver, "CarID"); driverItem.CarClass = parseIntValue(driver, "CarClassID"); driverItem.UserId = parseIntValue(driver, "UserID"); driverItem.CarIdx = parseIntValue(driver, "CarIdx"); driverItem.CarClassName = ( SharedData.theme != null ? SharedData.theme.getCarClass(driverItem.CarId) : "unknown" ); driverItem.iRating = parseIntValue(driver, "IRating"); // KJ: teamID! driverItem.TeamId = parseIntValue(driver, "TeamID"); int liclevel = parseIntValue(driver, "LicLevel"); int licsublevel = parseIntValue(driver, "LicSubLevel"); switch (liclevel) { case 0: case 1: case 2: case 3: case 4: driverItem.SR = "R" + ((double)licsublevel / 100).ToString("0.00"); break; case 5: case 6: case 7: case 8: driverItem.SR = "D" + ((double)licsublevel / 100).ToString("0.00"); break; case 9: case 10: case 11: case 12: driverItem.SR = "C" + ((double)licsublevel / 100).ToString("0.00"); break; case 14: case 15: case 16: case 17: driverItem.SR = "B" + ((double)licsublevel / 100).ToString("0.00"); break; case 18: case 19: case 20: case 21: driverItem.SR = "A" + ((double)licsublevel / 100).ToString("0.00"); break; case 22: case 23: case 24: case 25: driverItem.SR = "P" + ((double)licsublevel / 100).ToString("0.00"); break; case 26: case 27: case 28: case 29: driverItem.SR = "WC" + ((double)licsublevel / 100).ToString("0.00"); break; default: driverItem.SR = "Unknown"; break; } driverItem.CarClass = -1; int carclass = parseIntValue(driver, "CarClassID"); int freeslot = -1; for (int i = 0; i < SharedData.Classes.Length; i++) { if (SharedData.Classes[i] == carclass) { driverItem.CarClass = i; } else if (SharedData.Classes[i] == -1 && freeslot < 0) { freeslot = i; } } if (driverItem.CarClass < 0 && freeslot >= 0) { SharedData.Classes[freeslot] = carclass; driverItem.CarClass = freeslot; } if (!SharedData.externalPoints.ContainsKey(userId) && driverItem.CarIdx < 60) SharedData.externalPoints.Add(userId, 0); // fix bugges if (driverItem.NumberPlate == null) driverItem.NumberPlate = "000"; if (driverItem.Initials == null) driverItem.Initials = ""; // KJ: if we are team-racing: get the teamname or make one up ... if (driverItem.TeamId > 0) { if (SharedData.externalTeamData.ContainsKey(driverItem.TeamId)) { // found teamname for teamid in teams.csv string[] td_result; SharedData.externalTeamData.TryGetValue(driverItem.TeamId, out td_result); driverItem.TeamName = td_result[0]; } else if (SharedData.externalTeamData.ContainsKey(Int32.Parse(driverItem.NumberPlate))) { // found teamname for carnum in teams.csv string[] td_result; SharedData.externalTeamData.TryGetValue(Int32.Parse(driverItem.NumberPlate), out td_result); driverItem.TeamName = td_result[0]; } else { // make up generic teamname (to be parametrized in future) driverItem.TeamName = "Team #" + driverItem.NumberPlate; } } // KJ: if we have external data - perhaps we shall overload name data for the driver string[] external_driver; if (SharedData.externalData.TryGetValue(userId, out external_driver)) { // found external data for userid int ed_idx; SharedData.theme.getIniValue("General", "dataFullName"); if ((ed_idx = Int32.Parse(SharedData.theme.getIniValue("General", "dataFullName"))) >= 0 && external_driver.Length > ed_idx ) { // fullname gets replaced with column of data.csv driverItem.Name = external_driver[ed_idx]; } if ((ed_idx = Int32.Parse(SharedData.theme.getIniValue("General", "dataShortName"))) >= 0 && external_driver.Length > ed_idx ) { // shortname gets replaced with column of data.csv driverItem.Shortname = external_driver[ed_idx]; } if ((ed_idx = Int32.Parse(SharedData.theme.getIniValue("General", "dataInitials"))) >= 0 && external_driver.Length > ed_idx ) { // initials get replaced with column of data.csv driverItem.Initials = external_driver[ed_idx]; } } SharedData.Drivers.Add(driverItem); } } } } length = yaml.Length; start = yaml.IndexOf("SessionInfo:\n", 0, length); end = yaml.IndexOf("\n\n", start, length - start); string SessionInfo = yaml.Substring(start, end - start); length = SessionInfo.Length; start = SessionInfo.IndexOf(" Sessions:\n", 0, length); end = length; string Sessions = SessionInfo.Substring(start, end - start); string[] sessionList = Sessions.Split(new string[] { "\n - " }, StringSplitOptions.RemoveEmptyEntries); // Get Current running Session int _CurrentSession = (int)sdk.GetData("SessionNum"); foreach (string session in sessionList) { int sessionNum = parseIntValue(session, "SessionNum"); if (sessionNum < Int32.MaxValue) { int sessionIndex = SharedData.Sessions.SessionList.FindIndex(s => s.Id.Equals(sessionNum)); if (sessionIndex < 0) // add new session item { SessionInfo sessionItem = new SessionInfo(); sessionItem.Id = sessionNum; sessionItem.LapsTotal = parseIntValue(session, "SessionLaps"); sessionItem.SessionLength = parseFloatValue(session, "SessionTime", "sec"); sessionItem.Type = sessionTypeMap[parseStringValue(session, "SessionType")]; if (sessionItem.Type == SessionTypes.race) { sessionItem.FinishLine = parseIntValue(session, "SessionLaps") + 1; } else { sessionItem.FinishLine = Int32.MaxValue; } if (sessionItem.FinishLine < 0) { sessionItem.FinishLine = Int32.MaxValue; } sessionItem.Cautions = parseIntValue(session, "ResultsNumCautionFlags"); sessionItem.CautionLaps = parseIntValue(session, "ResultsNumCautionLaps"); sessionItem.LeadChanges = parseIntValue(session, "ResultsNumLeadChanges"); sessionItem.LapsComplete = parseIntValue(session, "ResultsLapsComplete"); length = session.Length; start = session.IndexOf(" ResultsFastestLap:\n", 0, length); end = length; string ResultsFastestLap = session.Substring(start, end - start); sessionItem.FastestLap = parseFloatValue(ResultsFastestLap, "FastestTime"); int index = SharedData.Drivers.FindIndex(d => d.CarIdx.Equals(parseIntValue(ResultsFastestLap, "CarIdx"))); if (index >= 0) { sessionItem.FastestLapDriver = SharedData.Drivers[index]; sessionItem.FastestLapNum = parseIntValue(ResultsFastestLap, "FastestLap"); } SharedData.Sessions.SessionList.Add(sessionItem); sessionIndex = SharedData.Sessions.SessionList.FindIndex(s => s.Id.Equals(sessionNum)); } else // update only non fixed fields { SharedData.Sessions.SessionList[sessionIndex].LeadChanges = parseIntValue(session, "ResultsNumLeadChanges"); SharedData.Sessions.SessionList[sessionIndex].LapsComplete = parseIntValue(session, "ResultsLapsComplete"); length = session.Length; start = session.IndexOf(" ResultsFastestLap:\n", 0, length) + " ResultsFastestLap:\n".Length; end = length; string ResultsFastestLap = session.Substring(start, end - start); SharedData.Sessions.SessionList[sessionIndex].FastestLap = parseFloatValue(ResultsFastestLap, "FastestTime"); int index = SharedData.Drivers.FindIndex(d => d.CarIdx.Equals(parseIntValue(ResultsFastestLap, "CarIdx"))); if (index >= 0) { SharedData.Sessions.SessionList[sessionIndex].FastestLapDriver = SharedData.Drivers[index]; SharedData.Sessions.SessionList[sessionIndex].FastestLapNum = parseIntValue(ResultsFastestLap, "FastestLap"); } } length = session.Length; start = session.IndexOf(" ResultsPositions:\n", 0, length); end = session.IndexOf(" ResultsFastestLap:\n", start, length - start); string Standings = session.Substring(start, end - start); string[] standingList = Standings.Split(new string[] { "\n - " }, StringSplitOptions.RemoveEmptyEntries); Int32 position = 1; List<DriverInfo> standingsDrivers = SharedData.Drivers.ToList(); foreach (string standing in standingList) { int carIdx = parseIntValue(standing, "CarIdx"); if (carIdx < Int32.MaxValue) { StandingsItem standingItem = new StandingsItem(); standingItem = SharedData.Sessions.SessionList[sessionIndex].FindDriver(carIdx); standingsDrivers.Remove(standingsDrivers.Find(s => s.CarIdx.Equals(carIdx))); if (parseFloatValue(standing, "LastTime") > 0) { if (parseFloatValue(standing, "LastTime") < SharedData.Sessions.SessionList[sessionIndex].FastestLap && SharedData.Sessions.SessionList[sessionIndex].FastestLap > 0) { // Race Condition? //SharedData.Sessions.SessionList[sessionIndex].FastestLap = parseFloatValue(standing, "FastestTime"); } } /* if (parseFloatValue(standing, "FastestTime") < SharedData.Sessions.SessionList[sessionIndex].FastestLap || SharedData.Sessions.SessionList[sessionIndex].FastestLap <= 0) { SharedData.Sessions.SessionList[sessionIndex].FastestLap = parseFloatValue(standing, "FastestTime"); } */ /* if (standingItem.Finished == false) { standingItem.PreviousLap.LapTime = parseFloatValue(standing, "LastTime"); if (standingItem.PreviousLap.LapTime <= 1) { standingItem.PreviousLap.LapTime = standingItem.CurrentLap.LapTime; } } */ if (SharedData.Sessions.SessionList[sessionIndex].Type == SharedData.Sessions.CurrentSession.Type) { if ((standingItem.CurrentTrackPct % 1.0) > 0.1) { standingItem.PreviousLap.Position = parseIntValue(standing, "Position"); standingItem.PreviousLap.Gap = parseFloatValue(standing, "Time"); standingItem.PreviousLap.GapLaps = parseIntValue(standing, "Lap"); standingItem.CurrentLap.Position = parseIntValue(standing, "Position"); } } if (standingItem.Driver.CarIdx < 0) { // insert item int driverIndex = SharedData.Drivers.FindIndex(d => d.CarIdx.Equals(carIdx)); standingItem.setDriver(carIdx); standingItem.FastestLap = parseFloatValue(standing, "FastestTime"); standingItem.LapsLed = parseIntValue(standing, "LapsLed"); standingItem.CurrentTrackPct = parseFloatValue(standing, "LapsDriven"); standingItem.Laps = new List<LapInfo>(); LapInfo newLap = new LapInfo(); newLap.LapNum = parseIntValue(standing, "LapsComplete"); newLap.LapTime = parseFloatValue(standing, "LastTime"); newLap.Position = parseIntValue(standing, "Position"); newLap.Gap = parseFloatValue(standing, "Time"); newLap.GapLaps = parseIntValue(standing, "Lap"); newLap.SectorTimes = new List<Sector>(3); standingItem.Laps.Add(newLap); standingItem.CurrentLap = new LapInfo(); standingItem.CurrentLap.LapNum = parseIntValue(standing, "LapsComplete") + 1; standingItem.CurrentLap.Position = parseIntValue(standing, "Position"); standingItem.CurrentLap.Gap = parseFloatValue(standing, "Time"); standingItem.CurrentLap.GapLaps = parseIntValue(standing, "Lap"); lock (SharedData.SharedDataLock) { SharedData.Sessions.SessionList[sessionIndex].Standings.Add(standingItem); SharedData.Sessions.SessionList[sessionIndex].UpdatePosition(); } } int lapnum = parseIntValue(standing, "LapsComplete"); standingItem.FastestLap = parseFloatValue(standing, "FastestTime"); standingItem.LapsLed = parseIntValue(standing, "LapsLed"); if (SharedData.Sessions.SessionList[sessionIndex].Type == SharedData.Sessions.CurrentSession.Type) { standingItem.PreviousLap.LapTime = parseFloatValue(standing, "LastTime"); } if (SharedData.Sessions.CurrentSession.State == SessionStates.cooldown) { standingItem.CurrentLap.Gap = parseFloatValue(standing, "Time"); standingItem.CurrentLap.GapLaps = parseIntValue(standing, "Lap"); standingItem.CurrentLap.Position = parseIntValue(standing, "Position"); standingItem.CurrentLap.LapNum = parseIntValue(standing, "LapsComplete"); } standingItem.Position = parseIntValue(standing, "Position"); standingItem.NotifySelf(); standingItem.NotifyLaps(); position++; } } // Trigger Overlay Event, but only in current active session if ((SharedData.Sessions.SessionList[sessionIndex].FastestLap != SharedData.Sessions.SessionList[sessionIndex].PreviousFastestLap) && (_CurrentSession == SharedData.Sessions.SessionList[sessionIndex].Id) ) { if (SharedData.Sessions.SessionList[sessionIndex].FastestLap > 0) { SessionEvent ev = new SessionEvent( SessionEventTypes.fastlap, (Int32)(((Double)sdk.GetData("SessionTime") * 60) + timeoffset), SharedData.Sessions.SessionList[sessionIndex].FastestLapDriver, "New session fastest lap (" + Utils.floatTime2String(SharedData.Sessions.SessionList[sessionIndex].FastestLap, 3, false) + ")", SharedData.Sessions.SessionList[sessionIndex].Type, SharedData.Sessions.SessionList[sessionIndex].FastestLapNum ); SharedData.Events.Add(ev); // Push Event to Overlay logger.Info("New fastest lap in Session {0} : {1}", _CurrentSession, SharedData.Sessions.SessionList[sessionIndex].FastestLap); SharedData.triggers.Push(TriggerTypes.fastestlap); } } // update/add position for drivers not in results foreach (DriverInfo driver in standingsDrivers) { StandingsItem standingItem = SharedData.Sessions.SessionList[sessionIndex].FindDriver(driver.CarIdx); if (standingItem.Driver.CarIdx < 0) { if (SharedData.settings.IncludeMe || (!SharedData.settings.IncludeMe && standingItem.Driver.CarIdx != 63)) { standingItem.setDriver(driver.CarIdx); standingItem.Position = position; standingItem.Laps = new List<LapInfo>(); lock (SharedData.SharedDataLock) { SharedData.Sessions.SessionList[sessionIndex].Standings.Add(standingItem); } position++; } } else if (!SharedData.settings.IncludeMe && driver.CarIdx < 63) { standingItem.Position = position; position++; } } } } // add qualify session if it doesn't exist when race starts and fill it with YAML QualifyResultsInfo SessionInfo qualifySession = SharedData.Sessions.findSessionByType(SessionTypes.qualify); if (qualifySession.Type == SessionTypes.none) { qualifySession.Type = SessionTypes.qualify; length = yaml.Length; start = yaml.IndexOf("QualifyResultsInfo:\n", 0, length); // if found if (start >= 0) { end = yaml.IndexOf("\n\n", start, length - start); string QualifyResults = yaml.Substring(start, end - start); length = QualifyResults.Length; start = QualifyResults.IndexOf(" Results:\n", 0, length); end = length; string Results = QualifyResults.Substring(start, end - start - 1); string[] resultList = Results.Split(new string[] { "\n - " }, StringSplitOptions.RemoveEmptyEntries); qualifySession.FastestLap = float.MaxValue; foreach (string result in resultList) { if (result != " Results:") { StandingsItem qualStandingsItem = qualifySession.FindDriver(parseIntValue(result, "CarIdx")); if (qualStandingsItem.Driver.CarIdx > 0) // check if driver is in quali session { qualStandingsItem.Position = parseIntValue(result, "Position") + 1; } else // add driver to quali session { qualStandingsItem.setDriver(parseIntValue(result, "CarIdx")); qualStandingsItem.Position = parseIntValue(result, "Position") + 1; qualStandingsItem.FastestLap = parseFloatValue(result, "FastestTime"); lock (SharedData.SharedDataLock) { qualifySession.Standings.Add(qualStandingsItem); } // update session fastest lap if (qualStandingsItem.FastestLap < qualifySession.FastestLap && qualStandingsItem.FastestLap > 0) qualifySession.FastestLap = qualStandingsItem.FastestLap; } } } SharedData.Sessions.SessionList.Add(qualifySession); // add quali session } } // get qualify results if race session standings is empty foreach (SessionInfo session in SharedData.Sessions.SessionList) { if (session.Type == SessionTypes.race && session.Standings.Count < 1) { length = yaml.Length; start = yaml.IndexOf("QualifyResultsInfo:\n", 0, length); // if found if (start >= 0) { end = yaml.IndexOf("\n\n", start, length - start); string QualifyResults = yaml.Substring(start, end - start); length = QualifyResults.Length; start = QualifyResults.IndexOf(" Results:\n", 0, length); end = length; string Results = QualifyResults.Substring(start, end - start - 1); string[] resultList = Results.Split(new string[] { "\n - " }, StringSplitOptions.RemoveEmptyEntries); foreach (string result in resultList) { if (result != " Results:") { StandingsItem standingItem = new StandingsItem(); standingItem.setDriver(parseIntValue(result, "CarIdx")); standingItem.Position = parseIntValue(result, "Position") + 1; lock (SharedData.SharedDataLock) { session.Standings.Add(standingItem); } } } } } } length = yaml.Length; start = yaml.IndexOf("CameraInfo:\n", 0, length); end = yaml.IndexOf("\n\n", start, length - start); string CameraInfo = yaml.Substring(start, end - start); length = CameraInfo.Length; start = CameraInfo.IndexOf(" Groups:\n", 0, length); end = length; string Cameras = CameraInfo.Substring(start, end - start - 1); string[] cameraList = Cameras.Split(new string[] { "\n - " }, StringSplitOptions.RemoveEmptyEntries); bool haveNewCam = false; foreach (string camera in cameraList) { int cameraNum = parseIntValue(camera, "GroupNum"); if (cameraNum < Int32.MaxValue) { CameraGroup camgrp = SharedData.Camera.FindId(cameraNum); if (camgrp.Id < 0) { CameraGroup cameraGroupItem = new CameraGroup(); cameraGroupItem.Id = cameraNum; cameraGroupItem.Name = parseStringValue(camera, "GroupName"); lock (SharedData.SharedDataLock) { SharedData.Camera.Groups.Add(cameraGroupItem); haveNewCam = true; } } } } if (SharedData.settings.CamerasButtonColumn && haveNewCam) // If we have a new cam and want Camera Buttons, then forece a refresh of the main window buttons SharedData.refreshButtons = true; length = yaml.Length; start = yaml.IndexOf("SplitTimeInfo:\n", 0, length); end = yaml.IndexOf("\n\n", start, length - start); string SplitTimeInfo = yaml.Substring(start, end - start); length = SplitTimeInfo.Length; start = SplitTimeInfo.IndexOf(" Sectors:\n", 0, length); end = length; string Sectors = SplitTimeInfo.Substring(start, end - start - 1); string[] sectorList = Sectors.Split(new string[] { "\n - " }, StringSplitOptions.RemoveEmptyEntries); if (sectorList.Length != SharedData.Sectors.Count) { SharedData.Sectors.Clear(); foreach (string sector in sectorList) { int sectornum = parseIntValue(sector, "SectorNum"); if (sectornum < 100) { float sectorborder = parseFloatValue(sector, "SectorStartPct"); SharedData.Sectors.Add(sectorborder); } } // automagic sector selection if (SharedData.SelectedSectors.Count == 0) { SharedData.SelectedSectors.Clear(); // load sectors CfgFile sectorsIni = new CfgFile(Directory.GetCurrentDirectory() + "\\sectors.ini"); string sectorValue = sectorsIni.getValue("Sectors", SharedData.Track.Id.ToString(),false,String.Empty,false); string[] selectedSectors = sectorValue.Split(';'); Array.Sort(selectedSectors); SharedData.SelectedSectors.Clear(); if (sectorValue.Length > 0) { foreach (string sector in selectedSectors) { float number; if (Single.TryParse(sector, out number)) { SharedData.SelectedSectors.Add(number); } } } else { if (SharedData.Sectors.Count == 2) { foreach (float sector in SharedData.Sectors) SharedData.SelectedSectors.Add(sector); } else { float prevsector = 0; foreach (float sector in SharedData.Sectors) { if (sector == 0 && SharedData.SelectedSectors.Count == 0) { SharedData.SelectedSectors.Add(sector); } else if (sector >= 0.333 && SharedData.SelectedSectors.Count == 1) { if (sector - 0.333 < Math.Abs(prevsector - 0.333)) { SharedData.SelectedSectors.Add(sector); } else { SharedData.SelectedSectors.Add(prevsector); } } else if (sector >= 0.666 && SharedData.SelectedSectors.Count == 2) { if (sector - 0.666 < Math.Abs(prevsector - 0.666)) { SharedData.SelectedSectors.Add(sector); } else { SharedData.SelectedSectors.Add(prevsector); } } prevsector = sector; } } } } } }
public Theme(string themeName) { path = "themes\\" + themeName; // if theme not found pick the first theme on theme dir if (!File.Exists(Directory.GetCurrentDirectory() + "\\" + path + "\\settings.ini")) { System.Windows.MessageBox.Show("Could not find theme named '" + themeName + "' from '" + Directory.GetCurrentDirectory() + "\\" + path + "\\'"); DirectoryInfo d = new DirectoryInfo(Directory.GetCurrentDirectory() + "\\themes\\"); DirectoryInfo[] dis = d.GetDirectories(); foreach (DirectoryInfo di in dis) { if (File.Exists(Directory.GetCurrentDirectory() + "\\themes\\" + di.Name + "\\settings.ini")) { themeName = di.Name; break; } } } path = "themes\\" + themeName; name = themeName; fontCache = new FontCache(); fontCache.SetPath(Path.Combine(Directory.GetCurrentDirectory(), "themes\\" + themeName)); settings = new CfgFile(path + "\\settings.ini"); if (getIniValueBool("General", "dynamic")) { logger.Info("Dynamic Theme configuration activated"); List<string> secs = settings.getAllSections(); Dictionary<string, List<string>> secStuff = new Dictionary<string, List<string>>(); foreach (string s in secs) { string[] parts = s.Split('-'); if (parts.Length != 2) continue; if ( !secStuff.ContainsKey( parts[0].ToLowerInvariant() ) ) secStuff[parts[0].ToLowerInvariant()] = new List<string>(); secStuff[parts[0].ToLowerInvariant()].Add(parts[1]); } foreach( string k in secStuff.Keys ) { logger.Info("Setting {0}s = {1}",k,String.Join(",", secStuff[k])); settings.setValue("General", k+"s", String.Join(",", secStuff[k]), false); } } string filename = Directory.GetCurrentDirectory() + "\\themes\\" + name + "\\tracks.ini"; if (!File.Exists(filename)) filename = Directory.GetCurrentDirectory() + "\\tracks.ini"; if (File.Exists(filename)) { TrackNames = new CfgFile(filename); } width = Int32.Parse(getIniValue("General", "width")); height = Int32.Parse(getIniValue("General", "height")); defaultFont = settings.getValue("General", "font", false, "Arial", false); // point schema pointscol = Int32.Parse(getIniValue("General", "pointscol")); minscoringdistance = Single.Parse(getIniValue("General", "minscoringdistance"))/100; if (minscoringdistance == 0.0f) minscoringdistance = 1.0f; string[] pointschemastr = getIniValue("General", "pointschema").Split(','); pointschema = new Int32[pointschemastr.Length]; for (int i = 0; i < pointschemastr.Length; i++) pointschema[i] = Int32.Parse(pointschemastr[i]); // load objects string tmp = getIniValue("General", "overlays"); string[] overlays; if (tmp != "0") { overlays = tmp.Split(','); objects = new ObjectProperties[overlays.Length]; } else { objects = new ObjectProperties[0]; overlays = new string[0]; } for(int i = 0; i < overlays.Length; i++) { objects[i].name = overlays[i]; objects[i].width = Int32.Parse(getIniValue("Overlay-" + overlays[i], "width")); objects[i].height = Int32.Parse(getIniValue("Overlay-" + overlays[i], "height")); objects[i].left = Int32.Parse(getIniValue("Overlay-" + overlays[i], "left")); objects[i].top = Int32.Parse(getIniValue("Overlay-" + overlays[i], "top")); objects[i].zIndex = Int32.Parse(getIniValue("Overlay-" + overlays[i], "zIndex")); objects[i].offset = Int32.Parse(getIniValue("Overlay-" + overlays[i], "offset")); objects[i].dataset = (DataSets)Enum.Parse(typeof(DataSets), getIniValue("Overlay-" + overlays[i], "dataset")); if (getIniValue("Overlay-" + overlays[i], "class") != "0") objects[i].carclass = getIniValue("Overlay-" + overlays[i], "class"); else objects[i].carclass = null; if (getIniValue("Overlay-" + overlays[i], "fixed") == "true") objects[i].presistent = true; else objects[i].presistent = false; if (getIniValue("Overlay-" + overlays[i], "leader") != "0") objects[i].leadervalue = getIniValue("Overlay-" + overlays[i], "leader"); else objects[i].leadervalue = null; objects[i].session = (SessionTypes)Enum.Parse(typeof(SessionTypes), getIniValue("Overlay-" + overlays[i], "session")); int extraHeight = 0; // load labels tmp = getIniValue("Overlay-" + overlays[i], "labels"); string[] labels = tmp.Split(','); objects[i].labels = new LabelProperties[labels.Length]; for (int j = 0; j < labels.Length; j++) { objects[i].labels[j] = loadLabelProperties("Overlay-" + overlays[i], labels[j]); if (objects[i].labels[j].height > extraHeight) extraHeight = objects[i].labels[j].height; if (objects[i].labels[j].session == SessionTypes.none) objects[i].labels[j].session = objects[i].session; } if (objects[i].dataset == DataSets.standing || objects[i].dataset == DataSets.points || objects[i].dataset == DataSets.pit) { objects[i].itemCount = Int32.Parse(getIniValue("Overlay-" + overlays[i], "number")); objects[i].itemSize = Int32.Parse(getIniValue("Overlay-" + overlays[i], "itemHeight")); objects[i].itemSize += Int32.Parse(getIniValue("Overlay-" + overlays[i], "itemsize")); objects[i].height = Math.Max(objects[i].height, (objects[i].itemCount * objects[i].itemSize) + extraHeight); objects[i].page = -1; objects[i].direction = (direction)Enum.Parse(typeof(direction), getIniValue("Overlay-" + overlays[i], "direction")); objects[i].offset = Int32.Parse(getIniValue("Overlay-" + overlays[i], "offset")); objects[i].maxpages = Int32.Parse(getIniValue("Overlay-" + overlays[i], "maxpages")); objects[i].skip = Int32.Parse(getIniValue("Overlay-" + overlays[i], "skip")); } switch (getIniValue("Overlay-" + overlays[i], "dataorder")) { case "fastestlap": objects[i].dataorder = DataOrders.fastestlap; break; case "previouslap": objects[i].dataorder = DataOrders.previouslap; break; case "class": objects[i].dataorder = DataOrders.previouslap; break; case "points": objects[i].dataorder = DataOrders.points; break; case "liveposition": objects[i].dataorder = DataOrders.liveposition; break; case "trackposition": objects[i].dataorder = DataOrders.trackposition; break; default: objects[i].dataorder = DataOrders.position; break; } objects[i].visible = false; } // load images tmp = getIniValue("General", "images"); string[] files; if (tmp != "0") { files = tmp.Split(','); images = new ImageProperties[files.Length]; } else { images = new ImageProperties[0]; files = new string[0]; } for (int i = 0; i < files.Length; i++) { images[i].filename = getIniValue("Image-" + files[i], "filename"); images[i].zIndex = Int32.Parse(getIniValue("Image-" + files[i], "zIndex")); images[i].visible = false; images[i].name = files[i]; images[i].width = Int32.Parse(getIniValue("Image-" + files[i], "width")); images[i].height = Int32.Parse(getIniValue("Image-" + files[i], "height")); images[i].left = Int32.Parse(getIniValue("Image-" + files[i], "left")); images[i].top = Int32.Parse(getIniValue("Image-" + files[i], "top")); if (getIniValue("Image-" + files[i], "dynamic") == "true") { images[i].dynamic = true; images[i].defaultFile = getIniValue("Image-" + files[i], "default"); } else images[i].dynamic = false; if (getIniValue("Image-" + files[i], "fixed") == "true") images[i].presistent = true; else images[i].presistent = false; if (getIniValue("Image-" + files[i], "animate") == "true") images[i].doAnimate = true; else images[i].doAnimate = false; } // load videos tmp = getIniValue("General", "videos"); if (tmp != "0") { files = tmp.Split(','); videos = new VideoProperties[files.Length]; } else { videos = new VideoProperties[0]; files = new string[0]; } for (int i = 0; i < files.Length; i++) { videos[i].filename = getIniValue("Video-" + files[i], "filename"); videos[i].zIndex = Int32.Parse(getIniValue("Video-" + files[i], "zIndex")); videos[i].width = Int32.Parse(getIniValue("Video-" + files[i], "width")); videos[i].height = Int32.Parse(getIniValue("Video-" + files[i], "height")); videos[i].left = Int32.Parse(getIniValue("Video-" + files[i], "left")); videos[i].top = Int32.Parse(getIniValue("Video-" + files[i], "top")); videos[i].visible = false; videos[i].playing = false; videos[i].name = files[i]; videos[i].muteSimulator = getIniValueBool("Video-" + files[i], "mute"); Double volume = 100.0; bool result = Double.TryParse(getIniValueWithDefault("Video-" + files[i], "volume", "100.0"), NumberStyles.AllowDecimalPoint, CultureInfo.CreateSpecificCulture("en-US"), out volume); if (!result) volume = 100.0; videos[i].volume = Math.Min(volume / 100.0, 100.0); if (videos[i].volume <= 0) videos[i].volume = 1.0; if (getIniValue("Video-" + files[i], "fixed") == "true") videos[i].presistent = true; else videos[i].presistent = false; if (getIniValue("Video-" + files[i], "loop") == "true") videos[i].loop = true; else videos[i].loop = false; } // load sounds tmp = getIniValue("General", "sounds"); if (tmp != "0") { files = tmp.Split(','); sounds = new SoundProperties[files.Length]; } else { sounds = new SoundProperties[0]; files = new string[0]; } for (int i = 0; i < files.Length; i++) { sounds[i].filename = getIniValue("Sound-" + files[i], "filename"); sounds[i].playing = false; sounds[i].name = files[i]; Double volume = 100.0; bool result = Double.TryParse(getIniValueWithDefault("Sound-" + files[i], "volume", "100.0"), NumberStyles.AllowDecimalPoint, CultureInfo.CreateSpecificCulture("en-US"), out volume); if (!result) volume = 100.0; sounds[i].volume = Math.Min(volume / 100.0, 100.0); if (sounds[i].volume <= 0) sounds[i].volume = 1.0; if (getIniValue("Sound-" + files[i], "loop") == "true") sounds[i].loop = true; else sounds[i].loop = false; } // load tickers tmp = getIniValue("General", "tickers"); string[] tickersnames; if (tmp != "0") { tickersnames = tmp.Split(','); tickers = new TickerProperties[tickersnames.Length]; } else { tickers = new TickerProperties[0]; tickersnames = new string[0]; } for (int i = 0; i < tickersnames.Length; i++) { tickers[i].name = tickersnames[i]; tickers[i].width = Int32.Parse(getIniValue("Ticker-" + tickersnames[i], "width")); tickers[i].height = Int32.Parse(getIniValue("Ticker-" + tickersnames[i], "height")); tickers[i].left = Int32.Parse(getIniValue("Ticker-" + tickersnames[i], "left")); tickers[i].top = Int32.Parse(getIniValue("Ticker-" + tickersnames[i], "top")); tickers[i].zIndex = Int32.Parse(getIniValue("Ticker-" + tickersnames[i], "zIndex")); tickers[i].dataset = (DataSets)Enum.Parse(typeof(DataSets), getIniValue("Ticker-" + tickersnames[i], "dataset")); if (getIniValue("Ticker-" + tickersnames[i], "class") != "0") tickers[i].carclass = getIniValue("Ticker-" + tickersnames[i], "class"); else tickers[i].carclass = null; switch (getIniValue("Ticker-" + tickersnames[i], "dataorder")) { case "fastestlap": tickers[i].dataorder = DataOrders.fastestlap; break; case "previouslap": tickers[i].dataorder = DataOrders.previouslap; break; case "class": tickers[i].dataorder = DataOrders.classposition; break; case "classposition": tickers[i].dataorder = DataOrders.classposition; break; default: tickers[i].dataorder = DataOrders.position; break; } if (getIniValue("Ticker-" + tickersnames[i], "speed") != "0") tickers[i].speed = Double.Parse(getIniValue("Ticker-" + tickersnames[i], "speed")); else tickers[i].speed = 1.0; if (getIniValue("Ticker-" + tickersnames[i], "header") != "0") tickers[i].header = loadLabelProperties("Ticker-" + tickersnames[i], getIniValue("Ticker-" + tickersnames[i], "header")); if (getIniValue("Ticker-" + tickersnames[i], "footer") != "0") tickers[i].footer = loadLabelProperties("Ticker-" + tickersnames[i], getIniValue("Ticker-" + tickersnames[i], "footer")); if (getIniValue("Ticker-" + tickersnames[i], "fillvertical") == "true") tickers[i].fillVertical = true; else tickers[i].fillVertical = false; if (getIniValue("Ticker-" + tickersnames[i], "fixed") == "true") tickers[i].presistent = true; else tickers[i].presistent = false; if (getIniValue("Ticker-" + tickersnames[i], "leader") != "0") tickers[i].leadervalue = getIniValue("Ticker-" + overlays[i], "leader"); else tickers[i].leadervalue = null; // load labels tmp = getIniValue("Ticker-" + tickersnames[i], "labels"); string[] labels = tmp.Split(','); tickers[i].labels = new LabelProperties[labels.Length]; for (int j = 0; j < labels.Length; j++) tickers[i].labels[j] = loadLabelProperties("Ticker-" + tickersnames[i], labels[j]); tickers[i].visible = false; } // load buttons tmp = getIniValue("General", "buttons"); string[] btns = tmp.Split(','); ButtonProperties[] tmpButtons = new ButtonProperties[btns.Length]; for (int i = 0; i < btns.Length; i++) { tmpButtons[i].name = btns[i]; tmpButtons[i].text = getIniValue("Button-" + btns[i], "text"); tmpButtons[i].row = Int32.Parse(getIniValue("Button-" + btns[i], "row")); tmpButtons[i].delay = Int32.Parse(getIniValue("Button-" + btns[i], "delay")); tmpButtons[i].order = Int32.Parse(getIniValue("Button-" + btns[i], "order")); tmpButtons[i].active = false; tmpButtons[i].pressed = DateTime.Now; if (getIniValue("Button-" + btns[i], "loop") == "true") tmpButtons[i].delayLoop = true; else tmpButtons[i].delayLoop = false; if (getIniValue("Button-" + btns[i], "hidden") == "true") tmpButtons[i].hidden = true; else tmpButtons[i].hidden = false; // hotkey string hotkey = settings.getValue("Button-" + btns[i], "hotkey", false, String.Empty, false); if (hotkey.Length > 0) { tmpButtons[i].hotkey = new HotKeyProperties(); tmpButtons[i].hotkey.key = new Key(); tmpButtons[i].hotkey.modifier = new KeyModifier(); string[] hotkeys = hotkey.Split('-'); tmpButtons[i].hotkey.key = (Key)Enum.Parse(typeof(Key), hotkeys[hotkeys.Length - 1]); tmpButtons[i].hotkey.modifier = KeyModifier.None; if (hotkeys.Length > 1) { for (int j = 0; j < hotkeys.Length - 1; j++) { tmpButtons[i].hotkey.modifier |= (KeyModifier)Enum.Parse(typeof(KeyModifier), hotkeys[j]); } } } // actions tmpButtons[i].actions = new string[Enum.GetValues(typeof(ButtonActions)).Length][]; foreach (ButtonActions action in Enum.GetValues(typeof(ButtonActions))) { tmp = getIniValue("Button-" + btns[i], action.ToString()); if (tmp != "0") { string[] objs = tmp.Split(','); tmpButtons[i].actions[(int)action] = new string[objs.Length]; for (int j = 0; j < objs.Length; j++) { tmpButtons[i].actions[(int)action][j] = objs[j]; } } else if (action == ButtonActions.replay) { string value = settings.getValue("Button-" + btns[i], "replay", false, String.Empty, false); if (value.Length > 0) { tmpButtons[i].actions[(int)action] = new string[1]; tmpButtons[i].actions[(int)action][0] = value; } } else { tmpButtons[i].actions[(int)action] = null; } } } // Sort and order buttons for display nicely buttons = new ButtonProperties[btns.Length]; int btnPos = 0; foreach (var currentButton in tmpButtons.OrderBy(b => b.row).ThenBy(b => b.order)) { #if DEBUG logger.Debug("{0},{1} {2}", currentButton.row, currentButton.order, currentButton.text); #endif buttons[btnPos] = currentButton; btnPos++; } // load triggers triggers = new TriggerProperties[Enum.GetValues(typeof(TriggerTypes)).Length]; int trigidx = 0; foreach (TriggerTypes trigger in Enum.GetValues(typeof(TriggerTypes))) { foreach (ThemeTypes type in Enum.GetValues(typeof(ThemeTypes))) { triggers[trigidx].name = trigger.ToString(); triggers[trigidx].actions = new string[Enum.GetValues(typeof(ButtonActions)).Length][]; foreach (ButtonActions action in Enum.GetValues(typeof(ButtonActions))) { tmp = getIniValue("Trigger-" + trigger.ToString(), action.ToString()); if (tmp != "0") { string[] objs = tmp.Split(','); triggers[trigidx].actions[(int)action] = new string[objs.Length]; for (int j = 0; j < objs.Length; j++) { triggers[trigidx].actions[(int)action][j] = objs[j]; } } else if (action == ButtonActions.replay) { string value = settings.getValue("Button-" + trigger.ToString(), "replay",false,String.Empty,false); if (value.Length > 0) { triggers[trigidx].actions[(int)action] = new string[1]; triggers[trigidx].actions[(int)action][0] = value; } } else { triggers[trigidx].actions[(int)action] = null; } } } trigidx++; } SharedData.refreshButtons = true; string[] translations = new string[20] { // default translations "lap", "laps", "minutes", "of", "race", "qualify", "practice", "out", "remaining", "gridding", "pacelap", "finallap", "finishing", "leader", "invalid", "replay", "Clear", "Partly Cloudy", "Mostly Cloudy", "Overcast" }; foreach (string word in translations) { string translatedword = getIniValue("Translation", word); if(translatedword == "0") // default is the name of the property translation.Add(word, word); else translation.Add(word, translatedword); } // signs if (getIniValue("General", "switchsign") == "true") { translation.Add("ahead", "+"); translation.Add("behind", "-"); } else { translation.Add("ahead", "-"); translation.Add("behind", "+"); } // load scripts SharedData.scripting = new Scripting(); tmp = getIniValue("General", "scripts"); string[] scripts = tmp.Split(','); for (int i = 0; i < scripts.Length; i++) { if (File.Exists(Directory.GetCurrentDirectory() + "\\" + path + "\\scripts\\" + scripts[i] + ".cs")) SharedData.scripting.loadScript(Directory.GetCurrentDirectory() + "\\" + path + "\\scripts\\" + scripts[i] + ".cs"); else if (File.Exists(Directory.GetCurrentDirectory() + "\\scripts\\" + scripts[i] + ".cs")) SharedData.scripting.loadScript(Directory.GetCurrentDirectory() + "\\scripts\\" + scripts[i] + ".cs"); else { IScript myScript = System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(scripts[i]) as IScript; if (myScript != null) SharedData.scripting.addScript(myScript); else Console.WriteLine("Script " + scripts[i] + ".cs not found!"); } } }
public string getCar(int car) { try { return carName[car]; } catch { string filename = Directory.GetCurrentDirectory() + "\\themes\\" + this.name + "\\cars.ini"; if (!File.Exists(filename)) filename = Directory.GetCurrentDirectory() + "\\cars.ini"; if (File.Exists(filename)) { CfgFile carNames = new CfgFile(filename); string name = carNames.getValue("Cars", car.ToString(),false,String.Empty,false); if (name.Length > 0) { carName.Add(car, name); return name; } else { carName.Add(car, car.ToString()); return car.ToString(); } } else { carName.Add(car, car.ToString()); return car.ToString(); } } }
public string getCarClass(int car) { try { return carClass[car]; } catch { string filename = Directory.GetCurrentDirectory() + "\\themes\\" + this.name + "\\cars.ini"; if (!File.Exists(filename)) filename = Directory.GetCurrentDirectory() + "\\cars.ini"; if (File.Exists(filename)) { CfgFile carNames = new CfgFile(filename); // update class order string[] order = carNames.getValue("Multiclass", "order", false,String.Empty,false).Split(','); SharedData.ClassOrder.Clear(); for (Int32 i = 0; i < order.Length; i++) SharedData.ClassOrder.Add(order[i], i); string name = carNames.getValue("Multiclass", car.ToString(), false, String.Empty, false); if (name.Length > 0) { carClass.Add(car, name); return name; } else { carClass.Add(car, car.ToString()); return car.ToString(); } } else { carClass.Add(car, car.ToString()); return car.ToString(); } } }
void sectorClick(object sender, RoutedEventArgs e) { CheckBox fe2 = (CheckBox)e.Source; int index = Int32.Parse(fe2.Name.Substring(1, fe2.Name.Length - 1)); if ((Boolean)fe2.IsChecked) { SharedData.SelectedSectors.Add(SharedData.Sectors[index]); } else { SharedData.SelectedSectors.Remove(SharedData.Sectors[index]); } SharedData.SelectedSectors.Sort(); CfgFile sectorsIni = new CfgFile(Directory.GetCurrentDirectory() + "\\sectors.ini"); sectorsIni.setValue("Sectors", SharedData.Track.Id.ToString(), String.Join(";", SharedData.SelectedSectors),false); sectorsIni.Save(); }