Пример #1
0
 public LeaderboardViewModel(GameViewModel owner)
     : base(owner)
 {
 }
Пример #2
0
        private void LoadGame(int gameId, string raCacheDirectory)
        {
            _game = new GameViewModel(GameId.Value.GetValueOrDefault(), "", raCacheDirectory);
            _game.PopulateEditorList(null);
            DialogTitle = "New Script - " + _game.Title;

            _achievements.Clear();
            _ticketNotes.Clear();
            _memoryItems.Clear();
            MemoryAddresses.Rows.Clear();

            var unofficialAchievements = new List <DumpAchievementItem>();

            foreach (var achievement in _game.Editors.OfType <GeneratedAchievementViewModel>())
            {
                AchievementViewModel source = achievement.Core;
                if (source.Achievement == null)
                {
                    source = achievement.Unofficial;
                    if (source.Achievement == null)
                    {
                        continue;
                    }
                }

                var dumpAchievement = new DumpAchievementItem(achievement.Id, source.Title.Text);
                if (achievement.Core.Achievement == null)
                {
                    dumpAchievement.IsUnofficial = true;
                    unofficialAchievements.Add(dumpAchievement);
                }
                else
                {
                    _achievements.Add(dumpAchievement);
                }

                foreach (var group in source.RequirementGroups)
                {
                    foreach (var requirement in group.Requirements)
                    {
                        if (requirement.Requirement == null)
                        {
                            continue;
                        }

                        if (requirement.Requirement.Left != null && requirement.Requirement.Left.IsMemoryReference)
                        {
                            var memoryItem = AddMemoryAddress(requirement.Requirement.Left);
                            if (memoryItem != null && !dumpAchievement.MemoryAddresses.Contains(memoryItem))
                            {
                                dumpAchievement.MemoryAddresses.Add(memoryItem);
                            }
                        }

                        if (requirement.Requirement.Right != null && requirement.Requirement.Right.IsMemoryReference)
                        {
                            var memoryItem = AddMemoryAddress(requirement.Requirement.Right);
                            if (memoryItem != null && !dumpAchievement.MemoryAddresses.Contains(memoryItem))
                            {
                                dumpAchievement.MemoryAddresses.Add(memoryItem);
                            }
                        }
                    }
                }

                dumpAchievement.IsSelected       = true;
                dumpAchievement.PropertyChanged += DumpAchievement_PropertyChanged;
            }

            foreach (var unofficialAchievement in unofficialAchievements)
            {
                _achievements.Add(unofficialAchievement);
            }

            foreach (var kvp in _game.Notes)
            {
                FieldSize size  = FieldSize.Byte;
                Token     token = new Token(kvp.Value, 0, kvp.Value.Length);
                if (token.Contains("16-bit", StringComparison.OrdinalIgnoreCase) ||
                    token.Contains("16 bit", StringComparison.OrdinalIgnoreCase))
                {
                    size = FieldSize.Word;
                }
                else if (token.Contains("32-bit", StringComparison.OrdinalIgnoreCase) ||
                         token.Contains("32 bit", StringComparison.OrdinalIgnoreCase))
                {
                    size = FieldSize.DWord;
                }

                AddMemoryAddress(new Field {
                    Size = size, Type = FieldType.MemoryAddress, Value = (uint)kvp.Key
                });
            }

            if (_achievements.Count == 0)
            {
                SelectedCodeNotesFilter = CodeNoteFilter.All;
            }

            UpdateMemoryGrid();

            IsGameLoaded     = true;
            GameId.IsEnabled = false;

            if (_achievements.Count > 0)
            {
                ServiceRepository.Instance.FindService <IBackgroundWorkerService>().RunAsync(MergeOpenTickets);
            }
        }
Пример #3
0
 public PlaybackEditorViewModel(GameViewModel owner, string filename)
     : base(owner)
 {
     _owner    = owner;
     _filename = filename;
 }
Пример #4
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 + ")");
                    }
                });
            }
        }
