private void DeleteRecordFile(bool reCreate) { if (NSMessageHandler.Owner != null && NSMessageHandler.Owner.Account != null) { MclSerialization st = Settings.SerializationType; string addressbookFile = Path.Combine(Settings.SavePath, NSMessageHandler.Owner.Account.GetHashCode() + ".mcl"); string deltasResultFile = Path.Combine(Settings.SavePath, NSMessageHandler.Owner.Account.GetHashCode() + "d" + ".mcl"); // Re-init addressbook { MclFile.Delete(addressbookFile, true); if (reCreate) { AddressBook = XMLContactList.LoadFromFile(addressbookFile, st, NSMessageHandler, false); AddressBook.Save(); } } //If we saved cachekey and preferred host in it, deltas can't be deleted. if (Deltas != null && reCreate) { Deltas.Truncate(); } else { MclFile.Delete(deltasResultFile, true); if (reCreate) { Deltas = DeltasList.LoadFromFile(deltasResultFile, st, NSMessageHandler.Credentials.Password, true); Deltas.Save(true); } } abSynchronized = false; } }
public override void Clear() { binarySemaphore.WaitOne(); { base.Clear(); // Last save for contact list files if (NSMessageHandler.IsSignedIn && AddressBook != null && Deltas != null) { try { AddressBook.Save(); Deltas.Truncate(); } catch (Exception error) { Trace.WriteLineIf(Settings.TraceSwitch.TraceError, error.Message, GetType().Name); } } AddressBook = null; Deltas = null; abSynchronized = false; } binarySemaphore.Release(); }
/// <summary> /// Rebuild the contactlist with the most recent data. /// </summary> /// <remarks> /// Synchronizing is the most complete way to retrieve data about groups, contacts, privacy settings, etc. /// This method is called automatically after owner profile received and then the addressbook is merged with deltas file. /// After that, SignedIn event occurs and the client programmer must set it's initial status by SetPresenceStatus(). /// Otherwise you won't receive online notifications from other clients or the connection is closed by the server. /// If you have an external contact list, you must track ProfileReceived, SignedIn and SynchronizationCompleted events. /// Between ProfileReceived and SignedIn: the internal addressbook is merged with deltas file. /// Between SignedIn and SynchronizationCompleted: the internal addressbook is merged with most recent data by soap request. /// All contact changes will be fired between ProfileReceived, SignedIn and SynchronizationCompleted events. /// e.g: ContactAdded, ContactRemoved, ReverseAdded, ReverseRemoved. /// </remarks> internal void SynchronizeContactList() { if (AddressBookSynchronized) { Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning, "SynchronizeContactList() was called, but the list has already been synchronized.", GetType().Name); return; } MclSerialization st = Settings.SerializationType; string addressbookFile = Path.Combine(Settings.SavePath, NSMessageHandler.Owner.Account.GetHashCode() + ".mcl"); string deltasResultsFile = Path.Combine(Settings.SavePath, NSMessageHandler.Owner.Account.GetHashCode() + "d" + ".mcl"); BinarySemaphore.WaitOne(); try { AddressBook = XMLContactList.LoadFromFile(addressbookFile, st, NSMessageHandler, false); Deltas = DeltasList.LoadFromFile(deltasResultsFile, st, NSMessageHandler.Credentials.Password, true); } catch (Exception) { // InvalidOperationException: Struct changed (Serialize error) DeleteRecordFile(true); // Reset addressbook. } finally { BinarySemaphore.Release(); } try { if (AddressBook.Version != XMLContactList.XMLContactListVersion || Deltas.Version != DeltasList.DeltasListVersion) { Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "Your MCL addressbook version is outdated: " + AddressBook.Version.ToString() + "\r\nAddressBook Version Required: " + XMLContactList.XMLContactListVersion + "\r\nThe old mcl files for this account will be deleted and a new request for getting full addressbook list will be post."); DeleteRecordFile(true); // Addressbook version changed. Reset addressbook. // SOFT ERROR(continue). } } catch (Exception ex) { Trace.WriteLineIf(Settings.TraceSwitch.TraceError, "Couldn't delete addressbook: " + ex.Message, GetType().Name); return; // HARD ERROR. Don't continue. I am dead. } // Should has no lock here. bool firstTime = false; BinarySemaphore.WaitOne(); try { if (AddressBook != null) { AddressBook.Initialize(); firstTime = (DateTime.MinValue == WebServiceDateTimeConverter.ConvertToDateTime(AddressBook.GetAddressBookLastChange(WebServiceConstants.MessengerIndividualAddressBookId))); } } catch (Exception) { } finally { BinarySemaphore.Release(); } if (firstTime) { Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "Getting your membership list for the first time. If you have a lot of contacts, please be patient!", GetType().Name); } // Should be no lock here, let the msRequest take care of the locks. try { msRequest( PartnerScenario.Initial, delegate { BinarySemaphore.WaitOne(); { if (AddressBook != null && Deltas != null) { BinarySemaphore.Release(); if (firstTime) { Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "Getting your address book for the first time. If you have a lot of contacts, please be patient!", GetType().Name); } // Should be no lock here, let the abRequest take care of the locks. try { abRequest(PartnerScenario.Initial, delegate { // Should be no lock here, let the InitialABRequestCompleted take care of the locks. InitialMembershipAndAbRequestCompleted(); } ); } catch (Exception abRequestEception) { OnServiceOperationFailed(this, new ServiceOperationFailedEventArgs("ABFindContactsPaged", new MSNPSharpException(abRequestEception.Message, abRequestEception))); Trace.WriteLineIf(Settings.TraceSwitch.TraceError, "An error occured while getting membership list: " + abRequestEception.Message, GetType().Name); return; } } else { //If addressbook is null, we are still locking. BinarySemaphore.Release(); } } // Should has no lock here. } ); } catch (Exception ex) { OnServiceOperationFailed(this, new ServiceOperationFailedEventArgs("FindMembership", new MSNPSharpException(ex.Message, ex))); Trace.WriteLineIf(Settings.TraceSwitch.TraceError, "An error occured while getting membership list: " + ex.Message, GetType().Name); } }