Added the "No upcoming songs." if it's the end of the playlist or if
[MenuTunes.git] / NetworkController.m
index 3ac6250..1e7a230 100755 (executable)
 
 #import "NetworkController.h"
 #import "MainController.h"
 
 #import "NetworkController.h"
 #import "MainController.h"
-#import "netinet/in.h"
-#import "arpa/inet.h"
+#import "NetworkObject.h"
+#import "PreferencesController.h"
 #import <ITFoundation/ITDebug.h>
 #import <ITFoundation/ITFoundation.h>
 #import <ITFoundation/ITDebug.h>
 #import <ITFoundation/ITFoundation.h>
-#import <ITMTRemote/ITMTRemote.h>
 
 static NetworkController *sharedController;
 
 
 static NetworkController *sharedController;
 
@@ -42,9 +41,10 @@ static NetworkController *sharedController;
 {
     [self disconnect];
     if (serverOn) {
 {
     [self disconnect];
     if (serverOn) {
-        [serverConnection invalidate];
         [serverConnection release];
     }
         [serverConnection release];
     }
+    [serverPass release];
+    [clientPass release];
     [clientProxy release];
     [remoteServices release];
     [browser release];
     [clientProxy release];
     [remoteServices release];
     [browser release];
@@ -69,15 +69,19 @@ static NetworkController *sharedController;
 {
     if (!serverOn && status) {
         NSString *name = [[NSUserDefaults standardUserDefaults] stringForKey:@"sharedPlayerName"];
 {
     if (!serverOn && status) {
         NSString *name = [[NSUserDefaults standardUserDefaults] stringForKey:@"sharedPlayerName"];
+        unsigned char buffer;
+        NSData *fullPass;
         //Turn on
         NS_DURING
             serverPort = [[NSSocketPort alloc] initWithTCPPort:SERVER_PORT];
             serverConnection = [[NSConnection alloc] initWithReceivePort:serverPort
                                                      sendPort:serverPort];
         //Turn on
         NS_DURING
             serverPort = [[NSSocketPort alloc] initWithTCPPort:SERVER_PORT];
             serverConnection = [[NSConnection alloc] initWithReceivePort:serverPort
                                                      sendPort:serverPort];
-            [serverConnection setRootObject:[[MainController sharedController] currentRemote]];
+            [serverConnection setRootObject:[[NetworkObject alloc] init]];
             [serverConnection registerName:@"ITMTPlayerHost"];
             [serverConnection registerName:@"ITMTPlayerHost"];
-            [serverConnection setDelegate:self];
         NS_HANDLER
         NS_HANDLER
+            [[serverConnection rootObject] release];
+            [serverConnection release];
+            [serverPort release];
             ITDebugLog(@"Error starting server!");
         NS_ENDHANDLER
         ITDebugLog(@"Started server.");
             ITDebugLog(@"Error starting server!");
         NS_ENDHANDLER
         ITDebugLog(@"Started server.");
@@ -88,50 +92,143 @@ static NetworkController *sharedController;
                                         type:@"_mttp._tcp."
                                         name:name
                                         port:SERVER_PORT];
                                         type:@"_mttp._tcp."
                                         name:name
                                         port:SERVER_PORT];
+        fullPass = [[NSUserDefaults standardUserDefaults] dataForKey:@"sharedPlayerPassword"];
+        if (fullPass) {
+            [fullPass getBytes:&buffer range:NSMakeRange(6, 4)];
+            [serverPass release];
+            serverPass = [[NSData alloc] initWithBytes:&buffer length:strlen(&buffer)];
+        } else {
+            serverPass = nil;
+        }
         [service publish];
         serverOn = YES;
     } else if (serverOn && !status && [serverConnection isValid]) {
         //Turn off
         [service stop];
         [serverConnection registerName:nil];
         [service publish];
         serverOn = YES;
     } else if (serverOn && !status && [serverConnection isValid]) {
         //Turn off
         [service stop];
         [serverConnection registerName:nil];
-        [serverPort invalidate];
-        [serverConnection invalidate];
+        [[serverConnection rootObject] release];
         [serverConnection release];
         ITDebugLog(@"Stopped server.");
         serverOn = NO;
     }
 }
 
         [serverConnection release];
         ITDebugLog(@"Stopped server.");
         serverOn = NO;
     }
 }
 
