/ src / Ryujinx.Gtk3 / UI / Windows / CheatWindow.cs
CheatWindow.cs
  1  using Gtk;
  2  using LibHac.Tools.FsSystem;
  3  using Ryujinx.HLE.FileSystem;
  4  using Ryujinx.HLE.HOS;
  5  using Ryujinx.UI.App.Common;
  6  using Ryujinx.UI.Common.Configuration;
  7  using System;
  8  using System.Collections.Generic;
  9  using System.IO;
 10  using System.Linq;
 11  using GUI = Gtk.Builder.ObjectAttribute;
 12  
 13  namespace Ryujinx.UI.Windows
 14  {
 15      public class CheatWindow : Window
 16      {
 17          private readonly string _enabledCheatsPath;
 18          private readonly bool _noCheatsFound;
 19  
 20  #pragma warning disable CS0649, IDE0044 // Field is never assigned to, Add readonly modifier
 21          [GUI] Label _baseTitleInfoLabel;
 22          [GUI] TextView _buildIdTextView;
 23          [GUI] TreeView _cheatTreeView;
 24          [GUI] Button _saveButton;
 25  #pragma warning restore CS0649, IDE0044
 26  
 27          public CheatWindow(VirtualFileSystem virtualFileSystem, ulong titleId, string titleName, string titlePath) : this(new Builder("Ryujinx.Gtk3.UI.Windows.CheatWindow.glade"), virtualFileSystem, titleId, titleName, titlePath) { }
 28  
 29          private CheatWindow(Builder builder, VirtualFileSystem virtualFileSystem, ulong titleId, string titleName, string titlePath) : base(builder.GetRawOwnedObject("_cheatWindow"))
 30          {
 31              builder.Autoconnect(this);
 32  
 33              IntegrityCheckLevel checkLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks
 34                  ? IntegrityCheckLevel.ErrorOnInvalid
 35                  : IntegrityCheckLevel.None;
 36  
 37              _baseTitleInfoLabel.Text = $"Cheats Available for {titleName} [{titleId:X16}]";
 38              _buildIdTextView.Buffer.Text = $"BuildId: {ApplicationData.GetBuildId(virtualFileSystem, checkLevel, titlePath)}";
 39  
 40              string modsBasePath = ModLoader.GetModsBasePath();
 41              string titleModsPath = ModLoader.GetApplicationDir(modsBasePath, titleId.ToString("X16"));
 42  
 43              _enabledCheatsPath = System.IO.Path.Combine(titleModsPath, "cheats", "enabled.txt");
 44  
 45              _cheatTreeView.Model = new TreeStore(typeof(bool), typeof(string), typeof(string), typeof(string));
 46  
 47              CellRendererToggle enableToggle = new();
 48              enableToggle.Toggled += (sender, args) =>
 49              {
 50                  _cheatTreeView.Model.GetIter(out TreeIter treeIter, new TreePath(args.Path));
 51                  bool newValue = !(bool)_cheatTreeView.Model.GetValue(treeIter, 0);
 52                  _cheatTreeView.Model.SetValue(treeIter, 0, newValue);
 53  
 54                  if (_cheatTreeView.Model.IterChildren(out TreeIter childIter, treeIter))
 55                  {
 56                      do
 57                      {
 58                          _cheatTreeView.Model.SetValue(childIter, 0, newValue);
 59                      }
 60                      while (_cheatTreeView.Model.IterNext(ref childIter));
 61                  }
 62              };
 63  
 64              _cheatTreeView.AppendColumn("Enabled", enableToggle, "active", 0);
 65              _cheatTreeView.AppendColumn("Name", new CellRendererText(), "text", 1);
 66              _cheatTreeView.AppendColumn("Path", new CellRendererText(), "text", 2);
 67  
 68              var buildIdColumn = _cheatTreeView.AppendColumn("Build Id", new CellRendererText(), "text", 3);
 69              buildIdColumn.Visible = false;
 70  
 71              string[] enabled = Array.Empty<string>();
 72  
 73              if (File.Exists(_enabledCheatsPath))
 74              {
 75                  enabled = File.ReadAllLines(_enabledCheatsPath);
 76              }
 77  
 78              int cheatAdded = 0;
 79  
 80              var mods = new ModLoader.ModCache();
 81  
 82              ModLoader.QueryContentsDir(mods, new DirectoryInfo(System.IO.Path.Combine(modsBasePath, "contents")), titleId);
 83  
 84              string currentCheatFile = string.Empty;
 85              string buildId = string.Empty;
 86              TreeIter parentIter = default;
 87  
 88              foreach (var cheat in mods.Cheats)
 89              {
 90                  if (cheat.Path.FullName != currentCheatFile)
 91                  {
 92                      currentCheatFile = cheat.Path.FullName;
 93                      string parentPath = currentCheatFile.Replace(titleModsPath, "");
 94  
 95                      buildId = System.IO.Path.GetFileNameWithoutExtension(currentCheatFile).ToUpper();
 96                      parentIter = ((TreeStore)_cheatTreeView.Model).AppendValues(false, buildId, parentPath, "");
 97                  }
 98  
 99                  string cleanName = cheat.Name[1..^7];
100                  ((TreeStore)_cheatTreeView.Model).AppendValues(parentIter, enabled.Contains($"{buildId}-{cheat.Name}"), cleanName, "", buildId);
101  
102                  cheatAdded++;
103              }
104  
105              if (cheatAdded == 0)
106              {
107                  ((TreeStore)_cheatTreeView.Model).AppendValues(false, "No Cheats Found", "", "");
108                  _cheatTreeView.GetColumn(0).Visible = false;
109  
110                  _noCheatsFound = true;
111  
112                  _saveButton.Visible = false;
113              }
114  
115              _cheatTreeView.ExpandAll();
116          }
117  
118          private void SaveButton_Clicked(object sender, EventArgs args)
119          {
120              if (_noCheatsFound)
121              {
122                  return;
123              }
124  
125              List<string> enabledCheats = new();
126  
127              if (_cheatTreeView.Model.GetIterFirst(out TreeIter parentIter))
128              {
129                  do
130                  {
131                      if (_cheatTreeView.Model.IterChildren(out TreeIter childIter, parentIter))
132                      {
133                          do
134                          {
135                              var enabled = (bool)_cheatTreeView.Model.GetValue(childIter, 0);
136  
137                              if (enabled)
138                              {
139                                  var name = _cheatTreeView.Model.GetValue(childIter, 1).ToString();
140                                  var buildId = _cheatTreeView.Model.GetValue(childIter, 3).ToString();
141  
142                                  enabledCheats.Add($"{buildId}-<{name} Cheat>");
143                              }
144                          }
145                          while (_cheatTreeView.Model.IterNext(ref childIter));
146                      }
147                  }
148                  while (_cheatTreeView.Model.IterNext(ref parentIter));
149              }
150  
151              Directory.CreateDirectory(System.IO.Path.GetDirectoryName(_enabledCheatsPath));
152  
153              File.WriteAllLines(_enabledCheatsPath, enabledCheats);
154  
155              Dispose();
156          }
157  
158          private void CancelButton_Clicked(object sender, EventArgs args)
159          {
160              Dispose();
161          }
162      }
163  }