private async void Quit_Game(object sender, RoutedEventArgs e) { // TODO need to make a UI element to display this text Task.Run(() => SpinnerBegin("Quitting...")).Wait(); // If we haven't used nv before, create it. if (nv == null) { try { await SpinnerBegin("Quitting"); Computer selected = (Computer)computerPicker.SelectedItem; nv = new NvHttp(selected.IpAddress); await nv.ServerIPAddress(); XmlQuery quit = new XmlQuery(nv.BaseUrl + "/cancel?uniqueid=" + nv.GetUniqueId()); } catch (Exception) { SpinnerEnd(); StreamSetupFailed("Unable to quit"); return; } finally { // Turn off the spinner SpinnerEnd(); } } }
/// <summary> /// Create start HTTP request /// </summary> private XmlQuery StartOrResumeApp(NvHttp nv, LimelightStreamConfiguration streamConfig) { XmlQuery serverInfo = new XmlQuery(nv.baseUrl + "/serverinfo?uniqueid=" + nv.GetUniqueId()); string currentGameString = serverInfo.XmlAttribute("currentgame"); byte[] aesIv = streamConfig.GetRiAesIv(); int riKeyId = (int)(((aesIv[0] << 24) & 0xFF000000) | ((aesIv[1] << 16) & 0xFF0000) | ((aesIv[2] << 8) & 0xFF00) | (aesIv[3] & 0xFF)); string riConfigString = "&rikey=" + Pairing.bytesToHex(streamConfig.GetRiAesKey()) + "&rikeyid=" + riKeyId; // Launch a new game if nothing is running if (currentGameString == null || currentGameString.Equals("0")) { return new XmlQuery(nv.baseUrl + "/launch?uniqueid=" + nv.GetUniqueId() + "&appid=" + selected.steamID + "&mode=" + streamConfig.GetWidth() + "x" + streamConfig.GetHeight() + "x" + streamConfig.GetFps() + "&additionalStates=1&sops=1" + // FIXME: make sops configurable riConfigString); } else { // A game was already running, so resume it // FIXME: Quit and relaunch if it's not the game we came to start return new XmlQuery(nv.baseUrl + "/resume?uniqueid=" + nv.GetUniqueId() + riConfigString); } }
/// <summary> /// Create start HTTP request /// </summary> private XmlQuery StartOrResumeApp(NvHttp nv, LimelightStreamConfiguration streamConfig) { XmlQuery serverInfo = new XmlQuery(nv.BaseUrl + "/serverinfo?uniqueid=" + nv.GetUniqueId()); string currentGameString = serverInfo.XmlAttribute("currentgame"); byte[] aesIv = streamConfig.GetRiAesIv(); int riKeyId = (int)(((aesIv[0] << 24) & 0xFF000000) | ((aesIv[1] << 16) & 0xFF0000) | ((aesIv[2] << 8) & 0xFF00) | (aesIv[3] & 0xFF)); string riConfigString = "&rikey=" + Pairing.bytesToHex(streamConfig.GetRiAesKey()) + "&rikeyid=" + riKeyId; // Launch a new game if nothing is running if (currentGameString == null || currentGameString.Equals("0")) { return(new XmlQuery(nv.BaseUrl + "/launch?uniqueid=" + nv.GetUniqueId() + "&appid=" + selected.steamID + "&mode=" + streamConfig.GetWidth() + "x" + streamConfig.GetHeight() + "x" + streamConfig.GetFps() + "&additionalStates=1&sops=1" + // FIXME: make sops configurable riConfigString)); } else { // A game was already running, so resume it // FIXME: Quit and relaunch if it's not the game we came to start return(new XmlQuery(nv.BaseUrl + "/resume?uniqueid=" + nv.GetUniqueId() + riConfigString)); } }
/// <summary> /// Executed when the user presses "Pair" /// </summary> private async void PairButton_Click(object sender, RoutedEventArgs e) { Computer selected = (Computer)computerPicker.SelectedItem; // User hasn't selected anything if (selected == null) { var dialog = new MessageDialog("No machine selected", "Pairing Failed"); await dialog.ShowAsync(); status_text.Text = ""; return; } nv = new NvHttp(selected.IpAddress); Pairing p = new Pairing(nv); // Stop polling timer while we're pairing mDnsTimer.Stop(); SaveSettings(); await p.Pair(selected); mDnsTimer.Stop(); }
/// <summary> /// Pair with the hostname in the textbox /// </summary> public async Task Pair(Computer c) { Debug.WriteLine("Pairing "); // Create NvHttp object with the user input as the URL try { nv = new NvHttp(c.IpAddress); } catch (Exception) { var dialog = new MessageDialog("Invalid Hostname", "Pairing Failed"); dialog.ShowAsync(); return; } // Get the server IP address try { await nv.ServerIPAddress(); } catch (Exception e) { var dialog = new MessageDialog("Error resolving hostname " + e.Message , "Pairing Failed"); dialog.ShowAsync(); return; } // "Please don't do this ever, but it's only okay because Cameron said so" -Cameron Gutman getClientCertificate(); // Get the pair state. bool? pairState = await QueryPairState(); if (pairState == true) { var dialog = new MessageDialog("This device is already paired to the host PC", "Already Paired"); dialog.ShowAsync(); Debug.WriteLine("Already paired"); return; } // pairstate = null. We've encountered an error else if (!pairState.HasValue) { var dialog = new MessageDialog("Failed to query pair state", "Pairing failed"); dialog.ShowAsync(); Debug.WriteLine("Query pair state failed"); return; } bool challenge = await Challenges(nv.GetUniqueId()); if (!challenge) { Debug.WriteLine("Challenges failed"); return; } // Otherwise, everything was successful MainPage.SaveComputer(c); var successDialog = new MessageDialog("Pairing successful", "Success"); await successDialog.ShowAsync(); }
/// <summary> /// Starts the connection by calling into Limelight Common /// </summary> private async Task StartConnection() { NvHttp nv = null; await SetStateText("Resolving hostname..."); try { nv = new NvHttp(selected.IpAddress); } catch (ArgumentNullException) { stageFailureText = "Error resolving hostname"; ConnectionFailed(); } XmlQuery launchApp; // Launch Steam await SetStateText("Launching Steam"); try { launchApp = new XmlQuery(nv.baseUrl + "/launch?uniqueid=" + nv.GetDeviceName() + "&appid=" + selected.steamID); } catch (Exception) { Debug.WriteLine("Can't find steam"); stageFailureText = "Error launching Steam"; ConnectionFailed(); return; } // Set up callbacks LimelightStreamConfiguration streamConfig = new LimelightStreamConfiguration(frameWidth, frameHeight, 30, 10000, 1024); // TODO a magic number. Get FPS from the settings LimelightDecoderRenderer drCallbacks = new LimelightDecoderRenderer(DrSetup, DrStart, DrStop, DrRelease, DrSubmitDecodeUnit); LimelightAudioRenderer arCallbacks = new LimelightAudioRenderer(ArInit, ArStart, ArStop, ArRelease, ArPlaySample); LimelightConnectionListener clCallbacks = new LimelightConnectionListener(ClStageStarting, ClStageComplete, ClStageFailed, ClConnectionStarted, ClConnectionTerminated, ClDisplayMessage, ClDisplayTransientMessage); // Call into Common to start the connection Debug.WriteLine("Starting connection"); uint addr = 0; //uint addr = (uint)nv.resolvedHost.ToString(); // TODO how to get the addr as a uint LimelightCommonRuntimeComponent.StartConnection(addr, streamConfig, clCallbacks, drCallbacks, arCallbacks); if (stageFailureText != null) { Debug.WriteLine("Stage failed"); ConnectionFailed(); return; } else { ConnectionSuccess(); } }
/// <summary> /// When the user presses "Start Streaming Steam", first check that they are paired /// </summary> private async Task StreamSetup(Computer computer) { // Resolve the hostname try { nv = new NvHttp(computer.IpAddress); } catch (Exception) { StreamSetupFailed("Invalid Hostname"); return; } // Get the Ip address of the streaming machine try { await nv.ServerIPAddress(); } catch (Exception) { StreamSetupFailed("Unable to get streaming machine's IP addresss"); return; } Pairing p = new Pairing(nv); // HACK: Preload the cert data p.getClientCertificate(); // If we can't get the pair state, return bool?pairState = await p.QueryPairState(); if (!pairState.HasValue) { StreamSetupFailed("Pair state query failed"); return; } // If we're not paired, return if (pairState == false) { StreamSetupFailed("Device not paired"); return; } // If we haven't cancelled and don't have the steam ID, query app list to get it if (computer.steamID == 0) { // If queryAppList fails, return computer.steamID = await Task.Run(() => QueryAppList()); if (computer.steamID == 0) { StreamSetupFailed("App list query failed"); return; } } StreamSetupComplete(); }
/// <summary> /// When the user presses "Start Streaming Steam", first check that they are paired /// </summary> private async Task StreamSetup(Computer computer) { // Resolve the hostname try { nv = new NvHttp(computer.IpAddress); } catch (Exception) { StreamSetupFailed("Invalid Hostname"); return; } // Get the Ip address of the streaming machine try { await nv.ServerIPAddress(); } catch (Exception) { StreamSetupFailed("Unable to get streaming machine's IP addresss"); return; } Pairing p = new Pairing(nv); // HACK: Preload the cert data p.getClientCertificate(); // If we can't get the pair state, return bool? pairState = await p.QueryPairState(); if (!pairState.HasValue) { await StreamSetupFailed("Pair state query failed"); return; } // If we're not paired, return if (pairState == false) { await StreamSetupFailed("Device not paired"); return; } // If we haven't cancelled and don't have the steam ID, query app list to get it if (computer.steamID == 0) { // If queryAppList fails, return computer.steamID = await Task.Run(() => QueryAppList()); if (computer.steamID == 0) { await StreamSetupFailed("App list query failed"); return; } } await StreamSetupComplete(); }
/// <summary> /// When the user presses "Start Streaming Steam", first check that they are paired in the background worker /// </summary> private async Task StreamSetup(string uri) { try { nv = new NvHttp(uri); } catch (Exception) { StreamSetupFailed("Invalid Hostname"); return; } try { await nv.GetServerIPAddress(); } catch (Exception) { StreamSetupFailed("Unable to get streaming machine's IP addresss"); } // If device is already paired, return. if (!await QueryPairState()) { await StreamSetupFailed("Pair state query failed"); return; } // If we haven't cancelled and don't have the steam ID, query app list to get it if (steamId == 0) { // If queryAppList fails, return if (!await Task.Run(() => QueryAppList())) { await StreamSetupFailed("App list query failed"); return; } } await StreamSetupComplete(); }
/// <summary> /// Pair with the hostname in the textbox /// </summary> private async Task Pair(string uri) { Debug.WriteLine("Pairing "); // Create NvHttp object with the user input as the URL try { nv = new NvHttp(uri); } catch (Exception) { var dialog = new MessageDialog("Invalid Hostname", "Pairing Failed"); dialog.ShowAsync(); return; } // Get the server IP address try { await nv.GetServerIPAddress(); } catch (Exception e) { var dialog = new MessageDialog("Error resolving hostname " + e.Message, "Pairing Failed"); dialog.ShowAsync(); return; } if (await QueryPairState()) { Debug.WriteLine("Already paired"); return; } Challenges(nv.GetDeviceName()); // Otherwise, everything was successful var successDialog = new MessageDialog("Pairing successful", "Success"); await successDialog.ShowAsync(); }
/// <summary> /// Constructor that sets nv /// </summary> /// <param name="nv">The NvHttp Object</param> public Pairing(NvHttp nv) { this.nv = nv; }
/// <summary> /// Executed when the user presses "Pair" /// </summary> private async void PairButton_Click(object sender, RoutedEventArgs e) { Computer selected = (Computer)computerPicker.SelectedItem; // User hasn't selected anything if (selected == null) { var dialog = new MessageDialog("No machine selected", "Pairing Failed"); await dialog.ShowAsync(); status_text.Text = ""; return; } nv = new NvHttp(selected.IpAddress); Pairing p = new Pairing(nv); // Stop polling timer while we're pairing mDnsTimer.Stop(); SaveSettings(); await p.Pair(selected); mDnsTimer.Stop(); }
/// <summary> /// Starts the connection by calling into Limelight Common /// </summary> private async Task StartConnection(LimelightStreamConfiguration streamConfig) { NvHttp nv = null; await SetStateText("Resolving hostname..."); try { nv = new NvHttp(selected.IpAddress); } catch (ArgumentNullException) { stageFailureText = "Error resolving hostname"; ConnectionFailed(); return; } try { await nv.ServerIPAddress(); } catch (Exception) { stageFailureText = "Error resolving hostname"; ConnectionFailed(); return; } // Set up callbacks LimelightDecoderRenderer drCallbacks = new LimelightDecoderRenderer(DrSetup, DrStart, DrStop, DrRelease, DrSubmitDecodeUnit); LimelightAudioRenderer arCallbacks = new LimelightAudioRenderer(ArInit, ArStart, ArStop, ArRelease, ArPlaySample); LimelightConnectionListener clCallbacks = new LimelightConnectionListener(ClStageStarting, ClStageComplete, ClStageFailed, ClConnectionStarted, ClConnectionTerminated, ClDisplayMessage, ClDisplayTransientMessage); XmlQuery launchApp; // Launch Steam await SetStateText("Launching Steam"); try { launchApp = StartOrResumeApp(nv, streamConfig); } catch (Exception) { Debug.WriteLine("Can't find steam"); stageFailureText = "Error launching Steam"; ConnectionFailed(); return; } // Call into Common to start the connection Debug.WriteLine("Starting connection"); Regex r = new Regex(@"^(?<octet1>\d+).(?<octet2>\d+).(?<octet3>\d+).(?<octet4>\d+)"); Match m = r.Match(selected.IpAddress); uint addr = (uint)(Convert.ToByte(m.Groups["octet4"].Value) << 24 | Convert.ToByte(m.Groups["octet3"].Value) << 16 | Convert.ToByte(m.Groups["octet2"].Value) << 8 | Convert.ToByte(m.Groups["octet1"].Value)); LimelightCommonRuntimeComponent.StartConnection(addr, streamConfig, clCallbacks, drCallbacks, arCallbacks); if (stageFailureText != null) { Debug.WriteLine("Stage failed"); ConnectionFailed(); return; } else { ConnectionSuccess(); } }
/// <summary> /// Starts the connection by calling into Limelight Common /// </summary> private async Task StartConnection(LimelightStreamConfiguration streamConfig) { NvHttp nv = null; await SetStateText("Resolving hostname..."); try { nv = new NvHttp(selected.IpAddress); } catch (ArgumentNullException) { stageFailureText = "Error resolving hostname"; ConnectionFailed(); return; } try { await nv.ServerIPAddress(); } catch (Exception) { stageFailureText = "Error resolving hostname"; ConnectionFailed(); return; } // Set up callbacks LimelightDecoderRenderer drCallbacks = new LimelightDecoderRenderer(DrSetup, DrStart, DrStop, DrRelease, DrSubmitDecodeUnit); LimelightAudioRenderer arCallbacks = new LimelightAudioRenderer(ArInit, ArStart, ArStop, ArRelease, ArPlaySample); LimelightConnectionListener clCallbacks = new LimelightConnectionListener(ClStageStarting, ClStageComplete, ClStageFailed, ClConnectionStarted, ClConnectionTerminated, ClDisplayMessage, ClDisplayTransientMessage); XmlQuery launchApp; // Launch Steam await SetStateText("Launching Steam"); try { launchApp = StartOrResumeApp(nv, streamConfig); } catch (Exception) { Debug.WriteLine("Can't find steam"); stageFailureText = "Error launching Steam"; ConnectionFailed(); return; } // Call into Common to start the connection Debug.WriteLine("Starting connection"); Regex r = new Regex(@"^(?<octet1>\d+).(?<octet2>\d+).(?<octet3>\d+).(?<octet4>\d+)"); Match m = r.Match(selected.IpAddress); uint addr = (uint)(Convert.ToByte(m.Groups["octet4"].Value) << 24 | Convert.ToByte(m.Groups["octet3"].Value) << 16 | Convert.ToByte(m.Groups["octet2"].Value) << 8 | Convert.ToByte(m.Groups["octet1"].Value)); LimelightCommonRuntimeComponent.StartConnection(addr, streamConfig, clCallbacks, drCallbacks, arCallbacks); if (stageFailureText != null) { Debug.WriteLine("Stage failed"); ConnectionFailed(); return; } else { ConnectionSuccess(); } }
/// <summary> /// Pair with the hostname in the textbox /// </summary> public async Task Pair(Computer c) { Debug.WriteLine("Pairing "); // Create NvHttp object with the user input as the URL try { nv = new NvHttp(c.IpAddress); } catch (Exception) { var dialog = new MessageDialog("Invalid Hostname", "Pairing Failed"); dialog.ShowAsync(); return; } // Get the server IP address try { await nv.ServerIPAddress(); } catch (Exception e) { var dialog = new MessageDialog("Error resolving hostname " + e.Message, "Pairing Failed"); dialog.ShowAsync(); return; } // "Please don't do this ever, but it's only okay because Cameron said so" -Cameron Gutman getClientCertificate(); // Get the pair state. bool?pairState = await QueryPairState(); if (pairState == true) { var dialog = new MessageDialog("This device is already paired to the host PC", "Already Paired"); dialog.ShowAsync(); Debug.WriteLine("Already paired"); return; } // pairstate = null. We've encountered an error else if (!pairState.HasValue) { var dialog = new MessageDialog("Failed to query pair state", "Pairing failed"); dialog.ShowAsync(); Debug.WriteLine("Query pair state failed"); return; } bool challenge = await Challenges(nv.GetUniqueId()); if (!challenge) { Debug.WriteLine("Challenges failed"); return; } // Otherwise, everything was successful MainPage.SaveComputer(c); var successDialog = new MessageDialog("Pairing successful", "Success"); await successDialog.ShowAsync(); }
/// <summary> /// Constructor that sets nv /// </summary> /// <param name="nv">The NvHttp Object</param> public Pairing(NvHttp nv) { this.nv = nv; }