-- (BOOL)connectToHost:(NSString *)host
+- (int)connectToHost:(NSString *)host
 {
 {
+    NSData *fullPass = [[NSUserDefaults standardUserDefaults] dataForKey:@"connectPassword"];
+    unsigned char buffer;
     ITDebugLog(@"Connecting to host: %@", host);
     ITDebugLog(@"Connecting to host: %@", host);
+    [remoteHost release];
+    remoteHost = [host copy];
+    if (fullPass) {
+        [fullPass getBytes:&buffer range:NSMakeRange(6, 4)];
+        [clientPass release];
+        clientPass = [[NSData alloc] initWithBytes:&buffer length:strlen(&buffer)];
+    } else {
+        clientPass = nil;
+    }
     NS_DURING
         clientPort = [[NSSocketPort alloc] initRemoteWithTCPPort:SERVER_PORT
                                            host:host];
         clientConnection = [[NSConnection connectionWithReceivePort:nil sendPort:clientPort] retain];
     NS_DURING
         clientPort = [[NSSocketPort alloc] initRemoteWithTCPPort:SERVER_PORT
                                            host:host];
         clientConnection = [[NSConnection connectionWithReceivePort:nil sendPort:clientPort] retain];
+        [clientConnection setReplyTimeout:5];
         clientProxy = [[clientConnection rootProxy] retain];
     NS_HANDLER
         clientProxy = [[clientConnection rootProxy] retain];
     NS_HANDLER
+        [clientConnection release];
+        [clientPort release];
         ITDebugLog(@"Connection to host failed: %@", host);
         return NO;
     NS_ENDHANDLER
         ITDebugLog(@"Connection to host failed: %@", host);
         return NO;
     NS_ENDHANDLER
-    [clientConnection setReplyTimeout:5];
+    
+    if (!clientProxy) {
+        ITDebugLog(@"Null proxy! Couldn't connect!");
+        [self disconnect];
+        return NO;
+    }
+    
+    if ([clientProxy requiresPassword]) {
+        ITDebugLog(@"Server requires password.");
+        //Check to see if a password is set in defaults
+        if ([[NSUserDefaults standardUserDefaults] dataForKey:@"connectPassword"] == nil) {
+            ITDebugLog(@"Asking for password.");
+            if (![[PreferencesController sharedPrefs] showPasswordPanel]) {
+                ITDebugLog(@"Giving up connection attempt.");
+                [self disconnect];
+                return -1;
+            }
+        }
+        
+        //Send the password
+        ITDebugLog(@"Sending password.");
+        while (![clientProxy sendPassword:[[NSUserDefaults standardUserDefaults] dataForKey:@"connectPassword"]]) {
+            ITDebugLog(@"Invalid password!");
+            if (![[PreferencesController sharedPrefs] showInvalidPasswordPanel]) {
+                ITDebugLog(@"Giving up connection attempt.");
+                [self disconnect];
+                return -1;
+            }
+        }
+    }
+    
     ITDebugLog(@"Connected to host: %@", host);
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(disconnect) name:NSConnectionDidDieNotification object:clientConnection];
     connectedToServer = YES;
     ITDebugLog(@"Connected to host: %@", host);
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(disconnect) name:NSConnectionDidDieNotification object:clientConnection];
     connectedToServer = YES;
-    return YES;
+    return 1;
 }
 
 - (BOOL)disconnect
 {
     ITDebugLog(@"Disconnecting from host.");
     connectedToServer = NO;
 }
 
 - (BOOL)disconnect
 {
     ITDebugLog(@"Disconnecting from host.");
     connectedToServer = NO;
+    [remoteHost release];
+    remoteHost = nil;
     [[NSNotificationCenter defaultCenter] removeObserver:self];
     [clientProxy release];
     [[NSNotificationCenter defaultCenter] removeObserver:self];
     [clientProxy release];
-    [clientConnection invalidate];
     [clientConnection release];
     return YES;
 }
 
     [clientConnection release];
     return YES;
 }
 
