コード例 #1
0
        private void UpdateLocal()
        {
            var game = Game;

            if (game == null)
            {
                MessageBoxViewModel.ShowMessage("No game loaded");
                return;
            }

            if (game.Script.Editor.ErrorsToolWindow.References.Count > 0)
            {
                MessageBoxViewModel.ShowMessage("Cannot update while errors exist.");
                game.Script.Editor.ErrorsToolWindow.IsVisible = true;
                return;
            }

            if (String.IsNullOrEmpty(game.RACacheDirectory))
            {
                MessageBoxViewModel.ShowMessage("Could not identify local directory.");
                return;
            }

            var dialog = new UpdateLocalViewModel(game);

            dialog.ShowDialog();
        }
コード例 #2
0
        /// <summary>
        /// Replaces all matching items with the new text.
        /// </summary>
        public void ReplaceAll()
        {
            int replaceCount = MatchCount;

            if (replaceCount > 0)
            {
                int matchCount = replaceCount;
                while (matchCount > 1)
                {
                    Replace();
                    matchCount--;
                }

                var line   = Owner.CursorLine;
                var column = Owner.CursorColumn;
                Replace();


                if (MatchCount == 0)
                {
                    Owner.MoveCursorTo(line, column + SearchText.Text.Length, CodeEditorViewModel.MoveCursorFlags.None);
                }
                else
                {
                    replaceCount -= MatchCount;
                }
            }

            MessageBoxViewModel.ShowMessage(string.Format("Replaced {0} occurrances", replaceCount));

            Owner.IsFocusRequested = true;
        }
コード例 #3
0
        /// <summary>
        /// Attempts to open an Access database.
        /// </summary>
        /// <param name="fileName">Path to the Access database.</param>
        public bool Connect(string fileName)
        {
            _logger.Write("Opening database: {0}", fileName);

            // try newer driver first
            string connectionString = "Driver={Microsoft Access Driver (*.mdb, *.accdb)}; DBQ=" + fileName;
            var    connection       = new OdbcConnection(connectionString);

            try
            {
                connection.Open();
            }
            catch (OdbcException ex)
            {
                _logger.Write("Failed to open database: " + ex.Message);

                if (ex.Message.Contains("[IM002]"))
                {
                    if (IntPtr.Size != 4 && File.Exists(fileName))
                    {
                        MessageBoxViewModel.ShowMessage("Access driver not found - assuming 64-bit access driver not installed");
                    }

                    // https://knowledge.autodesk.com/support/autocad/learn-explore/caas/sfdcarticles/sfdcarticles/How-to-install-64-bit-Microsoft-Database-Drivers-alongside-32-bit-Microsoft-Office.html
                    // * download AccessDatabaseEngine_X64.exe from https://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=13255
                    // * run it with the /quiet option: > AccessDatabaseEngine_X64.exe /quiet
                    // * delete or rename the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Common\FilesPaths\mso.dll registry key
                }

                return(false);
            }
            catch (InvalidOperationException ex)
            {
                _logger.Write("Failed to open database: " + ex.Message);

                // then try older driver
                connectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + fileName;
                connection       = new OdbcConnection(connectionString);
                connection.Open();
            }

            while (connection.State == System.Data.ConnectionState.Connecting)
            {
                System.Threading.Thread.Sleep(100);
            }

            if (connection.State == System.Data.ConnectionState.Open)
            {
                _logger.Write("Database opened");
                _connection = connection;
            }
            else
            {
                _logger.Write("Failed to open database: " + connection.State);
            }

            return(connection.State == System.Data.ConnectionState.Open);
        }
