using System;
+using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
+using System.Runtime.InteropServices;
using System.Threading.Tasks;
+using Gameloop.Vdf;
+using Gameloop.Vdf.Linq;
using Impostor.Client.Core.Events;
using Impostor.Shared.Innersloth;
using ErrorEventArgs = Impostor.Client.Core.Events.ErrorEventArgs;
{
public class AmongUsModifier
{
+ private const uint AppId = 945360;
private const string RegionName = "Impostor";
public const ushort DefaultPort = 22023;
-
+
private readonly string _amongUsDir;
private readonly string _regionFile;
-
+
public AmongUsModifier()
{
var appData = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "..", "LocalLow");
- var amongUsDir = Path.Combine(appData, "Innersloth", "Among Us");
- _amongUsDir = amongUsDir;
- _regionFile = Path.Combine(amongUsDir, "regionInfo.dat");
+ if (!Directory.Exists(appData))
+ {
+ appData = FindProtonAppData();
+ }
+
+ if (appData == null)
+ return;
+
+ _amongUsDir = Path.Combine(appData, "Innersloth", "Among Us");
+ _regionFile = Path.Combine(_amongUsDir, "regionInfo.dat");
+ }
+
+ private string FindProtonAppData()
+ {
+ string steamApps;
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ {
+ steamApps = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".steam", "steam", "steamapps");
+ }
+ else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ {
+ steamApps = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Library", "Application Support", "Steam", "steamapps");
+ }
+ else
+ {
+ return null;
+ }
+
+ if (!Directory.Exists(steamApps))
+ return null;
+
+ var libraries = new List<string>
+ {
+ steamApps
+ };
+
+ var vdf = Path.Combine(steamApps, "libraryfolders.vdf");
+ if (File.Exists(vdf))
+ {
+ var libraryFolders = VdfConvert.Deserialize(File.ReadAllText(vdf));
+
+ foreach (var libraryFolder in libraryFolders.Value.Children<VProperty>())
+ {
+ if (!int.TryParse(libraryFolder.Key, out _))
+ continue;
+
+ libraries.Add(Path.Combine(libraryFolder.Value.Value<string>(), "steamapps"));
+ }
+ }
+
+ foreach (var library in libraries)
+ {
+ var path = Path.Combine(library, "compatdata", AppId.ToString(), "pfx", "drive_c", "users", "steamuser", "AppData", "LocalLow");
+ if (Directory.Exists(path))
+ {
+ return path;
+ }
+ }
+
+ return null;
}
-
+
public async Task SaveIp(string input)
{
// Filter out whitespace.
input = input.Trim();
-
+
// Split port from ip.
// Only IPv4 is supported so just do it simple.
var ip = string.Empty;
var port = DefaultPort;
-
+
var parts = input.Split(':');
if (parts.Length >= 1)
{
{
ushort.TryParse(parts[1], out port);
}
-
+
// Check if a valid IP address was entered.
if (!IPAddress.TryParse(ip, out var ipAddress))
{
OnError("Invalid IP Address entered");
return;
}
-
+
// Use first IPv4 result.
ipAddress = hostAddresses.First(x => x.AddressFamily == AddressFamily.InterNetwork);
}
return;
}
}
-
+
// Only IPv4.
if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
{
/// <param name="port"></param>
private void WriteIp(IPAddress ipAddress, ushort port)
{
- if (ipAddress == null ||
+ if (ipAddress == null ||
ipAddress.AddressFamily != AddressFamily.InterNetwork)
{
throw new ArgumentException(nameof(ipAddress));
}
-
+
if (!Directory.Exists(_amongUsDir))
{
OnError("Among Us directory was not found, is it installed? Try running it once.");
return;
}
-
+
using (var file = File.Open(_regionFile, FileMode.Create, FileAccess.Write))
using (var writer = new BinaryWriter(file))
{
{
new ServerInfo($"{RegionName}-Master-1", ip, port)
});
-
+
region.Serialize(writer);
OnSaved(ip, port);
public bool TryLoadIp(out string ipAddress)
{
ipAddress = null;
-
+
if (!File.Exists(_regionFile))
{
return false;
var region = RegionInfo.Deserialize(reader);
if (region.Name == RegionName && region.Servers.Count >= 1)
{
- ipAddress = region.Servers[0].Ip;
+ ipAddress = region.Servers.ElementAt(0).Ip;
return true;
}
}
{
Saved?.Invoke(this, new SavedEventArgs(ipAddress, port));
}
-
+
public event EventHandler<ErrorEventArgs> Error;
public event EventHandler<SavedEventArgs> Saved;
}
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProjectGuid>{804CF172-0C87-4423-9688-BD97D549891E}</ProjectGuid>
- <OutputType>WinExe</OutputType>
- <RootNamespace>Impostor.Client</RootNamespace>
- <AssemblyName>Impostor</AssemblyName>
- <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
- <Deterministic>true</Deterministic>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
- <DebugType>none</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup>
- <StartupObject>Impostor.Client.Program</StartupObject>
- </PropertyGroup>
- <PropertyGroup>
- <ApplicationIcon>icon.ico</ApplicationIcon>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="System.Xml.Linq" />
- <Reference Include="System.Data.DataSetExtensions" />
- <Reference Include="Microsoft.CSharp" />
- <Reference Include="System.Data" />
- <Reference Include="System.Deployment" />
- <Reference Include="System.Drawing" />
- <Reference Include="System.Net.Http" />
- <Reference Include="System.Windows.Forms" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Core\AmongUsModifier.cs" />
- <Compile Include="Core\Configuration.cs" />
- <Compile Include="Core\Events\ErrorEventArgs.cs" />
- <Compile Include="Core\Events\SavedEventArgs.cs" />
- <Compile Include="Forms\FrmMain.cs">
- <SubType>Form</SubType>
- </Compile>
- <Compile Include="Forms\FrmMain.Designer.cs">
- <DependentUpon>FrmMain.cs</DependentUpon>
- </Compile>
- <Compile Include="Program.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- <EmbeddedResource Include="Forms\FrmMain.resx">
- <DependentUpon>FrmMain.cs</DependentUpon>
- </EmbeddedResource>
- <EmbeddedResource Include="Properties\Resources.resx">
- <Generator>ResXFileCodeGenerator</Generator>
- <LastGenOutput>Resources.Designer.cs</LastGenOutput>
- <SubType>Designer</SubType>
- </EmbeddedResource>
- <Compile Include="Properties\Resources.Designer.cs">
- <AutoGen>True</AutoGen>
- <DependentUpon>Resources.resx</DependentUpon>
- </Compile>
- <None Include="Properties\Settings.settings">
- <Generator>SettingsSingleFileGenerator</Generator>
- <LastGenOutput>Settings.Designer.cs</LastGenOutput>
- </None>
- <Compile Include="Properties\Settings.Designer.cs">
- <AutoGen>True</AutoGen>
- <DependentUpon>Settings.settings</DependentUpon>
- <DesignTimeSharedInput>True</DesignTimeSharedInput>
- </Compile>
- </ItemGroup>
- <ItemGroup>
- <None Include="App.config" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\Impostor.Shared\Impostor.Shared.csproj">
- <Project>{1d109a96-fadf-41b9-a845-457a7a5c0c5a}</Project>
- <Name>Impostor.Shared</Name>
- </ProjectReference>
- </ItemGroup>
- <ItemGroup>
- <Content Include="icon.ico" />
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <ProjectGuid>{804CF172-0C87-4423-9688-BD97D549891E}</ProjectGuid>
+ <OutputType>WinExe</OutputType>
+ <AssemblyName>Impostor</AssemblyName>
+ <TargetFramework>net462</TargetFramework>
+ <AssemblyTitle>Impostor</AssemblyTitle>
+ <Product>Impostor</Product>
+ <Copyright>Copyright © AeonLucid 2020</Copyright>
+ <ApplicationIcon>icon.ico</ApplicationIcon>
+
+ <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+ <GenerateResourceUsePreserializedResources>true</GenerateResourceUsePreserializedResources>
+ </PropertyGroup>
+
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>none</DebugType>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Impostor.Shared\Impostor.Shared.csproj" />
+ <PackageReference Include="Gameloop.Vdf" Version="0.6.1" />
+
+ <PackageReference Include="System.Resources.Extensions" Version="4.7.1" />
+ <Reference Include="System.Windows.Forms" />
+ </ItemGroup>
</Project>
\ No newline at end of file
+++ /dev/null
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Impostor")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Impostor")]
-[assembly: AssemblyCopyright("Copyright © AeonLucid 2020")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("804CF172-0C87-4423-9688-BD97D549891E")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
\ No newline at end of file