Skip to content

Commit

Permalink
functionality for multiple mods, workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
whichtwix committed Dec 10, 2022
1 parent f8fc367 commit 40c3db5
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 48 deletions.
54 changes: 54 additions & 0 deletions .github/workflows/Publishtask.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: .NET Core Desktop

on:
push:
branches: [ "Master" ]
pull_request:
branches: [ "Master" ]

jobs:

build:

strategy:
matrix:
configuration: [Release]

runs-on: windows-latest # For a list of available runner types, refer to
# https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on

env:
Test_Project_Path: src/Downloader.csproj # Replace with the path to your test project, i.e. MyWpfApp.Tests\MyWpfApp.Tests.csproj.
Root: src/


steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0

# Install the .NET Core workload
- name: Install .NET Core
uses: actions/setup-dotnet@v3
with:
dotnet-version: 6.0.x

# Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.0.2

# Restore the application to populate the obj folder with RuntimeIdentifiers
- name: Restore the application
run: msbuild $env:Test_Project_Path /t:restore /p:Configuration=$env:Configuration
- name: publish the application
run: msbuild $env:Test_Project_Path /t:publish /p:Configuration=$env:Configuration
env:
Configuration: ${{ matrix.configuration }}

# Upload the MSIX package: https://github.com/marketplace/actions/upload-a-build-artifact
- name: Upload build artifacts
uses: actions/upload-artifact@v3
with:
name: Modinstaller.exe
path: src\bin\Release\net6.0\win10-x64\publish\Downloader.exe
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
![GitHub all releases](https://img.shields.io/github/downloads/whichtwix/Modinstaller/total?color=%20%2332CD32&style=plastic)
![GitHub release (latest by date)](https://img.shields.io/github/v/release/whichtwix/Modinstaller?style=plastic)
# :hammer_and_wrench:Modinstaller
A small application that installs the Among Us mod [Town of Us](https://github.com/eDonnes124/Town-Of-Us-R) with minimal user interaction. Making manual installs automatic.It's also used by [Las Monjas](https://github.com/KiraYamato94/LasMonjas)
A small application that can install multiple mods with minimal user interaction, making manual installs automatic

An application for [The Other Roles](https://github.com/TheOtherRolesAU/TheOtherRoles/issues) is available [here](https://github.com/Teejay39/TOR-Installer) managed by a separate user

## :grey_question:Why this over [ModManager](https://github.com/MatuxGG/ModManager) and the ingame updater already present?
- ModManager requires setup before you can install your mods - here you can get right in
Expand All @@ -13,10 +12,10 @@ An application for [The Other Roles](https://github.com/TheOtherRolesAU/TheOther
- The updater is rendered unusable with mod updates aimed at new among us versions and a manual installation would have to be done anyway

## :gear:How it works
- A user inputs the file path to the folder to install the mod - this is the only thing they have to do
- A user inputs the file path to the folder to install the mod and what mod they want - they only have to do this
- The program fetches the latest download link and version number from the github repo's API
- The zip is downloaded, extracted, and contents are set up in the folder without further input

## Usage
- Refer to the [latest release](https://github.com/whichtwix/Modinstaller/releases/latest) to know what to do
- Refer to the [User guide](https://github.com/whichtwix/Modinstaller/wiki/User-guide) to know what to do
- You will need to install this once and can reuse it every update apart from any breaking changes that may occur to the exe's functionality
17 changes: 12 additions & 5 deletions src/Downloader.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,26 @@
<PropertyGroup>
<TargetFramework>Net6.0</TargetFramework>
<Configuration>Release</Configuration>
<Version>2.0.0</Version>
<Version>3.1.0</Version>
<DebugType>embedded</DebugType>
<LangVersion>latest</LangVersion>
<OutputType>Exe</OutputType>
</PropertyGroup>

<PropertyGroup>
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
<PublishSingleFile>true</PublishSingleFile>
<PublishTrimmed>true</PublishTrimmed>
</PropertyGroup>

<PropertyGroup>
<NoWarn>IL2026</NoWarn>
<NoWarn>IL2026</NoWarn>
<NoWarn>IL2105</NoWarn>
</PropertyGroup>
</Project>

<ItemGroup>
<PackageReference Include="Spectre.Console" Version="0.45.1-preview.0.45"/>
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.9"/>
</ItemGroup>

</Project>
139 changes: 101 additions & 38 deletions src/code/Downloader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,101 @@
using System.IO;
using System.IO.Compression;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
using System.Collections.Generic;
using Spectre.Console;

namespace Modinstaller
{
public sealed class Modinstaller
public partial class Modinstaller
{
public const string url = "https://api.github.com/repos/eDonnes124/Town-Of-Us-R/releases/latest";

public static string Touversion;
public static string modversion;

public static HttpClient client = new();
public static HttpClient client { get; set; } = new();

public static Dictionary<string, string> Mods { get; } = new()
{
{"Town of Us", "https://api.github.com/repos/eDonnes124/Town-Of-Us-R/releases/latest"},
{"The Other Roles", "https://api.github.com/repos/TheOtherRolesAU/TheOtherRoles/releases/latest"},
{"Town of Host", "https://api.github.com/repos/tukasa0001/TownOfHost/releases/latest"},
{"Las Monjas" , "https://api.github.com/repos/KiraYamato94/LasMonjas/releases/latest"},
{"Town of Host:The Other Roles", "https://api.github.com/repos/music-discussion/TownOfHost-TheOtherRoles/releases"}
};

public static async Task Main(string[] args)
{
bool useagain = true;
while (useagain)
{
string path = Setfolderpath();
Choosemod(out string mod);
Console.WriteLine($"Downloading {mod}");
await Handlezip(path, mod);
Movefiles(path, mod, modversion);
Console.WriteLine("installation of mod complete");
useagain = AnsiConsole.Confirm("Want to install another mod?");
}
}

public static void Choosemod(out string mod)
{
bool confirmed = false;
mod = string.Empty;

Console.WriteLine("Use arrow keys to navigate and click enter");
while (!confirmed)
{
mod = AnsiConsole.Prompt(
new SelectionPrompt<string>()
.Title("Select which mod you want to install:")
.PageSize(10)
.AddChoices(new[]
{
"Town of Us",
"The Other Roles",
"Las Monjas",
"Town of Host",
"Town of Host:The Other Roles"
}));

confirmed = AnsiConsole.Confirm($"Confirm you want to install {mod}");
}
}

public static string Setfolderpath()
{
bool acceptedpath = false;
string path = string.Empty;
while (acceptedpath != true)
{
Console.WriteLine("What is the path of your Amogus?:");
path = Console.ReadLine();
path = AnsiConsole.Ask<string>("Enter the path to your among us folder(copy paste here):");
if (Directory.Exists(path + "\\Among Us_Data")) acceptedpath = true;
else Console.WriteLine($"the path '{path}' is not valid; vanilla files could not be found");
}
Console.WriteLine("Downloading town of us");
await Handlezip(path);
Movefiles(path, Touversion);
return path;
}
public static async Task Handlezip(string path)

public static async Task Handlezip(string path, string selectedmod)
{
try
{
client.DefaultRequestHeaders.Add("User-Agent", "TownOfUs Downloader");
client.DefaultRequestHeaders.Add("User-Agent", "Modinstaller");
client.DefaultRequestHeaders.Add("X-GitHub-Api-Version", "2022-11-28");
client.Timeout = TimeSpan.FromMinutes(30);
HttpResponseMessage connection;

Json assets = await client.GetFromJsonAsync<Json>(url);
Assets linktozip = assets.Assets.Find(link => link.Browser_download_url.EndsWith("zip"));
Touversion = assets.Name;
var connection = await client.GetAsync(linktozip.Browser_download_url);
string url = Mods[selectedmod];
//we have to differentiate due to pre-releases
if (url.Contains("latest"))
{
connection = await Fetchlatestrelease(url);
}
else
{
connection = await Fetchfromallreleases(url);
}

string zippath = $@"{path}" + "\\tou.zip";
string zippath = $@"{path}" + "\\mod.zip";
var zip = new FileInfo(zippath);
if (connection.IsSuccessStatusCode)
{
Expand All @@ -55,36 +108,49 @@ public static async Task Handlezip(string path)
}
}
}
ZipFile.ExtractToDirectory(zippath, path);

if (Directory.Exists(path + "\\BepInEx")) Directory.Delete(path + "\\BepInEx", true);
if (Directory.Exists(path + "\\mono")) Directory.Delete(path + "\\mono", true);
if (Directory.Exists(path + "\\dotnet")) Directory.Delete(path + "\\dotnet", true);
ZipFile.ExtractToDirectory(zippath, path, true);
zip.Delete();
client.Dispose();
}
catch (Exception e)
{
Console.WriteLine("Error in Handlezip()");
string omitname = e.StackTrace.Split(@"C:\")[0];
string errorlocation = e.StackTrace.Split(@"C:\")[1].Substring(11);
Console.WriteLine(omitname + errorlocation);
Console.WriteLine(e);
Console.ReadLine();
}
}
public static void Movefiles(string path, string version)

public static void Movefiles(string path, string mod, string modversion)
{
//no intermediate folder thus nothing to move: return
//tou uses acronym in folder
//the Name property from the Json class gives the folder name for las monjas
try
{
if (Directory.Exists(path + "\\BepInEx")) Directory.Delete(path + "\\BepInEx", true);
//this check will be phased out once the penultimate latest update doesnt use mono
if (Directory.Exists(path + "\\mono")) Directory.Delete(path + "\\mono", true);
if (Directory.Exists(path + "\\dotnet")) Directory.Delete(path + "\\dotnet", true);

string subfolder = $@"{path}" + $"\\ToU {version}";
switch (mod)
{
case "The Other Roles":
case "Town of Host":
case "Town of Host:The Other Roles":
return;
case "Town of Us":
mod = "ToU";
break;
case "Las Monjas":
mod = modversion;
modversion = string.Empty;
break;
}

string subfolder = modversion != string.Empty ? $@"{path}" + $"\\{mod} {modversion}" : $@"{path}" + $"\\{mod}";
string[] files = Directory.GetFiles(subfolder);
foreach (string file in files)
{
File.Move($@"{file}", $@"{path}" + $"\\{file.Substring(subfolder.Length + 1)}", true);
}

string[] movablefolders = Directory.GetDirectories(subfolder);
foreach (string folder in movablefolders)
{
Expand All @@ -95,10 +161,7 @@ public static void Movefiles(string path, string version)
}
catch (Exception e)
{
Console.WriteLine("Error in Handlezip()");
string omitname = e.StackTrace.Split(@"C:\")[0];
string errorlocation = e.StackTrace.Split(@"C:\")[1].Substring(11);
Console.WriteLine(omitname + errorlocation);
Console.WriteLine(e);
Console.ReadLine();
}
}
Expand Down
30 changes: 30 additions & 0 deletions src/code/Fetchapi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
using System.Collections.Generic;

namespace Modinstaller
{
public partial class Modinstaller
{
public static async Task<HttpResponseMessage> Fetchlatestrelease(string url)
{
HttpResponseMessage connection;
Json assets = await client.GetFromJsonAsync<Json>(url);
Assets linktozip = assets.Assets.Find(link => link.Browser_download_url.EndsWith("zip"));
modversion = assets.Name;
return connection = await client.GetAsync(linktozip.Browser_download_url);
}

public static async Task<HttpResponseMessage> Fetchfromallreleases(string url)
{
HttpResponseMessage connection;
List<Json> data = new();
var jsonstring = client.GetAsync(url).Result;
data = await jsonstring.Content.ReadAsAsync<List<Json>>();
Json zip = data.Find(x => x.Assets[0].Browser_download_url.Contains("zip"));
System.Console.WriteLine(zip.Assets[0].Browser_download_url);
return connection = await client.GetAsync(zip.Assets[0].Browser_download_url);
}
}
}
2 changes: 1 addition & 1 deletion src/code/Json.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public sealed class Json
public string Name { get; set; }
public List<Assets> Assets { get; set; }
}
public class Assets
public sealed class Assets
{
public string Browser_download_url { get; set; }
}
Expand Down

0 comments on commit 40c3db5

Please sign in to comment.