mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
Downloads, resigns, and installs apps from start to finish
This commit is contained in:
BIN
AltServer/App.ipa
Normal file
BIN
AltServer/App.ipa
Normal file
Binary file not shown.
@@ -173,6 +173,27 @@ private extension ConnectionManager
|
||||
guard !self.connections.contains(where: { $0 === connection }) else { return }
|
||||
self.connections.append(connection)
|
||||
|
||||
func finish(error: ALTServerError?)
|
||||
{
|
||||
if let error = error
|
||||
{
|
||||
print("Failed to process request from \(connection.endpoint).", error)
|
||||
}
|
||||
else
|
||||
{
|
||||
print("Processed request from \(connection.endpoint).")
|
||||
}
|
||||
|
||||
let success = (error == nil)
|
||||
let response = ServerResponse(success: success, error: error)
|
||||
|
||||
self.send(response, to: connection) { (result) in
|
||||
print("Sent response to \(connection.endpoint) with result:", result)
|
||||
|
||||
self.disconnect(connection)
|
||||
}
|
||||
}
|
||||
|
||||
connection.stateUpdateHandler = { [weak self] (state) in
|
||||
switch state
|
||||
{
|
||||
@@ -181,6 +202,23 @@ private extension ConnectionManager
|
||||
case .ready:
|
||||
print("Connected to client:", connection.endpoint)
|
||||
|
||||
self?.receiveRequest(from: connection) { (result) in
|
||||
print("Received request with result:", result)
|
||||
|
||||
switch result
|
||||
{
|
||||
case .failure(let error): finish(error: error)
|
||||
case .success(let request, let fileURL):
|
||||
print("Installing to device..")
|
||||
|
||||
ALTDeviceManager.shared.installApp(at: fileURL, toDeviceWithUDID: request.udid) { (success, error) in
|
||||
print("Installed app with result:", result)
|
||||
let error = error.map { $0 as? ALTServerError ?? ALTServerError(.unknown) }
|
||||
finish(error: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case .waiting:
|
||||
print("Waiting for connection...")
|
||||
|
||||
@@ -196,50 +234,20 @@ private extension ConnectionManager
|
||||
}
|
||||
|
||||
connection.start(queue: self.dispatchQueue)
|
||||
|
||||
func finish(error: ALTServerError?)
|
||||
{
|
||||
if let error = error
|
||||
{
|
||||
print("Failed to process request from \(connection.endpoint).", error)
|
||||
}
|
||||
else
|
||||
{
|
||||
print("Processed request from \(connection.endpoint).")
|
||||
}
|
||||
|
||||
let success = (error == nil)
|
||||
let response = ServerResponse(success: success, error: error)
|
||||
|
||||
self.send(response, to: connection) { (result) in
|
||||
print("Sent response to \(connection) with result:", result)
|
||||
|
||||
self.disconnect(connection)
|
||||
}
|
||||
}
|
||||
|
||||
self.receiveRequest(from: connection) { (result) in
|
||||
switch result
|
||||
{
|
||||
case .failure(let error): finish(error: error)
|
||||
case .success(let request, let fileURL):
|
||||
ALTDeviceManager.shared.installApp(at: fileURL, toDeviceWithUDID: request.udid) { (success, error) in
|
||||
let error = error.map { $0 as? ALTServerError ?? ALTServerError(.unknown) }
|
||||
finish(error: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func receiveRequest(from connection: NWConnection, completionHandler: @escaping (Result<(ServerRequest, URL), ALTServerError>) -> Void)
|
||||
{
|
||||
let size = MemoryLayout<Int32>.size
|
||||
|
||||
print("Receiving request size")
|
||||
connection.receive(minimumIncompleteLength: size, maximumLength: size) { (data, _, _, error) in
|
||||
do
|
||||
{
|
||||
let data = try self.process(data: data, error: error, from: connection)
|
||||
|
||||
print("Receiving request")
|
||||
|
||||
let expectedBytes = Int(data.withUnsafeBytes { $0.load(as: Int32.self) })
|
||||
connection.receive(minimumIncompleteLength: expectedBytes, maximumLength: expectedBytes) { (data, _, _, error) in
|
||||
do
|
||||
@@ -247,6 +255,9 @@ private extension ConnectionManager
|
||||
let data = try self.process(data: data, error: error, from: connection)
|
||||
|
||||
let request = try JSONDecoder().decode(ServerRequest.self, from: data)
|
||||
|
||||
print("Receiving app data (Size: \(request.contentSize))")
|
||||
|
||||
self.process(request, from: connection, completionHandler: completionHandler)
|
||||
}
|
||||
catch
|
||||
@@ -267,10 +278,16 @@ private extension ConnectionManager
|
||||
connection.receive(minimumIncompleteLength: request.contentSize, maximumLength: request.contentSize) { (data, _, _, error) in
|
||||
do
|
||||
{
|
||||
print("Received app data!")
|
||||
|
||||
let data = try self.process(data: data, error: error, from: connection)
|
||||
|
||||
print("Processed app data!")
|
||||
|
||||
guard ALTDeviceManager.shared.connectedDevices.contains(where: { $0.identifier == request.udid }) else { throw ALTServerError(.deviceNotFound) }
|
||||
|
||||
print("Writing app data...")
|
||||
|
||||
let temporaryURL = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString + ".ipa")
|
||||
try data.write(to: temporaryURL, options: .atomic)
|
||||
|
||||
@@ -280,6 +297,8 @@ private extension ConnectionManager
|
||||
}
|
||||
catch
|
||||
{
|
||||
print("Error processing app data:", error)
|
||||
|
||||
completionHandler(.failure(ALTServerError(error)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ NSErrorDomain const ALTDeviceErrorDomain = @"com.rileytestut.ALTDeviceError";
|
||||
|
||||
@property (nonatomic, readonly) NSMutableDictionary<NSUUID *, void (^)(void)> *installationCompletionHandlers;
|
||||
@property (nonatomic, readonly) NSMutableDictionary<NSUUID *, NSProgress *> *installationProgress;
|
||||
@property (nonatomic, readonly) NSMutableDictionary<NSUUID *, NSValue *> *installationClients;
|
||||
|
||||
@end
|
||||
|
||||
@@ -47,6 +48,7 @@ NSErrorDomain const ALTDeviceErrorDomain = @"com.rileytestut.ALTDeviceError";
|
||||
{
|
||||
_installationCompletionHandlers = [NSMutableDictionary dictionary];
|
||||
_installationProgress = [NSMutableDictionary dictionary];
|
||||
_installationClients = [NSMutableDictionary dictionary];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -235,6 +237,9 @@ NSErrorDomain const ALTDeviceErrorDomain = @"com.rileytestut.ALTDeviceError";
|
||||
return progress;
|
||||
}
|
||||
|
||||
NSValue *value = [NSValue valueWithPointer:(const void *)np];
|
||||
|
||||
self.installationClients[UUID] = value;
|
||||
self.installationProgress[UUID] = progress;
|
||||
self.installationCompletionHandlers[UUID] = ^{
|
||||
finish(nil);
|
||||
@@ -357,18 +362,17 @@ NSErrorDomain const ALTDeviceErrorDomain = @"com.rileytestut.ALTDeviceError";
|
||||
#pragma mark - Getters -
|
||||
|
||||
- (NSArray<ALTDevice *> *)connectedDevices
|
||||
{
|
||||
{
|
||||
NSMutableArray *connectedDevices = [NSMutableArray array];
|
||||
|
||||
int count = 0;
|
||||
char **udids = NULL;
|
||||
|
||||
if (idevice_get_device_list(&udids, &count) < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Unable to retrieve device list!\n");
|
||||
return @[];
|
||||
}
|
||||
|
||||
NSMutableArray *connectedDevices = [NSMutableArray array];
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
char *udid = udids[i];
|
||||
@@ -435,9 +439,19 @@ void ALTDeviceManagerDidFinishAppInstallation(const char *notification, void *uu
|
||||
if (completionHandler != nil)
|
||||
{
|
||||
completionHandler();
|
||||
|
||||
ALTDeviceManager.sharedManager.installationCompletionHandlers[UUID] = nil;
|
||||
ALTDeviceManager.sharedManager.installationProgress[UUID] = nil;
|
||||
}
|
||||
|
||||
NSValue *value = ALTDeviceManager.sharedManager.installationClients[UUID];
|
||||
if (value != nil)
|
||||
{
|
||||
np_client_t np = (np_client_t)value.pointerValue;
|
||||
np_set_notify_callback(np, NULL, uuid);
|
||||
|
||||
ALTDeviceManager.sharedManager.installationClients[UUID] = nil;
|
||||
}
|
||||
}
|
||||
|
||||
void ALTDeviceManagerUpdateStatus(plist_t command, plist_t status, void *uuid)
|
||||
|
||||
@@ -276,8 +276,7 @@ private extension ViewController
|
||||
|
||||
func registerAppID(name appName: String, identifier: String, team: ALTTeam, completionHandler: @escaping (Result<ALTAppID, Error>) -> Void)
|
||||
{
|
||||
var bundleID = "com." + team.account.firstName.lowercased() + team.account.lastName.lowercased() + "." + identifier
|
||||
bundleID = bundleID.replacingOccurrences(of: " ", with: "")
|
||||
let bundleID = "com.\(team.identifier).\(identifier)"
|
||||
|
||||
ALTAppleAPI.shared.fetchAppIDs(for: team) { (appIDs, error) in
|
||||
do
|
||||
|
||||
Reference in New Issue
Block a user