Пример #5
0
        private void OpenFile(string filename)
        {
            if (!File.Exists(filename))
            {
                TaskDialogViewModel.ShowErrorMessage("Could not open " + Path.GetFileName(filename), filename + " was not found");
                return;
            }

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

            if (Game != null && Game.Script.Filename == filename)
            {
                if (Game.Script.CompareState == GeneratedCompareState.LocalDiffers)
                {
                    if (TaskDialogViewModel.ShowWarningPrompt("Revert to the last saved state?", "Your changes will be lost.") == DialogResult.No)
                    {
                        return;
                    }
                }

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

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

            if (File.Exists(backupFilename))
            {
                switch (TaskDialogViewModel.ShowWarningPrompt("Open autosave file?",
                                                              "An autosave file from " + File.GetLastWriteTime(backupFilename) + " was found for " + Path.GetFileName(filename) + ".",
                                                              TaskDialogViewModel.Buttons.YesNoCancel))
                {
                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)
            {
                TaskDialogViewModel.ShowErrorMessage("Unable to read " + Path.GetFileName(filename), ex.Message);
                return;
            }

            int    gameId    = 0;
            string gameTitle = null;

            var tokenizer = Tokenizer.CreateTokenizer(content);

            tokenizer.SkipWhitespace();
            while (tokenizer.Match("//"))
            {
                var comment = tokenizer.ReadTo('\n');
                if (comment.Contains("#ID"))
                {
                    var tokens = comment.Split('=');
                    if (tokens.Length > 1)
                    {
                        Int32.TryParse(tokens[1].ToString(), out gameId);
                    }

                    break;
                }
                else if (gameTitle == null)
                {
                    gameTitle = comment.Trim().ToString();
                }

                tokenizer.SkipWhitespace();
            }

            if (gameId == 0)
            {
                logger.WriteVerbose("Could not find game ID");
                TaskDialogViewModel.ShowWarningMessage("Could not find game ID", "The loaded file did not contain an #ID comment indicating which game the script is associated to.");
            }

            if (gameTitle == null)
            {
                gameTitle = Path.GetFileNameWithoutExtension(filename);
            }

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

            GameViewModel viewModel = null;

            if (gameId != 0)
            {
                logger.WriteVerbose("Game ID: " + gameId);

                foreach (var directory in ServiceRepository.Instance.FindService <ISettings>().EmulatorDirectories)
                {
                    var dataDirectory = Path.Combine(directory, "RACache", "Data");

                    var notesFile = Path.Combine(dataDirectory, gameId + "-Notes.json");
                    if (!File.Exists(notesFile))
                    {
                        notesFile = Path.Combine(dataDirectory, gameId + "-Notes2.txt");
                    }

                    if (File.Exists(notesFile))
                    {
                        logger.WriteVerbose("Found code notes in " + dataDirectory);
                        viewModel = new GameViewModel(gameId, gameTitle);
                        viewModel.AssociateRACacheDirectory(dataDirectory);
                    }
                }

                if (viewModel == null)
                {
                    logger.WriteVerbose("Could not find code notes");
                    TaskDialogViewModel.ShowWarningMessage("Could not locate code notes for game " + gameId,
                                                           "The game does not appear to have been recently loaded in any of the emulators specified in the Settings dialog.");

                    viewModel = new GameViewModel(gameId, gameTitle);
                }
            }
            else
            {
                viewModel = new GameViewModel(gameId, gameTitle);
            }


            var existingViewModel = Game;

            // 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)
            {
                // refresh any data from the emulator (code notes, published/local achievement definitions)
                if (!String.IsNullOrEmpty(viewModel.RACacheDirectory))
                {
                    existingViewModel.AssociateRACacheDirectory(viewModel.RACacheDirectory);
                }

                existingViewModel.Script.SetContent(content);
                viewModel = existingViewModel;

                existingViewModel.SelectedEditor = existingViewModel.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;
            }
        }
Пример #6
0
 public ViewerViewModelBase(GameViewModel owner)
 {
     _owner = owner;
 }
Пример #7
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;
            }
        }
Пример #8
0
        internal void UpdateCommonProperties(GameViewModel owner)
        {
            if (Local.Modified == ModifiedState.Unmodified)
            {
                var localAchievement = Local.Achievement;
                Local = new AchievementViewModel(owner, "Local");
                Local.LoadAchievement(localAchievement);
            }

            if (Unofficial.Modified == ModifiedState.Unmodified)
            {
                var unofficialAchievement = Unofficial.Achievement;
                Unofficial = new AchievementViewModel(owner, "Unofficial");
                Unofficial.LoadAchievement(unofficialAchievement);
            }

            if (Core.Modified == ModifiedState.Unmodified)
            {
                var coreAchievement = Core.Achievement;
                Core = new AchievementViewModel(owner, "Core");
                Core.LoadAchievement(coreAchievement);
            }

            if (Generated.Achievement != null)
            {
                Id = Generated.Id;
                SetBinding(TitleProperty, new ModelBinding(Generated.Title, TextFieldViewModel.TextProperty, ModelBindingMode.OneWay));
                SetBinding(DescriptionProperty, new ModelBinding(Generated.Description, TextFieldViewModel.TextProperty, ModelBindingMode.OneWay));
                SetBinding(PointsProperty, new ModelBinding(Generated.Points, IntegerFieldViewModel.ValueProperty, ModelBindingMode.OneWay));
            }
            else if (Core.Achievement != null)
            {
                Title       = Core.Title.Text;
                Description = Core.Description.Text;
                Points      = Core.Points.Value.GetValueOrDefault();
            }
            else if (Unofficial.Achievement != null)
            {
                Title       = Unofficial.Title.Text;
                Description = Unofficial.Description.Text;
                Points      = Unofficial.Points.Value.GetValueOrDefault();
            }
            else if (Local.Achievement != null)
            {
                Title       = Local.Title.Text;
                Description = Local.Description.Text;
                Points      = Local.Points.Value.GetValueOrDefault();
            }

            if (Core.Achievement != null)
            {
                Id = Core.Id;
            }
            else if (Unofficial.Achievement != null)
            {
                Id = Unofficial.Id;
            }
            else if (Local.Achievement != null)
            {
                Id = Local.Id;
            }

            UpdateModified();
        }
Пример #9
0
 public AchievementViewModel(GameViewModel owner)
     : base(owner)
 {
 }
Пример #10
0
 public RecordingEditorViewModel(GameViewModel owner)
     : base(owner)
 {
 }