public ImportExportContainer(GDTransferFile[] modFilter, IPlayerItemDao playerItemDao, StashManager sm)
 {
     InitializeComponent();
     this.modFilter     = modFilter;
     this.playerItemDao = playerItemDao;
     this.sm            = sm;
 }
Exemple #2
0
        private void MainWindow_FormClosing(object sender, FormClosingEventArgs e)
        {
            // No idea which of these are triggering on rare occasions, perhaps Deactivate, sizechanged or filterWindow.
            FormClosing -= MainWindow_FormClosing;
            SizeChanged -= OnMinimizeWindow;

            _stashFileMonitor?.Dispose();
            _stashFileMonitor = null;
            _stashManager     = null;

            _backupBackgroundTask?.Dispose();

            _timerReportUsage?.Stop();
            _timerReportUsage?.Dispose();
            _timerReportUsage = null;

            _tooltipHelper?.Dispose();

            _buddyBackgroundThread?.Dispose();
            _buddyBackgroundThread = null;

            panelHelp.Controls.Clear();

            _injector?.Dispose();
            _injector = null;

            _backupServiceWorker?.Dispose();
            _backupServiceWorker = null;

            _window?.Dispose();
            _window = null;

            IterAndCloseForms(Controls);
        }
Exemple #3
0
 public ImportMode(GDTransferFile[] modSelection, IPlayerItemDao playerItemDao, StashManager sm)
 {
     InitializeComponent();
     this.modSelection  = modSelection;
     this.playerItemDao = playerItemDao;
     this.sm            = sm;
 }
Exemple #4
0
        public SettingsWindow(
            CefBrowserHandler cefBrowserHandler,
            IItemTagDao itemTagDao,
            TooltipHelper tooltipHelper,
            Action itemViewUpdateTrigger,
            IDatabaseSettingDao settingsDao,
            IPlayerItemDao playerItemDao,
            ArzParser parser,
            GDTransferFile[] modFilter,
            StashManager stashManager, ParsingService parsingService)
        {
            InitializeComponent();
            this._cefBrowserHandler     = cefBrowserHandler;
            this._tooltipHelper         = tooltipHelper;
            this._itemViewUpdateTrigger = itemViewUpdateTrigger;
            this._settingsDao           = settingsDao;
            this._playerItemDao         = playerItemDao;
            this._parser       = parser;
            this._modFilter    = modFilter;
            this._stashManager = stashManager;
            _parsingService    = parsingService;
            _itemTagDao        = itemTagDao;

            _controller.BindCheckbox(cbMinimizeToTray);

            _controller.BindCheckbox(cbMergeDuplicates);
            _controller.BindCheckbox(cbTransferAnyMod);
            _controller.BindCheckbox(cbSecureTransfers);
            _controller.BindCheckbox(cbShowRecipesAsItems);
            _controller.BindCheckbox(cbAutoUpdateModSettings);
            _controller.BindCheckbox(cbAutoSearch);
            _controller.BindCheckbox(cbDisplaySkills);
            _controller.LoadDefaults();
        }
Exemple #5
0
 public ImportExportModePicker(GDTransferFile[] modFilter, IPlayerItemDao playerItemDao, Control.ControlCollection parentContainer, StashManager sm)
 {
     InitializeComponent();
     this.modFilter       = modFilter;
     this.playerItemDao   = playerItemDao;
     this.parentContainer = parentContainer;
     this.sm = sm;
 }