+- (BOOL)checkForServerAtHost:(NSString *)host
+{
+    NSData *fullPass = [[NSUserDefaults standardUserDefaults] dataForKey:@"connectPassword"];
+    unsigned char buffer;
+    NSConnection *testConnection;
+    NSSocketPort *testPort;
+    NetworkObject *tempProxy;
+    ITDebugLog(@"Checking for shared remote at %@.", host);
+    if (fullPass) {
+        [fullPass getBytes:&buffer range:NSMakeRange(6, 4)];
+        [clientPass release];
+        clientPass = [[NSData alloc] initWithBytes:&buffer length:strlen(&buffer)];
+    } else {
+        clientPass = nil;
+    }
+    
+    NS_DURING
+        testPort = [[NSSocketPort alloc] initRemoteWithTCPPort:SERVER_PORT
+                                         host:host];
+        testConnection = [[NSConnection connectionWithReceivePort:nil sendPort:testPort] retain];
+        [testConnection setReplyTimeout:2];
+        tempProxy = (NetworkObject *)[testConnection rootProxy];
+        [tempProxy serverName];
+    NS_HANDLER
+        ITDebugLog(@"Connection to host failed: %@", host);
+        [testConnection release];
+        [testPort release];
+        return NO;
+    NS_ENDHANDLER
+    
+    if (!clientProxy) {
+        ITDebugLog(@"Null proxy! Couldn't connect!");
+        [testConnection release];
+        [testPort release];
+        return NO;
+    }
+    [testConnection release];
+    [testPort release];
+    return YES;
+}
+
 - (BOOL)isServerOn
 {
     return serverOn;
 - (BOOL)isServerOn
 {
     return serverOn;
@@ -147,9 +244,14 @@ static NetworkController *sharedController;
     return connectedToServer;
 }
 
     return connectedToServer;
 }
 
-- (ITMTRemote *)sharedRemote
+- (NSString *)remoteHost
 {
 {
-    return (ITMTRemote *)clientProxy;
+    return remoteHost;
+}
+
+- (NetworkObject *)networkObject
+{
+    return clientProxy;
 }
 
 - (NSArray *)remoteServices
 }
 
 - (NSArray *)remoteServices
@@ -159,9 +261,19 @@ static NetworkController *sharedController;
 
 - (void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didFindService:(NSNetService *)aNetService moreComing:(BOOL)moreComing
 {
 
 - (void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didFindService:(NSNetService *)aNetService moreComing:(BOOL)moreComing
 {
+    ITDebugLog(@"Found service named %@.", [aNetService name]);
+    [remoteServices addObject:aNetService];
     [aNetService setDelegate:self];
     [aNetService resolve];
     [aNetService setDelegate:self];
     [aNetService resolve];
-    ITDebugLog(@"Found service named %@.", [aNetService name]);
+    if (!moreComing) {
+        [[NSNotificationCenter defaultCenter] postNotificationName:@"ITMTFoundNetService" object:nil];
+    }
+}
+
+- (void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didRemoveService:(NSNetService*)aNetService moreComing:(BOOL)moreComing
+{
+    ITDebugLog(@"Removed service named %@.", [aNetService name]);
+    [remoteServices removeObject:aNetService];
     if (!moreComing) {
         [[NSNotificationCenter defaultCenter] postNotificationName:@"ITMTFoundNetService" object:nil];
     }
     if (!moreComing) {
         [[NSNotificationCenter defaultCenter] postNotificationName:@"ITMTFoundNetService" object:nil];
     }
@@ -169,12 +281,10 @@ static NetworkController *sharedController;
 
 - (void)netServiceDidResolveAddress:(NSNetService *)sender
 {
 
 - (void)netServiceDidResolveAddress:(NSNetService *)sender
 {
-    [remoteServices addObject:[NSDictionary dictionaryWithObjectsAndKeys:[sender name], @"name",
-                                                                         [NSString stringWithCString:inet_ntoa((*(struct sockaddr_in*)[[[sender addresses] objectAtIndex:0] bytes]).sin_addr)], @"ip",
-                                                                         nil, nil]];
     ITDebugLog(@"Resolved service named %@.", [sender name]);
     ITDebugLog(@"Resolved service named %@.", [sender name]);
-    NSLog(@"found!");
+    NSLog(@"Resolved service named %@.", [sender name]);
     [[NSNotificationCenter defaultCenter] postNotificationName:@"ITMTFoundNetService" object:nil];
     [[NSNotificationCenter defaultCenter] postNotificationName:@"ITMTFoundNetService" object:nil];
+    [sender stop];
 }
 
 - (void)netServiceWillResolve:(NSNetService *)sender
 }
 
 - (void)netServiceWillResolve:(NSNetService *)sender