Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

installer for macos #21

Open
wants to merge 29 commits into
base: tunneling
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
4eaa026
:iphone: Add support for new rune stat shards
molenzwiebel Nov 24, 2018
58bdc18
:iphone: Remove accidental debugging code
molenzwiebel Nov 24, 2018
0e0f984
:newspaper: Update README
molenzwiebel Apr 20, 2019
507e260
Merge tunneling into master
molenzwiebel Jun 28, 2019
30f2fb5
Merge branch 'tunneling'
molenzwiebel Jun 28, 2019
9133c4a
:sparkles: Prefer returning existing codes over new ones
molenzwiebel Jun 28, 2019
692fdce
:iphone: Add TFT assets in lobby creation
molenzwiebel Jun 28, 2019
a1c5dd2
:electric_plug: Fix several issues and add debug logging (#15)
Jun 29, 2019
12366d8
:electric_plug: Bump version, add alert before elevating
molenzwiebel Jun 29, 2019
e7bbf60
:electric_plug: Dynamically update about window version
molenzwiebel Jun 29, 2019
313b17f
:iphone: Fix rune editor crashing on iOS
molenzwiebel Jun 29, 2019
21dc6af
:sparkles: PROPERLY check for duplicate pubkeys
molenzwiebel Jun 29, 2019
95b89fb
:iphone: Add filtering, champion names
molenzwiebel Jun 29, 2019
2f4dac9
:iphone: Add TFT background, better champ splashes
molenzwiebel Jun 29, 2019
3e8db7f
:iphone: Add icon for no bans
molenzwiebel Jun 30, 2019
d1ab5ee
:iphone: Finally merge #10, with changes.
molenzwiebel Jul 2, 2019
07db5aa
Making Rift PORT configurable via env variable (#18)
pyro2927 Jul 10, 2019
bdb1c99
:iphone: Lots of minor changes:
molenzwiebel Jul 31, 2019
3a84ab4
Merge branch 'master' of https://github.com/molenzwiebel/Mimic
molenzwiebel Jul 31, 2019
b7f42c9
:sparkles: Read Conduit connection params from URL
molenzwiebel Aug 1, 2019
4fae346
:electric_plug: Drop custom headers, use query URL for websocket
molenzwiebel Aug 1, 2019
bd34c49
:iphone: Work on making the website feel more native
molenzwiebel Aug 3, 2019
e5556a5
:iphone: More work on 'nativeness'
molenzwiebel Aug 3, 2019
1403a65
:iphone: Fix champion picking for 9.24
molenzwiebel Dec 16, 2019
dc3cc3a
:iphone: Aphelios and Sett default game version fix (#30)
xTeJk Feb 11, 2020
9d0ffd3
:iphone: Fix roles showing up as undefined.
molenzwiebel Feb 11, 2020
b053cfe
Removes white background for rounded home icons (#36)
ptejada Jun 23, 2020
3d5eab6
:iphone: Specify code when connecting to WS, bump ddragon
molenzwiebel Nov 9, 2020
86836fa
:iphone: Load ddragon version async for proper static data updates
molenzwiebel Dec 17, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
![Mimic Logo](assets/mimic-logo.png?raw=true)

[![Build Status](https://travis-ci.org/molenzwiebel/Mimic.svg?branch=master)](https://travis-ci.org/molenzwiebel/Mimic)
[![Mimic Discord](https://img.shields.io/badge/discord-Mimic-738bd7.svg?style=flat)](https://discord.gg/bfxdsRC)
[![Discord](https://discordapp.com/api/guilds/249481856687407104/widget.png?style=shield)](https://discord.gg/bfxdsRC)

# :satellite: Mimic
The new League client. Except it's on your phone.
Expand Down
2 changes: 1 addition & 1 deletion conduit/AboutWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
Title="Mimic Conduit - About" Height="430" Width="500" ResizeMode="NoResize" Closing="Window_Closing">
<Grid>
<Image x:Name="Logo" HorizontalAlignment="Left" Height="80" Margin="15,227,0,0" VerticalAlignment="Top" Width="80" />
<Label Content="Mimic Conduit v2.0.0" HorizontalAlignment="Left" Margin="100,227,0,0" VerticalAlignment="Top" FontSize="24" FontWeight="Bold" FontFamily="Arial"/>
<Label x:Name="AboutTitle" Content="Mimic Conduit v2.0.0" HorizontalAlignment="Left" Margin="100,227,0,0" VerticalAlignment="Top" FontSize="24" FontWeight="Bold" FontFamily="Arial"/>
<Label Content="Made with ♥ by molenzwiebel and contributors." HorizontalAlignment="Left" Margin="100,278,0,0" VerticalAlignment="Top" FontSize="14"/>
<Label Content="CONNECTION DETAILS" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" FontSize="16"/>
<Label Content="ABOUT" HorizontalAlignment="Left" Margin="10,184,0,0" VerticalAlignment="Top" FontSize="16"/>
Expand Down
2 changes: 2 additions & 0 deletions conduit/AboutWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public AboutWindow()
Logo.Source = Imaging.CreateBitmapSourceFromHIcon(Properties.Resources.mimic.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
StartOnStartupCheckbox.IsChecked = Persistence.LaunchesAtStartup();

AboutTitle.Content = "Mimic Conduit v" + Program.VERSION;

if (Persistence.GetHubCode() != null)
{
RenderCode();
Expand Down
42 changes: 42 additions & 0 deletions conduit/Administrator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Diagnostics;
using System.Reflection;
using System.Security.Principal;
using System.Windows.Forms;

namespace Conduit
{
public static class Administrator
{
public static bool IsAdmin()
{
using (WindowsIdentity identity = WindowsIdentity.GetCurrent())
{
WindowsPrincipal principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
}

public static void Elevate()
{
MessageBox.Show(
"Your League client is running as administrator, and Mimic cannot access it. Mimic will now attempt to restart as administrator. Press 'Yes' on the Windows prompt to allow this.",
"Mimic",
MessageBoxButtons.OK,
MessageBoxIcon.Error,
MessageBoxDefaultButton.Button1
);

var currentProcessInfo = new ProcessStartInfo
{
UseShellExecute = true,
WorkingDirectory = Environment.CurrentDirectory,
FileName = Assembly.GetEntryAssembly().Location,
Verb = "runas"
};

Process.Start(currentProcessInfo);
Environment.Exit(0);
}
}
}
7 changes: 5 additions & 2 deletions conduit/Conduit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
<Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
</Reference>
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
Expand All @@ -86,8 +87,8 @@
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="websocket-sharp-customheaders, Version=1.0.2.31869, Culture=neutral, PublicKeyToken=5660b08a1845a91e, processorArchitecture=MSIL">
<HintPath>packages\websocket-sharp-customheaders.1.0.2.31869\lib\net35\websocket-sharp-customheaders.dll</HintPath>
<Reference Include="websocket-sharp, Version=1.0.2.59611, Culture=neutral, PublicKeyToken=5660b08a1845a91e, processorArchitecture=MSIL">
<HintPath>packages\WebSocketSharp.1.0.3-rc11\lib\websocket-sharp.dll</HintPath>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
Expand All @@ -98,8 +99,10 @@
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="Administrator.cs" />
<Compile Include="ConnectionManager.cs" />
<Compile Include="CryptoHelpers.cs" />
<Compile Include="DebugLogger.cs" />
<Compile Include="DeviceConnectionPrompt.xaml.cs">
<DependentUpon>DeviceConnectionPrompt.xaml</DependentUpon>
</Compile>
Expand Down
31 changes: 23 additions & 8 deletions conduit/ConnectionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,15 @@ public ConnectionManager(App app)
// Hook up league events.
league.OnConnected += () =>
{
DebugLogger.Global.WriteMessage($"ConnectionManager is connected to League of Legends.");
isNewLaunch = true;
Connect();
};
league.OnDisconnected += Close;
league.OnDisconnected += () =>
{
DebugLogger.Global.WriteMessage($"ConnectionManager is disconnected from League of Legends.");
Close();
};
}

/**
Expand All @@ -45,16 +50,17 @@ public ConnectionManager(App app)
*/
public async void Connect()
{
Console.WriteLine("[+] Connecting to rift...");

if (hubConnectionHandler != null) throw new Exception("Already connected.");
if (!league.IsConnected) return;

try
{
DebugLogger.Global.WriteMessage("Connecting to Rift...");

// Cancel pending reconnect if there is one.
if (reconnectCancellationTokenSource != null)
{
DebugLogger.Global.WriteMessage($"Canceling older reconnect to Rift.");
reconnectCancellationTokenSource.Cancel();
reconnectCancellationTokenSource = null;
}
Expand All @@ -63,19 +69,23 @@ public async void Connect()
bool valid = false; // in case first startup and hub token is empty
if (!Persistence.GetHubToken().IsNullOrEmpty())
{
DebugLogger.Global.WriteMessage("Requesting hub token..");
var response = await httpClient.GetStringAsync(Program.HUB + "/check?token=" + Persistence.GetHubToken());
valid = response == "true";
DebugLogger.Global.WriteMessage($"Hub token validity: {(valid ? "valid" : "invalid")}.");
}

// ... and request a new one if it isn't.
if (!valid)
{
DebugLogger.Global.WriteMessage($"Requesting hub token..");
var payload = "{\"pubkey\":\"" + CryptoHelpers.ExportPublicKey() + "\"}";
var responseBlob = await httpClient.PostAsync(Program.HUB + "/register", new StringContent(payload, Encoding.UTF8, "application/json"));
var response = SimpleJson.DeserializeObject<dynamic>(await responseBlob.Content.ReadAsStringAsync());
if (!response["ok"]) throw new Exception("Could not receive JWT from Rift");

Persistence.SetHubToken(response["token"]);
DebugLogger.Global.WriteMessage($"Hub token: {response["token"]}.");
}

// Connect to hub. Will error if token is invalid or server is down, which will prompt a reconnection.
Expand All @@ -85,13 +95,16 @@ public async void Connect()
// We assume to be connected.
if (isNewLaunch)
{
DebugLogger.Global.WriteMessage($"Creating New Launch popup.");
app.ShowNotification("Connected to League. Click here for instructions on how to control your League client from your phone.");
isNewLaunch = false;
}

hasTriedImmediateReconnect = false;
} catch
}
catch (Exception e)
{
DebugLogger.Global.WriteError($"Connection to Rift failed, an exception occurred: {e.ToString()}");
// Something happened that we didn't anticipate for.
// Just try again in a bit.
CloseAndReconnect();
Expand All @@ -103,7 +116,7 @@ public async void Connect()
*/
public void Close()
{
Console.WriteLine("[+] Disconnecting from rift.");
DebugLogger.Global.WriteMessage("Disconnecting from rift.");

// Already closed, don't error but just ignore.
if (hubConnectionHandler == null) return;
Expand All @@ -130,17 +143,19 @@ public async void CloseAndReconnect()
// If this is an immediate reconnect,
if (hasTriedImmediateReconnect)
{
Console.WriteLine("[+] Reconnecting to rift in 5s...");
DebugLogger.Global.WriteWarning("Could not connect to Rift, retrying to connect to Rift in 5s...");
await Task.Delay(5000, reconnectCancellationTokenSource.Token);
} else
{
Console.WriteLine("[+] Reconnecting to rift immediately...");
DebugLogger.Global.WriteWarning("Could not connect to Rift, retrying to connect to Rift immediately...");
hasTriedImmediateReconnect = true;
}

Connect();
} catch (TaskCanceledException)
}
catch (TaskCanceledException e)
{
DebugLogger.Global.WriteError($"Our reconnect to Rift got canceled, reason: {e.ToString()}");
// Delay got cancelled. Ignore error.
}
}
Expand Down
35 changes: 35 additions & 0 deletions conduit/DebugLogger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.IO;

namespace Conduit
{
public class DebugLogger
{
public static DebugLogger Global = new DebugLogger("global.txt");

private StreamWriter writer;

public DebugLogger(string fileName)
{
writer = new StreamWriter(Path.Combine(Persistence.DATA_DIRECTORY, fileName), true);
writer.AutoFlush = true;
writer.WriteLine($"\n\n\n --- {DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss")} --- ");
writer.WriteLine($"Started logging to {fileName}...");
}

public void WriteError(string error)
{
writer.WriteLine($"[ERROR {DateTime.Now.ToString("HH:mm:ss")}] {error}");
}

public void WriteMessage(string message)
{
writer.WriteLine($"[MSG {DateTime.Now.ToString("HH:mm:ss")}] {message}");
}

public void WriteWarning(string warning)
{
writer.WriteLine($"[WRN {DateTime.Now.ToString("HH:mm:ss")}] {warning}");
}
}
}
13 changes: 7 additions & 6 deletions conduit/HubConnectionHandler.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Web;
using WebSocketSharp;

namespace Conduit
Expand All @@ -23,12 +24,12 @@ public HubConnectionHandler(LeagueConnection league)
{
this.league = league;

socket = new WebSocket(Program.HUB_WS);
socket.CustomHeaders = new Dictionary<string, string>()
{
{"Token", Persistence.GetHubToken()},
{"Public-Key", CryptoHelpers.ExportPublicKey()}
};
// Pass parameters in the URL.
socket = new WebSocket(
Program.HUB_WS
+ "?token=" + HttpUtility.UrlEncode(Persistence.GetHubToken())
+ "&publicKey=" + HttpUtility.UrlEncode(CryptoHelpers.ExportPublicKey())
);

socket.OnMessage += HandleMessage;
socket.OnClose += (sender, ev) =>
Expand Down
92 changes: 58 additions & 34 deletions conduit/LeagueConnection.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Diagnostics;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Authentication;
Expand All @@ -16,11 +17,7 @@ namespace Conduit
*/
class LeagueConnection
{
private static readonly HttpClient HTTP_CLIENT = new HttpClient(new HttpClientHandler()
{
SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls,
ServerCertificateCustomValidationCallback = (a, b, c, d) => true
});
private static HttpClient HTTP_CLIENT;

private WebSocket socketConnection;
private Tuple<Process, string, string> processInfo;
Expand All @@ -41,6 +38,24 @@ class LeagueConnection
*/
public LeagueConnection()
{
try
{
HTTP_CLIENT = new HttpClient(new HttpClientHandler()
{
SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls,
ServerCertificateCustomValidationCallback = (a, b, c, d) => true
});
}
catch
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

HTTP_CLIENT = new HttpClient(new HttpClientHandler()
{
ServerCertificateCustomValidationCallback = (a, b, c, d) => true
});
}

// Run after a slight delay.
Task.Delay(2000).ContinueWith(e => TryConnectOrRetry());
}
Expand All @@ -59,35 +74,44 @@ public void ClearAllListeners()
*/
private void TryConnect()
{
// We're already connected.
if (connected) return;

// Check league status, abort if league is not running.
var status = LeagueUtils.GetLeagueStatus();
if (status == null) return;

// Update local state.
processInfo = status;
connected = true;

// Set the password and base address for our httpclient so we don't have to specify it every time.
var byteArray = Encoding.ASCII.GetBytes("riot:" + status.Item2);
HTTP_CLIENT.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));

// Connect to our websocket.
socketConnection = new WebSocket("wss://127.0.0.1:" + status.Item3 + "/", "wamp");
socketConnection.SetCredentials("riot", status.Item2, true);
socketConnection.SslConfiguration.EnabledSslProtocols = SslProtocols.Tls12;
socketConnection.SslConfiguration.ServerCertificateValidationCallback = (a, b, c, d) => true;
socketConnection.OnMessage += HandleMessage;
socketConnection.OnClose += HandleDisconnect;
socketConnection.Connect();

// Subscribe to Json API events from the LCU.
socketConnection.Send("[5,\"OnJsonApiEvent\"]");

// Emit our events.
OnConnected?.Invoke();
try
{
// We're already connected.
if (connected) return;

// Check league status, abort if league is not running.
var status = LeagueUtils.GetLeagueStatus();
if (status == null) return;

// Set the password and base address for our httpclient so we don't have to specify it every time.
var byteArray = Encoding.ASCII.GetBytes("riot:" + status.Item2);
HTTP_CLIENT.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));

// Connect to our websocket.
socketConnection = new WebSocket("wss://127.0.0.1:" + status.Item3 + "/", "wamp");
socketConnection.SetCredentials("riot", status.Item2, true);

socketConnection.SslConfiguration.EnabledSslProtocols = SslProtocols.Tls12;
socketConnection.SslConfiguration.ServerCertificateValidationCallback = (a, b, c, d) => true;
socketConnection.OnMessage += HandleMessage;
socketConnection.OnClose += HandleDisconnect;
socketConnection.Connect();
// Subscribe to Json API events from the LCU.
socketConnection.Send("[5,\"OnJsonApiEvent\"]");

// Update local state.
processInfo = status;
connected = true;

// Emit our events.
OnConnected?.Invoke();
}
catch (Exception e)
{
processInfo = null;
connected = false;
DebugLogger.Global.WriteError($"Exception occurred trying to connect to League of Legends: {e.ToString()}");
}
}

/**
Expand Down
Loading