Exemple #6
0
        public SearchController(
            IDatabaseItemDao databaseItemDao,
            IPlayerItemDao playerItemDao,
            IDatabaseItemStatDao databaseItemStatDao,
            IItemSkillDao itemSkillDao,
            IBuddyItemDao buddyItemDao,
            StashManager stashManager,
            AugmentationItemRepo augmentationItemRepo
            )
        {
            this._dbItemDao              = databaseItemDao;
            this._playerItemDao          = playerItemDao;
            this._itemStatService        = new ItemStatService(databaseItemStatDao, itemSkillDao);
            this._itemPaginatorService   = new ItemPaginatorService(TakeSize);
            this._recipeService          = new RecipeService(databaseItemDao);
            this._costCalculationService = new CostCalculationService(playerItemDao, stashManager);
            this._buddyItemDao           = buddyItemDao;
            this._stashManager           = stashManager;
            this._augmentationItemRepo   = augmentationItemRepo;


            // Just make sure it writes .css/.html files before displaying anything to the browser
            //
            ItemHtmlWriter.ToJsonSerializeable(new List <PlayerHeldItem>()); // TODO: is this not a NOOP?
            JsBind.OnRequestItems += JsBind_OnRequestItems;

            // Return the ingredients for a given recipe
            JsBind.OnRequestRecipeIngredients += (sender, args) => {
                var recipeArgument = args as RequestRecipeArgument;
                var ingredients    = _recipeService.GetRecipeIngredients(recipeArgument?.RecipeRecord);
                _costCalculationService.Populate(ingredients);
                _costCalculationService.SetMod(_previousMod);

                _previousCallback = recipeArgument?.Callback;
                _previousRecipe   = recipeArgument?.RecipeRecord;
                Browser.SetRecipeIngredients(JsBind.Serialize(ingredients));
            };


            // Update the recipe when the stash has changed
            stashManager.StashUpdated += StashManagerOnStashUpdated;


            // Return the list of recipes
            JsBind.OnRequestRecipeList += (sender, args) => {
                var recipes = _recipeService.GetRecipeList();
                Browser.SetRecipes(JsBind.Serialize(recipes));
            };
        }
        public bool TransferToOpenStash(PlayerItem pi)
        {
            List <byte> buffer   = ItemInjectCallbackProcessor.Serialize(pi);
            var         stashTab = Properties.Settings.Default.StashToDepositTo;

            if (stashTab == 0)
            {
                // Find real tab.. Related to hotfix v1.0.4.0
                stashTab = StashManager.GetNumStashPages(GetTransferFile());
            }

            var position = _dynamicPacker.Insert(pi.BaseRecord, (uint)pi.Seed);

            if (position == null)
            {
                _logger.Warn("Item insert canceled, no valid position found.");
                _setFeedback(GlobalSettings.Language.GetTag("iatag_deposit_stash_full"));
                return(false);
            }
            buffer.InsertRange(0, BitConverter.GetBytes(position.X * 32));
            buffer.InsertRange(4, BitConverter.GetBytes(position.Y * 32));
            buffer.InsertRange(0, BitConverter.GetBytes(stashTab));

            using (NamedPipeClientStream pipeStream = new NamedPipeClientStream(".", "gdiahook", PipeDirection.InOut, PipeOptions.Asynchronous))
            {
                // The connect function will indefinitely wait for the pipe to become available
                // If that is not acceptable specify a maximum waiting time (in ms)
                try
                {
                    pipeStream.Connect(250);
                }
                catch (TimeoutException)
                {
                    return(false);
                }

                pipeStream.Write(buffer.ToArray(), 0, buffer.Count);
                _logger.Debug("Wrote item to pipe");
                _setFeedback(GlobalSettings.Language.GetTag("iatag_deposit_pipe_success"));
            }

            return(true);
        }
Exemple #8
0
 public ItemTransferController(
     CefBrowserHandler browser,
     Action <string> feedback,
     Action <string> setTooltip,
     ISettingsReadController settingsController,
     SearchWindow searchWindow,
     DynamicPacker dynamicPacker,
     IPlayerItemDao playerItemDao,
     StashManager stashManager,
     ItemStatService itemStatService
     )
 {
     this._browser            = browser;
     this._setFeedback        = feedback;
     this._setTooltip         = setTooltip;
     this._settingsController = settingsController;
     this._searchWindow       = searchWindow;
     this._dynamicPacker      = dynamicPacker;
     this._dao             = playerItemDao;
     this._stashManager    = stashManager;
     this._itemStatService = itemStatService;
 }
