Logo Search packages:      
Sourcecode: galaxium version File versions  Download package

MsnAccount.cs

/*
 * Galaxium Messenger
 * Copyright (C) 2005-2007 Philippe Durand <draekz@gmail.com>
 * Copyright (C) 2005-2007 Ben Motmans <ben.motmans@gmail.com>
 * Copyright (C) 2008 Paul Burton <paulburton89@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.Collections.Generic;
using System.IO;
using System.Web.Services.Protocols;
using System.Xml;

using Anculus.Core;

using Galaxium.Core;
using Galaxium.Gui;
using Galaxium.Protocol.Msn.Soap;
using Galaxium.Protocol.Msn.Soap.BodyParts;

namespace Galaxium.Protocol.Msn
{
      public sealed class MsnAccount : AbstractAccount, IMsnEntity
      {
            bool _allowUnknownContacts;
            bool _useHTTP = false;
            string _nsHostname = MsnConstants.DefaultNotificationServerHostname;
            int _nsPort = MsnConstants.DefaultNotificationServerPort;
            string _currentMedia;
            string _displayImageContext = null;
            string _displayImageFilename = null;
            
            internal long _contactID;
            
            internal Soap.BodyParts.Profile _profile = new Soap.BodyParts.Profile ();
            uint _profileTextUpdateTimer;
            
            public string CurrentMedia
            {
                  get { return _currentMedia; }
                  set
                  {
                        if ((Session != null) && (Session.Connection != null))
                        {
                              Session.Connection.Send (new UUXCommand (Session, DisplayMessage, value), delegate
                              {
                                    _currentMedia = value;
                              });
                        }
                        else
                              _currentMedia = value;
                  }
            }
            
            public override IDisplayImage DisplayImage
            {
                  get 
                  {
                        if ((!string.IsNullOrEmpty (_displayImageContext)) && (!string.IsNullOrEmpty (_displayImageFilename)) && (base.DisplayImage == null))
                        {
                              if (Session != null)
                                    return new MsnDisplayImage (Session, _displayImageContext);
                              else
                                    return new MsnDummyDisplayImage (_displayImageFilename);
                        }
                        
                        return base.DisplayImage;
                  }
                  set
                  {
                        if (DisplayImage == value)
                              return;
                        
                        if ((DisplayImage is MsnDisplayImage) && (value is MsnDisplayImage) && (((MsnDisplayImage)DisplayImage).Sha == ((MsnDisplayImage)value).Sha))
                              return;
                        
                        base.DisplayImage = value;
                        
                        if ((Session != null) && (Session.Connection != null))
                        {
                              Session.Connection.Send (new CHGCommand (Session, Presence, MsnClientIdentifier.Default, value as MsnDisplayImage), new CommandHandler (delegate
                              {
                                    ProfileHandle handle = new ProfileHandle ();
                                    handle.Alias = new ProfileAlias (_contactID.ToString (), "MyCidStuff");
                                    handle.RelationshipName = "/UserTiles";
                                    
                                    RemoveCurrentImage (handle, delegate
                                    {
                                          ProfileHandle expressionHandle = new ProfileHandle ();
                                          expressionHandle.ResourceID = _profile.ExpressionProfile.ResourceID;
                                          
                                          RemoveCurrentImage (expressionHandle, delegate
                                          {
                                                StoreDisplayImage (handle);
                                          });
                                    });
                              }));
                        }
                        else
                              base.DisplayImage = value;
                  }
            }
            
            // We can't set the DisplayImage directly when loading the account
            // because we don't have a session until later...
            // 
            // So we can store the context here and load it when the session is set
            public string DisplayImageContext
            {
                  get { return string.IsNullOrEmpty (_displayImageContext) ? (base.DisplayImage != null ? (base.DisplayImage as MsnDisplayImage).Context : string.Empty) : _displayImageContext; }
                  set { _displayImageContext = value; }
            }
            
            // Filename to use as the display image before session is set (for login window)
            public string DisplayImageFilename
            {
                  set { _displayImageFilename = value; }
            }
            
            public override string DisplayMessage
            {
                  get { return base.DisplayMessage; }
                  set
                  {
                        if (value == base.DisplayMessage)
                              return;
                        
                        base.DisplayMessage = value;
                        
                        if ((Session != null) && (Session.Connection != null))
                        {
                              Session.Connection.Send (new UUXCommand (Session, value, CurrentMedia), delegate
                              {
                                    if (DisplayMessage != _profile.ExpressionProfile.PersonalStatus)
                                          ScheduleProfileTextUpdate ();
                              });
                        }
                  }
            }
            
            public override string DisplayName
            {
                  get { return base.DisplayName; }
                  set
                  {
                        if (value == base.DisplayName)
                              return;
                        
                        base.DisplayName = value;
                        
                        if ((Session != null) && (Session.Connection != null))
                        {
                              Session.Connection.Send (new PRPCommand (Session, value), delegate
                              {
                                    if (DisplayName != _profile.ExpressionProfile.DisplayName)
                                          ScheduleProfileTextUpdate ();
                                    
                                    ABContact abContact = new ABContact ();
                                    abContact.Info = new ContactInfo ();
                                    abContact.Info.Type = ContactType.Me;
                                    abContact.Info.DisplayName = value;
                                    abContact.PropertiesChanged = "DisplayName";
                                    
                                    ABContactCollection abContacts = new ABContactCollection ();
                                    abContacts.Add (abContact);
                                    
                                    Session.ABService.BeginABContactUpdate (new Guid (), abContacts, null, null);
                              });
                        }
                  }
            }
            
            public override IPresence Presence
            {
                  get { return base.Presence; }
                  set
                  {
                        if ((Session != null) && (Session.Connection != null))
                        {
                              Session.Connection.Send (new CHGCommand (Session, value, MsnClientIdentifier.Default, DisplayImage as MsnDisplayImage));
                        }
                        else
                              base.Presence = value;
                  }
            }
            
            public override IProtocol Protocol
            {
                  get { return MsnProtocol.Instance; }
            }
            
            public new MsnSession Session
            {
                  get { return base.Session as MsnSession; }
            }
            
            public bool UseHTTP
            {
                  get { return _useHTTP; }
                  set { _useHTTP = value; }
            }
            
            public string NotificationServerHostname
            {
                  get { return this._nsHostname; }
                  set { _nsHostname = value; }
            }
            
            public int NotificationServerPort
            {
                  get { return this._nsPort; }
                  set { _nsPort = value; }
            }
            
            public bool AllowUnknownContacts
            {
                  get { return _allowUnknownContacts; }
                  set { _allowUnknownContacts = value; }
            }
            
            public Network Network
            {
                  get { return Network.WindowsLive; }
            }
            
            public MsnAccount (string uid) : base (null, uid)
            {
            }

            public MsnAccount (string uid, string password, string displayName, bool autoConnect, bool rememberPassword)
                  : base (null, uid, password, displayName, autoConnect, rememberPassword)
            {
            }
            
            internal void SetPresence (IPresence presence)
            {
                  base.Presence = presence;
            }
            
            protected override void OnSessionChange ()
            {
                  base.OnSessionChange ();
                  
                  _profile = new Profile ();
                  
                  if (!string.IsNullOrEmpty(_displayImageContext))
                  {
                        base.DisplayImage = MsnObject.Load (Session, _displayImageContext) as MsnDisplayImage;
                        _displayImageContext = null;
                        _displayImageFilename = null;
                  }
            }
            
            void ScheduleProfileTextUpdate ()
            {
                  // If we don't have our profile yet then we can't update it
                  if (string.IsNullOrEmpty (_profile.ResourceID))
                        return;
                  
                  if (_profileTextUpdateTimer != 0)
                        TimerUtility.ResetCallback (_profileTextUpdateTimer);
                  else
                  {
                        _profileTextUpdateTimer = TimerUtility.RequestCallback (delegate
                        {
                              _profileTextUpdateTimer = 0;
                              
                              Profile update = new Profile ();
                              update.ResourceID = _profile.ResourceID;
                              update.ExpressionProfile.FreeText = "Update";
                              update.ExpressionProfile.DisplayName = DisplayName;
                              update.ExpressionProfile.PersonalStatus = DisplayMessage;
                              update.ExpressionProfile.Flags = 0;
                              
                              Session.StoreService.BeginUpdateProfile (update, delegate (IAsyncResult asyncResult)
                              {
                                    try
                                    {
                                          Session.StoreService.EndUpdateProfile (asyncResult);
                                          Log.Debug ("Roaming profile successfully updated");
                                    }
                                    catch (SoapException ex)
                                    {
                                          Log.Error ("Error updating roaming profile: {0} {1}", ex.Code.Name, ex.Message);
                                    }
                                    catch (Exception ex)
                                    {
                                          Log.Error (ex, "Error updating roaming profile");
                                    }
                              }, null);
                        }, 2000);
                  }
            }
            
            void RemoveCurrentImage (ProfileHandle handle, VoidDelegate callback)
            {
                  if ((_profile == null) || (_profile.ExpressionProfile == null) || (_profile.ExpressionProfile.Photo == null))
                  {
                        callback ();
                        return;
                  }
                  
                  Session.StoreService.BeginDeleteRelationships (handle, new ObjectHandle[] { new ObjectHandle (_profile.ExpressionProfile.Photo.ResourceID) }, delegate (IAsyncResult asyncResult)
                  {
                        try
                        {
                              Session.StoreService.EndDeleteRelationships (asyncResult);
                              Log.Debug ("Successfully deleted display image relationship");
                              
                              callback ();
                        }
                        catch (SoapException ex)
                        {
                              if (MsnXmlUtility.FindText (ex.Detail as XmlElement, "errorcode") == "ItemDoesNotExist")
                              {
                                    // The photo didn't exist, we should continue anyway
                                    
                                    Log.Debug ("Roaming profile photo didn't exist");

                                    callback ();
                                    
                                    return;
                              }
                              
                              Log.Error ("Error deleting current display image relationship: {0} {1}", ex.Code.Name, ex.Message);
                        }
                        catch (Exception ex)
                        {
                              Log.Error (ex, "Error deleting current display image relationship");
                        }
                  }, null);
            }
            
            void StoreDisplayImage (ProfileHandle handle)
            {
                  Photo photo = new Photo ();
                  photo.Name = "GalaxiumDisplayImage";
                  
                  PhotoStream stream = new PhotoStream ();
                  stream.Type = DocumentStreamType.UserTileStatic;
                  stream.MimeType = "png"; //TODO: get real mime type
                  stream.Data = DisplayImage.ImageBuffer;
                  stream.DataSize = 0;
                  
                  photo.DocumentStreams.Add (stream);
                  
                  Session.StoreService.BeginCreateDocument (handle, photo, "Messenger User Tile", delegate (IAsyncResult asyncResult)
                  {
                        try
                        {
                              photo.ResourceID = Session.StoreService.EndCreateDocument (asyncResult);
                              
                              Log.Debug ("Successfully uploaded display image to roaming profile");
                              
                              Relationship relationship = new Relationship ();
                              relationship.SourceID = _profile.ExpressionProfile.ResourceID;
                              relationship.SourceType = SourceTypeEnum.SubProfile;
                              relationship.TargetID = photo.ResourceID;
                              relationship.TargetType = DocumentItemType.Photo;
                              relationship.RelationshipName = "ProfilePhoto";
                              
                              Session.StoreService.BeginCreateRelationships (new Relationship[] { relationship }, delegate (IAsyncResult asyncResult2)
                              {
                                    try
                                    {
                                          Session.StoreService.EndCreateRelationships (asyncResult2);
                                          
                                          Log.Debug ("Successfully related display image to roaming profile");
                                    }
                                    catch (SoapException ex)
                                    {
                                          Log.Error ("Error relating image to roaming profile: {0} {1}", ex.Code.Name, ex.Message);
                                    }
                                    catch (Exception ex)
                                    {
                                          Log.Error (ex, "Error relating image to roaming profile");
                                    }
                              }, null);
                        }
                        catch (SoapException ex)
                        {
                              Log.Error ("Error uploading image to roaming profile: {0} {1}", ex.Code.Name, ex.Message);
                        }
                        catch (Exception ex)
                        {
                              Log.Error (ex, "Error uploading image to roaming profile");
                        }
                  }, null);
            }
            
            class MsnDummyDisplayImage : IDisplayImage
            {
                  string _filename;
                  byte[] _data;
                  
                  public string Checksum
                  {
                        get { return null; }
                  }
                  
                  public byte[] ImageBuffer
                  {
                        get { return _data; }
                  }
                  
                  public string Filename
                  {
                        get { return _filename; }
                        set
                        {
                              _filename = value;
                              
                              _data = File.ReadAllBytes (_filename);
                        }
                  }
                  
                  public MsnDummyDisplayImage (string filename)
                  {
                        Filename = filename;
                  }
            }
      }
}

Generated by  Doxygen 1.6.0   Back to index