313 lines
14 KiB
C#
313 lines
14 KiB
C#
using GCMM.Properties;
|
|
using Newtonsoft.Json.Linq;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Reflection;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
|
|
namespace GCMM
|
|
{
|
|
public partial class MainForm : Form
|
|
{
|
|
public MainForm()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
private readonly Dictionary<string, ModInfo> mods = new Dictionary<string, ModInfo>();
|
|
private readonly ModInfo gcipa = new ModInfo { Author = "modtainers", Name = "GCIPA" };
|
|
private readonly ModInfo gcmm = new ModInfo { Author = "NorbiPeti", Name = "GCMM" };
|
|
private DateTime lastGameUpdateTime;
|
|
private const string defaultInfo = @"
|
|
Gamecraft Mod Manager
|
|
|
|
If you click on a mod it will show some info about it. The install instructions there are usually for manual installs.
|
|
To get started, click on a mod and select Install mod. Most mods need GamecraftModdingAPI as well.
|
|
Then, simply click Play. This will first download and run the patcher (GCIPA) if needed.
|
|
If all goes well, after some time a modded Gamecraft should launch.
|
|
|
|
After a Gamecraft update there's a good chance that mods will break. If this happens you may get errors when trying to start Gamecraft.
|
|
Until updated versions are released, use the ""Disable mods"" checkbox at the bottom to launch the game without mods.
|
|
|
|
You don't have to use the mod manager to run the game each time, though it will tell you about mod updates when they come.
|
|
However, you need to run it and click ""Patch & Play"" each time there's a Gamecraft update.
|
|
|
|
Disclaimer:
|
|
This mod manager and the mods in the list are made by the ExMods developers. We are not associated with Freejam or Gamecraft. Modify Gamecraft at your own risk.
|
|
|
|
If you encounter an issue while any mods are installed, report it to us. If you think it's an issue with the game, test again with the ""Disable mods"" option checked before reporting to Freejam.
|
|
You may also want to verify the game's files by right clicking the game in Steam and choosing Properties, going to Local files and clicking Verify integrity of game files.
|
|
";
|
|
|
|
private async void Form1_Load(object sender, EventArgs e)
|
|
{
|
|
await LoadEverything();
|
|
}
|
|
|
|
public async Task LoadEverything()
|
|
{
|
|
if (Settings.Default.NeedsUpdate)
|
|
{
|
|
Settings.Default.Upgrade();
|
|
Settings.Default.NeedsUpdate = false;
|
|
Settings.Default.Save();
|
|
}
|
|
modlist.Items.Clear();
|
|
mods.Clear(); //This method may get called twice when ran from the command line
|
|
UpdateButton(installbtn, false);
|
|
modinfobox.Text = defaultInfo;
|
|
if (string.IsNullOrWhiteSpace(Settings.Default.GamePath) || GetExe() == null)
|
|
{
|
|
Settings.Default.GamePath = GetGameFolder();
|
|
if (string.IsNullOrWhiteSpace(Settings.Default.GamePath))
|
|
Settings.Default.GamePath = SelectGameFolder();
|
|
else
|
|
MessageBox.Show("Found game at " + Settings.Default.GamePath);
|
|
Settings.Default.Save();
|
|
}
|
|
if(string.IsNullOrWhiteSpace(Settings.Default.GamePath))
|
|
{
|
|
status.Text = "Status: Game not found";
|
|
return;
|
|
}
|
|
DeleteEmptyPluginsDir(out bool pexists, out bool dexists);
|
|
if (!pexists && dexists)
|
|
unpatched.Checked = true; //It will call the event but that won't do anything
|
|
if(Settings.Default.AutoLaunch && string.IsNullOrWhiteSpace(Settings.Default.SteamConfigFileForAutoLaunch))
|
|
{
|
|
string path = @"C:\Program Files (x86)\Steam\userdata";
|
|
if(MessageBox.Show("Do you want GCMM to change the game's launch settings so it can ensure the game is patched?\n\n" +
|
|
"If you say yes, GCMM will do a quick check before the game is launched and updates if necessary. " +
|
|
"This way you (hopefully) won't see crashes after a Gamecraft update.\n\n" +
|
|
"Note that this also means that if you (re)move GCMM without disabling this then you won't be able to launch Gamecraft.",
|
|
"GCMM auto-patching", MessageBoxButtons.YesNo)==DialogResult.Yes)
|
|
{
|
|
var dirs = Directory.GetDirectories(path);
|
|
var goodPaths = (from dir in dirs
|
|
where File.Exists(dir + @"\config\localconfig.vdf")
|
|
select dir + @"\config\localconfig.vdf").ToArray();
|
|
if (goodPaths.Length != 1)
|
|
path = SelectSteamConfigFile();
|
|
else
|
|
path = goodPaths[0];
|
|
//if (path is not null)
|
|
if (path != null)
|
|
{
|
|
Settings.Default.SteamConfigFileForAutoLaunch = path;
|
|
UpdateSteamConfigToAutoStart(true);
|
|
}
|
|
else
|
|
Settings.Default.AutoLaunch = false;
|
|
Settings.Default.Save();
|
|
}
|
|
}
|
|
await RefreshEverything();
|
|
}
|
|
|
|
private async void playbtn_Click(object sender, EventArgs e)
|
|
{
|
|
if (playbtn.ForeColor == Color.Green) return; //Disabled
|
|
await UpdateAPI();
|
|
await PatchStartGame(); //It will call EndWork();
|
|
}
|
|
|
|
private void settingsbtn_Click(object sender, EventArgs e)
|
|
{
|
|
if (settingsbtn.ForeColor == Color.Green) return; //Disabled
|
|
var sf = new SettingsForm();
|
|
sf.ShowDialog(this);
|
|
}
|
|
|
|
private void modlist_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
if (working) return;
|
|
modinfobox.Clear();
|
|
switch (modlist.SelectedItems.Count)
|
|
{
|
|
case 0:
|
|
modinfobox.Text = defaultInfo;
|
|
UpdateButton(installbtn, false);
|
|
UpdateButton(uninstallbtn, false);
|
|
break;
|
|
case 1:
|
|
default:
|
|
installbtn.Text = "Install mod";
|
|
UpdateButton(installbtn, false);
|
|
UpdateButton(uninstallbtn, false);
|
|
bool install = false, update = false;
|
|
Action<string, Color> addText = (txt, color) =>
|
|
{
|
|
int start = modinfobox.Text.Length;
|
|
modinfobox.AppendText(txt + Environment.NewLine + Environment.NewLine);
|
|
modinfobox.Select(start, txt.Length);
|
|
modinfobox.SelectionColor = color;
|
|
modinfobox.DeselectAll();
|
|
modinfobox.SelectionColor = modinfobox.ForeColor;
|
|
};
|
|
foreach (ListViewItem item in modlist.SelectedItems)
|
|
{
|
|
var mod = mods[item.Name];
|
|
if (modlist.SelectedItems.Count == 1)
|
|
{
|
|
if (mod.Updatable)
|
|
addText("New version available! " + mod.UpdateDetails, Color.Aqua);
|
|
if (mod.LastUpdated < lastGameUpdateTime)
|
|
addText("Outdated mod! It may not work properly on the latest version of the game.", Color.DarkOrange);
|
|
if (mod.Description != null)
|
|
modinfobox.AppendText(mod.Description.Replace("\n", Environment.NewLine));
|
|
}
|
|
else
|
|
modinfobox.Text = modlist.SelectedItems.Count + " mods selected";
|
|
if (mod.DownloadURL != null && !(mod.LatestVersion <= mod.Version))
|
|
{
|
|
UpdateButton(installbtn, true);
|
|
if (mod.Version != null)
|
|
update = true;
|
|
else
|
|
install = true;
|
|
}
|
|
if (mod.Version != null)
|
|
UpdateButton(uninstallbtn, true);
|
|
}
|
|
if (install && update)
|
|
installbtn.Text = "Install and update mod";
|
|
else if (update)
|
|
installbtn.Text = "Update mod";
|
|
else
|
|
installbtn.Text = "Install mod";
|
|
break;
|
|
}
|
|
if (unpatched.Checked)
|
|
{ //Don't allow (un)installing mods if mods are disabled
|
|
UpdateButton(installbtn, false);
|
|
UpdateButton(uninstallbtn, false);
|
|
modlist.Enabled = false;
|
|
}
|
|
else
|
|
modlist.Enabled = true;
|
|
}
|
|
|
|
private async void installbtn_Click(object sender, EventArgs e)
|
|
{
|
|
if (installbtn.ForeColor == Color.Green) return; //Disabled
|
|
if (!BeginWork()) return;
|
|
foreach (ListViewItem item in modlist.SelectedItems)
|
|
{
|
|
var mod = mods[item.Name];
|
|
if (item.Group.Name == "installed" && (mod.DownloadURL == null || mod.LatestVersion <= mod.Version)) continue;
|
|
await InstallMod(mod);
|
|
}
|
|
EndWork();
|
|
}
|
|
|
|
private void uninstallbtn_Click(object sender, EventArgs e)
|
|
{
|
|
if (uninstallbtn.ForeColor == Color.Green) return; //Disabled
|
|
foreach (ListViewItem item in modlist.SelectedItems)
|
|
{
|
|
if (item.Group.Name != "installed") continue;
|
|
UninstallMod(mods[item.Name]);
|
|
}
|
|
EndWork(); //Update button states
|
|
}
|
|
|
|
private void findlog_Click(object sender, EventArgs e)
|
|
{
|
|
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
|
|
{
|
|
if (CheckNoExe(out string exe))
|
|
return;
|
|
Process.Start("explorer.exe", $@"/select,{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}Low\Freejam\{exe.Replace(".exe", "")}\Player.log");
|
|
}
|
|
}
|
|
|
|
private void unpatched_CheckedChanged(object sender, EventArgs e)
|
|
{ //Not using the patcher's revert option because sometimes it restores the wrong files - the game can be patched without mods
|
|
if (CheckNoExe())
|
|
return;
|
|
CheckIfPatched();
|
|
modlist_SelectedIndexChanged(modlist, null);
|
|
string plugins = GamePath("\\Plugins");
|
|
string disabled = GamePath("\\Plugins_Disabled");
|
|
DeleteEmptyPluginsDir(out bool pexists, out bool dexists);
|
|
if (unpatched.Checked)
|
|
{
|
|
if (pexists)
|
|
{
|
|
if (dexists)
|
|
Directory.Delete(disabled, true); //Resolving conflicts would be complicated so delete the other mods - this shouldn't happen normally
|
|
Directory.Move(plugins, disabled);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (dexists)
|
|
{
|
|
if (pexists)
|
|
Directory.Delete(plugins, true);
|
|
Directory.Move(disabled, plugins);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DeleteEmptyPluginsDir(out bool pexists, out bool dexists)
|
|
{
|
|
string plugins = GamePath("\\Plugins");
|
|
string disabled = GamePath("\\Plugins_Disabled");
|
|
pexists = Directory.Exists(plugins);
|
|
dexists = Directory.Exists(disabled);
|
|
if (pexists && !Directory.EnumerateFiles(plugins).Any())
|
|
{
|
|
Directory.Delete(plugins);
|
|
pexists = false;
|
|
}
|
|
if (dexists && !Directory.EnumerateFiles(disabled).Any())
|
|
{
|
|
Directory.Delete(disabled);
|
|
dexists = false;
|
|
}
|
|
}
|
|
|
|
private async void refreshbtn_Click(object sender, EventArgs e)
|
|
{
|
|
await RefreshEverything();
|
|
}
|
|
|
|
private async Task RefreshEverything()
|
|
{
|
|
CheckIfPatched(); //Set from placeholder
|
|
lastGameUpdateTime = await GetLastGameUpdateTime();
|
|
var mods = GetInstalledMods();
|
|
await GetAvailableMods();
|
|
CheckUninstalledMods(mods);
|
|
CheckIfPatched(); //Check after getting the available mods to show GCIPA updates
|
|
}
|
|
|
|
private void validatebtn_Click(object sender, EventArgs e)
|
|
{
|
|
if (CheckNoExe())
|
|
return;
|
|
if (MessageBox.Show("Validating the game's files is useful if the game doesn't start even without mods. Make sure to click Refresh once Steam finished verifying the game. The Steam window that shows the progress might open in the background. Note that you will need to patch the game again using the Play button in order to use mods.\n\nContinue?", "Verify game files", MessageBoxButtons.OKCancel) == DialogResult.Cancel)
|
|
return;
|
|
string exe = GetExe();
|
|
File.Delete(GamePath($@"\{exe.Replace(".exe", "")}_Data\Managed\IllusionInjector.dll")); //Used to check if game is patched
|
|
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
|
|
Process.Start("steam://validate/1078000/");
|
|
else
|
|
Process.Start("xdg-open", "steam://validate/1078000/");
|
|
}
|
|
|
|
private void MainForm_Shown(object sender, EventArgs e)
|
|
{
|
|
Focus();
|
|
}
|
|
}
|
|
}
|