Exemple #9
0
        public SettingsWindow(
            IItemTagDao itemTagDao,
            TooltipHelper tooltipHelper,
            Action itemViewUpdateTrigger,
            IDatabaseSettingDao settingsDao,
            IDatabaseItemDao itemDao,
            IPlayerItemDao playerItemDao,
            ArzParser parser,
            GDTransferFile[] modFilter,
            StashManager stashManager, ParsingService parsingService)
        {
            InitializeComponent();
            this._tooltipHelper         = tooltipHelper;
            this._itemViewUpdateTrigger = itemViewUpdateTrigger;
            this._settingsDao           = settingsDao;
            this._itemDao       = itemDao;
            this._playerItemDao = playerItemDao;
            this._parser        = parser;
            this._modFilter     = modFilter;
            this._stashManager  = stashManager;
            _parsingService     = parsingService;
            _itemTagDao         = itemTagDao;

            _controller.BindCheckbox(cbMinimizeToTray);

            _controller.BindCheckbox(cbMergeDuplicates);
            _controller.BindCheckbox(cbTransferAnyMod);
            _controller.BindCheckbox(cbSecureTransfers);
            _controller.BindCheckbox(cbShowRecipesAsItems);
            _controller.BindCheckbox(cbAutoUpdateModSettings);
            //_controller.BindCheckbox(cbInstalootDisabled);
            _controller.BindCheckbox(cbInstaTransfer);
            _controller.BindCheckbox(cbAutoSearch);
            _controller.BindCheckbox(cbDisplaySkills);
            _controller.LoadDefaults();

            cbInstalootEnabled.Checked = (InstalootSettingType)Properties.Settings.Default.InstalootSetting == InstalootSettingType.Enabled;
        }
 public ItemReceivedProcessor(SearchWindow searchWindow, StashManager stashManager, IPlayerItemDao playerItemDao)
 {
     this.searchWindow  = searchWindow;
     this.stashManager  = stashManager;
     this.playerItemDao = playerItemDao;
 }
 public CostCalculationService(IPlayerItemDao playerItemDao, StashManager stashManager)
 {
     _playerItemDao = playerItemDao;
     _stashManager  = stashManager;
 }