コード例 #4
0
        private void RefreshFromServer(int gameId, IFileSystemService fileSystemService, IHttpRequestService httpRequestService)
        {
            var file = Path.Combine(_settings.DumpDirectory, String.Format("{0}.json", gameId));

            if (fileSystemService.FileExists(file))
            {
                bool fileValid = (DateTime.Now - fileSystemService.GetFileLastModified(file)) < TimeSpan.FromHours(16);
                if (fileValid)
                {
                    return;
                }
            }

            Debug.WriteLine(String.Format("{0} fetching patch data {1}", DateTime.Now, gameId));
            var url = String.Format("http://retroachievements.org/dorequest.php?u={0}&t={1}&g={2}&h=1&r=patch",
                                    _settings.UserName, _settings.DoRequestToken, gameId);
            var request  = new HttpRequest(url);
            var response = httpRequestService.Request(request);

            if (response.Status == System.Net.HttpStatusCode.OK)
            {
                using (var outputStream = fileSystemService.CreateFile(file))
                {
                    byte[] buffer = new byte[4096];
                    using (var stream = response.GetResponseStream())
                    {
                        int bytesRead;
                        while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            if (bytesRead < 100)
                            {
                                var str = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                                if (str.Contains("Error"))
                                {
                                    if (_progress != null)
                                    {
                                        _progress.IsEnabled = false;
                                        _progress.Label     = String.Empty;
                                    }
                                    _backgroundWorkerService.InvokeOnUiThread(() => MessageBoxViewModel.ShowMessage(str));
                                    return;
                                }
                            }
                            outputStream.Write(buffer, 0, bytesRead);
                        }
                    }
                }

                string contents;
                using (var stream = new StreamReader(fileSystemService.OpenFile(file, OpenFileMode.Read)))
                {
                    contents = stream.ReadToEnd();
                }
            }
        }
コード例 #5
0
        /// <summary>
        /// Commits the achivement list back to the 'XXX-User.txt' file.
        /// </summary>
        public void Commit(string author)
        {
            var warning = new StringBuilder();

            using (var writer = new StreamWriter(_fileSystemService.CreateFile(_filename)))
            {
                writer.WriteLine(_version);
                writer.WriteLine(Title);

                foreach (var achievement in _achievements)
                {
                    writer.Write(achievement.Id);
                    writer.Write(":\"");

                    var requirements = AchievementBuilder.SerializeRequirements(achievement);
                    if (requirements.Length > AchievementMaxLength)
                    {
                        warning.AppendFormat("Achievement \"{0}\" exceeds serialized limit ({1}/{2})", achievement.Title, requirements.Length, AchievementMaxLength);
                        warning.AppendLine();
                    }

                    writer.Write(requirements);
                    writer.Write("\":\"");

                    WriteEscaped(writer, achievement.Title);
                    writer.Write("\":\"");

                    WriteEscaped(writer, achievement.Description);
                    writer.Write("\":");

                    writer.Write(" : : :"); // discontinued features

                    writer.Write(author);   // author
                    writer.Write(':');

                    writer.Write(achievement.Points);
                    writer.Write(':');

                    writer.Write("0:0:0:0:"); // created, modified, upvotes, downvotes

                    writer.Write(achievement.BadgeName);
                    writer.WriteLine();
                }
            }

            if (warning.Length > 0)
            {
                MessageBoxViewModel.ShowMessage(warning.ToString());
            }
        }
コード例 #6
0
        private void OpenTickets()
        {
            var settings = ServiceRepository.Instance.FindService <ISettings>();

            if (String.IsNullOrEmpty(settings.Cookie))
            {
                MessageBoxViewModel.ShowMessage("This feature requires a Cookie value to be set in the ini file.");
                return;
            }

            if (String.IsNullOrEmpty(settings.UserName))
            {
                MessageBoxViewModel.ShowMessage("This feature requires a User value to be set in the ini file.");
                return;
            }

            var vm = new OpenTicketsViewModel();

            vm.ShowDialog();
        }
コード例 #7
0
        private void Search()
        {
            int gameId = GameId.Value.GetValueOrDefault();

            foreach (var directory in ServiceRepository.Instance.FindService <ISettings>().DataDirectories)
            {
                var notesFile = Path.Combine(directory, gameId + "-Notes.json");
                if (!File.Exists(notesFile))
                {
                    notesFile = Path.Combine(directory, gameId + "-Notes2.txt");
                }

                if (File.Exists(notesFile))
                {
                    LoadGame(gameId, directory);
                    return;
                }
            }

            MessageBoxViewModel.ShowMessage("Could not locate notes file for game " + gameId);
            return;
        }
