diff --git a/AltStore/Server/Server.swift b/AltStore/Server/Server.swift index 4314c1df..86d26606 100644 --- a/AltStore/Server/Server.swift +++ b/AltStore/Server/Server.swift @@ -31,6 +31,7 @@ extension Server case wireless case wired case local + case manual } } @@ -48,12 +49,23 @@ struct Server: Equatable extension Server { // Defined in extension so we can still use the automatically synthesized initializer. - init?(service: NetService, txtData: Data) + init?(service: NetService, txtData: Data) // TODO: this is all that's needed for a server connection { let txtDictionary = NetService.dictionary(fromTXTRecord: txtData) - guard let identifierData = txtDictionary["serverID"], let identifier = String(data: identifierData, encoding: .utf8) else { return nil } + guard let identifierData = txtDictionary["serverID"], let identifier = String(data: identifierData, encoding: .utf8) else { + NSLog("Ahh, no serverID in TXT record for service: \(service)") + return nil + } self.service = service self.identifier = identifier } + + init?(service: NetService) + { + self.service = service + self.connectionType = .manual + self.identifier = String(data: "yolo".data(using: .utf8)!, encoding: .utf8) + } } + diff --git a/AltStore/Server/ServerManager.swift b/AltStore/Server/ServerManager.swift index abc88c43..8083668b 100644 --- a/AltStore/Server/ServerManager.swift +++ b/AltStore/Server/ServerManager.swift @@ -42,10 +42,21 @@ extension ServerManager { guard !self.isDiscovering else { return } self.isDiscovering = true - + self.serviceBrowser.searchForServices(ofType: ALTServerServiceType, inDomain: "") - + self.startListeningForWiredConnections() + + // Print log mentioning that we are manually adding this + NSLog("Manually adding server") + let ianTestService = NetService(domain: "69.69.0.1", type: "_altserver._tcp", name: "AltStore", port: 43311) + + if let server = Server(service: ianTestService) + { + self.addDiscoveredServer(server) + } else { + NSLog("Check for manual server failed!!") + } } func stopDiscovering() @@ -78,7 +89,8 @@ extension ServerManager { case .local: self.connectToLocalServer(server, completion: finish(_:)) case .wired: - guard let incomingConnectionsSemaphore = self.incomingConnectionsSemaphore else { return finish(.failure(ALTServerError(.connectionFailed))) } + guard let incomingConnectionsSemaphore = self.incomingConnectionsSemaphore else { return +finish(.failure(ALTServerError(.connectionFailed))) } print("Waiting for incoming connection...") @@ -87,7 +99,7 @@ extension ServerManager switch server.connectionType { case .wired: CFNotificationCenterPostNotification(notificationCenter, .wiredServerConnectionStartRequest, nil, nil, true) - case .local, .wireless: break + case .local, .wireless, .manual: break } _ = incomingConnectionsSemaphore.wait(timeout: .now() + 10.0) @@ -101,13 +113,23 @@ extension ServerManager finish(.failure(ALTServerError(.connectionFailed))) } - case .wireless: + case .wireless: guard let service = server.service else { return finish(.failure(ALTServerError(.connectionFailed))) } - print("Connecting to service:", service) + print("Connecting to mDNS service:", service) let connection = NWConnection(to: .service(name: service.name, type: service.type, domain: service.domain, interface: nil), using: .tcp) self.connectToRemoteServer(server, connection: connection, completion: finish(_:)) + case .manual: + guard let service = server.service else { return finish(.failure(ALTServerError(.connectionFailed))) } + + connectNetmuxd() + + print("Connecting to manual service:", service.domain) + print("Port: ", String(service.port.description)) + + let connection = NWConnection(host: NWEndpoint.Host(service.domain), port: NWEndpoint.Port(String(service.port))!, using: .tcp) + self.connectToRemoteServer(server, connection: connection, completion: finish(_:)) } } } @@ -186,7 +208,7 @@ private extension ServerManager @unknown default: break } } - + print("Connected to server!") connection.start(queue: self.dispatchQueue) } @@ -215,6 +237,9 @@ extension ServerManager: NetServiceBrowserDelegate func netServiceBrowserWillSearch(_ browser: NetServiceBrowser) { print("Discovering servers...") + + // Send a post request to JitStreamer to deal with the devil + connectNetmuxd() } func netServiceBrowserDidStopSearch(_ browser: NetServiceBrowser) @@ -272,3 +297,70 @@ extension ServerManager: NetServiceDelegate print("Service \(sender) updated TXT Record:", txtDict) } } + +func connectNetmuxd() { + + // declare the parameter as a dictionary that contains string as key and value combination. considering inputs are valid + + let parameters: [String: Any] = ["nothing": 0] + + // create the url with URL + let url = URL(string: "http://69.69.0.1/netmuxd/")! + + // create the session object + let session = URLSession.shared + + // now create the URLRequest object using the url object + var request = URLRequest(url: url) + request.httpMethod = "POST" //set http method as POST + + // add headers for the request + request.addValue("application/json", forHTTPHeaderField: "Content-Type") // change as per server requirements + request.addValue("application/json", forHTTPHeaderField: "Accept") + + do { + // convert parameters to Data and assign dictionary to httpBody of request + request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted) + } catch let error { + print(error.localizedDescription) + return + } + + // create dataTask using the session object to send data to the server + let task = session.dataTask(with: request) { data, response, error in + + if let error = error { + print("Post Request Error: \(error.localizedDescription)") + return + } + + // ensure there is valid response code returned from this HTTP response + guard let httpResponse = response as? HTTPURLResponse, + (200...299).contains(httpResponse.statusCode) + else { + print("Invalid Response received from the server") + return + } + + // ensure there is data returned + guard let responseData = data else { + print("nil Data received from the server") + return + } + + do { + // create json object from data or use JSONDecoder to convert to Model stuct + if let jsonResponse = try JSONSerialization.jsonObject(with: responseData, options: .mutableContainers) as? [String: Any] { + print(jsonResponse) + // handle json response + } else { + print("data maybe corrupted or in wrong format") + throw URLError(.badServerResponse) + } + } catch let error { + print(error.localizedDescription) + } + } + // perform the task + task.resume() +}