diff --git a/CallLcds/CallLcds.csproj b/CallLcds/CallLcds.csproj
index be2b5ca..16c6554 100644
--- a/CallLcds/CallLcds.csproj
+++ b/CallLcds/CallLcds.csproj
@@ -66,10 +66,6 @@
-
- False
- ..\lib\rtmp-sharp.dll
-
@@ -94,6 +90,10 @@
{4516f4a5-7594-402c-b0d8-2dd6f80ec8ea}
FinalesFunkeln
+
+ {aa1a4f5d-3bd4-4832-9f5d-90727007727e}
+ rtmp-sharp
+
diff --git a/FinalesFunkeln/FinalesFunkeln.csproj b/FinalesFunkeln/FinalesFunkeln.csproj
index 138a4f6..ddd8e1a 100644
--- a/FinalesFunkeln/FinalesFunkeln.csproj
+++ b/FinalesFunkeln/FinalesFunkeln.csproj
@@ -98,6 +98,9 @@
False
..\lib\Xceed.Wpf.AvalonDock.dll
+
+ ..\packages\YamlDotNet.4.2.2\lib\net35\YamlDotNet.dll
+
@@ -147,6 +150,7 @@
+
diff --git a/FinalesFunkeln/IO/YamlFile.cs b/FinalesFunkeln/IO/YamlFile.cs
new file mode 100644
index 0000000..99a01ee
--- /dev/null
+++ b/FinalesFunkeln/IO/YamlFile.cs
@@ -0,0 +1,98 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using YamlDotNet.Serialization;
+
+namespace FinalesFunkeln.IO
+{
+ public class YamlFile : DynamicObject, IDynamicMetaObjectProvider,IEnumerable>
+ {
+ Dictionary _backingDict = new Dictionary();
+ string _fileName;
+ bool _readOnly;
+ public YamlFile(string fileName, bool autoInit = true, bool readOnly = false)
+ {
+ if (string.IsNullOrEmpty(fileName))
+ throw new ArgumentNullException("fileName");
+ _fileName = fileName;
+ _readOnly = readOnly;
+ if (autoInit)
+ Read();
+ }
+
+ public void Read()
+ {
+ using (var x = new FileStream(_fileName, FileMode.Open))
+ {
+ var des = new Deserializer();
+ var dict = des.Deserialize>(new StreamReader(x));
+ foreach(var entry in dict)
+ {
+ this[entry.Key] = entry.Value;
+ }
+ }
+
+
+ }
+ public void Write()
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool GetBoolean(string key)
+ {
+ return Convert.ToBoolean(this[key]);
+ }
+
+ public Int32 GetInt32(string key)
+ {
+ return Convert.ToInt32(this[key]);
+ }
+
+ public double GetDouble(string key)
+ {
+ return Convert.ToDouble(this[key]);
+ }
+
+ public string GetString(string key)
+ {
+ return (string)this[key];
+ }
+
+ public object this[string key]
+ {
+ get { return _backingDict[key]; }
+ set { if (_readOnly) throw new InvalidOperationException("Cannot change a value because it's set to read-only"); else _backingDict[key] = value; }
+ }
+
+ public override IEnumerable GetDynamicMemberNames()
+ {
+ return _backingDict.Keys;
+ }
+ public override bool TryGetMember(GetMemberBinder binder, out object result)
+ {
+ result= this[binder.Name];
+ return true;
+ }
+ public override bool TrySetMember(SetMemberBinder binder, object value)
+ {
+ _backingDict[binder.Name] = value;
+ return true;
+ }
+
+ public IEnumerator> GetEnumerator()
+ {
+ return _backingDict.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return _backingDict.GetEnumerator();
+ }
+ }
+}
diff --git a/FinalesFunkeln/Lol/LolClient.cs b/FinalesFunkeln/Lol/LolClient.cs
index 54d833f..70a1bf3 100644
--- a/FinalesFunkeln/Lol/LolClient.cs
+++ b/FinalesFunkeln/Lol/LolClient.cs
@@ -20,19 +20,19 @@ public class LolClient
public LolClientGameData GameData { get; private set; }
- public PropertiesFile Properties { get; private set; }
+ public YamlFile Properties { get; private set; }
public LolConnection Connection { get; private set; }
public ExtensionManager ExtensionManager { get; }
- internal LolClient(string directory, PropertiesFile properties, LolProxy proxy, Process process, ExtensionManager extManager)
+ internal LolClient(string directory, YamlFile properties, LolProxy proxy, Process process, ExtensionManager extManager)
{
if (proxy == null)
throw new ArgumentNullException("proxy");
if(!Directory.Exists(directory))
throw new ArgumentException("directory");
- GameData = new LolClientGameData(Path.Combine(directory, GameDataFile));
- Images = new LolClientImages(directory, GameData);
+ //GameData = new LolClientGameData(Path.Combine(directory, GameDataFile));
+ //Images = new LolClientImages(directory, GameData);
Connection=new LolConnection(proxy, extManager);
Process = process;
Properties = properties;
diff --git a/FinalesFunkeln/MainWindow.xaml.cs b/FinalesFunkeln/MainWindow.xaml.cs
index 75a3c95..92dc4e8 100644
--- a/FinalesFunkeln/MainWindow.xaml.cs
+++ b/FinalesFunkeln/MainWindow.xaml.cs
@@ -40,7 +40,9 @@ partial class MainWindow
const string InternalConfigDir = "config/internal/";
const string LayoutConfigFilename = "Layout.cbf";
const string DefaultLayoutDefinition = "FinalesFunkeln.Resources.Config.Layout.cbf";
- const string LolPropertiesFilename = "lol.properties";
+ const string LolPropertiesFilename = "system.yaml";
+ const string LcuSettingsFilename = "LeagueClientSettings.yaml";
+ const string LcuSettingsPath = "../../../../../../Config/";
const string CertFileName = "data/certs/{0}.p12";
const int RtmpPort = 2099;
@@ -51,7 +53,8 @@ partial class MainWindow
string _rtmpAddress;
X509Certificate2 _certificate;
ExtensionManager _extensionManager;
- PropertiesFile _lolProperties;
+ YamlFile _lolProperties;
+ YamlFile _lcuSettings;
Process _lolClientProcess;
LolClient _lolClient;
@@ -69,12 +72,13 @@ private void Window_Initialized(object sender, EventArgs e)
{
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US");
- if (!Directory.Exists("data") || !File.Exists("sqlite3.dll"))
+
+ if (!Directory.Exists("data"))
{
MessageBox.Show(Debugger.IsAttached ? @"""data"" folder and/or sqlite3.dll not found. Make sure to copy the data folder and sqlite3.dll to the output directory." : "Some files are missing, please reinstall.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
Environment.Exit(-1);
}
-
+
if (!Debugger.IsAttached)
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
_uiManager = new UiManager();
@@ -212,28 +216,12 @@ void ProcessInjector_ProcessFound(object sender, Process e)
{
ProcessInjector pi = sender as ProcessInjector;
if (pi == null) return;
-
-#if !LCU //The new lol client has a separate process for the UI
- //sometimes it takes a while for the main module to be loaded...
- while (e.MainWindowHandle == IntPtr.Zero)
-#endif
+
Thread.Sleep(1000);
string loldir = null;
try
{
-#if AIRDEBUG && DEBUG
- string wmiQuery = string.Format("select CommandLine from Win32_Process where Name='{0}'", "adl.exe");
- ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmiQuery);
- ManagementObjectCollection retObjectCollection = searcher.Get();
- foreach (ManagementObject retObject in retObjectCollection)
- loldir = ProcessHelper.SplitCommandLineArgs((string)retObject["CommandLine"])[2];
-#elif LCU
- loldir = Path.GetDirectoryName(e.MainModule.FileName) ?? string.Empty;
- loldir = Path.Combine(loldir, @"../../../../lol_air_client/releases/0.0.4.147/deploy");
- //TODO this directory is just a placeholder
-#else
loldir = Path.GetDirectoryName(e.MainModule.FileName) ?? string.Empty;
-#endif
}
catch (Win32Exception)
{
@@ -241,9 +229,11 @@ void ProcessInjector_ProcessFound(object sender, Process e)
return;
}
- _lolProperties = new PropertiesFile(Path.Combine(loldir, LolPropertiesFilename));
- var host = _lolProperties["host"];
- _rtmpAddress = host.Contains(",") ? host.Substring(0, host.IndexOf(',')) : host;
+
+ _lolProperties = new YamlFile(Path.Combine(loldir, LolPropertiesFilename));
+ _lcuSettings = new YamlFile(Path.Combine(loldir, LcuSettingsPath, LcuSettingsFilename));
+ //string host = ((dynamic)_lolProperties)["region_data"][((dynamic)_lcuSettings)["install"]["globals"]["region"]]["servers"]["lcds"]["lcds_host"];
+ _rtmpAddress = ((dynamic)_lolProperties)["region_data"][((dynamic)_lcuSettings)["install"]["globals"]["region"]]["servers"]["lcds"]["lcds_host"];
if (_rtmpAddress == null) return;
@@ -296,7 +286,10 @@ void InitProxy()
#if !LCU
_proxy = new LolProxy(new IPEndPoint(IPAddress.Loopback, RtmpPort), new Uri(string.Format("rtmps://{0}:{1}", _rtmpAddress, RtmpPort)), _serializationContext, _certificate);
#else
- _proxy = new LolProxy(new IPEndPoint(IPAddress.Loopback, RtmpPort), new Uri(string.Format("rtmps://{0}:{1}", _rtmpAddress, RtmpPort)), _serializationContext,_certificate);
+ //CEF does not allow self-signed certs so we have to disable TLS for the new client
+ //(locally only, TLS will still be used to communicate with the actual server)
+ //TLS can be disabled for the client in /system.yaml
+ _proxy = new LolProxy(new IPEndPoint(IPAddress.Loopback, RtmpPort), new Uri(string.Format("rtmps://{0}:{1}", _rtmpAddress, RtmpPort)), _serializationContext);
#endif
_proxy.AcknowledgeMessageReceived += OnAckMessageReceived;
@@ -394,7 +387,7 @@ void pi_Injected(object sender, EventArgs e)
{
Dispatcher.Invoke(DispatcherPriority.Input, new ThreadStart(() =>
{
- Title = "Finales Funkeln - Injected [" + _lolProperties["platformId"] + "]";
+ Title = "Finales Funkeln - Injected [" + ((dynamic)_lcuSettings)["install"]["globals"]["region"] + "]";
}));
}
diff --git a/FinalesFunkeln/RiotObjects/BroadcastNotification.cs b/FinalesFunkeln/RiotObjects/BroadcastNotification.cs
index d2021b5..7a8f998 100644
--- a/FinalesFunkeln/RiotObjects/BroadcastNotification.cs
+++ b/FinalesFunkeln/RiotObjects/BroadcastNotification.cs
@@ -8,7 +8,7 @@
namespace FinalesFunkeln.RiotObjects
{
[Serializable]
- [SerializedName("com.riotgames.platform.broadcast.BroadcastNotification")]
+ //[SerializedName("com.riotgames.platform.broadcast.BroadcastNotification")]
public class BroadcastNotification : ExternalizableJsonObject
{
public BroadcastNotification():base("com.riotgames.platform.broadcast.BroadcastNotification") { }
diff --git a/FinalesFunkeln/RiotObjects/ClientSystemStatesNotification.cs b/FinalesFunkeln/RiotObjects/ClientSystemStatesNotification.cs
index b416a73..32ae6e0 100644
--- a/FinalesFunkeln/RiotObjects/ClientSystemStatesNotification.cs
+++ b/FinalesFunkeln/RiotObjects/ClientSystemStatesNotification.cs
@@ -8,7 +8,7 @@
namespace FinalesFunkeln.RiotObjects
{
[Serializable]
- [SerializedName("com.riotgames.platform.systemstate.ClientSystemStatesNotification")]
+ //[SerializedName("com.riotgames.platform.systemstate.ClientSystemStatesNotification")]
public class ClientSystemStatesNotification : ExternalizableJsonObject
{
public ClientSystemStatesNotification():base("com.riotgames.platform.systemstate.ClientSystemStatesNotification") { }
diff --git a/FinalesFunkeln/Util/ProcessInjector.cs b/FinalesFunkeln/Util/ProcessInjector.cs
index 079aaf3..b79bec9 100644
--- a/FinalesFunkeln/Util/ProcessInjector.cs
+++ b/FinalesFunkeln/Util/ProcessInjector.cs
@@ -13,9 +13,14 @@ namespace FinalesFunkeln.Util
{
class ProcessInjector:IDisposable
{
- readonly byte[] _connectCc =
- {
- 0x55, //PUSH EBP
+#if LCU
+ const string CONNECT_FUNCTION = "WSAConnect";
+#else
+ const string CONNECT_FUNCTION = "connect";
+#endif
+ readonly byte[] _connectCc =
+ {
+ 0x55, //PUSH EBP
0x8B, 0xEC, //MOV EBP, ESP
0x60, //PUSHAD
0x8B, 0x45, 0x0C, //MOV EAX, [EBP+C]
@@ -117,7 +122,7 @@ internal void Inject()
int jmpaddrloc = connect.Length - 4;
var mod = ProcessMemory.GetModule("ws2_32.dll");
- Int32 reladdr = notemem.GetAddress(mod, "connect");
+ Int32 reladdr = notemem.GetAddress(mod, CONNECT_FUNCTION);
reladdr -= mod;
var lolmod = GetModuleAddress(CurrentProcess, mem, "ws2_32.dll");
diff --git a/FinalesFunkeln/packages.config b/FinalesFunkeln/packages.config
index d92eb9d..7bd012e 100644
--- a/FinalesFunkeln/packages.config
+++ b/FinalesFunkeln/packages.config
@@ -2,4 +2,5 @@
+
\ No newline at end of file
diff --git a/lib/rtmp-sharp b/lib/rtmp-sharp
index 43b8eb1..3720769 160000
--- a/lib/rtmp-sharp
+++ b/lib/rtmp-sharp
@@ -1 +1 @@
-Subproject commit 43b8eb1dd1073e2d1ce7a7b39aeeef9d3657ef15
+Subproject commit 3720769e1162e91b8865c7cff61cdc1bc87345bf
diff --git a/lib/rtmpsharpgit/rtmp-sharp b/lib/rtmpsharpgit/rtmp-sharp
new file mode 160000
index 0000000..43b8eb1
--- /dev/null
+++ b/lib/rtmpsharpgit/rtmp-sharp
@@ -0,0 +1 @@
+Subproject commit 43b8eb1dd1073e2d1ce7a7b39aeeef9d3657ef15