Exemple #12
0
        private void MainWindow_Load(object sender, EventArgs e)
        {
            if (Thread.CurrentThread.Name == null)
            {
                Thread.CurrentThread.Name = "UI";
            }

            ExceptionReporter.EnableLogUnhandledOnThread();
            SizeChanged += OnMinimizeWindow;

            _stashManager = new StashManager(_playerItemDao, _databaseItemStatDao, SetFeedback, ListviewUpdateTrigger);
            _stashFileMonitor.OnStashModified += (_, __) => {
                StashEventArg args = __ as StashEventArg;
                if (_stashManager != null && _stashManager.TryLootStashFile(args?.Filename))
                {
                    // STOP TIMER
                    _stashFileMonitor.CancelQueuedNotify();
                } // TODO: This logic should be changed to 're queue' but only trigger once, if its slow it triggers multiple times.
            };

            if (!_stashFileMonitor.StartMonitorStashfile(GlobalPaths.SavePath))
            {
                MessageBox.Show("Ooops!\nIt seems you are synchronizing your saves to steam cloud..\nThis tool is unfortunately not compatible.\n");
                Process.Start("http://www.grimdawn.com/forums/showthread.php?t=20752");

                if (!Debugger.IsAttached)
                {
                    Close();
                }
            }

            // Chicken and the egg..
            SearchController searchController = new SearchController(
                _databaseItemDao,
                _playerItemDao,
                _databaseItemStatDao,
                _itemSkillDao,
                _buddyItemDao,
                _stashManager,
                _augmentationItemRepo
                );

            _cefBrowserHandler.InitializeChromium(searchController.JsBind, Browser_IsBrowserInitializedChanged);
            searchController.Browser             = _cefBrowserHandler;
            searchController.JsBind.OnClipboard += SetItemsClipboard;

            // Load the grim database
            string gdPath = GrimDawnDetector.GetGrimLocation();

            if (!string.IsNullOrEmpty(gdPath))
            {
            }
            else
            {
                Logger.Warn("Could not find the Grim Dawn install location");
                statusLabel.Text = "Could not find the Grim Dawn install location";

                var timer = new System.Windows.Forms.Timer();
                timer.Tick    += TimerTickLookForGrimDawn;
                timer.Interval = 10000;
                timer.Start();
            }

            // Load recipes
            foreach (string file in GlobalPaths.FormulasFiles)
            {
                if (!string.IsNullOrEmpty(file))
                {
                    bool isHardcore = file.EndsWith("gsh");
                    Logger.InfoFormat("Reading recipes at \"{0}\", IsHardcore={1}", file, isHardcore);
                    _recipeParser.UpdateFormulas(file, isHardcore);
                }
            }

            var addAndShow = UIHelper.AddAndShow;

            // Create the tab contents
            _buddySettingsWindow = new BuddySettings(delegate(bool b) { BuddySyncEnabled = b; },
                                                     _buddyItemDao,
                                                     _buddySubscriptionDao
                                                     );

            addAndShow(_buddySettingsWindow, buddyPanel);

            _authAuthService = new AzureAuthService(_cefBrowserHandler, new AuthenticationProvider());
            var backupSettings = new BackupSettings(_playerItemDao, _authAuthService);

            addAndShow(backupSettings, backupPanel);
            addAndShow(new ModsDatabaseConfig(DatabaseLoadedTrigger, _playerItemDao, _parsingService), modsPanel);
            addAndShow(new HelpTab(), panelHelp);
            addAndShow(new LoggingWindow(), panelLogging);
            var backupService = new BackupService(_authAuthService, _playerItemDao, _azurePartitionDao, () => Settings.Default.UsingDualComputer);

            _backupServiceWorker            = new BackupServiceWorker(backupService);
            backupService.OnUploadComplete += (o, args) => _searchWindow.UpdateListView();
            searchController.OnSearch      += (o, args) => backupService.OnSearch();

            _searchWindow = new SplitSearchWindow(_cefBrowserHandler.BrowserControl, SetFeedback, _playerItemDao, searchController, _itemTagDao);
            addAndShow(_searchWindow, searchPanel);
            _stashManager.StashUpdated += (_, __) => {
                _searchWindow.UpdateListView();
            };

            addAndShow(
                new SettingsWindow(
                    _cefBrowserHandler,
                    _itemTagDao,
                    _tooltipHelper,
                    ListviewUpdateTrigger,
                    _databaseSettingDao,
                    _playerItemDao,
                    _arzParser,
                    _searchWindow.ModSelectionHandler.GetAvailableModSelection(),
                    _stashManager,
                    _parsingService
                    ),
                settingsPanel);

            new StashTabPicker(_stashManager.NumStashTabs).SaveStashSettingsToRegistry();

#if !DEBUG
            ThreadPool.QueueUserWorkItem(m => ExceptionReporter.ReportUsage());
            CheckForUpdates();
#endif

            int min  = 1000 * 60;
            int hour = 60 * min;
            _timerReportUsage = new Timer();
            _timerReportUsage.Start();
            _timerReportUsage.Elapsed += (a1, a2) => {
                if (Thread.CurrentThread.Name == null)
                {
                    Thread.CurrentThread.Name = "ReportUsageThread";
                }
                ReportUsage();
            };
            _timerReportUsage.Interval  = 12 * hour;
            _timerReportUsage.AutoReset = true;
            _timerReportUsage.Start();

            Shown += (_, __) => { StartInjector(); };

            //settingsController.Data.budd
            BuddySyncEnabled = (bool)Settings.Default.BuddySyncEnabled;

            // Start the backup task
            _backupBackgroundTask = new BackgroundTask(new FileBackup(_playerItemDao));

            LocalizationLoader.ApplyLanguage(Controls, GlobalSettings.Language);
            EasterEgg.Activate(this);

            // Initialize the "stash packer" used to find item positions for transferring items ingame while the stash is open
            {
                _dynamicPacker.Initialize(8, 16);

                var transferFiles = GlobalPaths.TransferFiles;
                if (transferFiles.Count > 0)
                {
                    var file  = transferFiles.MaxBy(m => m.LastAccess);
                    var stash = StashManager.GetStash(file.Filename);
                    if (stash != null)
                    {
                        _dynamicPacker.Initialize(stash.Width, stash.Height);
                        if (stash.Tabs.Count >= 3)
                        {
                            foreach (var item in stash.Tabs[2].Items)
                            {
                                byte[] bx = BitConverter.GetBytes(item.XOffset);
                                uint   x  = (uint)BitConverter.ToSingle(bx, 0);

                                byte[] by = BitConverter.GetBytes(item.YOffset);
                                uint   y  = (uint)BitConverter.ToSingle(by, 0);

                                _dynamicPacker.Insert(item.BaseRecord, item.Seed, x, y);
                            }
                        }
                    }
                }
            }

            _messageProcessors.Add(new ItemPositionFinder(_dynamicPacker));
            _messageProcessors.Add(new PlayerPositionTracker());
            _messageProcessors.Add(new StashStatusHandler());
            _messageProcessors.Add(new ItemReceivedProcessor(_searchWindow, _stashFileMonitor, _playerItemDao));
            _messageProcessors.Add(new ItemInjectCallbackProcessor(_searchWindow.UpdateListViewDelayed, _playerItemDao));
            _messageProcessors.Add(new ItemSpawnedProcessor());
            _messageProcessors.Add(new CloudDetectorProcessor(SetFeedback));
            _messageProcessors.Add(new GenericErrorHandler());
            //messageProcessors.Add(new LogMessageProcessor());
#if DEBUG
            //messageProcessors.Add(new DebugMessageProcessor());
#endif

            GlobalSettings.StashStatusChanged += GlobalSettings_StashStatusChanged;

            _transferController = new ItemTransferController(
                _cefBrowserHandler,
                SetFeedback,
                SetTooltipAtmouse,
                _settingsController,
                _searchWindow,
                _dynamicPacker,
                _playerItemDao,
                _stashManager,
                new ItemStatService(_databaseItemStatDao, _itemSkillDao)
                );
            Application.AddMessageFilter(new MousewheelMessageFilter());


            var titleTag = GlobalSettings.Language.GetTag("iatag_ui_itemassistant");
            if (!string.IsNullOrEmpty(titleTag))
            {
                this.Text += $" - {titleTag}";
            }


            // Popup login diag
            if (_authAuthService.CheckAuthentication() == AzureAuthService.AccessStatus.Unauthorized)
            {
                var t = new System.Windows.Forms.Timer {
                    Interval = 100
                };
                t.Tick += (o, args) => {
                    if (_cefBrowserHandler.BrowserControl.IsBrowserInitialized)
                    {
                        _authAuthService.Authenticate();
                        t.Stop();
                    }
                };
                t.Start();
            }


            _cefBrowserHandler.TransferSingleRequested += TransferSingleItem;
            _cefBrowserHandler.TransferAllRequested    += TransferAllItems;
            new WindowSizeManager(this);
        }
        private void MainWindow_Load(object sender, EventArgs e) {
            if (Thread.CurrentThread.Name == null)
                Thread.CurrentThread.Name = "UI";


            ExceptionReporter.EnableLogUnhandledOnThread();
            SizeChanged += OnMinimizeWindow;

            buttonDevTools.Visible = Debugger.IsAttached;


            _stashManager = new StashManager(_playerItemDao, _databaseItemStatDao);
            if (!_stashManager.StartMonitorStashfile(SetFeedback, ListviewUpdateTrigger)) {
                MessageBox.Show("Ooops!\nIt seems you are synchronizing your saves to steam cloud..\nThis tool is unfortunately not compatible.\n");
                Process.Start("http://www.grimdawn.com/forums/showthread.php?t=20752");

                if (!Debugger.IsAttached)
                    Close();

            }

            //ItemHtmlWriter.Write(new List<PlayerHeldItem>());

            // Chicken and the egg..
            SearchController searchController = new SearchController(
                _databaseItemDao,
                _playerItemDao, 
                _databaseItemStatDao, 
                _itemSkillDao, 
                _buddyItemDao,
                _stashManager
                );
            _cefBrowserHandler.InitializeChromium(searchController.JsBind, Browser_IsBrowserInitializedChanged);
            searchController.Browser = _cefBrowserHandler;
            searchController.JsBind.OnTransfer += TransferItem;
            searchController.JsBind.OnClipboard += SetItemsClipboard;

            // Load the grim database
            string gdPath = GrimDawnDetector.GetGrimLocation();
            if (!string.IsNullOrEmpty(gdPath)) {
            } else {
                Logger.Warn("Could not find the Grim Dawn install location");
                statusLabel.Text = "Could not find the Grim Dawn install location";

                var timer = new System.Windows.Forms.Timer();
                timer.Tick += TimerTickLookForGrimDawn;
                timer.Interval = 10000;
                timer.Start();
            }

    

            var addAndShow = UIHelper.AddAndShow;


            // Create the tab contents
            _buddySettingsWindow = new BuddySettings(delegate (bool b) { BuddySyncEnabled = b; }, 
                _buddyItemDao, 
                _buddySubscriptionDao
                );

            addAndShow(_buddySettingsWindow, buddyPanel);

            var backupSettings = new BackupSettings(EnableOnlineBackups, _playerItemDao);
            tabControl1.Selected += ((s, ev) => {
                if (ev.TabPage == tabPageBackups)
                    backupSettings?.BackupSettings_GotFocus();
            });
            addAndShow(backupSettings, backupPanel);
            addAndShow(new ModsDatabaseConfig(DatabaseLoadedTrigger, _databaseSettingDao, _arzParser, _playerItemDao), modsPanel);
            addAndShow(new HelpTab(), panelHelp);            
            addAndShow(new LoggingWindow(), panelLogging);


            _searchWindow = new SearchWindow(_cefBrowserHandler.BrowserControl, SetFeedback, _playerItemDao, searchController, _databaseItemDao);
            addAndShow(_searchWindow, searchPanel);


            addAndShow(
                new SettingsWindow(_tooltipHelper,
                    ListviewUpdateTrigger,
                    _databaseSettingDao,
                    _databaseItemDao,
                    _playerItemDao,
                    _arzParser,
                    _searchWindow.ModSelectionHandler.GetAvailableModSelection(),
                    _stashManager
                ),
                settingsPanel);


            new StashTabPicker(_stashManager.NumStashTabs).SaveStashSettingsToRegistry();

#if !DEBUG
            ThreadPool.QueueUserWorkItem(m => ExceptionReporter.ReportUsage());
            CheckForUpdates();
#endif

            int min = 1000 * 60;
            int hour = 60 * min;
            _timerReportUsage = new Timer();
            _timerReportUsage.Start();
            _timerReportUsage.Elapsed += (a1, a2) => {
                if (Thread.CurrentThread.Name == null)
                    Thread.CurrentThread.Name = "ReportUsageThread";
                ReportUsage();
            };
            _timerReportUsage.Interval = 12 * hour;
            _timerReportUsage.AutoReset = true;
            _timerReportUsage.Start();


            Shown += (_, __) => { StartInjector(); };

            //settingsController.Data.budd
            BuddySyncEnabled = (bool)Settings.Default.BuddySyncEnabled;

            // Start the backup task
            _backupBackgroundTask = new BackgroundTask(new CloudBackup(_playerItemDao));



            LocalizationLoader.ApplyLanguage(Controls, GlobalSettings.Language);
            EasterEgg.Activate(this);
Exemple #14
0
        public void startChopShopJob(Client player, params object[] arguments)
        {
            if (player.position.DistanceTo(startPoint) >= 5)
            {
                return;
            }

            Mission mission;

            if (API.hasEntityData(player, "Mission"))
            {
                mission = API.getEntityData(player, "Mission");
                if (mission.MissionObjectiveCount > 0)
                {
                    API.sendChatMessageToPlayer(player, "~r~You seem to already have a mission running.");
                    return;
                }
                API.setEntitySyncedData(player, "Mission_New_Instance", true);
                API.setEntityData(player, "Mission", mission);
                mission.addPlayer(player);
            }
            else
            {
                mission = new Mission();
                API.setEntitySyncedData(player, "Mission_New_Instance", true);
                API.setEntityData(player, "Mission", mission);
                mission.addPlayer(player);
            }

            // Basic Setup.
            mission.useTimer();
            mission.MissionTime              = 60 * 5;
            mission.MissionReward            = reward;
            mission.MissionTitle             = "Chop Shop";
            mission.RemoveFromMissionOnDeath = true;

            StashInfo stash = StashManager.getStashInfoByID(1);

            if (stash == null)
            {
                API.sendChatMessageToPlayer(player, "~r~Something went wrong with stashes. Contact an administrator.");
                return;
            }

            mission.AttachStashInfo = stash;

            // Setup a unique ID for the vehicle we'll be using.
            int uniqueID = new Random().Next(1, 50000);
            // == First Major Objective
            // = Create an empty objective to house information. Create an empty ObjectiveInfo Add our first objective, and associate the Vehicle ID with our objective.
            Objective     objective     = mission.addEmptyObjective(mission);
            ObjectiveInfo objectiveInfo = objective.addEmptyObjectiveInfo();

            objectiveInfo.Location = midPoint;
            objectiveInfo.Type     = Objective.ObjectiveTypes.Location;
            objectiveInfo.Lockpick = new minigames.Lockpick();

            // == Second Major Objective
            int     missionIndex = new Random().Next(0, locations.Count);
            int     carIndex     = new Random().Next(0, vehicleList.Count);
            Vector3 location     = locations[missionIndex].Location;
            Vector3 rotation     = locations[missionIndex].Rotation;

            objective              = mission.addEmptyObjective(mission);
            objectiveInfo          = objective.addEmptyObjectiveInfo();
            objectiveInfo.Location = location;
            objectiveInfo.Type     = Objective.ObjectiveTypes.BreakIntoVehicle;
            objectiveInfo.Lockpick = new minigames.Lockpick();
            NetHandle vehicle = objective.addObjectiveVehicle(mission, location.Add(new Vector3(0, 0, 0.2)), API.vehicleNameToModel(vehicleList[carIndex]), rotation, uniqueID);

            API.setVehiclePrimaryColor(vehicle, new Random().Next(0, 159));
            API.setVehicleSecondaryColor(vehicle, new Random().Next(0, 159));

            API.setEntityPositionFrozen(vehicle, true);
            API.delay(5000, true, () =>
            {
                API.setVehicleLocked(vehicle, true);
                API.setVehicleEngineStatus(vehicle, false);
                API.setEntityPositionFrozen(vehicle, false);
            });

            // == Third Major Objective - Take Vehicle
            objective                     = mission.addEmptyObjective(mission);
            objectiveInfo                 = objective.addEmptyObjectiveInfo();
            objectiveInfo.Location        = location;
            objectiveInfo.Type            = Objective.ObjectiveTypes.RetrieveVehicle;
            objectiveInfo.UniqueVehicleID = uniqueID;
            objectiveInfo                 = objective.addEmptyObjectiveInfo();
            objectiveInfo.Type            = Objective.ObjectiveTypes.UnlockVehicles;
            objectiveInfo.Location        = new Vector3();
            objectiveInfo.UniqueVehicleID = uniqueID;

            // == Parse End Point
            objective                     = mission.addEmptyObjective(mission);
            objectiveInfo                 = objective.addEmptyObjectiveInfo();
            objectiveInfo.Location        = endPoint;
            objectiveInfo.Type            = Objective.ObjectiveTypes.VehicleLocation;
            objectiveInfo.UniqueVehicleID = uniqueID;

            // == Start Mission

            mission.startMission();
        }