コード例 #8
0
        private void DoPlayback()
        {
            var    backgroundWorkerService = ServiceRepository.Instance.FindService <IBackgroundWorkerService>();
            string line;
            {
                var builder = new StringBuilder();

                while ((line = _reader.ReadLine()) != null)
                {
                    if (line == "==-==-==-==-==-==")
                    {
                        break;
                    }

                    builder.AppendLine(line);
                }

                backgroundWorkerService.InvokeOnUiThread(() =>
                {
                    SetContent(builder.ToString());
                });
            }

            int totalTime = 0;
            var stopwatch = Stopwatch.StartNew();

            while ((line = _reader.ReadLine()) != null)
            {
                var parts = line.Split(' ');
                var delay = Int32.Parse(parts[0]);
                totalTime += delay;
                if (delay > 1000)
                {
                    delay = 1000;
                }
                if (delay > 5) // adjust the sleep just a little bit to accomodate for thread marshalling
                {
                    delay -= 5;
                }

                System.Threading.Thread.Sleep(delay);

                if (parts.Length == 2)
                {
                    if (parts[1].Length == 1)
                    {
                        TypeCharacter(parts[1][0]);
                    }
                    else
                    {
                        var modifiers = ModifierKeys.None;
                        foreach (var modifier in parts[1].Split('+'))
                        {
                            if (modifier == "Ctrl")
                            {
                                modifiers |= ModifierKeys.Control;
                            }
                            else if (modifier == "Shift")
                            {
                                modifiers |= ModifierKeys.Shift;
                            }
                            else if (modifier == "Alt")
                            {
                                modifiers |= ModifierKeys.Alt;
                            }
                            else
                            {
                                Key key;
                                if (Enum.TryParse(modifier, out key))
                                {
                                    if (key == Key.S && modifiers == ModifierKeys.Control)
                                    {
                                        _owner.Script.ResetModified();
                                    }
                                    else
                                    {
                                        var e = new KeyPressedEventArgs(key, modifiers);
                                        backgroundWorkerService.InvokeOnUiThread(() =>
                                        {
                                            OnKeyPressed(e);
                                        });
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    var flags = MoveCursorFlags.None;
                    if (parts[1] == "Shift+Click")
                    {
                        flags = MoveCursorFlags.Highlighting;
                    }

                    var location    = parts[2].Split(',');
                    var clickLine   = Int32.Parse(location[0]);
                    var clickColumn = Int32.Parse(location[1]);

                    backgroundWorkerService.InvokeOnUiThread(() =>
                    {
                        MoveCursorTo(clickLine, clickColumn, flags);
                    });
                }
            }

            _reader.Close();

            stopwatch.Stop();

            var totalElapsed    = TimeSpan.FromMilliseconds(totalTime);
            var playbackElapsed = stopwatch.Elapsed;

            backgroundWorkerService.InvokeOnUiThread(() =>
            {
                MessageBoxViewModel.ShowMessage(String.Format("Playback complete.\n\n" +
                                                              "Original time: {0}\nPlayback time: {1}", totalElapsed, playbackElapsed));
            });
        }
コード例 #9
0
        public RichPresenceViewModel(GameViewModel owner, string richPresence)
        {
            Title = "Rich Presence";

            _richPresence = richPresence ?? string.Empty;
            var genLines = _richPresence.Trim().Length > 0 ? _richPresence.Replace("\r\n", "\n").Split('\n') : new string[0];

            string[] localLines = new string[0];

            if (String.IsNullOrEmpty(owner.RACacheDirectory))
            {
                UpdateLocalCommand = DisabledCommand.Instance;
            }
            else
            {
                UpdateLocalCommand = new DelegateCommand(UpdateLocal);

                _richFile = Path.Combine(owner.RACacheDirectory, owner.GameId + "-Rich.txt");
                if (File.Exists(_richFile))
                {
                    var coreRichPresence = File.ReadAllText(_richFile);
                    RichPresenceLength = coreRichPresence.Length;
                    if (RichPresenceLength > 0)
                    {
                        localLines = coreRichPresence.Replace("\r\n", "\n").Split('\n');
                    }
                }
            }

            var  lines = new List <RichPresenceLine>();
            int  genIndex = 0, localIndex = 0;
            bool isModified = false;

            var genTags = new TinyDictionary <string, int>();

            for (int i = 0; i < genLines.Length; i++)
            {
                var line = genLines[i];
                if (line.StartsWith("Format:") || line.StartsWith("Lookup:") || line.StartsWith("Display:"))
                {
                    genTags[line] = i;
                }
            }

            var localTags = new TinyDictionary <string, int>();

            for (int i = 0; i < localLines.Length; i++)
            {
                var line = localLines[i];
                if (line.StartsWith("Format:") || line.StartsWith("Lookup:") || line.StartsWith("Display:"))
                {
                    localTags[line] = i;
                }
            }

            _hasGenerated = genLines.Length > 0;
            _hasLocal     = localLines.Length > 0;

            while (genIndex < genLines.Length && localIndex < localLines.Length)
            {
                if (genLines[genIndex] == localLines[localIndex])
                {
                    // matching lines, advance both
                    lines.Add(new RichPresenceLine(localLines[localIndex++], genLines[genIndex++]));
                    continue;
                }

                isModified = true;

                if (genLines[genIndex].Length == 0)
                {
                    // blank generated line, advance core
                    lines.Add(new RichPresenceLine(localLines[localIndex++], genLines[genIndex]));
                    continue;
                }

                if (localLines[localIndex].Length == 0)
                {
                    // blank core line, advance generated
                    lines.Add(new RichPresenceLine(localLines[localIndex], genLines[genIndex++]));
                    continue;
                }

                // if we're starting a lookup or value, try to line them up
                int genTagLine, localTagLine;
                if (!genTags.TryGetValue(localLines[localIndex], out genTagLine))
                {
                    genTagLine = -1;
                }
                if (!localTags.TryGetValue(genLines[genIndex], out localTagLine))
                {
                    localTagLine = -1;
                }

                if (genTagLine != -1 && localTagLine != -1)
                {
                    if (genTagLine > localTagLine)
                    {
                        genTagLine = -1;
                    }
                    else
                    {
                        localTagLine = -1;
                    }
                }

                if (genTagLine != -1)
                {
                    do
                    {
                        lines.Add(new RichPresenceLine("", genLines[genIndex++]));
                    } while (genIndex < genLines.Length && genLines[genIndex].Length > 0);

                    if (genIndex < genLines.Length)
                    {
                        lines.Add(new RichPresenceLine("", genLines[genIndex++]));
                    }
                    continue;
                }

                if (localTagLine != -1)
                {
                    do
                    {
                        lines.Add(new RichPresenceLine(localLines[localIndex++], ""));
                    } while (localIndex < localLines.Length && localLines[localIndex].Length > 0);

                    if (localIndex < localLines.Length)
                    {
                        lines.Add(new RichPresenceLine(localLines[localIndex++], ""));
                    }
                    continue;
                }

                // non-matching lines, scan ahead to find a match
                bool found = false;
                for (int temp = genIndex + 1; temp < genLines.Length; temp++)
                {
                    if (genLines[temp].Length == 0)
                    {
                        break;
                    }

                    if (genLines[temp] == localLines[localIndex])
                    {
                        while (genIndex < temp)
                        {
                            lines.Add(new RichPresenceLine("", genLines[genIndex++]));
                        }

                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    for (int temp = localIndex + 1; temp < localLines.Length; temp++)
                    {
                        if (localLines[temp].Length == 0)
                        {
                            break;
                        }

                        if (localLines[temp] == genLines[genIndex])
                        {
                            while (localIndex < temp)
                            {
                                lines.Add(new RichPresenceLine(localLines[localIndex++], ""));
                            }

                            found = true;
                            break;
                        }
                    }
                }

                // if a match was found, the next iteration will match them. if one wasn't found, advance both.
                if (!found)
                {
                    lines.Add(new RichPresenceLine(localLines[localIndex++], genLines[genIndex++]));
                }
            }

            if (!_hasGenerated)
            {
                foreach (var line in localLines)
                {
                    lines.Add(new RichPresenceLine(line));
                }

                GeneratedSource = "Local (Not Generated)";
                CompareSource   = String.Empty;

                ModificationMessage = null;
                CompareState        = GeneratedCompareState.None;
                CanUpdate           = false;
            }
            else if (isModified || genIndex != genLines.Length || localIndex != localLines.Length)
            {
                while (genIndex < genLines.Length)
                {
                    lines.Add(new RichPresenceLine("", genLines[genIndex++]));
                }
                while (localIndex < localLines.Length)
                {
                    lines.Add(new RichPresenceLine(localLines[localIndex++], ""));
                }

                if (!_hasLocal)
                {
                    GeneratedSource = "Generated (Not in Local)";
                    CompareSource   = String.Empty;
                }

                RichPresenceLength  = _richPresence.Length;
                ModificationMessage = _hasLocal ? "Local value differs from generated value" : "Local value does not exist";
                CompareState        = GeneratedCompareState.LocalDiffers;
                CanUpdate           = true;
            }
            else
            {
                GeneratedSource = "Generated (Same as Local)";
                CompareSource   = String.Empty;

                ModificationMessage = null;
                CanUpdate           = false;

                lines.Clear();
                foreach (var line in genLines)
                {
                    lines.Add(new RichPresenceLine(line));
                }
            }

            Lines = lines;

            if (_hasGenerated)
            {
                CopyToClipboardCommand = new DelegateCommand(() =>
                {
                    ServiceRepository.Instance.FindService <IClipboardService>().SetData(_richPresence);

                    if (_richPresence.Length > RichPresenceMaxLength)
                    {
                        MessageBoxViewModel.ShowMessage("Rich Presence exceeds maximum length of " + RichPresenceMaxLength + " characters (" + _richPresence.Length + ")");
                    }
                });
            }
        }
コード例 #10
0
        private void LoadTickets()
        {
            var games        = new Dictionary <int, GameTickets>();
            var tickets      = new Dictionary <int, AchievementTickets>();
            int totalTickets = 0;

            Progress.Reset(25);
            Progress.Label = "Fetching Open Tickets";

            int pageTickets;
            int page = 0;

            do
            {
                var ticketsPage = RAWebCache.Instance.GetOpenTicketsPage(page);
                if (ticketsPage == null)
                {
                    return;
                }

                if (page == 0 && !ticketsPage.Contains("<title>Ticket"))
                {
                    _backgroundWorkerService.InvokeOnUiThread(() =>
                    {
                        MessageBoxViewModel.ShowMessage("Could not retrieve open tickets. Please make sure the Cookie value is up to date in your ini file.");
                        Progress.Label = String.Empty;
                    });
                    var filename = Path.Combine(Path.GetTempPath(), String.Format("raTickets{0}.html", page));
                    File.Delete(filename);
                    return;
                }

                pageTickets = GetPageTickets(games, tickets, ticketsPage);

                ++page;
                totalTickets += pageTickets;
                Progress.Current++;
            } while (pageTickets == 100);

            Progress.Label = "Sorting data";

            var ticketList = new List <AchievementTickets>(tickets.Count);

            foreach (var kvp in tickets)
            {
                ticketList.Add(kvp.Value);
            }
            ticketList.Sort((l, r) =>
            {
                var diff = r.OpenTickets.Count - l.OpenTickets.Count;
                if (diff == 0)
                {
                    diff = String.Compare(l.AchievementName, r.AchievementName, StringComparison.OrdinalIgnoreCase);
                }
                return(diff);
            });

            TopAchievements = ticketList;

            var gameList = new List <GameTickets>(games.Count);

            foreach (var kvp in games)
            {
                gameList.Add(kvp.Value);
            }
            gameList.Sort((l, r) =>
            {
                var diff = r.OpenTickets - l.OpenTickets;
                if (diff == 0)
                {
                    diff = String.Compare(l.GameName, r.GameName, StringComparison.OrdinalIgnoreCase);
                }
                return(diff);
            });

            TopGames = gameList;

            OpenTickets = totalTickets;
            DialogTitle = "Open Tickets: " + totalTickets;

            Progress.Label = String.Empty;
        }
コード例 #11
0
        private void OpenFile(string filename)
        {
            if (!File.Exists(filename))
            {
                MessageBoxViewModel.ShowMessage("Could not open " + filename);
                return;
            }

            int    line           = 1;
            int    column         = 1;
            string selectedEditor = null;

            if (Game != null && Game.Script.Filename == filename)
            {
                if (Game.Script.CompareState == GeneratedCompareState.LocalDiffers)
                {
                    var vm = new MessageBoxViewModel("Revert to the last saved state? Your changes will be lost.");
                    vm.DialogTitle = "Revert Script";
                    if (vm.ShowOkCancelDialog() == DialogResult.Cancel)
                    {
                        return;
                    }
                }

                // capture current location so we can restore it after refreshing
                line           = Game.Script.Editor.CursorLine;
                column         = Game.Script.Editor.CursorColumn;
                selectedEditor = Game.SelectedEditor.Title;
            }
            else if (!CloseEditor())
            {
                return;
            }

            var  backupFilename = ScriptViewModel.GetBackupFilename(filename);
            bool usingBackup    = false;

            if (File.Exists(backupFilename))
            {
                var vm2 = new MessageBoxViewModel("Found an autosave file from " + File.GetLastWriteTime(backupFilename) + ".\nDo you want to open it instead?");
                vm2.DialogTitle = Path.GetFileName(filename);
                switch (vm2.ShowYesNoCancelDialog())
                {
                case DialogResult.Cancel:
                    return;

                case DialogResult.Yes:
                    filename    = backupFilename;
                    usingBackup = true;
                    break;

                default:
                    break;
                }
            }

            var logger = ServiceRepository.Instance.FindService <ILogService>().GetLogger("RATools");

            logger.WriteVerbose("Opening " + filename);

            string content;

            try
            {
                content = File.ReadAllText(filename);
            }
            catch (IOException ex)
            {
                MessageBoxViewModel.ShowMessage(ex.Message);
                return;
            }

            var tokenizer       = Tokenizer.CreateTokenizer(content);
            var expressionGroup = new AchievementScriptParser().Parse(tokenizer);

            int gameId    = 0;
            var idComment = expressionGroup.Comments.FirstOrDefault(c => c.Value.Contains("#ID"));

            if (idComment != null)
            {
                var tokens = idComment.Value.Split('=');
                if (tokens.Length > 1)
                {
                    Int32.TryParse(tokens[1].ToString(), out gameId);
                }
            }

            if (gameId == 0)
            {
                logger.WriteVerbose("Could not find game ID");
                MessageBoxViewModel.ShowMessage("Could not find game id");
                return;
            }

            if (!usingBackup)
            {
                AddRecentFile(filename);
            }

            logger.WriteVerbose("Game ID: " + gameId);

            var           gameTitle = expressionGroup.Comments[0].Value.Substring(2).Trim();
            GameViewModel viewModel = null;

            foreach (var directory in ServiceRepository.Instance.FindService <ISettings>().DataDirectories)
            {
                var notesFile = Path.Combine(directory, gameId + "-Notes2.txt");
                if (File.Exists(notesFile))
                {
                    logger.WriteVerbose("Found code notes in " + directory);

                    viewModel = new GameViewModel(gameId, gameTitle, directory.ToString());
                }
                else
                {
                    notesFile = Path.Combine(directory, gameId + "-Notes.json");
                    if (File.Exists(notesFile))
                    {
                        logger.WriteVerbose("Found code notes in " + directory);

                        viewModel = new GameViewModel(gameId, gameTitle, directory.ToString());
                    }
                }
            }

            if (viewModel == null)
            {
                logger.WriteVerbose("Could not find code notes");
                MessageBoxViewModel.ShowMessage("Could not locate notes file for game " + gameId);

                viewModel = new GameViewModel(gameId, gameTitle);
            }

            var existingViewModel = Game as GameViewModel;

            // if we're just refreshing the current game script, only update the script content,
            // which will be reprocessed and update the editor list. If it's not the same script,
            // or notes have changed, use the new view model.
            if (existingViewModel != null && existingViewModel.GameId == viewModel.GameId &&
                existingViewModel.Script.Filename == filename &&
                existingViewModel.Notes.Count == viewModel.Notes.Count)
            {
                existingViewModel.Script.SetContent(content);
                viewModel = existingViewModel;

                existingViewModel.SelectedEditor = Game.Editors.FirstOrDefault(e => e.Title == selectedEditor);
                existingViewModel.Script.Editor.MoveCursorTo(line, column, Jamiras.ViewModels.CodeEditor.CodeEditorViewModel.MoveCursorFlags.None);
            }
            else
            {
                if (usingBackup)
                {
                    viewModel.Script.Filename = Path.GetFileName(filename);
                    var title = viewModel.Title + " (from backup)";
                    viewModel.SetValue(GameViewModel.TitleProperty, title);
                }
                else
                {
                    viewModel.Script.Filename = filename;
                }

                viewModel.Script.SetContent(content);
                Game = viewModel;
            }

            if (viewModel.Script.Editor.ErrorsToolWindow.References.Count > 0)
            {
                viewModel.Script.Editor.ErrorsToolWindow.IsVisible = true;
            }
        }
コード例 #12
0
ファイル: GameStatsViewModel.cs プロジェクト: Jamiras/RATools
        internal void LoadGameFromServer(string gamePage, List <AchievementStats> achievementStats, List <UserStats> userStats)
        {
            NumberOfPlayers = 0; // reset so it gets updated from server data

            AchievementStats mostWon, leastWon;

            TotalPoints = LoadAchievementStatsFromServer(gamePage, achievementStats, out mostWon, out leastWon);

            var masteryPoints = (TotalPoints * 2).ToString();
            var masters       = GetMastersFromServer(gamePage, masteryPoints);

            Progress.Label = "Fetching user stats";
            Progress.Reset(achievementStats.Count);

            achievementStats.Sort((l, r) =>
            {
                var diff = r.EarnedHardcoreBy - l.EarnedHardcoreBy;
                if (diff == 0)
                {
                    diff = String.Compare(l.Title, r.Title, StringComparison.OrdinalIgnoreCase);
                }

                return(diff);
            });

            var possibleMasters  = new List <string>();
            var nonHardcoreUsers = new List <string>();

            foreach (var achievement in achievementStats)
            {
                var achievementPage = RAWebCache.Instance.GetAchievementPage(achievement.Id);
                if (achievementPage != null)
                {
                    var tokenizer = Tokenizer.CreateTokenizer(achievementPage);
                    tokenizer.ReadTo("<h3>Winners</h3>");

                    // NOTE: this only lists the ~50 most recent unlocks! For games with more than 50 users who have mastered it, the oldest may be missed!
                    do
                    {
                        var front = tokenizer.ReadTo("<a href='/user/");
                        if (tokenizer.NextChar == '\0')
                        {
                            break;
                        }

                        if (front.Contains("<div id=\"rightcontainer\">"))
                        {
                            break;
                        }

                        tokenizer.ReadTo("'>");
                        tokenizer.Advance(2);

                        // skip user image, we'll get the name from the text
                        var user = tokenizer.ReadTo("</a>");
                        if (user.StartsWith("<img"))
                        {
                            continue;
                        }

                        var mid = tokenizer.ReadTo("<small>");
                        if (mid.Contains("Hardcore!"))
                        {
                            tokenizer.Advance(7);
                            var when = tokenizer.ReadTo("</small>");
                            var date = DateTime.Parse(when.ToString());
                            date = DateTime.SpecifyKind(date, DateTimeKind.Utc);

                            var stats = new UserStats {
                                User = user.ToString()
                            };
                            var index = userStats.BinarySearch(stats, stats);
                            if (index < 0)
                            {
                                userStats.Insert(~index, stats);
                            }
                            else
                            {
                                stats = userStats[index];
                            }

                            stats.Achievements[achievement.Id] = date;

                            if (ReferenceEquals(achievement, leastWon))
                            {
                                if (!masters.Contains(stats.User))
                                {
                                    possibleMasters.Add(stats.User);
                                }
                            }
                        }
                        else
                        {
                            if (!nonHardcoreUsers.Contains(user.ToString()))
                            {
                                nonHardcoreUsers.Add(user.ToString());
                            }
                        }
                    } while (true);
                }

                Progress.Current++;
            }

            // if more than 50 people have earned achievements, people who mastered the game early may no longer display
            // in the individual pages. fetch mastery data by user
            if (mostWon == null || mostWon.EarnedBy <= 50)
            {
                HardcoreMasteredUserCountEstimated = false;
            }
            else
            {
                HardcoreMasteredUserCountEstimated = (leastWon.EarnedBy > 50);

                bool incompleteData = false;
                possibleMasters.AddRange(masters);

                Progress.Reset(possibleMasters.Count);
                foreach (var user in possibleMasters)
                {
                    Progress.Current++;

                    var stats = new UserStats {
                        User = user
                    };
                    var index = userStats.BinarySearch(stats, stats);
                    if (index < 0)
                    {
                        userStats.Insert(~index, stats);
                    }
                    else
                    {
                        stats = userStats[index];
                        if (stats.Achievements.Count >= achievementStats.Count)
                        {
                            continue;
                        }
                    }

                    if (!incompleteData && !MergeUserGameMastery(stats))
                    {
                        incompleteData = true;
                    }

                    stats.Incomplete = incompleteData;
                }

                if (incompleteData)
                {
                    _backgroundWorkerService.InvokeOnUiThread(() =>
                    {
                        var settings = ServiceRepository.Instance.FindService <ISettings>();
                        if (String.IsNullOrEmpty(settings.ApiKey))
                        {
                            MessageBoxViewModel.ShowMessage("Data is limited without an ApiKey in the ini file.");
                        }
                        else
                        {
                            MessageBoxViewModel.ShowMessage("Failed to fetch mastery information. Please make sure the ApiKey value is up to date in your ini file.");
                        }
                    });
                }
            }

            NonHardcoreUserCount = nonHardcoreUsers.Count;

            WriteGameStats(_gameName, achievementStats, userStats);
        }