mirror of
https://github.com/moonlight-stream/moonlight-ios.git
synced 2025-07-01 23:35:59 +00:00
parent
a2b15ed2ac
commit
4f03dd8c08
@ -15,6 +15,7 @@
|
||||
@property (atomic) PairState pairState;
|
||||
@property (atomic, nullable, retain) NSString * activeAddress;
|
||||
@property (atomic, nullable, retain) NSString * currentGame;
|
||||
@property (atomic) unsigned short httpsPort;
|
||||
|
||||
@property (atomic, nullable, retain) NSData *serverCert;
|
||||
@property (atomic, nullable, retain) NSString *address;
|
||||
|
@ -20,7 +20,7 @@ static const int MAX_ATTEMPTS = 5;
|
||||
- (void) main {
|
||||
int attempts = 0;
|
||||
while (![self isCancelled] && attempts++ < MAX_ATTEMPTS) {
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_host.activeAddress uniqueId:[IdManager getUniqueId] serverCert:_host.serverCert];
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_host];
|
||||
AppAssetResponse* appAssetResp = [[AppAssetResponse alloc] init];
|
||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:appAssetResp withUrlRequest:[hMan newAppAssetRequestWithAppId:self.app.id]]];
|
||||
|
||||
|
@ -7,14 +7,14 @@
|
||||
//
|
||||
|
||||
#import "AppListResponse.h"
|
||||
#import "TemporaryHost.h"
|
||||
|
||||
#ifndef ConnectionHelper_h
|
||||
#define ConnectionHelper_h
|
||||
|
||||
|
||||
@interface ConnectionHelper : NSObject
|
||||
|
||||
+(AppListResponse*) getAppListForHostWithHostIP:(NSString*) hostIP serverCert:(NSData*) serverCert uniqueID:(NSString*) uniqueId;
|
||||
+(AppListResponse*) getAppListForHost:(TemporaryHost*)host;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -14,8 +14,8 @@
|
||||
|
||||
@implementation ConnectionHelper
|
||||
|
||||
+(AppListResponse*) getAppListForHostWithHostIP:(NSString*) hostIP serverCert:(NSData*) cert uniqueID:(NSString*) uniqueId {
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:hostIP uniqueId:uniqueId serverCert:cert];
|
||||
+(AppListResponse*) getAppListForHost:(TemporaryHost*)host {
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:host];
|
||||
|
||||
// Try up to 5 times to get the app list
|
||||
AppListResponse* appListResp = nil;
|
||||
|
@ -120,7 +120,7 @@
|
||||
}
|
||||
|
||||
- (ServerInfoResponse*) getServerInfoResponseForAddress:(NSString*)address {
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:address uniqueId:_uniqueId serverCert:nil];
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithAddress:address httpsPort:0 serverCert:nil];
|
||||
ServerInfoResponse* serverInfoResponse = [[ServerInfoResponse alloc] init];
|
||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResponse withUrlRequest:[hMan newServerInfoRequest:false] fallbackError:401 fallbackRequest:[hMan newHttpServerInfoRequest]]];
|
||||
return serverInfoResponse;
|
||||
|
@ -103,8 +103,8 @@ static const float POLL_RATE = 2.0f; // Poll every 2 seconds
|
||||
ServerInfoResponse* serverInfoResp = [self requestInfoAtAddress:address cert:_host.serverCert];
|
||||
receivedResponse = [self checkResponse:serverInfoResp];
|
||||
if (receivedResponse) {
|
||||
[serverInfoResp populateHost:_host];
|
||||
_host.activeAddress = address;
|
||||
[serverInfoResp populateHost:_host];
|
||||
|
||||
// Update the database using the response
|
||||
DataManager *dataManager = [[DataManager alloc] init];
|
||||
@ -126,9 +126,7 @@ static const float POLL_RATE = 2.0f; // Poll every 2 seconds
|
||||
}
|
||||
|
||||
- (ServerInfoResponse*) requestInfoAtAddress:(NSString*)address cert:(NSData*)cert {
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:address
|
||||
uniqueId:_uniqueId
|
||||
serverCert:cert];
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithAddress:address httpsPort:0 serverCert:cert];
|
||||
ServerInfoResponse* response = [[ServerInfoResponse alloc] init];
|
||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:response
|
||||
withUrlRequest:[hMan newServerInfoRequest:true]
|
||||
|
@ -9,10 +9,12 @@
|
||||
#import "HttpResponse.h"
|
||||
#import "HttpRequest.h"
|
||||
#import "StreamConfiguration.h"
|
||||
#import "TemporaryHost.h"
|
||||
|
||||
@interface HttpManager : NSObject <NSURLSessionDelegate>
|
||||
|
||||
- (id) initWithHost:(NSString*) host uniqueId:(NSString*) uniqueId serverCert:(NSData*) serverCert;
|
||||
- (id) initWithHost:(TemporaryHost*) host;
|
||||
- (id) initWithAddress:(NSString*) hostAddressPortString httpsPort:(unsigned short) httpsPort serverCert:(NSData*) serverCert;
|
||||
- (void) setServerCert:(NSData*) serverCert;
|
||||
- (NSURLRequest*) newPairRequest:(NSData*)salt clientCert:(NSData*)clientCert;
|
||||
- (NSURLRequest*) newUnpairRequest;
|
||||
|
@ -10,6 +10,7 @@
|
||||
#import "HttpRequest.h"
|
||||
#import "CryptoManager.h"
|
||||
#import "TemporaryApp.h"
|
||||
#import "ServerInfoResponse.h"
|
||||
|
||||
#include <libxml2/libxml/xmlreader.h>
|
||||
#include <string.h>
|
||||
@ -23,8 +24,8 @@
|
||||
|
||||
@implementation HttpManager {
|
||||
NSURLSession* _urlSession;
|
||||
NSString* _urlSafeHostName;
|
||||
NSString* _baseHTTPURL;
|
||||
NSString* _baseHTTPSURL;
|
||||
NSString* _uniqueId;
|
||||
NSString* _deviceName;
|
||||
NSData* _serverCert;
|
||||
@ -32,12 +33,12 @@
|
||||
NSData* _requestResp;
|
||||
dispatch_semaphore_t _requestLock;
|
||||
|
||||
TemporaryHost *_host; // May be nil
|
||||
NSString* _baseHTTPSURL;
|
||||
|
||||
NSError* _error;
|
||||
}
|
||||
|
||||
static const NSString* HTTP_PORT = @"47989";
|
||||
static const NSString* HTTPS_PORT = @"47984";
|
||||
|
||||
+ (NSData*) fixXmlVersion:(NSData*) xmlData {
|
||||
NSString* dataString = [[NSString alloc] initWithData:xmlData encoding:NSUTF8StringEncoding];
|
||||
NSString* xmlString = [dataString stringByReplacingOccurrencesOfString:@"UTF-16" withString:@"UTF-8" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [dataString length])];
|
||||
@ -49,7 +50,13 @@ static const NSString* HTTPS_PORT = @"47984";
|
||||
_serverCert = serverCert;
|
||||
}
|
||||
|
||||
- (id) initWithHost:(NSString*) host uniqueId:(NSString*) uniqueId serverCert:(NSData*) serverCert {
|
||||
- (id) initWithHost:(TemporaryHost*) host {
|
||||
self = [self initWithAddress:host.activeAddress httpsPort:host.httpsPort serverCert:host.serverCert];
|
||||
_host = host;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithAddress:(NSString*) hostAddressPortString httpsPort:(unsigned short)httpsPort serverCert:(NSData*) serverCert {
|
||||
self = [super init];
|
||||
// Use the same UID for all Moonlight clients to allow them
|
||||
// quit games started on another Moonlight client.
|
||||
@ -61,21 +68,64 @@ static const NSString* HTTPS_PORT = @"47984";
|
||||
NSURLSessionConfiguration* config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
|
||||
_urlSession = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
|
||||
|
||||
NSString* address = [Utils addressPortStringToAddress:hostAddressPortString];
|
||||
unsigned short port = [Utils addressPortStringToPort:hostAddressPortString];
|
||||
|
||||
// If this is an IPv6 literal, we must properly enclose it in brackets
|
||||
NSString* urlSafeHost;
|
||||
if ([host containsString:@":"]) {
|
||||
urlSafeHost = [NSString stringWithFormat:@"[%@]", host];
|
||||
if ([address containsString:@":"]) {
|
||||
_urlSafeHostName = [NSString stringWithFormat:@"[%@]", address];
|
||||
} else {
|
||||
urlSafeHost = host;
|
||||
_urlSafeHostName = address;
|
||||
}
|
||||
|
||||
_baseHTTPURL = [NSString stringWithFormat:@"http://%@:%@", urlSafeHost, HTTP_PORT];
|
||||
_baseHTTPSURL = [NSString stringWithFormat:@"https://%@:%@", urlSafeHost, HTTPS_PORT];
|
||||
_baseHTTPURL = [NSString stringWithFormat:@"http://%@:%u", _urlSafeHostName, port];
|
||||
|
||||
if (httpsPort) {
|
||||
_baseHTTPSURL = [NSString stringWithFormat:@"https://%@:%u", _urlSafeHostName, httpsPort];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL) ensureHttpsUrlPopulated:(bool)fastFail {
|
||||
if (!_baseHTTPSURL) {
|
||||
// Use the caller's provided port if one was specified
|
||||
if (_host && _host.httpsPort != 0) {
|
||||
_baseHTTPSURL = [NSString stringWithFormat:@"https://%@:%u", _urlSafeHostName, _host.httpsPort];
|
||||
}
|
||||
else {
|
||||
// Query the host to retrieve the HTTPS port
|
||||
ServerInfoResponse* serverInfoResponse = [[ServerInfoResponse alloc] init];
|
||||
[self executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResponse withUrlRequest:[self newHttpServerInfoRequest:false]]];
|
||||
TemporaryHost* dummyHost = [[TemporaryHost alloc] init];
|
||||
if (![serverInfoResponse isStatusOk]) {
|
||||
return NO;
|
||||
}
|
||||
[serverInfoResponse populateHost:dummyHost];
|
||||
|
||||
// Pass the port back if the caller provided storage for it
|
||||
if (_host) {
|
||||
_host.httpsPort = dummyHost.httpsPort;
|
||||
}
|
||||
|
||||
_baseHTTPSURL = [NSString stringWithFormat:@"https://%@:%u", _urlSafeHostName, dummyHost.httpsPort];
|
||||
}
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) executeRequestSynchronously:(HttpRequest*)request {
|
||||
// This is a special case to handle failure of HTTPS port fetching
|
||||
if (!request.request) {
|
||||
if (request.response) {
|
||||
request.response.statusCode = EHOSTDOWN;
|
||||
request.response.statusMessage = @"Host is unreachable";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
[_respData setLength:0];
|
||||
_error = nil;
|
||||
|
||||
@ -174,11 +224,19 @@ static const NSString* HTTPS_PORT = @"47984";
|
||||
}
|
||||
|
||||
- (NSURLRequest*) newPairChallenge {
|
||||
if (![self ensureHttpsUrlPopulated:NO]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&phrase=pairchallenge", _baseHTTPSURL, _uniqueId, _deviceName];
|
||||
return [self createRequestFromString:urlString timeout:NORMAL_TIMEOUT_SEC];
|
||||
}
|
||||
|
||||
- (NSURLRequest *)newAppListRequest {
|
||||
if (![self ensureHttpsUrlPopulated:NO]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/applist?uniqueid=%@", _baseHTTPSURL, _uniqueId];
|
||||
return [self createRequestFromString:urlString timeout:NORMAL_TIMEOUT_SEC];
|
||||
}
|
||||
@ -189,6 +247,10 @@ static const NSString* HTTPS_PORT = @"47984";
|
||||
return [self newHttpServerInfoRequest:fastFail];
|
||||
}
|
||||
|
||||
if (![self ensureHttpsUrlPopulated:fastFail]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/serverinfo?uniqueid=%@", _baseHTTPSURL, _uniqueId];
|
||||
return [self createRequestFromString:urlString timeout:(fastFail ? SHORT_TIMEOUT_SEC : NORMAL_TIMEOUT_SEC)];
|
||||
}
|
||||
@ -203,6 +265,10 @@ static const NSString* HTTPS_PORT = @"47984";
|
||||
}
|
||||
|
||||
- (NSURLRequest*) newLaunchRequest:(StreamConfiguration*)config {
|
||||
if (![self ensureHttpsUrlPopulated:NO]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Using an FPS value over 60 causes SOPS to default to 720p60,
|
||||
// so force it to 0 to ensure the correct resolution is set. We
|
||||
// used to use 60 here but that locked the frame rate to 60 FPS
|
||||
@ -225,6 +291,10 @@ static const NSString* HTTPS_PORT = @"47984";
|
||||
}
|
||||
|
||||
- (NSURLRequest*) newResumeRequest:(StreamConfiguration*)config {
|
||||
if (![self ensureHttpsUrlPopulated:NO]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/resume?uniqueid=%@&rikey=%@&rikeyid=%d&surroundAudioInfo=%d",
|
||||
_baseHTTPSURL, _uniqueId,
|
||||
[Utils bytesToHex:config.riKey], config.riKeyId,
|
||||
@ -235,11 +305,19 @@ static const NSString* HTTPS_PORT = @"47984";
|
||||
}
|
||||
|
||||
- (NSURLRequest*) newQuitAppRequest {
|
||||
if (![self ensureHttpsUrlPopulated:NO]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/cancel?uniqueid=%@", _baseHTTPSURL, _uniqueId];
|
||||
return [self createRequestFromString:urlString timeout:LONG_TIMEOUT_SEC];
|
||||
}
|
||||
|
||||
- (NSURLRequest*) newAppAssetRequestWithAppId:(NSString *)appId {
|
||||
if (![self ensureHttpsUrlPopulated:NO]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/appasset?uniqueid=%@&appid=%@&AssetType=2&AssetIdx=0", _baseHTTPSURL, _uniqueId, appId];
|
||||
return [self createRequestFromString:urlString timeout:NORMAL_TIMEOUT_SEC];
|
||||
}
|
||||
|
@ -72,16 +72,21 @@ static NSString* NV_SERVICE_TYPE = @"_nvstream._tcp";
|
||||
struct sockaddr* addr = (struct sockaddr*)[addrData bytes];
|
||||
if (addr->sa_family == AF_INET) {
|
||||
inet_ntop(addr->sa_family, &((struct sockaddr_in*)addr)->sin_addr, addrStr, sizeof(addrStr));
|
||||
unsigned short port = ntohs(((struct sockaddr_in*)addr)->sin_port);
|
||||
return [NSString stringWithFormat: @"%s:%u", addrStr, port];
|
||||
}
|
||||
else {
|
||||
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)addr;
|
||||
inet_ntop(addr->sa_family, &sin6->sin6_addr, addrStr, sizeof(addrStr));
|
||||
unsigned short port = ntohs(((struct sockaddr_in6*)addr)->sin6_port);
|
||||
if (sin6->sin6_scope_id != 0) {
|
||||
// Link-local addresses with scope IDs are special
|
||||
return [NSString stringWithFormat: @"%s%%%u", addrStr, sin6->sin6_scope_id];
|
||||
return [NSString stringWithFormat: @"[%s%%%u]:%u", addrStr, sin6->sin6_scope_id, port];
|
||||
}
|
||||
else {
|
||||
return [NSString stringWithFormat: @"[%s]:%u", addrStr, port];
|
||||
}
|
||||
}
|
||||
return [NSString stringWithFormat: @"%s", addrStr];
|
||||
}
|
||||
|
||||
+ (BOOL)isAddress:(uint8_t*)address inSubnet:(uint8_t*)subnet netmask:(int)bits {
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#define TAG_HOSTNAME @"hostname"
|
||||
#define TAG_EXTERNAL_IP @"ExternalIP"
|
||||
#define TAG_HTTPS_PORT @"HttpsPort"
|
||||
#define TAG_LOCAL_IP @"LocalIP"
|
||||
#define TAG_UNIQUE_ID @"uniqueid"
|
||||
#define TAG_MAC_ADDRESS @"mac"
|
||||
@ -18,6 +19,9 @@
|
||||
#define TAG_STATE @"state"
|
||||
#define TAG_CURRENT_GAME @"currentgame"
|
||||
|
||||
// Sunshine extension
|
||||
#define TAG_EXTERNAL_PORT @"ExternalPort"
|
||||
|
||||
@interface ServerInfoResponse : HttpResponse <Response>
|
||||
|
||||
- (void) populateWithData:(NSData *)data;
|
||||
|
@ -23,17 +23,58 @@
|
||||
host.mac = [[self getStringTag:TAG_MAC_ADDRESS] trim];
|
||||
host.currentGame = [[self getStringTag:TAG_CURRENT_GAME] trim];
|
||||
|
||||
NSInteger httpsPort;
|
||||
if ([self getIntTag:TAG_HTTPS_PORT value:&httpsPort]) {
|
||||
host.httpsPort = (unsigned short)httpsPort;
|
||||
}
|
||||
else {
|
||||
// Use the default if it's not specified
|
||||
host.httpsPort = 47984;
|
||||
}
|
||||
|
||||
// We might get an IPv4 loopback address if we're using GS IPv6 Forwarder
|
||||
NSString *lanAddr = [[self getStringTag:TAG_LOCAL_IP] trim];
|
||||
if (![lanAddr hasPrefix:@"127."]) {
|
||||
host.localAddress = lanAddr;
|
||||
unsigned short localPort;
|
||||
|
||||
// If we reached this host through this port, store our port there
|
||||
if (host.activeAddress && [lanAddr isEqualToString:[Utils addressPortStringToAddress:host.activeAddress]]) {
|
||||
localPort = [Utils addressPortStringToPort:host.activeAddress];
|
||||
}
|
||||
else if (host.localAddress) {
|
||||
// If there's an existing local address, use the port from that
|
||||
localPort = [Utils addressPortStringToPort:host.localAddress];
|
||||
}
|
||||
else {
|
||||
// If all else fails, use 47989
|
||||
localPort = 47989;
|
||||
}
|
||||
|
||||
host.localAddress = [Utils addressAndPortToAddressPortString:lanAddr port:localPort];
|
||||
}
|
||||
|
||||
// This is a Sunshine extension for WAN port remapping
|
||||
NSInteger externalHttpPort;
|
||||
if (![self getIntTag:TAG_EXTERNAL_PORT value:&externalHttpPort]) {
|
||||
// Use our active port if it's not specified
|
||||
if (host.activeAddress) {
|
||||
externalHttpPort = [Utils addressPortStringToPort:host.activeAddress];
|
||||
}
|
||||
else {
|
||||
// Otherwise use the default
|
||||
externalHttpPort = 47989;
|
||||
}
|
||||
}
|
||||
|
||||
// Modern GFE versions don't actually give us a WAN address anymore
|
||||
// so we leave the one that we populated from mDNS discovery via STUN.
|
||||
NSString *wanAddr = [[self getStringTag:TAG_EXTERNAL_IP] trim];
|
||||
if (wanAddr) {
|
||||
host.externalAddress = wanAddr;
|
||||
host.externalAddress = [Utils addressAndPortToAddressPortString:wanAddr port:externalHttpPort];
|
||||
}
|
||||
else if (host.externalAddress) {
|
||||
// If we have an external address (via STUN) already, we still need to populate the port
|
||||
host.externalAddress = [Utils addressAndPortToAddressPortString:[Utils addressPortStringToAddress:host.externalAddress] port:externalHttpPort];
|
||||
}
|
||||
|
||||
NSString *state = [[self getStringTag:TAG_STATE] trim];
|
||||
|
@ -38,29 +38,32 @@ static const int ports[numPorts] = {
|
||||
NSData* wolPayload = [WakeOnLanManager createPayload:host];
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
const char* address;
|
||||
NSString* address;
|
||||
struct addrinfo hints, *res, *curr;
|
||||
|
||||
// try all ip addresses
|
||||
if (i == 0 && host.localAddress != nil) {
|
||||
address = [host.localAddress UTF8String];
|
||||
address = host.localAddress;
|
||||
} else if (i == 1 && host.externalAddress != nil) {
|
||||
address = [host.externalAddress UTF8String];
|
||||
address = host.externalAddress;
|
||||
} else if (i == 2 && host.address != nil) {
|
||||
address = [host.address UTF8String];
|
||||
address = host.address;
|
||||
} else if (i == 3 && host.ipv6Address != nil) {
|
||||
address = [host.ipv6Address UTF8String];
|
||||
address = host.ipv6Address;
|
||||
} else if (i == 4) {
|
||||
address = "255.255.255.255";
|
||||
address = @"255.255.255.255";
|
||||
} else {
|
||||
// Requested address wasn't present
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the raw address from the address+port string
|
||||
NSString* rawAddress = [Utils addressPortStringToAddress:address];
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_flags = AI_ADDRCONFIG;
|
||||
if (getaddrinfo(address, NULL, &hints, &res) != 0 || res == NULL) {
|
||||
if (getaddrinfo([rawAddress UTF8String], NULL, &hints, &res) != 0 || res == NULL) {
|
||||
// Failed to resolve address
|
||||
Log(LOG_E, @"Failed to resolve WOL address");
|
||||
continue;
|
||||
|
@ -344,8 +344,9 @@ void ClSetHdrMode(bool enabled)
|
||||
videoStatsLock = [[NSLock alloc] init];
|
||||
}
|
||||
|
||||
NSString *rawAddress = [Utils addressPortStringToAddress:config.host];
|
||||
strncpy(_hostString,
|
||||
[config.host cStringUsingEncoding:NSUTF8StringEncoding],
|
||||
[rawAddress cStringUsingEncoding:NSUTF8StringEncoding],
|
||||
sizeof(_hostString));
|
||||
strncpy(_appVersionString,
|
||||
[config.appVersion cStringUsingEncoding:NSUTF8StringEncoding],
|
||||
|
@ -9,6 +9,7 @@
|
||||
@interface StreamConfiguration : NSObject
|
||||
|
||||
@property NSString* host;
|
||||
@property unsigned short httpsPort;
|
||||
@property NSString* appVersion;
|
||||
@property NSString* gfeVersion;
|
||||
@property NSString* appID;
|
||||
|
@ -9,5 +9,5 @@
|
||||
#import "StreamConfiguration.h"
|
||||
|
||||
@implementation StreamConfiguration
|
||||
@synthesize host, appID, width, height, frameRate, bitRate, riKeyId, riKey, gamepadMask, appName, optimizeGameSettings, playAudioOnPC, swapABXYButtons, audioConfiguration, enableHdr, multiController, allowHevc, serverCert, rtspSessionUrl;
|
||||
@synthesize host, httpsPort, appID, width, height, frameRate, bitRate, riKeyId, riKey, gamepadMask, appName, optimizeGameSettings, playAudioOnPC, swapABXYButtons, audioConfiguration, enableHdr, multiController, allowHevc, serverCert, rtspSessionUrl;
|
||||
@end
|
||||
|
@ -39,10 +39,8 @@
|
||||
|
||||
- (void)main {
|
||||
[CryptoManager generateKeyPairUsingSSL];
|
||||
NSString* uniqueId = [IdManager getUniqueId];
|
||||
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_config.host
|
||||
uniqueId:uniqueId
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithAddress:_config.host httpsPort:_config.httpsPort
|
||||
serverCert:_config.serverCert];
|
||||
|
||||
ServerInfoResponse* serverInfoResp = [[ServerInfoResponse alloc] init];
|
||||
@ -67,7 +65,8 @@
|
||||
return;
|
||||
}
|
||||
|
||||
if (_config.width > 4096 || _config.height > 4096) {
|
||||
// Only perform this check on GFE (as indicated by MJOLNIR in state value)
|
||||
if ((_config.width > 4096 || _config.height > 4096) && [serverState containsString:@"MJOLNIR"]) {
|
||||
// Pascal added support for 8K HEVC encoding support. Maxwell 2 could encode HEVC but only up to 4K.
|
||||
// We can't directly identify Pascal, but we can look for HEVC Main10 which was added in the same generation.
|
||||
NSString* codecSupport = [serverInfoResp getStringTag:@"ServerCodecModeSupport"];
|
||||
|
@ -27,6 +27,10 @@ FOUNDATION_EXPORT NSString *const deviceName;
|
||||
+ (NSData*) hexToBytes:(NSString*) hex;
|
||||
+ (void) addHelpOptionToDialog:(UIAlertController*)dialog;
|
||||
+ (BOOL) isActiveNetworkVPN;
|
||||
+ (BOOL) parseAddressPortString:(NSString*)addressPort address:(NSRange*)address port:(NSRange*)port;
|
||||
+ (NSString*) addressPortStringToAddress:(NSString*)addressPort;
|
||||
+ (unsigned short) addressPortStringToPort:(NSString*)addressPort;
|
||||
+ (NSString*) addressAndPortToAddressPortString:(NSString*)address port:(unsigned short)port;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -73,6 +73,73 @@ NSString *const deviceName = @"roth";
|
||||
#endif
|
||||
}
|
||||
|
||||
+ (BOOL) parseAddressPortString:(NSString*)addressPort address:(NSRange*)address port:(NSRange*)port {
|
||||
if (![addressPort containsString:@":"]) {
|
||||
// If there's no port or IPv6 separator, the whole thing is an address
|
||||
*address = NSMakeRange(0, [addressPort length]);
|
||||
*port = NSMakeRange(NSNotFound, 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NSInteger locationOfOpeningBracket = [addressPort rangeOfString:@"["].location;
|
||||
NSInteger locationOfClosingBracket = [addressPort rangeOfString:@"]"].location;
|
||||
if (locationOfOpeningBracket != NSNotFound || locationOfClosingBracket != NSNotFound) {
|
||||
// If we have brackets, it's an IPv6 address
|
||||
if (locationOfOpeningBracket == NSNotFound || locationOfClosingBracket == NSNotFound ||
|
||||
locationOfClosingBracket < locationOfOpeningBracket) {
|
||||
// Invalid address format
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Cut at the brackets
|
||||
*address = NSMakeRange(locationOfOpeningBracket + 1, locationOfClosingBracket - locationOfOpeningBracket - 1);
|
||||
}
|
||||
else {
|
||||
// It's an IPv4 address, so just cut at the port separator
|
||||
*address = NSMakeRange(0, [addressPort rangeOfString:@":"].location);
|
||||
}
|
||||
|
||||
NSUInteger remainingStringLocation = address->location + address->length;
|
||||
NSRange remainingStringRange = NSMakeRange(remainingStringLocation, [addressPort length] - remainingStringLocation);
|
||||
NSInteger locationOfPortSeparator = [addressPort rangeOfString:@":" options:0 range:remainingStringRange].location;
|
||||
if (locationOfPortSeparator != NSNotFound) {
|
||||
*port = NSMakeRange(locationOfPortSeparator + 1, [addressPort length] - locationOfPortSeparator - 1);
|
||||
}
|
||||
else {
|
||||
*port = NSMakeRange(NSNotFound, 0);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+ (NSString*) addressPortStringToAddress:(NSString*)addressPort {
|
||||
NSRange addressRange, portRange;
|
||||
if (![self parseAddressPortString:addressPort address:&addressRange port:&portRange]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
return [addressPort substringWithRange:addressRange];
|
||||
}
|
||||
|
||||
+ (unsigned short) addressPortStringToPort:(NSString*)addressPort {
|
||||
NSRange addressRange, portRange;
|
||||
if (![self parseAddressPortString:addressPort address:&addressRange port:&portRange] || portRange.location == NSNotFound) {
|
||||
return 47989;
|
||||
}
|
||||
|
||||
return [[addressPort substringWithRange:portRange] integerValue];
|
||||
}
|
||||
|
||||
+ (NSString*) addressAndPortToAddressPortString:(NSString*)address port:(unsigned short)port {
|
||||
if ([address containsString:@":"]) {
|
||||
// IPv6 addresses require escaping
|
||||
return [NSString stringWithFormat:@"[%@]:%u", address, port];
|
||||
}
|
||||
else {
|
||||
return [NSString stringWithFormat:@"%@:%u", address, port];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSString (NSStringWithTrim)
|
||||
|
@ -168,7 +168,7 @@ static NSMutableSet* hostList;
|
||||
// Exempt this host from discovery while handling the applist query
|
||||
[self->_discMan pauseDiscoveryForHost:host];
|
||||
|
||||
AppListResponse* appListResp = [ConnectionHelper getAppListForHostWithHostIP:host.activeAddress serverCert:host.serverCert uniqueID:self->_uniqueId];
|
||||
AppListResponse* appListResp = [ConnectionHelper getAppListForHost:host];
|
||||
|
||||
[self->_discMan resumeDiscoveryForHost:host];
|
||||
|
||||
@ -373,7 +373,7 @@ static NSMutableSet* hostList;
|
||||
return;
|
||||
}
|
||||
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:host.activeAddress uniqueId:self->_uniqueId serverCert:host.serverCert];
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:host];
|
||||
ServerInfoResponse* serverInfoResp = [[ServerInfoResponse alloc] init];
|
||||
|
||||
// Exempt this host from discovery while handling the serverinfo request
|
||||
@ -593,6 +593,7 @@ static NSMutableSet* hostList;
|
||||
- (void) prepareToStreamApp:(TemporaryApp *)app {
|
||||
_streamConfig = [[StreamConfiguration alloc] init];
|
||||
_streamConfig.host = app.host.activeAddress;
|
||||
_streamConfig.httpsPort = app.host.httpsPort;
|
||||
_streamConfig.appID = app.id;
|
||||
_streamConfig.appName = app.name;
|
||||
_streamConfig.serverCert = app.host.serverCert;
|
||||
@ -718,7 +719,7 @@ static NSMutableSet* hostList;
|
||||
Log(LOG_I, @"Quitting application: %@", currentApp.name);
|
||||
[self showLoadingFrame: ^{
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:app.host.activeAddress uniqueId:self->_uniqueId serverCert:app.host.serverCert];
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:app.host];
|
||||
HttpResponse* quitResponse = [[HttpResponse alloc] init];
|
||||
HttpRequest* quitRequest = [HttpRequest requestForResponse: quitResponse withUrlRequest:[hMan newQuitAppRequest]];
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user