diff --git a/Example/AddContactForm.Designer.cs b/Example/AddContactForm.Designer.cs
new file mode 100644
index 0000000..de731e6
--- /dev/null
+++ b/Example/AddContactForm.Designer.cs
@@ -0,0 +1,123 @@
+namespace MSNPSharpClient
+{
+ partial class AddContactForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.lblAccount = new System.Windows.Forms.Label();
+ this.txtAccount = new System.Windows.Forms.TextBox();
+ this.txtInvitation = new System.Windows.Forms.TextBox();
+ this.lblInvitation = new System.Windows.Forms.Label();
+ this.btnOK = new System.Windows.Forms.Button();
+ this.btnCancel = new System.Windows.Forms.Button();
+ this.SuspendLayout();
+ //
+ // lblAccount
+ //
+ this.lblAccount.AutoSize = true;
+ this.lblAccount.Location = new System.Drawing.Point(4, 21);
+ this.lblAccount.Name = "lblAccount";
+ this.lblAccount.Size = new System.Drawing.Size(106, 13);
+ this.lblAccount.TabIndex = 0;
+ this.lblAccount.Text = "Messenger address:*";
+ //
+ // txtAccount
+ //
+ this.txtAccount.CharacterCasing = System.Windows.Forms.CharacterCasing.Lower;
+ this.txtAccount.Location = new System.Drawing.Point(115, 18);
+ this.txtAccount.Name = "txtAccount";
+ this.txtAccount.Size = new System.Drawing.Size(250, 20);
+ this.txtAccount.TabIndex = 1;
+ //
+ // txtInvitation
+ //
+ this.txtInvitation.Location = new System.Drawing.Point(115, 47);
+ this.txtInvitation.Name = "txtInvitation";
+ this.txtInvitation.Size = new System.Drawing.Size(250, 20);
+ this.txtInvitation.TabIndex = 2;
+ //
+ // lblInvitation
+ //
+ this.lblInvitation.AutoSize = true;
+ this.lblInvitation.Location = new System.Drawing.Point(12, 50);
+ this.lblInvitation.Name = "lblInvitation";
+ this.lblInvitation.Size = new System.Drawing.Size(98, 13);
+ this.lblInvitation.TabIndex = 4;
+ this.lblInvitation.Text = "Invitation message:";
+ //
+ // btnOK
+ //
+ this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.btnOK.Location = new System.Drawing.Point(209, 84);
+ this.btnOK.Name = "btnOK";
+ this.btnOK.Size = new System.Drawing.Size(75, 23);
+ this.btnOK.TabIndex = 3;
+ this.btnOK.Text = "OK";
+ this.btnOK.UseVisualStyleBackColor = true;
+ this.btnOK.Click += new System.EventHandler(this.btn_Click);
+ //
+ // btnCancel
+ //
+ this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.btnCancel.Location = new System.Drawing.Point(290, 84);
+ this.btnCancel.Name = "btnCancel";
+ this.btnCancel.Size = new System.Drawing.Size(75, 23);
+ this.btnCancel.TabIndex = 4;
+ this.btnCancel.Text = "Cancel";
+ this.btnCancel.UseVisualStyleBackColor = true;
+ this.btnCancel.Click += new System.EventHandler(this.btn_Click);
+ //
+ // AddContactForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(373, 119);
+ this.Controls.Add(this.btnCancel);
+ this.Controls.Add(this.btnOK);
+ this.Controls.Add(this.txtInvitation);
+ this.Controls.Add(this.lblInvitation);
+ this.Controls.Add(this.txtAccount);
+ this.Controls.Add(this.lblAccount);
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "AddContactForm";
+ this.Text = "Add New Contact";
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Label lblAccount;
+ private System.Windows.Forms.TextBox txtAccount;
+ private System.Windows.Forms.TextBox txtInvitation;
+ private System.Windows.Forms.Label lblInvitation;
+ private System.Windows.Forms.Button btnOK;
+ private System.Windows.Forms.Button btnCancel;
+ }
+}
\ No newline at end of file
diff --git a/Example/AddContactForm.cs b/Example/AddContactForm.cs
new file mode 100644
index 0000000..d0a3634
--- /dev/null
+++ b/Example/AddContactForm.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+
+namespace MSNPSharpClient
+{
+ public partial class AddContactForm : Form
+ {
+ public AddContactForm(string account)
+ {
+ InitializeComponent();
+
+ if (!String.IsNullOrEmpty(account))
+ {
+ this.account = account;
+ txtAccount.Text = account;
+ }
+ }
+
+ private string account;
+ public string Account
+ {
+ get
+ {
+ return account;
+ }
+ }
+
+ private string invitationMessage;
+ public string InvitationMessage
+ {
+ get
+ {
+ return invitationMessage;
+ }
+ }
+
+ private void btn_Click(object sender, EventArgs e)
+ {
+ account = txtAccount.Text;
+ invitationMessage = txtInvitation.Text;
+
+ Close();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Example/AddContactForm.resx b/Example/AddContactForm.resx
new file mode 100644
index 0000000..19dc0dd
--- /dev/null
+++ b/Example/AddContactForm.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Example/ContactCardForm.Designer.cs b/Example/ContactCardForm.Designer.cs
new file mode 100644
index 0000000..ca17b2e
--- /dev/null
+++ b/Example/ContactCardForm.Designer.cs
@@ -0,0 +1,240 @@
+namespace MSNPSharpClient
+{
+ partial class ContactCardForm
+ {
+ ///
+ /// 必需的设计器变量。
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// 清理所有正在使用的资源。
+ ///
+ /// 如果应释放托管资源,为 true;否则为 false。
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows 窗体设计器生成的代码
+
+ ///
+ /// 设计器支持所需的方法 - 不要
+ /// 使用代码编辑器修改此方法的内容。
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ this.pnlSpace = new System.Windows.Forms.Panel();
+ this.panel3 = new System.Windows.Forms.Panel();
+ this.lblSpaceTitle = new System.Windows.Forms.LinkLabel();
+ this.lblDisplayName = new System.Windows.Forms.Label();
+ this.picDisplayImage = new System.Windows.Forms.PictureBox();
+ this.pnlAlbum = new System.Windows.Forms.Panel();
+ this.tlpnlAlbum = new System.Windows.Forms.TableLayoutPanel();
+ this.lnkAlbumName = new System.Windows.Forms.LinkLabel();
+ this.pnlBlog = new System.Windows.Forms.Panel();
+ this.lnkBlogContent = new System.Windows.Forms.LinkLabel();
+ this.lnkBlogTitle = new System.Windows.Forms.LinkLabel();
+ this.pnlProfile = new System.Windows.Forms.Panel();
+ this.ttips = new System.Windows.Forms.ToolTip(this.components);
+ this.pnlSpace.SuspendLayout();
+ this.panel3.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.picDisplayImage)).BeginInit();
+ this.pnlAlbum.SuspendLayout();
+ this.pnlBlog.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // pnlSpace
+ //
+ this.pnlSpace.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(128)))), ((int)(((byte)(255)))));
+ this.pnlSpace.Controls.Add(this.panel3);
+ this.pnlSpace.Controls.Add(this.picDisplayImage);
+ this.pnlSpace.Dock = System.Windows.Forms.DockStyle.Top;
+ this.pnlSpace.Location = new System.Drawing.Point(0, 0);
+ this.pnlSpace.Name = "pnlSpace";
+ this.pnlSpace.Padding = new System.Windows.Forms.Padding(10);
+ this.pnlSpace.Size = new System.Drawing.Size(272, 76);
+ this.pnlSpace.TabIndex = 1;
+ //
+ // panel3
+ //
+ this.panel3.Controls.Add(this.lblSpaceTitle);
+ this.panel3.Controls.Add(this.lblDisplayName);
+ this.panel3.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.panel3.Location = new System.Drawing.Point(69, 10);
+ this.panel3.Name = "panel3";
+ this.panel3.Size = new System.Drawing.Size(193, 56);
+ this.panel3.TabIndex = 2;
+ //
+ // lblSpaceTitle
+ //
+ this.lblSpaceTitle.Dock = System.Windows.Forms.DockStyle.Top;
+ this.lblSpaceTitle.LinkBehavior = System.Windows.Forms.LinkBehavior.HoverUnderline;
+ this.lblSpaceTitle.Location = new System.Drawing.Point(0, 23);
+ this.lblSpaceTitle.Margin = new System.Windows.Forms.Padding(0);
+ this.lblSpaceTitle.Name = "lblSpaceTitle";
+ this.lblSpaceTitle.Padding = new System.Windows.Forms.Padding(10, 0, 0, 0);
+ this.lblSpaceTitle.Size = new System.Drawing.Size(193, 19);
+ this.lblSpaceTitle.TabIndex = 2;
+ this.lblSpaceTitle.TabStop = true;
+ this.lblSpaceTitle.Text = "Space Title";
+ this.lblSpaceTitle.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lblSpaceTitle_LinkClicked);
+ //
+ // lblDisplayName
+ //
+ this.lblDisplayName.Dock = System.Windows.Forms.DockStyle.Top;
+ this.lblDisplayName.Location = new System.Drawing.Point(0, 0);
+ this.lblDisplayName.Margin = new System.Windows.Forms.Padding(0);
+ this.lblDisplayName.Name = "lblDisplayName";
+ this.lblDisplayName.Padding = new System.Windows.Forms.Padding(10, 0, 0, 0);
+ this.lblDisplayName.Size = new System.Drawing.Size(193, 23);
+ this.lblDisplayName.TabIndex = 1;
+ this.lblDisplayName.Text = "Display Name";
+ //
+ // picDisplayImage
+ //
+ this.picDisplayImage.BackColor = System.Drawing.Color.White;
+ this.picDisplayImage.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.picDisplayImage.Dock = System.Windows.Forms.DockStyle.Left;
+ this.picDisplayImage.Location = new System.Drawing.Point(10, 10);
+ this.picDisplayImage.Name = "picDisplayImage";
+ this.picDisplayImage.Size = new System.Drawing.Size(59, 56);
+ this.picDisplayImage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
+ this.picDisplayImage.TabIndex = 1;
+ this.picDisplayImage.TabStop = false;
+ //
+ // pnlAlbum
+ //
+ this.pnlAlbum.BackColor = System.Drawing.Color.Linen;
+ this.pnlAlbum.Controls.Add(this.tlpnlAlbum);
+ this.pnlAlbum.Controls.Add(this.lnkAlbumName);
+ this.pnlAlbum.Dock = System.Windows.Forms.DockStyle.Top;
+ this.pnlAlbum.Location = new System.Drawing.Point(0, 76);
+ this.pnlAlbum.Name = "pnlAlbum";
+ this.pnlAlbum.Padding = new System.Windows.Forms.Padding(5);
+ this.pnlAlbum.Size = new System.Drawing.Size(272, 65);
+ this.pnlAlbum.TabIndex = 2;
+ //
+ // tlpnlAlbum
+ //
+ this.tlpnlAlbum.ColumnCount = 6;
+ this.tlpnlAlbum.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 16.66667F));
+ this.tlpnlAlbum.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 16.66667F));
+ this.tlpnlAlbum.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 16.66667F));
+ this.tlpnlAlbum.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 16.66667F));
+ this.tlpnlAlbum.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 16.66667F));
+ this.tlpnlAlbum.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 16.66667F));
+ this.tlpnlAlbum.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.tlpnlAlbum.Location = new System.Drawing.Point(5, 17);
+ this.tlpnlAlbum.Name = "tlpnlAlbum";
+ this.tlpnlAlbum.RowCount = 1;
+ this.tlpnlAlbum.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tlpnlAlbum.Size = new System.Drawing.Size(262, 43);
+ this.tlpnlAlbum.TabIndex = 1;
+ //
+ // lnkAlbumName
+ //
+ this.lnkAlbumName.Dock = System.Windows.Forms.DockStyle.Top;
+ this.lnkAlbumName.LinkBehavior = System.Windows.Forms.LinkBehavior.HoverUnderline;
+ this.lnkAlbumName.Location = new System.Drawing.Point(5, 5);
+ this.lnkAlbumName.Name = "lnkAlbumName";
+ this.lnkAlbumName.Size = new System.Drawing.Size(262, 12);
+ this.lnkAlbumName.TabIndex = 0;
+ this.lnkAlbumName.TabStop = true;
+ this.lnkAlbumName.Text = "Album Name";
+ this.lnkAlbumName.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lnkAlbumName_LinkClicked);
+ //
+ // pnlBlog
+ //
+ this.pnlBlog.BackColor = System.Drawing.Color.Linen;
+ this.pnlBlog.Controls.Add(this.lnkBlogContent);
+ this.pnlBlog.Controls.Add(this.lnkBlogTitle);
+ this.pnlBlog.Dock = System.Windows.Forms.DockStyle.Top;
+ this.pnlBlog.Location = new System.Drawing.Point(0, 141);
+ this.pnlBlog.Name = "pnlBlog";
+ this.pnlBlog.Padding = new System.Windows.Forms.Padding(5);
+ this.pnlBlog.Size = new System.Drawing.Size(272, 58);
+ this.pnlBlog.TabIndex = 3;
+ //
+ // lnkBlogContent
+ //
+ this.lnkBlogContent.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.lnkBlogContent.LinkBehavior = System.Windows.Forms.LinkBehavior.HoverUnderline;
+ this.lnkBlogContent.Location = new System.Drawing.Point(5, 17);
+ this.lnkBlogContent.Name = "lnkBlogContent";
+ this.lnkBlogContent.Size = new System.Drawing.Size(262, 36);
+ this.lnkBlogContent.TabIndex = 1;
+ this.lnkBlogContent.TabStop = true;
+ this.lnkBlogContent.Text = "Blog Content";
+ this.lnkBlogContent.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lnkBlogContent_LinkClicked);
+ //
+ // lnkBlogTitle
+ //
+ this.lnkBlogTitle.Dock = System.Windows.Forms.DockStyle.Top;
+ this.lnkBlogTitle.LinkBehavior = System.Windows.Forms.LinkBehavior.HoverUnderline;
+ this.lnkBlogTitle.LinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
+ this.lnkBlogTitle.Location = new System.Drawing.Point(5, 5);
+ this.lnkBlogTitle.Name = "lnkBlogTitle";
+ this.lnkBlogTitle.Size = new System.Drawing.Size(262, 12);
+ this.lnkBlogTitle.TabIndex = 0;
+ this.lnkBlogTitle.TabStop = true;
+ this.lnkBlogTitle.Text = "Blog Title";
+ this.lnkBlogTitle.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lnkBlogTitle_LinkClicked);
+ //
+ // pnlProfile
+ //
+ this.pnlProfile.BackColor = System.Drawing.Color.Linen;
+ this.pnlProfile.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.pnlProfile.Location = new System.Drawing.Point(0, 199);
+ this.pnlProfile.Name = "pnlProfile";
+ this.pnlProfile.Padding = new System.Windows.Forms.Padding(5);
+ this.pnlProfile.Size = new System.Drawing.Size(272, 35);
+ this.pnlProfile.TabIndex = 4;
+ //
+ // ContactCardForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(272, 234);
+ this.Controls.Add(this.pnlProfile);
+ this.Controls.Add(this.pnlBlog);
+ this.Controls.Add(this.pnlAlbum);
+ this.Controls.Add(this.pnlSpace);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.MaximizeBox = false;
+ this.Name = "ContactCardForm";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+ this.Text = "ContactCard";
+ this.Load += new System.EventHandler(this.ContactCardForm_Load);
+ this.pnlSpace.ResumeLayout(false);
+ this.panel3.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.picDisplayImage)).EndInit();
+ this.pnlAlbum.ResumeLayout(false);
+ this.pnlBlog.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Panel pnlSpace;
+ private System.Windows.Forms.Panel panel3;
+ private System.Windows.Forms.LinkLabel lblSpaceTitle;
+ private System.Windows.Forms.Label lblDisplayName;
+ private System.Windows.Forms.PictureBox picDisplayImage;
+ private System.Windows.Forms.Panel pnlAlbum;
+ private System.Windows.Forms.TableLayoutPanel tlpnlAlbum;
+ private System.Windows.Forms.LinkLabel lnkAlbumName;
+ private System.Windows.Forms.Panel pnlBlog;
+ private System.Windows.Forms.Panel pnlProfile;
+ private System.Windows.Forms.LinkLabel lnkBlogContent;
+ private System.Windows.Forms.LinkLabel lnkBlogTitle;
+ private System.Windows.Forms.ToolTip ttips;
+
+ }
+}
\ No newline at end of file
diff --git a/Example/ContactCardForm.cs b/Example/ContactCardForm.cs
new file mode 100644
index 0000000..6521a72
--- /dev/null
+++ b/Example/ContactCardForm.cs
@@ -0,0 +1,109 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using MSNPSharp;
+using System.Diagnostics;
+
+namespace MSNPSharpClient
+{
+ public partial class ContactCardForm : Form
+ {
+ private ContactCard card = null;
+
+ public ContactCardForm(ContactCard cc)
+ {
+ InitializeComponent();
+ card = cc;
+ }
+
+ private void ContactCardForm_Load(object sender, EventArgs e)
+ {
+ lblDisplayName.Text = card.DisplayName;
+ lblSpaceTitle.Text = (card.Space != null) ? card.Space.Title : String.Empty;
+
+ if (String.IsNullOrEmpty(card.DisplayImageUrl))
+ {
+ picDisplayImage.Visible = false;
+ }
+ else
+ {
+ picDisplayImage.LoadAsync(card.DisplayImageUrl);
+ }
+
+ if (card.Album != null)
+ {
+ lnkAlbumName.Text = card.Album.Title;
+ int col = 0;
+ foreach (ThumbnailImage img in card.Album.Photos) //Setting the thumbnail pictures.
+ {
+ PictureBox lnkPic = new PictureBox();
+ lnkPic.Dock = DockStyle.Fill;
+ lnkPic.Margin = new Padding(6);
+ lnkPic.BorderStyle = BorderStyle.FixedSingle;
+ lnkPic.SizeMode = PictureBoxSizeMode.Zoom;
+ lnkPic.BackColor = Color.White;
+ lnkPic.LoadAsync(img.ThumbnailUrl);
+
+ tlpnlAlbum.Controls.Add(lnkPic, col, 0);
+ lnkPic.Tag = col;
+ lnkPic.Visible = true;
+ lnkPic.Click += new EventHandler(lnkPic_Click);
+ ttips.SetToolTip(lnkPic, img.ToolTip);
+ col++;
+ }
+ }
+ else
+ {
+ pnlAlbum.Visible = false;
+ }
+
+ if (card.NewPost != null)
+ {
+ lnkBlogTitle.Text = card.NewPost.Title;
+ ttips.SetToolTip(lnkBlogTitle, card.NewPost.Description);
+ lnkBlogContent.Text = card.NewPost.Description;
+ ttips.SetToolTip(lnkBlogContent, card.NewPost.Description);
+ }
+ else
+ {
+ pnlBlog.Visible = false;
+ }
+
+ Text = card.DisplayName + "'s ContactCard";
+ }
+
+ void lnkPic_Click(object sender, EventArgs e)
+ {
+ Process.Start(card.Album.Photos[(int)((PictureBox)sender).Tag].Url);
+ }
+
+ void lnkPic_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
+ {
+ Process.Start(card.Album.Photos[(int)((LinkLabel)sender).Tag].Url);
+ }
+
+ private void lblSpaceTitle_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
+ {
+ Process.Start(card.Space.Url);
+ }
+
+ private void lnkAlbumName_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
+ {
+ Process.Start(card.Album.Url);
+ }
+
+ private void lnkBlogTitle_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
+ {
+ Process.Start(card.NewPost.Url);
+ }
+
+ private void lnkBlogContent_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
+ {
+ Process.Start(card.NewPost.Url);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Example/ContactCardForm.resx b/Example/ContactCardForm.resx
new file mode 100644
index 0000000..1d5cd69
--- /dev/null
+++ b/Example/ContactCardForm.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/Example/ConversationForm.cs b/Example/ConversationForm.cs
new file mode 100644
index 0000000..042b525
--- /dev/null
+++ b/Example/ConversationForm.cs
@@ -0,0 +1,1077 @@
+using System;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Collections;
+using System.Windows.Forms;
+using System.ComponentModel;
+using System.Drawing.Imaging;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Threading;
+
+namespace MSNPSharpClient
+{
+ using MSNPSharp;
+ using MSNPSharp.DataTransfer;
+ using MSNPSharp.Core;
+ using MSNPSharp.Utilities;
+
+ ///
+ /// Summary description for ConversationForm.
+ ///
+ public class ConversationForm : System.Windows.Forms.Form
+ {
+ private IContainer components;
+ #region Windows Form Designer generated code
+
+ private Panel panel1;
+ private TextBox inputTextBox;
+ private Panel panel2;
+ private RtfRichTextBox richTextHistory;
+ private PictureBox displayOwner;
+ private PictureBox displayUser;
+
+ private OpenFileDialog openFileDialog;
+ private ToolStrip tsMessage;
+ private ToolStripComboBox cbMessageFontName;
+ private ToolStripComboBox cbMessageFontSize;
+ private ToolStripSeparator tssMessageSeperator1;
+ private ToolStripButton bMessageBold;
+ private ToolStripButton bMessageItalic;
+ private ToolStripButton bMessageUnderline;
+ private ToolStripSeparator tssMessageSeperator2;
+ private ToolStripButton bMessageSend;
+ private ToolStripButton bMessageSendNudge;
+ private Button btnSendFiles;
+ private Button btnInviteUsers;
+ private Button btnCustomEmoticon;
+ private Button btnActivityTest;
+ private ToolStripDropDownButton bMessageInsertEmoticon;
+ private ToolStripMenuItem toolStripMenuItem1;
+ private ToolStripMenuItem bigRinToolStripMenuItem;
+ private ToolStripMenuItem sadToolStripMenuItem;
+ private ToolStripMenuItem winkToolStripMenuItem;
+ private ToolStripMenuItem tongueOutToolStripMenuItem;
+ private ContextMenuStrip onlineUsersDropDown;
+ private ToolStripButton bMessageFontColor;
+ private OpenFileDialog openCustomEmoticonDialog;
+ private ColorDialog dlgColor;
+
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ this.panel1 = new System.Windows.Forms.Panel();
+ this.tsMessage = new System.Windows.Forms.ToolStrip();
+ this.bMessageInsertEmoticon = new System.Windows.Forms.ToolStripDropDownButton();
+ this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
+ this.bigRinToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.sadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.winkToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.tongueOutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.bMessageSendNudge = new System.Windows.Forms.ToolStripButton();
+ this.tssMessageSeperator1 = new System.Windows.Forms.ToolStripSeparator();
+ this.bMessageFontColor = new System.Windows.Forms.ToolStripButton();
+ this.bMessageBold = new System.Windows.Forms.ToolStripButton();
+ this.bMessageItalic = new System.Windows.Forms.ToolStripButton();
+ this.bMessageUnderline = new System.Windows.Forms.ToolStripButton();
+ this.cbMessageFontName = new System.Windows.Forms.ToolStripComboBox();
+ this.cbMessageFontSize = new System.Windows.Forms.ToolStripComboBox();
+ this.tssMessageSeperator2 = new System.Windows.Forms.ToolStripSeparator();
+ this.bMessageSend = new System.Windows.Forms.ToolStripButton();
+ this.displayOwner = new System.Windows.Forms.PictureBox();
+ this.inputTextBox = new System.Windows.Forms.TextBox();
+ this.panel2 = new System.Windows.Forms.Panel();
+ this.btnActivityTest = new System.Windows.Forms.Button();
+ this.btnCustomEmoticon = new System.Windows.Forms.Button();
+ this.btnInviteUsers = new System.Windows.Forms.Button();
+ this.onlineUsersDropDown = new System.Windows.Forms.ContextMenuStrip(this.components);
+ this.btnSendFiles = new System.Windows.Forms.Button();
+ this.displayUser = new System.Windows.Forms.PictureBox();
+ this.richTextHistory = new MSNPSharpClient.RtfRichTextBox();
+ this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
+ this.dlgColor = new System.Windows.Forms.ColorDialog();
+ this.openCustomEmoticonDialog = new System.Windows.Forms.OpenFileDialog();
+ this.panel1.SuspendLayout();
+ this.tsMessage.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.displayOwner)).BeginInit();
+ this.panel2.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.displayUser)).BeginInit();
+ this.SuspendLayout();
+ //
+ // panel1
+ //
+ this.panel1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(163)))), ((int)(((byte)(163)))), ((int)(((byte)(186)))));
+ this.panel1.Controls.Add(this.tsMessage);
+ this.panel1.Controls.Add(this.displayOwner);
+ this.panel1.Controls.Add(this.inputTextBox);
+ this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.panel1.Location = new System.Drawing.Point(0, 272);
+ this.panel1.Name = "panel1";
+ this.panel1.Size = new System.Drawing.Size(663, 111);
+ this.panel1.TabIndex = 0;
+ //
+ // tsMessage
+ //
+ this.tsMessage.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.tsMessage.AutoSize = false;
+ this.tsMessage.Dock = System.Windows.Forms.DockStyle.None;
+ this.tsMessage.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
+ this.tsMessage.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.bMessageInsertEmoticon,
+ this.bMessageSendNudge,
+ this.tssMessageSeperator1,
+ this.bMessageFontColor,
+ this.bMessageBold,
+ this.bMessageItalic,
+ this.bMessageUnderline,
+ this.cbMessageFontName,
+ this.cbMessageFontSize,
+ this.tssMessageSeperator2,
+ this.bMessageSend});
+ this.tsMessage.Location = new System.Drawing.Point(109, 3);
+ this.tsMessage.Name = "tsMessage";
+ this.tsMessage.Padding = new System.Windows.Forms.Padding(3, 0, 1, 0);
+ this.tsMessage.Size = new System.Drawing.Size(550, 25);
+ this.tsMessage.TabIndex = 8;
+ //
+ // bMessageInsertEmoticon
+ //
+ this.bMessageInsertEmoticon.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+ this.bMessageInsertEmoticon.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.toolStripMenuItem1,
+ this.bigRinToolStripMenuItem,
+ this.sadToolStripMenuItem,
+ this.winkToolStripMenuItem,
+ this.tongueOutToolStripMenuItem});
+ this.bMessageInsertEmoticon.Image = global::MSNPSharpClient.Properties.Resources.smiley;
+ this.bMessageInsertEmoticon.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.bMessageInsertEmoticon.Name = "bMessageInsertEmoticon";
+ this.bMessageInsertEmoticon.Size = new System.Drawing.Size(29, 22);
+ this.bMessageInsertEmoticon.Text = "toolStripDropDownButton1";
+ //
+ // toolStripMenuItem1
+ //
+ this.toolStripMenuItem1.Image = global::MSNPSharpClient.Properties.Resources.smiley;
+ this.toolStripMenuItem1.Name = "toolStripMenuItem1";
+ this.toolStripMenuItem1.Size = new System.Drawing.Size(138, 22);
+ this.toolStripMenuItem1.Text = "Simley";
+ this.toolStripMenuItem1.ToolTipText = ":)";
+ this.toolStripMenuItem1.Click += new System.EventHandler(this.emotionDropDown_Click);
+ //
+ // bigRinToolStripMenuItem
+ //
+ this.bigRinToolStripMenuItem.Image = global::MSNPSharpClient.Properties.Resources.biggrin;
+ this.bigRinToolStripMenuItem.Name = "bigRinToolStripMenuItem";
+ this.bigRinToolStripMenuItem.Size = new System.Drawing.Size(138, 22);
+ this.bigRinToolStripMenuItem.Text = "Big Grin";
+ this.bigRinToolStripMenuItem.ToolTipText = ":d";
+ this.bigRinToolStripMenuItem.Click += new System.EventHandler(this.emotionDropDown_Click);
+ //
+ // sadToolStripMenuItem
+ //
+ this.sadToolStripMenuItem.Image = global::MSNPSharpClient.Properties.Resources.sad;
+ this.sadToolStripMenuItem.Name = "sadToolStripMenuItem";
+ this.sadToolStripMenuItem.Size = new System.Drawing.Size(138, 22);
+ this.sadToolStripMenuItem.Text = "Sad";
+ this.sadToolStripMenuItem.ToolTipText = ":(";
+ this.sadToolStripMenuItem.Click += new System.EventHandler(this.emotionDropDown_Click);
+ //
+ // winkToolStripMenuItem
+ //
+ this.winkToolStripMenuItem.Image = global::MSNPSharpClient.Properties.Resources.wink;
+ this.winkToolStripMenuItem.Name = "winkToolStripMenuItem";
+ this.winkToolStripMenuItem.Size = new System.Drawing.Size(138, 22);
+ this.winkToolStripMenuItem.Text = "Wink";
+ this.winkToolStripMenuItem.ToolTipText = ";)";
+ this.winkToolStripMenuItem.Click += new System.EventHandler(this.emotionDropDown_Click);
+ //
+ // tongueOutToolStripMenuItem
+ //
+ this.tongueOutToolStripMenuItem.Image = global::MSNPSharpClient.Properties.Resources.tongueout;
+ this.tongueOutToolStripMenuItem.Name = "tongueOutToolStripMenuItem";
+ this.tongueOutToolStripMenuItem.Size = new System.Drawing.Size(138, 22);
+ this.tongueOutToolStripMenuItem.Text = "Tongue Out";
+ this.tongueOutToolStripMenuItem.ToolTipText = ":p";
+ this.tongueOutToolStripMenuItem.Click += new System.EventHandler(this.emotionDropDown_Click);
+ //
+ // bMessageSendNudge
+ //
+ this.bMessageSendNudge.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+ this.bMessageSendNudge.Image = global::MSNPSharpClient.Properties.Resources.nudge;
+ this.bMessageSendNudge.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
+ this.bMessageSendNudge.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.bMessageSendNudge.Name = "bMessageSendNudge";
+ this.bMessageSendNudge.Size = new System.Drawing.Size(28, 22);
+ this.bMessageSendNudge.Text = "Send a &nudge";
+ this.bMessageSendNudge.Click += new System.EventHandler(this.bMessageSendNudge_Click);
+ //
+ // tssMessageSeperator1
+ //
+ this.tssMessageSeperator1.Name = "tssMessageSeperator1";
+ this.tssMessageSeperator1.Size = new System.Drawing.Size(6, 25);
+ //
+ // bMessageFontColor
+ //
+ this.bMessageFontColor.Image = global::MSNPSharpClient.Properties.Resources.Color_fontHS;
+ this.bMessageFontColor.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.bMessageFontColor.Name = "bMessageFontColor";
+ this.bMessageFontColor.Size = new System.Drawing.Size(56, 22);
+ this.bMessageFontColor.Text = "Color";
+ this.bMessageFontColor.Click += new System.EventHandler(this.bMessageFontColor_Click);
+ //
+ // bMessageBold
+ //
+ this.bMessageBold.CheckOnClick = true;
+ this.bMessageBold.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
+ this.bMessageBold.Font = new System.Drawing.Font("Times New Roman", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.bMessageBold.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.bMessageBold.Name = "bMessageBold";
+ this.bMessageBold.Size = new System.Drawing.Size(23, 22);
+ this.bMessageBold.Text = "B";
+ this.bMessageBold.ToolTipText = "Bold";
+ this.bMessageBold.CheckedChanged += new System.EventHandler(this.bMessageBoldItalicUnderline_CheckedChanged);
+ //
+ // bMessageItalic
+ //
+ this.bMessageItalic.CheckOnClick = true;
+ this.bMessageItalic.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
+ this.bMessageItalic.Font = new System.Drawing.Font("Times New Roman", 9.75F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.bMessageItalic.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.bMessageItalic.Name = "bMessageItalic";
+ this.bMessageItalic.Size = new System.Drawing.Size(23, 22);
+ this.bMessageItalic.Text = "I";
+ this.bMessageItalic.ToolTipText = "Italic";
+ this.bMessageItalic.CheckedChanged += new System.EventHandler(this.bMessageBoldItalicUnderline_CheckedChanged);
+ //
+ // bMessageUnderline
+ //
+ this.bMessageUnderline.CheckOnClick = true;
+ this.bMessageUnderline.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
+ this.bMessageUnderline.Font = new System.Drawing.Font("Times New Roman", 9.75F, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.bMessageUnderline.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.bMessageUnderline.Name = "bMessageUnderline";
+ this.bMessageUnderline.Size = new System.Drawing.Size(23, 22);
+ this.bMessageUnderline.Text = "U";
+ this.bMessageUnderline.ToolTipText = "Underline";
+ this.bMessageUnderline.CheckedChanged += new System.EventHandler(this.bMessageBoldItalicUnderline_CheckedChanged);
+ //
+ // cbMessageFontName
+ //
+ this.cbMessageFontName.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend;
+ this.cbMessageFontName.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
+ this.cbMessageFontName.DropDownWidth = 200;
+ this.cbMessageFontName.MaxDropDownItems = 12;
+ this.cbMessageFontName.Name = "cbMessageFontName";
+ this.cbMessageFontName.Size = new System.Drawing.Size(140, 25);
+ this.cbMessageFontName.ToolTipText = "Font Name";
+ this.cbMessageFontName.SelectedIndexChanged += new System.EventHandler(this.cbMessageFontName_SelectedIndexChanged);
+ this.cbMessageFontName.Validating += new System.ComponentModel.CancelEventHandler(this.cbMessageFontName_Validating);
+ this.cbMessageFontName.Validated += new System.EventHandler(this.cbMessageFontName_Validated);
+ //
+ // cbMessageFontSize
+ //
+ this.cbMessageFontSize.Items.AddRange(new object[] {
+ "8",
+ "9",
+ "10",
+ "11",
+ "12",
+ "14",
+ "16",
+ "18",
+ "20",
+ "22",
+ "24",
+ "26",
+ "28",
+ "36",
+ "48",
+ "72"});
+ this.cbMessageFontSize.MaxDropDownItems = 12;
+ this.cbMessageFontSize.Name = "cbMessageFontSize";
+ this.cbMessageFontSize.Size = new System.Drawing.Size(75, 25);
+ this.cbMessageFontSize.ToolTipText = "Font Size";
+ this.cbMessageFontSize.SelectedIndexChanged += new System.EventHandler(this.cbMessageFontSize_SelectedIndexChanged);
+ this.cbMessageFontSize.Validating += new System.ComponentModel.CancelEventHandler(this.cbMessageFontSize_Validating);
+ this.cbMessageFontSize.Validated += new System.EventHandler(this.cbMessageFontSize_Validated);
+ //
+ // tssMessageSeperator2
+ //
+ this.tssMessageSeperator2.Name = "tssMessageSeperator2";
+ this.tssMessageSeperator2.Size = new System.Drawing.Size(6, 25);
+ //
+ // bMessageSend
+ //
+ this.bMessageSend.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
+ this.bMessageSend.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
+ this.bMessageSend.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold);
+ this.bMessageSend.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.bMessageSend.Name = "bMessageSend";
+ this.bMessageSend.Overflow = System.Windows.Forms.ToolStripItemOverflow.Never;
+ this.bMessageSend.Size = new System.Drawing.Size(57, 22);
+ this.bMessageSend.Text = " &Send ";
+ this.bMessageSend.Click += new System.EventHandler(this.bMessageSend_Click);
+ //
+ // displayOwner
+ //
+ this.displayOwner.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.displayOwner.BackColor = System.Drawing.Color.White;
+ this.displayOwner.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.displayOwner.Location = new System.Drawing.Point(3, 3);
+ this.displayOwner.Name = "displayOwner";
+ this.displayOwner.Size = new System.Drawing.Size(100, 100);
+ this.displayOwner.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
+ this.displayOwner.TabIndex = 0;
+ this.displayOwner.TabStop = false;
+ //
+ // inputTextBox
+ //
+ this.inputTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.inputTextBox.Location = new System.Drawing.Point(109, 31);
+ this.inputTextBox.Multiline = true;
+ this.inputTextBox.Name = "inputTextBox";
+ this.inputTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+ this.inputTextBox.Size = new System.Drawing.Size(550, 72);
+ this.inputTextBox.TabIndex = 1;
+ this.inputTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.inputTextBox_KeyDown);
+ this.inputTextBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.inputTextBox_KeyPress);
+ //
+ // panel2
+ //
+ this.panel2.Controls.Add(this.btnActivityTest);
+ this.panel2.Controls.Add(this.btnCustomEmoticon);
+ this.panel2.Controls.Add(this.btnInviteUsers);
+ this.panel2.Controls.Add(this.btnSendFiles);
+ this.panel2.Controls.Add(this.displayUser);
+ this.panel2.Controls.Add(this.richTextHistory);
+ this.panel2.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.panel2.Location = new System.Drawing.Point(0, 0);
+ this.panel2.Name = "panel2";
+ this.panel2.Size = new System.Drawing.Size(663, 272);
+ this.panel2.TabIndex = 0;
+ //
+ // btnActivityTest
+ //
+ this.btnActivityTest.Location = new System.Drawing.Point(3, 98);
+ this.btnActivityTest.Name = "btnActivityTest";
+ this.btnActivityTest.Size = new System.Drawing.Size(100, 24);
+ this.btnActivityTest.TabIndex = 4;
+ this.btnActivityTest.Text = "Activity Test";
+ this.btnActivityTest.UseVisualStyleBackColor = true;
+ this.btnActivityTest.Click += new System.EventHandler(this.btnActivityTest_Click);
+ //
+ // btnCustomEmoticon
+ //
+ this.btnCustomEmoticon.Location = new System.Drawing.Point(3, 41);
+ this.btnCustomEmoticon.Name = "btnCustomEmoticon";
+ this.btnCustomEmoticon.Size = new System.Drawing.Size(100, 23);
+ this.btnCustomEmoticon.TabIndex = 3;
+ this.btnCustomEmoticon.Text = "Custom Emoticon";
+ this.btnCustomEmoticon.UseVisualStyleBackColor = true;
+ this.btnCustomEmoticon.Click += new System.EventHandler(this.bMessageSendCustomEmoticon_Click);
+ //
+ // btnInviteUsers
+ //
+ this.btnInviteUsers.ContextMenuStrip = this.onlineUsersDropDown;
+ this.btnInviteUsers.Location = new System.Drawing.Point(3, 70);
+ this.btnInviteUsers.Name = "btnInviteUsers";
+ this.btnInviteUsers.Size = new System.Drawing.Size(100, 23);
+ this.btnInviteUsers.TabIndex = 2;
+ this.btnInviteUsers.Text = "Invite Users";
+ this.btnInviteUsers.UseVisualStyleBackColor = true;
+ this.btnInviteUsers.Click += new System.EventHandler(this.btnInviteUsers_Click);
+ //
+ // onlineUsersDropDown
+ //
+ this.onlineUsersDropDown.Name = "onlineUsersDropDown";
+ this.onlineUsersDropDown.Size = new System.Drawing.Size(61, 4);
+ //
+ // btnSendFiles
+ //
+ this.btnSendFiles.Location = new System.Drawing.Point(3, 12);
+ this.btnSendFiles.Name = "btnSendFiles";
+ this.btnSendFiles.Size = new System.Drawing.Size(100, 23);
+ this.btnSendFiles.TabIndex = 1;
+ this.btnSendFiles.Text = "Send Files";
+ this.btnSendFiles.UseVisualStyleBackColor = true;
+ this.btnSendFiles.Click += new System.EventHandler(this.bMessageSendFiles_Click);
+ //
+ // displayUser
+ //
+ this.displayUser.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.displayUser.BackColor = System.Drawing.Color.White;
+ this.displayUser.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.displayUser.Location = new System.Drawing.Point(3, 166);
+ this.displayUser.Name = "displayUser";
+ this.displayUser.Size = new System.Drawing.Size(100, 101);
+ this.displayUser.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
+ this.displayUser.TabIndex = 0;
+ this.displayUser.TabStop = false;
+ //
+ // richTextHistory
+ //
+ this.richTextHistory.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.richTextHistory.BackColor = System.Drawing.Color.Snow;
+ this.richTextHistory.BorderStyle = System.Windows.Forms.BorderStyle.None;
+ this.richTextHistory.HiglightColor = MSNPSharpClient.RtfRichTextBox.RtfColor.White;
+ this.richTextHistory.Location = new System.Drawing.Point(109, 3);
+ this.richTextHistory.Name = "richTextHistory";
+ this.richTextHistory.ReadOnly = true;
+ this.richTextHistory.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.Vertical;
+ this.richTextHistory.Size = new System.Drawing.Size(554, 264);
+ this.richTextHistory.TabIndex = 0;
+ this.richTextHistory.TabStop = false;
+ this.richTextHistory.Text = "";
+ this.richTextHistory.TextColor = MSNPSharpClient.RtfRichTextBox.RtfColor.Black;
+ //
+ // openFileDialog
+ //
+ this.openFileDialog.Multiselect = true;
+ //
+ // openCustomEmoticonDialog
+ //
+ this.openCustomEmoticonDialog.Filter = "Image File (*.png, *.jpg, *.bmp, *.gif|*.png;*.jpg;*.bmp;*.gif";
+ this.openCustomEmoticonDialog.Title = "Open Image to transfer as an custom emoticon";
+ //
+ // ConversationForm
+ //
+ this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
+ this.ClientSize = new System.Drawing.Size(663, 383);
+ this.Controls.Add(this.panel2);
+ this.Controls.Add(this.panel1);
+ this.Name = "ConversationForm";
+ this.Text = "Conversation - MSNPSharp";
+ this.Load += new System.EventHandler(this.ConversationForm_Load);
+ this.Shown += new System.EventHandler(this.ConversationForm_Shown);
+ this.Closing += new System.ComponentModel.CancelEventHandler(this.ConversationForm_Closing);
+ this.panel1.ResumeLayout(false);
+ this.panel1.PerformLayout();
+ this.tsMessage.ResumeLayout(false);
+ this.tsMessage.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.displayOwner)).EndInit();
+ this.panel2.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.displayUser)).EndInit();
+ this.ResumeLayout(false);
+
+ }
+ #endregion
+
+ private Messenger _messenger = null;
+ private ConversationID activeconversationID = null;
+
+ bool isYIM = false;
+
+
+ public ConversationID ConversationID
+ {
+ get
+ {
+ return activeconversationID;
+ }
+
+ private set
+ {
+ activeconversationID = value;
+ }
+ }
+
+ protected ConversationForm()
+ {
+ }
+
+ ///
+ /// For sending and receiving YIM messages.
+ ///
+ ///
+ ///
+ public ConversationForm(Messenger messenger, Contact contact, ConversationID convId)
+ {
+ InitializeComponent();
+
+ _messenger = messenger;
+ activeconversationID = convId;
+
+ isYIM = (ConversationID.NetworkType == ClientType.EmailMember);
+
+ if (isYIM)
+ {
+ btnActivityTest.Enabled = false;
+ btnCustomEmoticon.Enabled = false;
+ btnInviteUsers.Enabled = false;
+ btnSendFiles.Enabled = false;
+ }
+ }
+
+ public void OnMessageReceived(object sender, MessageArrivedEventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new EventHandler(OnMessageReceived), new object[] { sender, e });
+ }
+ else
+ {
+ switch (e.MessageType)
+ {
+ case NetworkMessageType.Nudge:
+ MakeVisible(sender, e);
+ PrintNudge(e.Sender);
+ break;
+ case NetworkMessageType.Text:
+ MakeVisible(sender, e);
+ PrintText(e.Sender, (e as TextMessageArrivedEventArgs).TextMessage);
+ break;
+ case NetworkMessageType.Emoticon:
+ {
+ Emoticon emo = (e as EmoticonArrivedEventArgs).Emoticon;
+ if (emo != null)
+ {
+ MemoryStream ms = new MemoryStream();
+ byte[] byt = new byte[emo.OpenStream().Length];
+ emo.OpenStream().Seek(0, SeekOrigin.Begin);
+ emo.OpenStream().Read(byt, 0, byt.Length);
+ ms.Write(byt, 0, byt.Length);
+
+ richTextHistory.Emotions[emo.Shortcut] = new Bitmap(Image.FromStream(ms));
+
+ ms.Close();
+ }
+
+ while (richTextHistory.HasEmotion)
+ {
+ richTextHistory.InsertEmotion();
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (components != null)
+ {
+ components.Dispose();
+ }
+ }
+ base.Dispose(disposing);
+ }
+
+ protected override void OnShown(EventArgs e)
+ {
+ base.OnShown(e);
+ }
+
+
+ private void inputTextBox_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
+ {
+ if ((e.KeyCode == Keys.Return) && (e.Alt || e.Control || e.Shift))
+ {
+ return;
+ }
+
+ try
+ {
+ _messenger.MessageManager.SendTyping(ConversationID);
+
+ }
+ catch (Exception)
+ {
+ }
+
+ if (e.KeyCode == Keys.Return)
+ {
+ if (!inputTextBox.Text.Equals(String.Empty))
+ {
+ bMessageSend.PerformClick();
+ }
+ e.Handled = true;
+ }
+
+
+ }
+
+ private void inputTextBox_KeyPress(object sender, KeyPressEventArgs e)
+ {
+ if (e.KeyChar == '\x001b')
+ {
+ Close();
+ }
+ else if ((e.KeyChar == '\r') && inputTextBox.Text.Equals(string.Empty))
+ {
+ e.Handled = true;
+ }
+ }
+
+ private void MakeVisible(object sender, EventArgs e)
+ {
+ Show();
+ }
+
+ private void PrintNudge(Contact sender)
+ {
+ DisplaySystemMessage(sender.Name + " has sent a nudge!");
+ PerformNudge();
+ }
+
+
+ public void DisplaySystemMessage(string systemMessage)
+ {
+ richTextHistory.SelectionColor = Color.Red;
+ richTextHistory.SelectionFont = new Font("Verdana", 8f, FontStyle.Bold);
+ richTextHistory.SelectionIndent = 30;
+ richTextHistory.AppendText("* " + systemMessage + " *");
+ richTextHistory.SelectionColor = Color.Black;
+ richTextHistory.SelectionIndent = 0;
+ richTextHistory.SelectionFont = new Font("Verdana", 8f);
+ richTextHistory.AppendText(Environment.NewLine);
+ richTextHistory.ScrollToCaret();
+ }
+
+
+ private void ConversationForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
+ {
+ ConversationID.RemoteOwner.DisplayImageChanged -= Contact_DisplayImageChanged;
+ ConversationID.RemoteOwner.DisplayImageContextChanged -= Contact_DisplayImageConextChanged;
+ _messenger.MessageManager.EndConversation(activeconversationID);
+ }
+
+ private void PrintText(Contact c, TextMessage message)
+ {
+ richTextHistory.SelectionColor = Color.Navy;
+ richTextHistory.SelectionIndent = 0;
+ richTextHistory.AppendText("[" + DateTime.Now.ToLongTimeString() + "]" + " ");
+ richTextHistory.SelectionColor = c.Mail == _messenger.ContactList.Owner.Mail ? Color.Blue : Color.Black;
+ richTextHistory.AppendText(c.Name + " <" + c.Mail + ">" + Environment.NewLine);
+ richTextHistory.SelectionColor = message.Color;
+ richTextHistory.SelectionIndent = 10;
+ richTextHistory.AppendText(message.Text);
+ richTextHistory.AppendText(Environment.NewLine);
+ richTextHistory.ScrollToCaret();
+
+ while (richTextHistory.HasEmotion)
+ {
+ richTextHistory.InsertEmotion();
+ }
+ }
+
+ private Image CreateImageFromColor(Color color, Size buttonSize)
+ {
+ Bitmap bitmap = new Bitmap(buttonSize.Width, buttonSize.Height);
+ using (Graphics graphics = Graphics.FromImage(bitmap))
+ {
+ graphics.Clear(color);
+ }
+ return bitmap;
+ }
+
+ private void UpdateTextFonts()
+ {
+ FontStyle fontStyle = FontStyle.Regular;
+
+ if (bMessageBold.Checked)
+ fontStyle |= FontStyle.Bold;
+ if (bMessageItalic.Checked)
+ fontStyle |= FontStyle.Italic;
+ if (bMessageUnderline.Checked)
+ fontStyle |= FontStyle.Underline;
+
+ Single fontSize = Single.Parse(cbMessageFontSize.Text);
+ Font messageFont = null;
+
+ CreateFont:
+ try
+ {
+ messageFont = new Font(cbMessageFontName.Text, fontSize, fontStyle, GraphicsUnit.Point);
+ }
+ catch (ArgumentException)
+ {
+ fontStyle++;
+ if (fontStyle <= (FontStyle.Strikeout | FontStyle.Underline | FontStyle.Italic | FontStyle.Bold))
+ goto CreateFont;
+ }
+
+ if (messageFont == null)
+ return;
+
+ bMessageBold.Checked = (fontStyle & FontStyle.Bold) != FontStyle.Regular;
+ bMessageItalic.Checked = (fontStyle & FontStyle.Italic) != FontStyle.Regular;
+ bMessageUnderline.Checked = (fontStyle & FontStyle.Underline) != FontStyle.Regular;
+
+ richTextHistory.Font = new Font(richTextHistory.Font.FontFamily, messageFont.Size);
+ inputTextBox.Font = messageFont;
+ }
+
+ private void ConversationForm_Load(object sender, EventArgs e)
+ {
+ Text = "Conversation with " + ConversationID.RemoteOwner.Mail + " - MSNPSharp";
+ Icon = (Icon)((ConversationID.RemoteOwner.ClientType == ClientType.PassportMember) ? Properties.Resources.msn_ico : Properties.Resources.yahoo_ico);
+
+ if (_messenger.ContactList.Owner.DisplayImage.Image != null)
+ displayOwner.Image = _messenger.ContactList.Owner.DisplayImage.Image;
+ else
+ displayOwner.Image = DisplayImage.DefaultImage;
+
+ lock (richTextHistory.Emotions)
+ {
+ richTextHistory.Emotions[":)"] = Properties.Resources.smiley;
+ richTextHistory.Emotions[":d"] = Properties.Resources.biggrin;
+ richTextHistory.Emotions[":("] = Properties.Resources.sad;
+ richTextHistory.Emotions[";)"] = Properties.Resources.wink;
+ richTextHistory.Emotions[":p"] = Properties.Resources.tongueout;
+ }
+
+ foreach (FontFamily ff in FontFamily.Families)
+ {
+ cbMessageFontName.Items.Add(ff.Name);
+ }
+ cbMessageFontName.Text = inputTextBox.Font.Name;
+ cbMessageFontSize.Text = inputTextBox.Font.Size.ToString();
+ bMessageFontColor.Image = CreateImageFromColor(inputTextBox.ForeColor, inputTextBox.Size);
+
+ cbMessageFontName.Tag = cbMessageFontName.Text;
+ cbMessageFontSize.Tag = cbMessageFontSize.Text;
+
+ UpdateTextFonts();
+
+ inputTextBox.Select();
+ }
+
+ private void ConversationForm_Shown(object sender, EventArgs e)
+ {
+ if (!isYIM)
+ {
+ if (ConversationID.RemoteOwner.DisplayImage.Image != null)
+ displayUser.Image = ConversationID.RemoteOwner.DisplayImage.Image;
+ else
+ displayUser.Image = DisplayImage.DefaultImage;
+ }
+ else
+ displayUser.Image = Properties.Resources.YahooMessenger_logo.Clone() as Image;
+
+ ConversationID.RemoteOwner.DisplayImageChanged += new EventHandler(Contact_DisplayImageChanged);
+ ConversationID.RemoteOwner.DisplayImageContextChanged += new EventHandler(Contact_DisplayImageConextChanged);
+
+ // request the image, if not already available
+ if (ConversationID.RemoteOwner.Status != PresenceStatus.Offline)
+ {
+ if (ConversationID.RemoteOwner.DisplayImage != ConversationID.RemoteOwner.UserTileLocation)
+ {
+ try
+ {
+ RequestDisplayImage(ConversationID.RemoteOwner, null);
+ }
+ catch (Exception ex)
+ {
+ Trace.WriteLineIf(Settings.TraceSwitch.TraceError, ex.Message + "\r\n StackTrace: " + ex.StackTrace);
+ }
+ }
+
+
+ }
+ }
+
+ private void RequestDisplayImage(Contact remoteContact, DisplayImage updateImage)
+ {
+ if (remoteContact.ClientType == ClientType.PassportMember &&
+ updateImage != remoteContact.UserTileLocation)
+ {
+ if (updateImage == null)
+ updateImage = remoteContact.DisplayImage;
+
+ // by sending an invitation a P2PTransferSession is automatically created.
+ // the session object takes care of the actual data transfer to the remote client,
+ // in contrast to the msnslpHandler object, which only deals with the protocol chatting.
+ P2PTransferSession session = _messenger.RequestMsnObject(remoteContact, updateImage);
+ }
+ }
+
+ private void Contact_DisplayImageConextChanged(object sender, DisplayImageChangedEventArgs e)
+ {
+ try
+ {
+ RequestDisplayImage(ConversationID.RemoteOwner, null);
+ }
+ catch (Exception ex)
+ {
+ Trace.WriteLineIf(Settings.TraceSwitch.TraceError, ex.Message + "\r\n StackTrace: " + ex.StackTrace);
+ }
+ }
+
+ private void Contact_DisplayImageChanged(object sender, DisplayImageChangedEventArgs e)
+ {
+ if (displayUser.InvokeRequired)
+ {
+ Invoke(new EventHandler(Contact_DisplayImageChanged), new object[] { sender, e });
+ }
+ else
+ {
+ displayUser.Image = e.NewDisplayImage.Image;
+ }
+ }
+
+ private void emotionDropDown_Click(object sender, EventArgs args)
+ {
+ ToolStripItem item = (ToolStripItem)sender;
+ inputTextBox.AppendText(item.ToolTipText);
+ inputTextBox.Focus();
+ }
+
+ private void PerformNudge()
+ {
+ Stopwatch stopwatch = new Stopwatch();
+
+ Random rnd = new Random();
+ int x = Left;
+ int y = Top;
+
+ stopwatch.Start();
+ while (stopwatch.ElapsedMilliseconds < 500)
+ {
+ Left = rnd.Next(Location.X - 5, Location.X + 5);
+ Top = rnd.Next(Location.Y - 1, Location.Y + 1);
+
+ System.Threading.Thread.Sleep(10);
+ Application.DoEvents();
+ }
+ stopwatch.Stop();
+
+ Left = x;
+ Top = y;
+ }
+
+ private void bMessageSend_Click(object sender, EventArgs e)
+ {
+ if (inputTextBox.Text.Length == 0)
+ return;
+
+ TextMessage message = new TextMessage(inputTextBox.Text);
+ message.Font = inputTextBox.Font.Name;
+ message.Color = inputTextBox.ForeColor;
+
+ if (inputTextBox.Font.Bold)
+ message.Decorations |= TextDecorations.Bold;
+ if (inputTextBox.Font.Italic)
+ message.Decorations |= TextDecorations.Italic;
+ if (inputTextBox.Font.Underline)
+ message.Decorations |= TextDecorations.Underline;
+
+ inputTextBox.Clear();
+ inputTextBox.Focus();
+
+
+ ConversationID = _messenger.MessageManager.SendTextMessage(ConversationID, message);
+ PrintText(_messenger.ContactList.Owner, message);
+
+
+ }
+
+ private void btnInviteUsers_Click(object sender, EventArgs e)
+ {
+ int x = Location.X + 10 + btnInviteUsers.Width;
+ int y = Location.Y + 10 + btnInviteUsers.Height + 20;
+
+ onlineUsersDropDown.Items.Clear();
+ foreach (Contact c in _messenger.ContactList.Forward)
+ {
+ if (c.Online && c.ClientType == ClientType.PassportMember)
+ {
+ onlineUsersDropDown.Items.Add(c.Mail, null, onlineUsersDropDown_Click).ToolTipText = c.Mail;
+ }
+ }
+
+ onlineUsersDropDown.Show(x, y);
+ onlineUsersDropDown.Focus();
+ }
+
+ private void onlineUsersDropDown_Click(object sender, EventArgs args)
+ {
+ ToolStripItem item = (ToolStripItem)sender;
+ if (_messenger.ContactList.HasContact(item.ToolTipText, ClientType.PassportMember))
+ {
+ activeconversationID = _messenger.MessageManager.InviteContactToConversation(activeconversationID, _messenger.ContactList.GetContact(item.ToolTipText));
+ }
+ else
+ {
+ DisplaySystemMessage("Cannot find PassportMember: " + item.ToolTipText);
+ }
+ }
+
+ private void bMessageSendNudge_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ ConversationID = _messenger.MessageManager.SendNudge(ConversationID);
+ DisplaySystemMessage("You send a nudge.");
+ PerformNudge();
+ }
+ catch (Exception)
+ {
+
+ DisplaySystemMessage("Remote contact not online.");
+ }
+ }
+
+ private void bMessageSendFiles_Click(object sender, EventArgs e)
+ {
+ if (ConversationID.RemoteOwner.Online == false || ConversationID.RemoteOwner == null)
+ {
+ DisplaySystemMessage("All contacts are offline or this contact doesn't support receiving files.");
+ return;
+ }
+
+ if (openFileDialog.ShowDialog() == DialogResult.OK)
+ {
+
+ try
+ {
+
+ foreach (string filename in openFileDialog.FileNames)
+ {
+ FileStream fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
+ P2PTransferSession session = _messenger.SendFile(ConversationID.RemoteOwner, filename, fileStream);
+ }
+ }
+ catch (MSNPSharpException ex)
+ {
+ MessageBox.Show(ex.Message);
+ }
+
+
+
+ }
+ }
+
+ private void bMessageSendCustomEmoticon_Click(object sender, EventArgs e)
+ {
+ if (openCustomEmoticonDialog.ShowDialog() != DialogResult.OK)
+ return;
+
+ MemoryStream mem = new MemoryStream();
+ Bitmap img = new Bitmap(Image.FromFile(openCustomEmoticonDialog.FileName));
+ img.Save(mem, ImageFormat.Png);
+ Emoticon emotest = new Emoticon(_messenger.Owner.Mail, mem, Path.GetFileName(openCustomEmoticonDialog.FileName), Path.GetFileName(openCustomEmoticonDialog.FileName));
+ MSNObjectCatalog.GetInstance().Add(emotest);
+ List emolist = new List();
+ emolist.Add(emotest);
+
+ if (!richTextHistory.Emotions.ContainsKey(emotest.Shortcut))
+ {
+ richTextHistory.Emotions[emotest.Shortcut] = img;
+ }
+
+ try
+ {
+ ConversationID = _messenger.MessageManager.SendEmoticonDefinitions(ConversationID, emolist, EmoticonType.StaticEmoticon);
+ TextMessage emotxt = new TextMessage("Hey, this is a custom emoticon: " + emotest.Shortcut);
+ ConversationID = _messenger.MessageManager.SendTextMessage(ConversationID, emotxt);
+ DisplaySystemMessage("You send a custom emoticon with text message: Hey, this is a custom emoticon: [" + emotest.Shortcut + "].");
+ }
+ catch (Exception)
+ {
+ if (!isYIM)
+ DisplaySystemMessage("Remote contact not online, emoticon will not be sent.");
+ }
+ }
+
+ private void bMessageBoldItalicUnderline_CheckedChanged(object sender, EventArgs e)
+ {
+ UpdateTextFonts();
+ inputTextBox.Select();
+ }
+
+ private void bMessageFontColor_Click(object sender, EventArgs e)
+ {
+ if (dlgColor.ShowDialog() == DialogResult.OK)
+ {
+ bMessageFontColor.Image = CreateImageFromColor(dlgColor.Color, bMessageFontColor.Image.Size);
+ inputTextBox.ForeColor = dlgColor.Color;
+ }
+ }
+
+ private void cbMessageFontName_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ Validate();
+ }
+
+ private void cbMessageFontName_Validated(object sender, EventArgs e)
+ {
+ cbMessageFontName.Tag = cbMessageFontName.Text;
+ UpdateTextFonts();
+ inputTextBox.Select();
+ }
+
+ private void cbMessageFontName_Validating(object sender, CancelEventArgs e)
+ {
+ if (cbMessageFontName.FindStringExact(cbMessageFontName.Text) == -1 && cbMessageFontName.Tag != null)
+ {
+ cbMessageFontName.Text = cbMessageFontName.Tag.ToString();
+ }
+
+ }
+
+ private void cbMessageFontSize_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ Validate();
+ }
+
+ private void cbMessageFontSize_Validated(object sender, EventArgs e)
+ {
+ cbMessageFontSize.Tag = cbMessageFontSize.Text;
+ UpdateTextFonts();
+ inputTextBox.Select();
+ }
+
+ private void cbMessageFontSize_Validating(object sender, CancelEventArgs e)
+ {
+ float fontSize = float.MinValue;
+ float.TryParse(cbMessageFontSize.Text, out fontSize);
+
+ if (fontSize < 8f || fontSize > 72f && cbMessageFontSize.Tag != null)
+ {
+ cbMessageFontSize.Text = cbMessageFontSize.Tag.ToString();
+ }
+ }
+
+ private void MSNSLPHandler_TransferSessionClosed(object sender, P2PTransferSessionEventArgs e)
+ {
+ if (!richTextHistory.InvokeRequired)
+ {
+ DisplaySystemMessage("Activity session closed.");
+ }
+ else
+ {
+ richTextHistory.Invoke(new EventHandler(MSNSLPHandler_TransferSessionClosed), new object[] { sender,e });
+ }
+ }
+
+ private void btnActivityTest_Click(object sender, EventArgs e)
+ {
+ String activityID = "7"; //"20521364"; //The activityID of Music Mix activity.
+ String activityName = "Activity Test"; //Th name of acticvity
+ MSNSLPHandler msnslpHandler = _messenger.GetMSNSLPHandler(ConversationID.RemoteOwner);
+ P2PTransferSession session = msnslpHandler.SendInvitation(_messenger.ContactList.Owner, ConversationID.RemoteOwner, activityID, activityName, @"http://code.google.com/p/msnp-sharp");
+
+ msnslpHandler.TransferSessionClosed += delegate(object s, P2PTransferSessionEventArgs ea)
+ {
+ if (ea.TransferSession == session)
+ MSNSLPHandler_TransferSessionClosed(s, ea);
+ };
+ }
+ }
+};
diff --git a/Example/ConversationForm.resx b/Example/ConversationForm.resx
new file mode 100644
index 0000000..67504b6
--- /dev/null
+++ b/Example/ConversationForm.resx
@@ -0,0 +1,135 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 274, 14
+
+
+ 397, 18
+
+
+ 17, 17
+
+
+ 158, 20
+
+
+ 17, 57
+
+
\ No newline at end of file
diff --git a/Example/DotMSNClient.Designer.cs b/Example/DotMSNClient.Designer.cs
new file mode 100644
index 0000000..00d27e7
--- /dev/null
+++ b/Example/DotMSNClient.Designer.cs
@@ -0,0 +1,876 @@
+using System.Windows.Forms;
+
+namespace MSNPSharpClient
+{
+ partial class ClientForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ this.ImageList1 = new System.Windows.Forms.ImageList(this.components);
+ this.userMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
+ this.sendIMMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.sendOIMMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.sendMIMMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator();
+ this.importContactsMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.createCircleMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
+ this.blockMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.unblockMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.deleteMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
+ this.openImageDialog = new System.Windows.Forms.OpenFileDialog();
+ this.tmrKeepOnLine = new System.Windows.Forms.Timer(this.components);
+ this.tmrNews = new System.Windows.Forms.Timer(this.components);
+ this.sortContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
+ this.toolStripSortByStatus = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripSortBygroup = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripDeleteGroup = new System.Windows.Forms.ToolStripMenuItem();
+ this.groupContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
+ this.toolTipChangePhoto = new System.Windows.Forms.ToolTip(this.components);
+ this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
+ this.WhatsUpPanel = new System.Windows.Forms.Panel();
+ this.lblNewsLink = new System.Windows.Forms.LinkLabel();
+ this.lblNews = new System.Windows.Forms.Label();
+ this.pbNewsPicture = new System.Windows.Forms.PictureBox();
+ this.cmdNext = new System.Windows.Forms.Button();
+ this.cmdPrev = new System.Windows.Forms.Button();
+ this.lblWhatsup = new System.Windows.Forms.Label();
+ this.splitContainer1 = new System.Windows.Forms.SplitContainer();
+ this.propertyGrid = new System.Windows.Forms.PropertyGrid();
+ this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
+ this.pnlTreeViewsContainer = new System.Windows.Forms.Panel();
+ this.treeViewFilterList = new System.Windows.Forms.TreeView();
+ this.treeViewFavoriteList = new System.Windows.Forms.TreeView();
+ this.SortPanel = new System.Windows.Forms.Panel();
+ this.txtSearch = new System.Windows.Forms.TextBox();
+ this.btnAddNew = new System.Windows.Forms.Button();
+ this.btnSortBy = new System.Windows.Forms.Button();
+ this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
+ this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel();
+ this.tableLayoutPanel5 = new System.Windows.Forms.TableLayoutPanel();
+ this.displayImageBox = new System.Windows.Forms.PictureBox();
+ this.panel1 = new System.Windows.Forms.Panel();
+ this.tableLayoutPanel6 = new System.Windows.Forms.TableLayoutPanel();
+ this.pnlLogin = new System.Windows.Forms.Panel();
+ this.pnlNameAndPM = new System.Windows.Forms.Panel();
+ this.btnSetMusic = new System.Windows.Forms.Button();
+ this.lblPM = new System.Windows.Forms.TextBox();
+ this.lblName = new System.Windows.Forms.TextBox();
+ this.cbRobotMode = new System.Windows.Forms.CheckBox();
+ this.accountTextBox = new System.Windows.Forms.TextBox();
+ this.loginButton = new System.Windows.Forms.Button();
+ this.passwordTextBox = new System.Windows.Forms.TextBox();
+ this.tableLayoutPanel7 = new System.Windows.Forms.TableLayoutPanel();
+ this.comboPlaces = new System.Windows.Forms.ComboBox();
+ this.comboStatus = new System.Windows.Forms.ComboBox();
+ this.statusBar = new System.Windows.Forms.Label();
+ this.userMenuStrip.SuspendLayout();
+ this.sortContextMenu.SuspendLayout();
+ this.groupContextMenu.SuspendLayout();
+ this.tableLayoutPanel1.SuspendLayout();
+ this.WhatsUpPanel.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.pbNewsPicture)).BeginInit();
+ this.splitContainer1.Panel1.SuspendLayout();
+ this.splitContainer1.Panel2.SuspendLayout();
+ this.splitContainer1.SuspendLayout();
+ this.tableLayoutPanel2.SuspendLayout();
+ this.pnlTreeViewsContainer.SuspendLayout();
+ this.SortPanel.SuspendLayout();
+ this.tableLayoutPanel3.SuspendLayout();
+ this.tableLayoutPanel4.SuspendLayout();
+ this.tableLayoutPanel5.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.displayImageBox)).BeginInit();
+ this.panel1.SuspendLayout();
+ this.tableLayoutPanel6.SuspendLayout();
+ this.pnlLogin.SuspendLayout();
+ this.pnlNameAndPM.SuspendLayout();
+ this.tableLayoutPanel7.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // ImageList1
+ //
+ this.ImageList1.ColorDepth = System.Windows.Forms.ColorDepth.Depth32Bit;
+ this.ImageList1.ImageSize = new System.Drawing.Size(10, 10);
+ this.ImageList1.TransparentColor = System.Drawing.Color.Transparent;
+ //
+ // userMenuStrip
+ //
+ this.userMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.sendIMMenuItem,
+ this.sendOIMMenuItem,
+ this.sendMIMMenuItem,
+ this.toolStripMenuItem3,
+ this.importContactsMenuItem,
+ this.createCircleMenuItem,
+ this.toolStripMenuItem2,
+ this.blockMenuItem,
+ this.unblockMenuItem,
+ this.deleteMenuItem});
+ this.userMenuStrip.Name = "contextMenuStrip1";
+ this.userMenuStrip.Size = new System.Drawing.Size(201, 192);
+ //
+ // sendIMMenuItem
+ //
+ this.sendIMMenuItem.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Bold);
+ this.sendIMMenuItem.Name = "sendIMMenuItem";
+ this.sendIMMenuItem.Size = new System.Drawing.Size(200, 22);
+ this.sendIMMenuItem.Text = "Send Instant Message";
+ this.sendIMMenuItem.Click += new System.EventHandler(this.sendMessageToolStripMenuItem_Click);
+ //
+ // sendOIMMenuItem
+ //
+ this.sendOIMMenuItem.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Bold);
+ this.sendOIMMenuItem.Name = "sendOIMMenuItem";
+ this.sendOIMMenuItem.Size = new System.Drawing.Size(200, 22);
+ this.sendOIMMenuItem.Text = "Send Offline Message";
+ this.sendOIMMenuItem.Click += new System.EventHandler(this.sendOfflineMessageToolStripMenuItem_Click);
+ //
+ // sendMIMMenuItem
+ //
+ this.sendMIMMenuItem.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Bold);
+ this.sendMIMMenuItem.Name = "sendMIMMenuItem";
+ this.sendMIMMenuItem.Size = new System.Drawing.Size(200, 22);
+ this.sendMIMMenuItem.Text = "Send Mobile Message";
+ this.sendMIMMenuItem.Click += new System.EventHandler(this.sendMIMMenuItem_Click);
+ //
+ // toolStripMenuItem3
+ //
+ this.toolStripMenuItem3.Name = "toolStripMenuItem3";
+ this.toolStripMenuItem3.Size = new System.Drawing.Size(197, 6);
+ //
+ // importContactsMenuItem
+ //
+ this.importContactsMenuItem.Name = "importContactsMenuItem";
+ this.importContactsMenuItem.Size = new System.Drawing.Size(200, 22);
+ this.importContactsMenuItem.Text = "Import Contacts";
+ this.importContactsMenuItem.Click += new System.EventHandler(this.importContactsMenuItem_Click);
+ //
+ // createCircleMenuItem
+ //
+ this.createCircleMenuItem.Name = "createCircleMenuItem";
+ this.createCircleMenuItem.Size = new System.Drawing.Size(200, 22);
+ this.createCircleMenuItem.Text = "Circle Tests";
+ this.createCircleMenuItem.Click += new System.EventHandler(this.createCircleMenuItem_Click);
+ //
+ // toolStripMenuItem2
+ //
+ this.toolStripMenuItem2.Name = "toolStripMenuItem2";
+ this.toolStripMenuItem2.Size = new System.Drawing.Size(197, 6);
+ //
+ // blockMenuItem
+ //
+ this.blockMenuItem.Name = "blockMenuItem";
+ this.blockMenuItem.Size = new System.Drawing.Size(200, 22);
+ this.blockMenuItem.Text = "Block";
+ this.blockMenuItem.Click += new System.EventHandler(this.blockToolStripMenuItem_Click);
+ //
+ // unblockMenuItem
+ //
+ this.unblockMenuItem.Name = "unblockMenuItem";
+ this.unblockMenuItem.Size = new System.Drawing.Size(200, 22);
+ this.unblockMenuItem.Text = "Unblock";
+ this.unblockMenuItem.Click += new System.EventHandler(this.unblockMenuItem_Click);
+ //
+ // deleteMenuItem
+ //
+ this.deleteMenuItem.Name = "deleteMenuItem";
+ this.deleteMenuItem.Size = new System.Drawing.Size(200, 22);
+ this.deleteMenuItem.Text = "Delete";
+ this.deleteMenuItem.Click += new System.EventHandler(this.deleteMenuItem_Click);
+ //
+ // openFileDialog
+ //
+ this.openFileDialog.Multiselect = true;
+ //
+ // openImageDialog
+ //
+ this.openImageDialog.Filter = "Supported Images|*.png;*.jpg;*.jpeg;*.gif";
+ this.openImageDialog.Multiselect = true;
+ this.openImageDialog.Title = "Select display image";
+ //
+ // tmrKeepOnLine
+ //
+ this.tmrKeepOnLine.Interval = 1000;
+ //
+ // tmrNews
+ //
+ this.tmrNews.Interval = 5000;
+ this.tmrNews.Tick += new System.EventHandler(this.tmrNews_Tick);
+ //
+ // sortContextMenu
+ //
+ this.sortContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.toolStripSortByStatus,
+ this.toolStripSortBygroup});
+ this.sortContextMenu.Name = "sortContextMenu";
+ this.sortContextMenu.ShowCheckMargin = true;
+ this.sortContextMenu.ShowImageMargin = false;
+ this.sortContextMenu.Size = new System.Drawing.Size(140, 48);
+ //
+ // toolStripSortByStatus
+ //
+ this.toolStripSortByStatus.Checked = true;
+ this.toolStripSortByStatus.CheckOnClick = true;
+ this.toolStripSortByStatus.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.toolStripSortByStatus.Name = "toolStripSortByStatus";
+ this.toolStripSortByStatus.ShowShortcutKeys = false;
+ this.toolStripSortByStatus.Size = new System.Drawing.Size(139, 22);
+ this.toolStripSortByStatus.Text = "Sort by status";
+ this.toolStripSortByStatus.Click += new System.EventHandler(this.toolStripSortByStatus_Click);
+ //
+ // toolStripSortBygroup
+ //
+ this.toolStripSortBygroup.CheckOnClick = true;
+ this.toolStripSortBygroup.Name = "toolStripSortBygroup";
+ this.toolStripSortBygroup.ShowShortcutKeys = false;
+ this.toolStripSortBygroup.Size = new System.Drawing.Size(139, 22);
+ this.toolStripSortBygroup.Text = "Sort by group";
+ this.toolStripSortBygroup.Click += new System.EventHandler(this.toolStripSortBygroup_Click);
+ //
+ // toolStripDeleteGroup
+ //
+ this.toolStripDeleteGroup.Name = "toolStripDeleteGroup";
+ this.toolStripDeleteGroup.Size = new System.Drawing.Size(142, 22);
+ this.toolStripDeleteGroup.Text = "Delete group";
+ this.toolStripDeleteGroup.Click += new System.EventHandler(this.toolStripDeleteGroup_Click);
+ //
+ // groupContextMenu
+ //
+ this.groupContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.toolStripDeleteGroup});
+ this.groupContextMenu.Name = "sortContextMenu";
+ this.groupContextMenu.ShowCheckMargin = true;
+ this.groupContextMenu.ShowImageMargin = false;
+ this.groupContextMenu.Size = new System.Drawing.Size(143, 26);
+ //
+ // tableLayoutPanel1
+ //
+ this.tableLayoutPanel1.ColumnCount = 1;
+ this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel1.Controls.Add(this.WhatsUpPanel, 0, 2);
+ this.tableLayoutPanel1.Controls.Add(this.splitContainer1, 0, 1);
+ this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel3, 0, 0);
+ this.tableLayoutPanel1.Controls.Add(this.statusBar, 0, 3);
+ this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
+ this.tableLayoutPanel1.Name = "tableLayoutPanel1";
+ this.tableLayoutPanel1.RowCount = 4;
+ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 128F));
+ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 57F));
+ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30F));
+ this.tableLayoutPanel1.Size = new System.Drawing.Size(643, 634);
+ this.tableLayoutPanel1.TabIndex = 3;
+ //
+ // WhatsUpPanel
+ //
+ this.WhatsUpPanel.BackColor = System.Drawing.Color.White;
+ this.WhatsUpPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.WhatsUpPanel.Controls.Add(this.lblNewsLink);
+ this.WhatsUpPanel.Controls.Add(this.lblNews);
+ this.WhatsUpPanel.Controls.Add(this.pbNewsPicture);
+ this.WhatsUpPanel.Controls.Add(this.cmdNext);
+ this.WhatsUpPanel.Controls.Add(this.cmdPrev);
+ this.WhatsUpPanel.Controls.Add(this.lblWhatsup);
+ this.WhatsUpPanel.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.WhatsUpPanel.Location = new System.Drawing.Point(3, 551);
+ this.WhatsUpPanel.Name = "WhatsUpPanel";
+ this.WhatsUpPanel.Size = new System.Drawing.Size(637, 50);
+ this.WhatsUpPanel.TabIndex = 8;
+ //
+ // lblNewsLink
+ //
+ this.lblNewsLink.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.lblNewsLink.Location = new System.Drawing.Point(506, 25);
+ this.lblNewsLink.Name = "lblNewsLink";
+ this.lblNewsLink.Size = new System.Drawing.Size(69, 21);
+ this.lblNewsLink.TabIndex = 5;
+ this.lblNewsLink.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ this.lblNewsLink.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lblNewsLink_LinkClicked);
+ //
+ // lblNews
+ //
+ this.lblNews.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.lblNews.AutoEllipsis = true;
+ this.lblNews.BackColor = System.Drawing.Color.Transparent;
+ this.lblNews.Location = new System.Drawing.Point(97, 3);
+ this.lblNews.Name = "lblNews";
+ this.lblNews.Size = new System.Drawing.Size(402, 42);
+ this.lblNews.TabIndex = 4;
+ this.lblNews.Text = " *";
+ this.lblNews.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // pbNewsPicture
+ //
+ this.pbNewsPicture.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.pbNewsPicture.BackColor = System.Drawing.Color.Transparent;
+ this.pbNewsPicture.Cursor = System.Windows.Forms.Cursors.Hand;
+ this.pbNewsPicture.Location = new System.Drawing.Point(589, 1);
+ this.pbNewsPicture.Name = "pbNewsPicture";
+ this.pbNewsPicture.Size = new System.Drawing.Size(45, 45);
+ this.pbNewsPicture.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
+ this.pbNewsPicture.TabIndex = 3;
+ this.pbNewsPicture.TabStop = false;
+ //
+ // cmdNext
+ //
+ this.cmdNext.Location = new System.Drawing.Point(42, 22);
+ this.cmdNext.Name = "cmdNext";
+ this.cmdNext.Size = new System.Drawing.Size(22, 22);
+ this.cmdNext.TabIndex = 2;
+ this.cmdNext.Text = ">";
+ this.cmdNext.UseVisualStyleBackColor = true;
+ this.cmdNext.Click += new System.EventHandler(this.cmdNext_Click);
+ //
+ // cmdPrev
+ //
+ this.cmdPrev.Location = new System.Drawing.Point(15, 22);
+ this.cmdPrev.Name = "cmdPrev";
+ this.cmdPrev.Size = new System.Drawing.Size(22, 22);
+ this.cmdPrev.TabIndex = 1;
+ this.cmdPrev.Text = "<";
+ this.cmdPrev.UseVisualStyleBackColor = true;
+ this.cmdPrev.Click += new System.EventHandler(this.cmdPrev_Click);
+ //
+ // lblWhatsup
+ //
+ this.lblWhatsup.AutoSize = true;
+ this.lblWhatsup.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(162)));
+ this.lblWhatsup.Location = new System.Drawing.Point(11, 3);
+ this.lblWhatsup.Name = "lblWhatsup";
+ this.lblWhatsup.Size = new System.Drawing.Size(66, 13);
+ this.lblWhatsup.TabIndex = 0;
+ this.lblWhatsup.Text = "What\'s Up";
+ //
+ // splitContainer1
+ //
+ this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.splitContainer1.Location = new System.Drawing.Point(3, 131);
+ this.splitContainer1.Name = "splitContainer1";
+ //
+ // splitContainer1.Panel1
+ //
+ this.splitContainer1.Panel1.BackColor = System.Drawing.Color.White;
+ this.splitContainer1.Panel1.Controls.Add(this.propertyGrid);
+ //
+ // splitContainer1.Panel2
+ //
+ this.splitContainer1.Panel2.Controls.Add(this.tableLayoutPanel2);
+ this.splitContainer1.Size = new System.Drawing.Size(637, 413);
+ this.splitContainer1.SplitterDistance = 252;
+ this.splitContainer1.TabIndex = 0;
+ //
+ // propertyGrid
+ //
+ this.propertyGrid.BackColor = System.Drawing.Color.White;
+ this.propertyGrid.CommandsBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(128)))));
+ this.propertyGrid.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.propertyGrid.HelpBackColor = System.Drawing.Color.White;
+ this.propertyGrid.LineColor = System.Drawing.SystemColors.ScrollBar;
+ this.propertyGrid.Location = new System.Drawing.Point(0, 0);
+ this.propertyGrid.Name = "propertyGrid";
+ this.propertyGrid.Size = new System.Drawing.Size(252, 413);
+ this.propertyGrid.TabIndex = 5;
+ //
+ // tableLayoutPanel2
+ //
+ this.tableLayoutPanel2.ColumnCount = 1;
+ this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel2.Controls.Add(this.pnlTreeViewsContainer, 0, 1);
+ this.tableLayoutPanel2.Controls.Add(this.SortPanel, 0, 0);
+ this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.tableLayoutPanel2.Location = new System.Drawing.Point(0, 0);
+ this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(1);
+ this.tableLayoutPanel2.Name = "tableLayoutPanel2";
+ this.tableLayoutPanel2.RowCount = 2;
+ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 29F));
+ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
+ this.tableLayoutPanel2.Size = new System.Drawing.Size(381, 413);
+ this.tableLayoutPanel2.TabIndex = 0;
+ //
+ // pnlTreeViewsContainer
+ //
+ this.pnlTreeViewsContainer.Controls.Add(this.treeViewFilterList);
+ this.pnlTreeViewsContainer.Controls.Add(this.treeViewFavoriteList);
+ this.pnlTreeViewsContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.pnlTreeViewsContainer.Location = new System.Drawing.Point(3, 32);
+ this.pnlTreeViewsContainer.Name = "pnlTreeViewsContainer";
+ this.pnlTreeViewsContainer.Size = new System.Drawing.Size(375, 378);
+ this.pnlTreeViewsContainer.TabIndex = 3;
+ //
+ // treeViewFilterList
+ //
+ this.treeViewFilterList.BackColor = System.Drawing.Color.White;
+ this.treeViewFilterList.BorderStyle = System.Windows.Forms.BorderStyle.None;
+ this.treeViewFilterList.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.treeViewFilterList.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(162)));
+ this.treeViewFilterList.FullRowSelect = true;
+ this.treeViewFilterList.HideSelection = false;
+ this.treeViewFilterList.Indent = 20;
+ this.treeViewFilterList.ItemHeight = 20;
+ this.treeViewFilterList.Location = new System.Drawing.Point(0, 0);
+ this.treeViewFilterList.Name = "treeViewFilterList";
+ this.treeViewFilterList.ShowLines = false;
+ this.treeViewFilterList.ShowPlusMinus = false;
+ this.treeViewFilterList.ShowRootLines = false;
+ this.treeViewFilterList.Size = new System.Drawing.Size(375, 378);
+ this.treeViewFilterList.TabIndex = 5;
+ this.treeViewFilterList.Visible = false;
+ this.treeViewFilterList.NodeMouseDoubleClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.treeView1_NodeMouseDoubleClick);
+ this.treeViewFilterList.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.treeView1_NodeMouseClick);
+ //
+ // treeViewFavoriteList
+ //
+ this.treeViewFavoriteList.AllowDrop = true;
+ this.treeViewFavoriteList.BackColor = System.Drawing.Color.White;
+ this.treeViewFavoriteList.BorderStyle = System.Windows.Forms.BorderStyle.None;
+ this.treeViewFavoriteList.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.treeViewFavoriteList.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(162)));
+ this.treeViewFavoriteList.FullRowSelect = true;
+ this.treeViewFavoriteList.HideSelection = false;
+ this.treeViewFavoriteList.ImageIndex = 0;
+ this.treeViewFavoriteList.ImageList = this.ImageList1;
+ this.treeViewFavoriteList.Indent = 15;
+ this.treeViewFavoriteList.ItemHeight = 20;
+ this.treeViewFavoriteList.Location = new System.Drawing.Point(0, 0);
+ this.treeViewFavoriteList.Name = "treeViewFavoriteList";
+ this.treeViewFavoriteList.SelectedImageIndex = 0;
+ this.treeViewFavoriteList.ShowLines = false;
+ this.treeViewFavoriteList.ShowPlusMinus = false;
+ this.treeViewFavoriteList.ShowRootLines = false;
+ this.treeViewFavoriteList.Size = new System.Drawing.Size(375, 378);
+ this.treeViewFavoriteList.TabIndex = 4;
+ this.treeViewFavoriteList.NodeMouseDoubleClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.treeView1_NodeMouseDoubleClick);
+ this.treeViewFavoriteList.DragDrop += new System.Windows.Forms.DragEventHandler(this.treeViewFavoriteList_DragDrop);
+ this.treeViewFavoriteList.DragEnter += new System.Windows.Forms.DragEventHandler(this.treeViewFavoriteList_DragEnter);
+ this.treeViewFavoriteList.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.treeView1_NodeMouseClick);
+ this.treeViewFavoriteList.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.treeViewFavoriteList_ItemDrag);
+ this.treeViewFavoriteList.DragOver += new System.Windows.Forms.DragEventHandler(this.treeViewFavoriteList_DragOver);
+ //
+ // SortPanel
+ //
+ this.SortPanel.BackColor = System.Drawing.Color.White;
+ this.SortPanel.Controls.Add(this.txtSearch);
+ this.SortPanel.Controls.Add(this.btnAddNew);
+ this.SortPanel.Controls.Add(this.btnSortBy);
+ this.SortPanel.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.SortPanel.Location = new System.Drawing.Point(1, 1);
+ this.SortPanel.Margin = new System.Windows.Forms.Padding(1);
+ this.SortPanel.Name = "SortPanel";
+ this.SortPanel.Size = new System.Drawing.Size(379, 27);
+ this.SortPanel.TabIndex = 2;
+ //
+ // txtSearch
+ //
+ this.txtSearch.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.txtSearch.ForeColor = System.Drawing.SystemColors.ScrollBar;
+ this.txtSearch.Location = new System.Drawing.Point(6, 4);
+ this.txtSearch.Name = "txtSearch";
+ this.txtSearch.Size = new System.Drawing.Size(279, 21);
+ this.txtSearch.TabIndex = 9;
+ this.txtSearch.Text = "Search contacts";
+ this.txtSearch.TextChanged += new System.EventHandler(this.txtSearch_TextChanged);
+ this.txtSearch.Leave += new System.EventHandler(this.txtSearch_Leave);
+ this.txtSearch.Enter += new System.EventHandler(this.txtSearch_Enter);
+ //
+ // btnAddNew
+ //
+ this.btnAddNew.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.btnAddNew.BackColor = System.Drawing.SystemColors.Control;
+ this.btnAddNew.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(162)));
+ this.btnAddNew.Location = new System.Drawing.Point(334, 2);
+ this.btnAddNew.Name = "btnAddNew";
+ this.btnAddNew.Size = new System.Drawing.Size(44, 22);
+ this.btnAddNew.TabIndex = 7;
+ this.btnAddNew.Text = "+";
+ this.btnAddNew.UseVisualStyleBackColor = true;
+ this.btnAddNew.Click += new System.EventHandler(this.btnAddNew_Click);
+ //
+ // btnSortBy
+ //
+ this.btnSortBy.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.btnSortBy.BackColor = System.Drawing.SystemColors.Control;
+ this.btnSortBy.Cursor = System.Windows.Forms.Cursors.Arrow;
+ this.btnSortBy.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(162)));
+ this.btnSortBy.Location = new System.Drawing.Point(290, 2);
+ this.btnSortBy.Name = "btnSortBy";
+ this.btnSortBy.Size = new System.Drawing.Size(44, 22);
+ this.btnSortBy.TabIndex = 0;
+ this.btnSortBy.Text = "sort";
+ this.btnSortBy.UseVisualStyleBackColor = true;
+ this.btnSortBy.Click += new System.EventHandler(this.btnSortBy_Click);
+ //
+ // tableLayoutPanel3
+ //
+ this.tableLayoutPanel3.BackColor = System.Drawing.Color.White;
+ this.tableLayoutPanel3.BackgroundImage = global::MSNPSharpClient.Properties.Resources.app_banner;
+ this.tableLayoutPanel3.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
+ this.tableLayoutPanel3.ColumnCount = 2;
+ this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 380F));
+ this.tableLayoutPanel3.Controls.Add(this.tableLayoutPanel4, 1, 0);
+ this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.tableLayoutPanel3.Location = new System.Drawing.Point(3, 3);
+ this.tableLayoutPanel3.Name = "tableLayoutPanel3";
+ this.tableLayoutPanel3.RowCount = 1;
+ this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel3.Size = new System.Drawing.Size(637, 122);
+ this.tableLayoutPanel3.TabIndex = 9;
+ //
+ // tableLayoutPanel4
+ //
+ this.tableLayoutPanel4.ColumnCount = 1;
+ this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel4.Controls.Add(this.tableLayoutPanel5, 0, 0);
+ this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.tableLayoutPanel4.Location = new System.Drawing.Point(260, 3);
+ this.tableLayoutPanel4.Name = "tableLayoutPanel4";
+ this.tableLayoutPanel4.RowCount = 1;
+ this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 126F));
+ this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 126F));
+ this.tableLayoutPanel4.Size = new System.Drawing.Size(374, 116);
+ this.tableLayoutPanel4.TabIndex = 0;
+ //
+ // tableLayoutPanel5
+ //
+ this.tableLayoutPanel5.ColumnCount = 2;
+ this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 87F));
+ this.tableLayoutPanel5.Controls.Add(this.displayImageBox, 1, 0);
+ this.tableLayoutPanel5.Controls.Add(this.panel1, 0, 0);
+ this.tableLayoutPanel5.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.tableLayoutPanel5.Location = new System.Drawing.Point(3, 3);
+ this.tableLayoutPanel5.Name = "tableLayoutPanel5";
+ this.tableLayoutPanel5.RowCount = 1;
+ this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 120F));
+ this.tableLayoutPanel5.Size = new System.Drawing.Size(368, 120);
+ this.tableLayoutPanel5.TabIndex = 0;
+ //
+ // displayImageBox
+ //
+ this.displayImageBox.BackColor = System.Drawing.Color.White;
+ this.displayImageBox.Cursor = System.Windows.Forms.Cursors.Hand;
+ this.displayImageBox.Location = new System.Drawing.Point(284, 3);
+ this.displayImageBox.Name = "displayImageBox";
+ this.displayImageBox.Size = new System.Drawing.Size(80, 80);
+ this.displayImageBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
+ this.displayImageBox.TabIndex = 3;
+ this.displayImageBox.TabStop = false;
+ this.displayImageBox.Click += new System.EventHandler(this.displayImageBox_Click);
+ //
+ // panel1
+ //
+ this.panel1.Controls.Add(this.tableLayoutPanel6);
+ this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.panel1.Location = new System.Drawing.Point(3, 3);
+ this.panel1.Name = "panel1";
+ this.panel1.Size = new System.Drawing.Size(275, 114);
+ this.panel1.TabIndex = 4;
+ //
+ // tableLayoutPanel6
+ //
+ this.tableLayoutPanel6.ColumnCount = 1;
+ this.tableLayoutPanel6.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel6.Controls.Add(this.pnlLogin, 0, 0);
+ this.tableLayoutPanel6.Controls.Add(this.tableLayoutPanel7, 0, 1);
+ this.tableLayoutPanel6.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.tableLayoutPanel6.Location = new System.Drawing.Point(0, 0);
+ this.tableLayoutPanel6.Name = "tableLayoutPanel6";
+ this.tableLayoutPanel6.RowCount = 2;
+ this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 35F));
+ this.tableLayoutPanel6.Size = new System.Drawing.Size(275, 114);
+ this.tableLayoutPanel6.TabIndex = 5;
+ //
+ // pnlLogin
+ //
+ this.pnlLogin.Controls.Add(this.pnlNameAndPM);
+ this.pnlLogin.Controls.Add(this.cbRobotMode);
+ this.pnlLogin.Controls.Add(this.accountTextBox);
+ this.pnlLogin.Controls.Add(this.loginButton);
+ this.pnlLogin.Controls.Add(this.passwordTextBox);
+ this.pnlLogin.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.pnlLogin.Location = new System.Drawing.Point(3, 3);
+ this.pnlLogin.Name = "pnlLogin";
+ this.pnlLogin.Size = new System.Drawing.Size(269, 73);
+ this.pnlLogin.TabIndex = 1;
+ //
+ // pnlNameAndPM
+ //
+ this.pnlNameAndPM.Controls.Add(this.btnSetMusic);
+ this.pnlNameAndPM.Controls.Add(this.lblPM);
+ this.pnlNameAndPM.Controls.Add(this.lblName);
+ this.pnlNameAndPM.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.pnlNameAndPM.Location = new System.Drawing.Point(0, 0);
+ this.pnlNameAndPM.Name = "pnlNameAndPM";
+ this.pnlNameAndPM.Size = new System.Drawing.Size(269, 73);
+ this.pnlNameAndPM.TabIndex = 15;
+ this.pnlNameAndPM.Visible = false;
+ //
+ // btnSetMusic
+ //
+ this.btnSetMusic.Location = new System.Drawing.Point(233, 25);
+ this.btnSetMusic.Name = "btnSetMusic";
+ this.btnSetMusic.Size = new System.Drawing.Size(33, 22);
+ this.btnSetMusic.TabIndex = 8;
+ this.btnSetMusic.Tag = "0";
+ this.btnSetMusic.Text = "M";
+ this.btnSetMusic.UseVisualStyleBackColor = true;
+ this.btnSetMusic.Click += new System.EventHandler(this.btnSetMusic_Click);
+ //
+ // lblPM
+ //
+ this.lblPM.Location = new System.Drawing.Point(3, 26);
+ this.lblPM.Name = "lblPM";
+ this.lblPM.Size = new System.Drawing.Size(228, 21);
+ this.lblPM.TabIndex = 7;
+ this.lblPM.Leave += new System.EventHandler(this.lblName_Leave);
+ //
+ // lblName
+ //
+ this.lblName.Location = new System.Drawing.Point(3, 1);
+ this.lblName.Name = "lblName";
+ this.lblName.Size = new System.Drawing.Size(263, 21);
+ this.lblName.TabIndex = 6;
+ this.lblName.Leave += new System.EventHandler(this.lblName_Leave);
+ //
+ // cbRobotMode
+ //
+ this.cbRobotMode.AutoSize = true;
+ this.cbRobotMode.Location = new System.Drawing.Point(3, 54);
+ this.cbRobotMode.Name = "cbRobotMode";
+ this.cbRobotMode.Size = new System.Drawing.Size(136, 19);
+ this.cbRobotMode.TabIndex = 11;
+ this.cbRobotMode.Text = "Provisioned Account";
+ this.cbRobotMode.UseVisualStyleBackColor = true;
+ this.cbRobotMode.CheckedChanged += new System.EventHandler(this.cbRobotMode_CheckedChanged);
+ //
+ // accountTextBox
+ //
+ this.accountTextBox.Location = new System.Drawing.Point(3, 2);
+ this.accountTextBox.Name = "accountTextBox";
+ this.accountTextBox.Size = new System.Drawing.Size(263, 21);
+ this.accountTextBox.TabIndex = 9;
+ this.accountTextBox.Text = "example@escargot.chat";
+ this.accountTextBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.login_KeyPress);
+ //
+ // loginButton
+ //
+ this.loginButton.Location = new System.Drawing.Point(145, 50);
+ this.loginButton.Name = "loginButton";
+ this.loginButton.Size = new System.Drawing.Size(121, 22);
+ this.loginButton.TabIndex = 8;
+ this.loginButton.Tag = "0";
+ this.loginButton.Text = "> Sign in";
+ this.loginButton.UseVisualStyleBackColor = true;
+ this.loginButton.Click += new System.EventHandler(this.loginButton_Click);
+ //
+ // passwordTextBox
+ //
+ this.passwordTextBox.Location = new System.Drawing.Point(3, 27);
+ this.passwordTextBox.Name = "passwordTextBox";
+ this.passwordTextBox.PasswordChar = '*';
+ this.passwordTextBox.Size = new System.Drawing.Size(263, 21);
+ this.passwordTextBox.TabIndex = 10;
+ this.passwordTextBox.Text = "sneakysource";
+ this.passwordTextBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.login_KeyPress);
+ //
+ // tableLayoutPanel7
+ //
+ this.tableLayoutPanel7.ColumnCount = 2;
+ this.tableLayoutPanel7.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
+ this.tableLayoutPanel7.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
+ this.tableLayoutPanel7.Controls.Add(this.comboPlaces, 0, 0);
+ this.tableLayoutPanel7.Controls.Add(this.comboStatus, 0, 0);
+ this.tableLayoutPanel7.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.tableLayoutPanel7.Location = new System.Drawing.Point(3, 82);
+ this.tableLayoutPanel7.Name = "tableLayoutPanel7";
+ this.tableLayoutPanel7.RowCount = 1;
+ this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
+ this.tableLayoutPanel7.Size = new System.Drawing.Size(269, 29);
+ this.tableLayoutPanel7.TabIndex = 0;
+ //
+ // comboPlaces
+ //
+ this.comboPlaces.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.comboPlaces.DropDownWidth = 220;
+ this.comboPlaces.FormattingEnabled = true;
+ this.comboPlaces.Location = new System.Drawing.Point(137, 3);
+ this.comboPlaces.Name = "comboPlaces";
+ this.comboPlaces.Size = new System.Drawing.Size(129, 23);
+ this.comboPlaces.TabIndex = 6;
+ this.comboPlaces.Visible = false;
+ this.comboPlaces.SelectedIndexChanged += new System.EventHandler(this.comboPlaces_SelectedIndexChanged);
+ //
+ // comboStatus
+ //
+ this.comboStatus.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
+ this.comboStatus.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.comboStatus.FormattingEnabled = true;
+ this.comboStatus.ItemHeight = 15;
+ this.comboStatus.Items.AddRange(new object[] {
+ "Online",
+ "Busy",
+ "Away",
+ "Hidden",
+ "Offline"});
+ this.comboStatus.Location = new System.Drawing.Point(3, 3);
+ this.comboStatus.Name = "comboStatus";
+ this.comboStatus.Size = new System.Drawing.Size(128, 21);
+ this.comboStatus.TabIndex = 5;
+ this.comboStatus.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.comboStatus_DrawItem);
+ this.comboStatus.SelectedIndexChanged += new System.EventHandler(this.comboStatus_SelectedIndexChanged);
+ this.comboStatus.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.comboStatus_KeyPress);
+ //
+ // statusBar
+ //
+ this.statusBar.AutoSize = true;
+ this.statusBar.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.statusBar.Location = new System.Drawing.Point(3, 604);
+ this.statusBar.Name = "statusBar";
+ this.statusBar.Size = new System.Drawing.Size(637, 30);
+ this.statusBar.TabIndex = 10;
+ this.statusBar.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // ClientForm
+ //
+ this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
+ this.BackColor = System.Drawing.Color.White;
+ this.ClientSize = new System.Drawing.Size(643, 634);
+ this.Controls.Add(this.tableLayoutPanel1);
+ this.Font = new System.Drawing.Font("Arial", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.MinimumSize = new System.Drawing.Size(640, 480);
+ this.Name = "ClientForm";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+ this.Text = "MSNPSharp Example Client for Escargot";
+ this.Load += new System.EventHandler(this.ClientForm_Load);
+ this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.ClientForm_FormClosing);
+ this.userMenuStrip.ResumeLayout(false);
+ this.sortContextMenu.ResumeLayout(false);
+ this.groupContextMenu.ResumeLayout(false);
+ this.tableLayoutPanel1.ResumeLayout(false);
+ this.tableLayoutPanel1.PerformLayout();
+ this.WhatsUpPanel.ResumeLayout(false);
+ this.WhatsUpPanel.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.pbNewsPicture)).EndInit();
+ this.splitContainer1.Panel1.ResumeLayout(false);
+ this.splitContainer1.Panel2.ResumeLayout(false);
+ this.splitContainer1.ResumeLayout(false);
+ this.tableLayoutPanel2.ResumeLayout(false);
+ this.pnlTreeViewsContainer.ResumeLayout(false);
+ this.SortPanel.ResumeLayout(false);
+ this.SortPanel.PerformLayout();
+ this.tableLayoutPanel3.ResumeLayout(false);
+ this.tableLayoutPanel4.ResumeLayout(false);
+ this.tableLayoutPanel5.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.displayImageBox)).EndInit();
+ this.panel1.ResumeLayout(false);
+ this.tableLayoutPanel6.ResumeLayout(false);
+ this.pnlLogin.ResumeLayout(false);
+ this.pnlLogin.PerformLayout();
+ this.pnlNameAndPM.ResumeLayout(false);
+ this.pnlNameAndPM.PerformLayout();
+ this.tableLayoutPanel7.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private OpenFileDialog openFileDialog;
+ private OpenFileDialog openImageDialog;
+ private System.Windows.Forms.Timer tmrKeepOnLine;
+ private System.Windows.Forms.Timer tmrNews;
+ private ImageList ImageList1;
+ private ContextMenuStrip userMenuStrip;
+ private ToolStripMenuItem sendIMMenuItem;
+ private ToolStripMenuItem blockMenuItem;
+ private ToolStripSeparator toolStripMenuItem2;
+ private ToolStripMenuItem unblockMenuItem;
+ private ToolStripMenuItem sendOIMMenuItem;
+ private ToolStripSeparator toolStripMenuItem3;
+ private ToolStripMenuItem sendMIMMenuItem;
+ private ContextMenuStrip sortContextMenu;
+ private ToolStripMenuItem toolStripSortByStatus;
+ private ToolStripMenuItem toolStripSortBygroup;
+ private ToolStripMenuItem toolStripDeleteGroup;
+ private ContextMenuStrip groupContextMenu;
+ private ToolStripMenuItem importContactsMenuItem;
+ private ToolStripMenuItem createCircleMenuItem;
+ private ToolStripMenuItem deleteMenuItem;
+ private ToolTip toolTipChangePhoto;
+ private TableLayoutPanel tableLayoutPanel1;
+ private Panel WhatsUpPanel;
+ private LinkLabel lblNewsLink;
+ private Label lblNews;
+ private PictureBox pbNewsPicture;
+ private Button cmdNext;
+ private Button cmdPrev;
+ private Label lblWhatsup;
+ private SplitContainer splitContainer1;
+ private PropertyGrid propertyGrid;
+ private TableLayoutPanel tableLayoutPanel2;
+ private Panel SortPanel;
+ private TextBox txtSearch;
+ private Button btnAddNew;
+ private Button btnSortBy;
+ private TableLayoutPanel tableLayoutPanel3;
+ private Panel pnlTreeViewsContainer;
+ private TreeView treeViewFavoriteList;
+ private Label statusBar;
+ private TreeView treeViewFilterList;
+ private TableLayoutPanel tableLayoutPanel4;
+ private TableLayoutPanel tableLayoutPanel5;
+ private Panel panel1;
+ private TableLayoutPanel tableLayoutPanel6;
+ private Panel pnlLogin;
+ private Panel pnlNameAndPM;
+ private Button btnSetMusic;
+ private TextBox lblPM;
+ private TextBox lblName;
+ private CheckBox cbRobotMode;
+ private TextBox accountTextBox;
+ private Button loginButton;
+ private TextBox passwordTextBox;
+ private TableLayoutPanel tableLayoutPanel7;
+ private ComboBox comboPlaces;
+ private ComboBox comboStatus;
+ private PictureBox displayImageBox;
+
+ }
+}
diff --git a/Example/DotMSNClient.cs b/Example/DotMSNClient.cs
new file mode 100644
index 0000000..f1299ee
--- /dev/null
+++ b/Example/DotMSNClient.cs
@@ -0,0 +1,2343 @@
+using System;
+using System.IO;
+using System.Data;
+using System.Drawing;
+using System.Collections;
+using System.Diagnostics;
+using System.Windows.Forms;
+using System.ComponentModel;
+using System.Collections.Generic;
+using System.Threading;
+using System.Xml;
+
+namespace MSNPSharpClient
+{
+ using MSNPSharp;
+ using MSNPSharp.Core;
+ using MSNPSharp.DataTransfer;
+ using MSNPSharp.MSNWS.MSNABSharingService;
+ using MSNPSharp.Utilities;
+
+ ///
+ /// MSNPSharp Client example.
+ ///
+ public partial class ClientForm : System.Windows.Forms.Form
+ {
+ // Create a Messenger object to use MSNPSharp.
+ private Messenger messenger = new Messenger();
+ private List convforms = new List(0);
+ private TraceForm traceform = new TraceForm();
+
+ public List ConversationForms
+ {
+ get
+ {
+ return convforms;
+ }
+ }
+
+ public Messenger Messenger
+ {
+ get
+ {
+ return messenger;
+ }
+ }
+
+ public ClientForm()
+ {
+ //
+ // Required for Windows Form Designer support
+ //
+ InitializeComponent();
+
+ this.Icon = Properties.Resources.MSNPSharp_logo_small_ico;
+
+ // You can set proxy settings here
+ // for example: messenger.ConnectivitySettings.ProxyHost = "10.0.0.2";
+
+ Settings.TraceSwitch.Level = System.Diagnostics.TraceLevel.Verbose;
+
+ //Set the p2p invitation interval in the whole invitation request queue (in ms)
+ Schedulers.P2PInvitationScheduler.DelayTime = 5000;
+ Schedulers.SwitchBoardRequestScheduler.DelayTime = 1000;
+
+ if (Settings.IsMono) //I am running on Mono.
+ {
+ // Don't enable this on mono, because mono raises NotImplementedException.
+ Settings.EnableGzipCompressionForWebServices = false;
+ }
+
+#if DEBUG
+
+ //How to save your personal addressbook.
+ //If you want your addressbook have a better reading/writting performance, use MclSerialization.None
+ //In this case, your addressbook will be save as a xml file, everyone can read it.
+ //If you want your addressbook has a smaller size, use MclSerialization.Compression.
+ //In this case, your addressbook file will be save in gzip format, none can read it, but the performance is not so good.
+ Settings.SerializationType = MSNPSharp.IO.MclSerialization.None;
+#elif TRACE
+ Settings.SerializationType = MSNPSharp.IO.MclSerialization.Compression | MSNPSharp.IO.MclSerialization.Cryptography;
+#endif
+
+ // The following line is very IMPOTANT.
+ // Keep the messenger sending PNG to the server in a proper frequency, or it will be kicked offline.
+ this.tmrKeepOnLine.Tick += new EventHandler(tmrKeepOnLine_Tick);
+
+ // If you want to use it in an environment that does not have write permission, set NoSave to true.
+ //Settings.NoSave = true;
+
+ // set the events that we will handle
+ // remember that the nameserver is the server that sends contact lists, notifies you of contact status changes, etc.
+ // a switchboard server handles the individual conversation sessions.
+ messenger.NameserverProcessor.ConnectionEstablished += new EventHandler(NameserverProcessor_ConnectionEstablished);
+ messenger.Nameserver.SignedIn += new EventHandler(Nameserver_SignedIn);
+ messenger.Nameserver.SignedOff += new EventHandler(Nameserver_SignedOff);
+ messenger.NameserverProcessor.ConnectingException += new EventHandler(NameserverProcessor_ConnectingException);
+ messenger.Nameserver.ExceptionOccurred += new EventHandler(Nameserver_ExceptionOccurred);
+ messenger.Nameserver.AuthenticationError += new EventHandler(Nameserver_AuthenticationError);
+ messenger.Nameserver.ServerErrorReceived += new EventHandler(Nameserver_ServerErrorReceived);
+
+ // Receive messages send by MSN contacts.
+ messenger.MessageManager.MessageArrived += new EventHandler(MessageManager_MessageArrived);
+
+ // Listen for the data transfer events (i.e. file transfer invitation, activity invitation)
+ messenger.TransferInvitationReceived += new EventHandler(messenger_TransferInvitationReceived);
+
+ // Listen to ping answer event. In each ping answer, MSN will give you a number. That is the interval to send the next Ping.
+ // You can send a Ping by using Messenger.Nameserver.SendPing().
+ messenger.Nameserver.PingAnswer += new EventHandler(Nameserver_PingAnswer);
+
+ messenger.Nameserver.OwnerVerified += new EventHandler(Nameserver_OwnerVerified);
+ messenger.Nameserver.ContactOnline += new EventHandler(Nameserver_ContactOnline);
+ messenger.Nameserver.ContactOffline += new EventHandler(Nameserver_ContactOffline);
+
+
+ // SynchronizationCompleted will fired after the updated operation for your contact list has completed.
+ messenger.ContactService.SynchronizationCompleted += new EventHandler(ContactService_SynchronizationCompleted);
+ // ReverseAdded will fired after a contact adds you to his/her contact list.
+ messenger.ContactService.ReverseAdded += new EventHandler(Nameserver_ReverseAdded);
+
+ messenger.ContactService.ReverseRemoved += new EventHandler(ContactService_ReverseRemoved);
+ // ContactAdded will fired after a contact added to any role list.
+ messenger.ContactService.ContactAdded += new EventHandler(ContactService_ContactAdded);
+ // ContactRemoved will fired after a contact removed from any role list.
+ messenger.ContactService.ContactRemoved += new EventHandler(ContactService_ContactRemoved);
+
+ #region Circle events
+
+ // These are circle events. They will be fired after corresponding circle operation completed.
+ messenger.ContactService.CreateCircleCompleted += new EventHandler(ContactService_CircleCreated);
+ messenger.ContactService.JoinedCircleCompleted += new EventHandler(ContactService_JoinedCircle);
+ messenger.ContactService.JoinCircleInvitationReceived += new EventHandler(ContactService_JoinCircleInvitationReceived);
+ messenger.ContactService.ExitCircleCompleted += new EventHandler(ContactService_ExitCircle);
+ messenger.ContactService.CircleMemberJoined += new EventHandler(ContactService_CircleMemberJoined);
+ messenger.ContactService.CircleMemberLeft += new EventHandler(ContactService_CircleMemberLeft);
+ messenger.Nameserver.CircleOnline += new EventHandler(Nameserver_CircleOnline);
+ messenger.Nameserver.CircleOffline += new EventHandler(Nameserver_CircleOffline);
+ messenger.Nameserver.CircleMemberOnline += new EventHandler(Nameserver_CircleMemberOnline);
+ messenger.Nameserver.CircleMemberOffline += new EventHandler(Nameserver_CircleMemberOffline);
+ messenger.Nameserver.LeftCircleConversation += new EventHandler(Nameserver_CircleMemberLeftConversation);
+ messenger.Nameserver.JoinedCircleConversation += new EventHandler(Nameserver_CircleMemberJoinedConversation);
+ messenger.Nameserver.CircleTextMessageReceived += new EventHandler(Nameserver_CircleTextMessageReceived);
+ messenger.Nameserver.CircleNudgeReceived += new EventHandler(Nameserver_CircleNudgeReceived);
+
+ #endregion
+
+
+ #region Offline Message Operation events
+
+ // OIMReceived will be triggered after receved an Offline Message.
+ messenger.OIMService.OIMReceived += new EventHandler(Nameserver_OIMReceived);
+
+ // Triggered after the send operation for an Offline Message has been completed.
+ // If the operation failed, there will contains an error in the event args.
+ messenger.OIMService.OIMSendCompleted += new EventHandler(OIMService_OIMSendCompleted);
+
+ #endregion
+
+
+ messenger.WhatsUpService.GetWhatsUpCompleted += new EventHandler(WhatsUpService_GetWhatsUpCompleted);
+
+ #region Webservice Error handler
+
+ // Handle Service Operation Errors
+ //In most cases, these error are not so important.
+ messenger.ContactService.ServiceOperationFailed += new EventHandler(ServiceOperationFailed);
+ messenger.OIMService.ServiceOperationFailed += new EventHandler(ServiceOperationFailed);
+ messenger.StorageService.ServiceOperationFailed += new EventHandler(ServiceOperationFailed);
+ messenger.WhatsUpService.ServiceOperationFailed += new EventHandler(ServiceOperationFailed);
+
+ #endregion
+ }
+
+ public static class ImageIndexes
+ {
+ public const int Closed = 0;
+ public const int Open = 1;
+ public const int Circle = 2;
+
+ public const int Online = 3;
+ public const int Busy = 4;
+ public const int Away = 5;
+ public const int Idle = 6;
+ public const int Hidden = 7;
+ public const int Offline = 8;
+
+ // Show always (0/0)
+ public const string FavoritesNodeKey = "__10F";
+ public const string CircleNodeKey = "__20C";
+ // Sort by status (0)
+ public const string MobileNodeKey = "__30M";
+ public const string OnlineNodeKey = "__32N";
+ public const string OfflineNodeKey = "__34F";
+ // Sort by categories (0/0)
+ public const string NoGroupNodeKey = "ZZZZZ";
+
+ public static int GetStatusIndex(PresenceStatus status)
+ {
+ switch (status)
+ {
+ case PresenceStatus.Online:
+ return Online;
+
+ case PresenceStatus.Busy:
+ case PresenceStatus.Phone:
+ return Busy;
+
+ case PresenceStatus.BRB:
+ case PresenceStatus.Away:
+ case PresenceStatus.Lunch:
+ return Away;
+
+ case PresenceStatus.Idle:
+ return Idle;
+ case PresenceStatus.Hidden:
+ return Hidden;
+
+ case PresenceStatus.Offline:
+ return Offline;
+
+ default:
+ return Offline;
+ }
+ }
+ }
+
+ private void ClientForm_Load(object sender, EventArgs e)
+ {
+ ImageList1.Images.Add(MSNPSharpClient.Properties.Resources.closed);
+ ImageList1.Images.Add(MSNPSharpClient.Properties.Resources.open);
+ ImageList1.Images.Add(MSNPSharpClient.Properties.Resources.circle);
+
+ ImageList1.Images.Add(MSNPSharpClient.Properties.Resources.online);
+ ImageList1.Images.Add(MSNPSharpClient.Properties.Resources.busy);
+ ImageList1.Images.Add(MSNPSharpClient.Properties.Resources.away);
+ ImageList1.Images.Add(MSNPSharpClient.Properties.Resources.idle);
+ ImageList1.Images.Add(MSNPSharpClient.Properties.Resources.hidden);
+ ImageList1.Images.Add(MSNPSharpClient.Properties.Resources.offline);
+
+ Version dllVersion = messenger.GetType().Assembly.GetName().Version;
+ Text += " (v" + dllVersion.Major + "." + dllVersion.Minor + "." + dllVersion.Build + " r" + dllVersion.Revision + ")";
+ treeViewFavoriteList.TreeViewNodeSorter = StatusSorter.Default;
+
+ comboStatus.SelectedIndex = 0;
+
+ if (toolStripSortByStatus.Checked)
+ SortByStatus(null);
+ else
+ SortByGroup(null);
+
+ // ******* Listen traces *****
+ traceform.Show();
+ }
+
+
+ private void ClientForm_FormClosing(object sender, FormClosingEventArgs e)
+ {
+ if (Messenger.Connected)
+ {
+ Messenger.Nameserver.SignedOff -= Nameserver_SignedOff;
+
+ ResetAll();
+ Messenger.Disconnect();
+ }
+
+ traceform.Close();
+ }
+
+ void Nameserver_CircleMemberOffline(object sender, CircleMemberEventArgs e)
+ {
+ RefreshCircleList(sender, e);
+ }
+
+ void Nameserver_CircleMemberOnline(object sender, CircleMemberEventArgs e)
+ {
+ RefreshCircleList(sender, e);
+ }
+
+ void Nameserver_CircleNudgeReceived(object sender, CircleMemberEventArgs e)
+ {
+ Trace.WriteLine("Circle " + e.Circle.ToString() + ": Member: " + e.Member.ToString() + " send you a nudge.");
+ AutoGroupMessageReply(e.Circle);
+ }
+
+ private void AutoGroupMessageReply(Circle circle)
+ {
+ if (Messenger.ContactList.Owner.Status != PresenceStatus.Hidden || Messenger.ContactList.Owner.Status != PresenceStatus.Offline)
+ circle.SendMessage(new TextMessage("MSNPSharp example client auto reply."));
+ }
+
+ void Nameserver_CircleTextMessageReceived(object sender, CircleTextMessageEventArgs e)
+ {
+ Trace.WriteLine("Circle " + e.Sender.ToString() + ": Member: " + e.TriggerMember.ToString() + " send you a message :" + e.Message.ToString());
+ AutoGroupMessageReply(e.Sender);
+ }
+
+ void Nameserver_CircleMemberJoinedConversation(object sender, CircleMemberEventArgs e)
+ {
+ Trace.WriteLine("Circle member " + e.Member.ToString() + " joined the circle conversation: " + e.Circle.ToString());
+ }
+
+ void Nameserver_CircleMemberLeftConversation(object sender, CircleMemberEventArgs e)
+ {
+ Trace.WriteLine("Circle member " + e.Member.ToString() + " has left the circle: " + e.Circle.ToString());
+ }
+
+ void Nameserver_CircleOnline(object sender, CircleEventArgs e)
+ {
+ Trace.WriteLine("Circle go online: " + e.Circle.ToString());
+ RefreshCircleList(sender, e);
+ }
+
+ void Nameserver_CircleOffline(object sender, CircleEventArgs e)
+ {
+ Trace.WriteLine("Circle go offline: " + e.Circle.ToString());
+ RefreshCircleList(sender, e);
+ }
+
+ void ContactService_ExitCircle(object sender, CircleEventArgs e)
+ {
+ RefreshCircleList(sender, e);
+ }
+
+ void ContactService_JoinedCircle(object sender, CircleEventArgs e)
+ {
+ RefreshCircleList(sender, e);
+ messenger.ContactService.ExitCircle(e.Circle); //Demostrate how to leave a circle.
+ }
+
+
+ void ContactService_CircleMemberLeft(object sender, CircleMemberEventArgs e)
+ {
+ RefreshCircleList(sender, null);
+ }
+
+ void ContactService_CircleMemberJoined(object sender, CircleMemberEventArgs e)
+ {
+ RefreshCircleList(sender, null);
+ }
+
+ void ContactService_JoinCircleInvitationReceived(object sender, CircleEventArgs e)
+ {
+ messenger.ContactService.AcceptCircleInvitation(e.Circle);
+ }
+
+ void ContactService_CircleCreated(object sender, CircleEventArgs e)
+ {
+ RefreshCircleList(sender, e);
+ }
+
+ void RefreshCircleList(object sender, EventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ BeginInvoke(new EventHandler(RefreshCircleList), new object[] { sender, e });
+ return;
+ }
+
+ Contact circle = null;
+
+ if (e is CircleMemberEventArgs)
+ circle = (e as CircleMemberEventArgs).Circle;
+ else if (e is CircleEventArgs)
+ circle = (e as CircleEventArgs).Circle;
+
+ if (toolStripSortByStatus.Checked)
+ {
+ SortByStatus(circle);
+ }
+ else
+ {
+ SortByGroup(circle);
+ }
+ }
+
+ void ServiceOperationFailed(object sender, ServiceOperationFailedEventArgs e)
+ {
+ Trace.WriteLineIf(Settings.TraceSwitch.TraceError, e.Method + ": " + e.Exception.ToString(), sender.GetType().Name);
+ }
+
+ void ContactService_SynchronizationCompleted(object sender, EventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new EventHandler(ContactService_SynchronizationCompleted), sender, e);
+ return;
+ }
+
+ lblNews.Text = "Getting your friends' news...";
+ messenger.WhatsUpService.GetWhatsUp(200);
+ }
+
+ List activities = new List();
+ void WhatsUpService_GetWhatsUpCompleted(object sender, GetWhatsUpCompletedEventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ BeginInvoke(new EventHandler(WhatsUpService_GetWhatsUpCompleted), new object[] { sender, e });
+ return;
+ }
+
+ if (e.Error != null)
+ {
+ lblNews.Text = "ERROR: " + e.Error.ToString();
+ }
+ else
+ {
+ activities.Clear();
+
+ foreach (ActivityDetailsType activityDetails in e.Response.Activities)
+ {
+ // Show status news
+ if (activityDetails.ApplicationId == "6262816084389410")
+ {
+ activities.Add(activityDetails);
+ }
+
+ Contact c = messenger.ContactList.GetContactByCID(long.Parse(activityDetails.OwnerCID));
+
+ if (c != null)
+ {
+ c.Activities.Add(activityDetails);
+ }
+ }
+
+ if (activities.Count == 0)
+ {
+ lblNews.Text = "No news";
+ return;
+ }
+
+ lblNewsLink.Text = "Get Feeds";
+ lblNewsLink.Tag = e.Response.FeedUrl;
+ tmrNews.Enabled = true;
+ }
+ }
+
+ private int currentActivity = 0;
+ private bool activityForward = true;
+ private void tmrNews_Tick(object sender, EventArgs e)
+ {
+ if (currentActivity >= activities.Count || currentActivity < 0)
+ {
+ currentActivity = 0;
+ }
+
+ ActivityDetailsType activitiy = activities[currentActivity];
+ if (activitiy.ApplicationId == "6262816084389410")
+ {
+ string name = string.Empty;
+ string status = string.Empty;
+
+ foreach (TemplateVariableBaseType t in activitiy.TemplateVariables)
+ {
+ if (t is PublisherIdTemplateVariable)
+ {
+ name = ((PublisherIdTemplateVariable)t).NameHint;
+ }
+ else if (t is TextTemplateVariable)
+ {
+ status = ((TextTemplateVariable)t).Value;
+ }
+ }
+
+ lblNews.Text = name + ": " + status;
+
+ Contact c = messenger.ContactList.GetContactByCID(long.Parse(activitiy.OwnerCID));
+
+ if (c != null)
+ {
+ if (c.DisplayImage != null && c.DisplayImage.Image != null)
+ {
+ pbNewsPicture.Image = c.DisplayImage.Image;
+ }
+ else if (c.UserTileURL != null)
+ {
+ pbNewsPicture.LoadAsync(c.UserTileURL.AbsoluteUri);
+ }
+ else
+ {
+ pbNewsPicture.Image = null;
+ }
+ }
+ }
+ if (activityForward)
+ currentActivity++;
+ else
+ currentActivity--;
+ }
+
+ private void cmdPrev_Click(object sender, EventArgs e)
+ {
+ if (activities.Count > 0)
+ {
+ activityForward = false;
+
+ if (currentActivity > 0)
+ currentActivity--;
+ else
+ currentActivity = activities.Count - 1;
+
+ if (tmrNews.Enabled)
+ tmrNews_Tick(this, EventArgs.Empty);
+ }
+ }
+
+ private void cmdNext_Click(object sender, EventArgs e)
+ {
+ if (activities.Count > 0)
+ {
+ activityForward = true;
+
+ if (currentActivity < activities.Count)
+ currentActivity++;
+
+ if (tmrNews.Enabled)
+ tmrNews_Tick(this, EventArgs.Empty);
+ }
+ }
+
+ private void lblNewsLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
+ {
+ if (lblNewsLink.Tag != null)
+ {
+ Process.Start(lblNewsLink.Tag.ToString());
+ }
+ }
+
+ void Owner_PersonalMessageChanged(object sender, EventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ BeginInvoke(new EventHandler(Owner_PersonalMessageChanged), new object[] { sender, e });
+ return;
+ }
+
+ lblName.Text = Messenger.ContactList.Owner.Name;
+
+ if (Messenger.ContactList.Owner.PersonalMessage != null && Messenger.ContactList.Owner.PersonalMessage.Message != null)
+ {
+ lblPM.Text = System.Web.HttpUtility.HtmlDecode(Messenger.ContactList.Owner.PersonalMessage.Message);
+ }
+ }
+
+ void Owner_DisplayImageChanged(object sender, DisplayImageChangedEventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ displayImageBox.BeginInvoke(new EventHandler(Owner_DisplayImageChanged), new object[] { sender, e });
+ return;
+ }
+
+ displayImageBox.Image = e.NewDisplayImage.Image;
+ }
+
+
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new ClientForm());
+ }
+
+ void Nameserver_OwnerVerified(object sender, EventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new EventHandler(Nameserver_OwnerVerified), sender, e);
+ return;
+ }
+
+ Messenger.ContactList.Owner.DisplayImageChanged += new EventHandler(Owner_DisplayImageChanged);
+ Messenger.ContactList.Owner.PersonalMessageChanged += new EventHandler(Owner_PersonalMessageChanged);
+ Messenger.ContactList.Owner.ScreenNameChanged += new EventHandler(Owner_PersonalMessageChanged);
+ Messenger.ContactList.Owner.PlacesChanged += new EventHandler(Owner_PlacesChanged);
+ Messenger.ContactList.Owner.StatusChanged += new EventHandler(Owner_StatusChanged);
+ }
+
+ void Nameserver_ContactOnline(object sender, ContactEventArgs e)
+ {
+ BeginInvoke(new EventHandler(ContactOnlineOffline), new object[] { sender, e });
+ }
+
+ void Nameserver_ContactOffline(object sender, ContactEventArgs e)
+ {
+ Invoke(new EventHandler(ContactOnlineOffline), new object[] { sender, e });
+ }
+
+ void ContactOnlineOffline(object sender, ContactEventArgs e)
+ {
+ if (toolStripSortByStatus.Checked)
+ SortByStatus(e.Contact);
+ else
+ SortByGroup(e.Contact);
+ }
+
+ void Nameserver_PingAnswer(object sender, PingAnswerEventArgs e)
+ {
+ nextPing = e.SecondsToWait;
+ }
+
+ void Nameserver_OIMReceived(object sender, OIMReceivedEventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new EventHandler(Nameserver_OIMReceived), sender, e);
+ return;
+ }
+
+ if (DialogResult.Yes == MessageBox.Show(
+ "OIM received at : " + e.ReceivedTime + "\r\nFrom : " + e.NickName + " (" + e.Email + ") " + ":\r\n"
+ + e.Message + "\r\n\r\n\r\nClick yes, if you want to receive this message next time you login.",
+ "Offline Message from " + e.Email, MessageBoxButtons.YesNoCancel))
+ {
+ e.IsRead = false;
+ }
+ }
+
+
+ void MessageManager_MessageArrived(object sender, MessageArrivedEventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ BeginInvoke(new EventHandler(MessageManager_MessageArrived), new object[] { sender, e });
+ return;
+ }
+ else
+ {
+ foreach (ConversationForm cform in ConversationForms)
+ {
+ if (cform.ConversationID == e.ConversationID)
+ {
+ //TODO: print message on the form.
+ cform.OnMessageReceived(sender, e);
+ return;
+ }
+ }
+
+ CreateConversationForm(e.Sender, e.ConversationID).OnMessageReceived(sender, e);
+ }
+ }
+
+ void OIMService_OIMSendCompleted(object sender, OIMSendCompletedEventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new EventHandler(OIMService_OIMSendCompleted), sender, e);
+ return;
+ }
+
+ if (e.Error != null)
+ {
+ MessageBox.Show(e.Error.Message, "OIM Send Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+ }
+
+ void ContactService_ContactRemoved(object sender, ListMutateEventArgs e)
+ {
+ Trace.WriteLine(e.Contact.Hash + " removed from the " + e.AffectedList + " role list.");
+ }
+
+ void ContactService_ContactAdded(object sender, ListMutateEventArgs e)
+ {
+ if (Messenger.Nameserver.IsSignedIn)
+ {
+ e.Contact.OnForwardList = true;
+ e.Contact.OnAllowedList = true;
+ }
+ Trace.WriteLine(e.Contact.Hash + " added to the " + e.AffectedList + " role list.");
+
+ }
+
+ void ContactService_ReverseRemoved(object sender, ContactEventArgs e)
+ {
+ Trace.WriteLine(e.Contact.Hash + " removed you their contact (forward) list.");
+ }
+
+ void Nameserver_ReverseAdded(object sender, ContactEventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new EventHandler(Nameserver_ReverseAdded), sender, e);
+ return;
+ }
+
+ Contact contact = e.Contact;
+ if (messenger.ContactList.Owner.NotifyPrivacy == NotifyPrivacy.PromptOnAdd
+ /* || messenger.Nameserver.BotMode */) //If you want your provisioned account in botmode to fire ReverseAdded event, uncomment this.
+ {
+ // Show pending window if it is necessary.
+ if (contact.OnPendingList ||
+ (contact.OnReverseList && !contact.OnAllowedList && !contact.OnBlockedList))
+ {
+ ReverseAddedForm form = new ReverseAddedForm(contact);
+ form.FormClosed += delegate(object f, FormClosedEventArgs fce)
+ {
+ form = f as ReverseAddedForm;
+ if (DialogResult.OK == form.DialogResult)
+ {
+ if (form.AddToContactList)
+ {
+ messenger.ContactService.AddNewContact(contact.Mail);
+ System.Threading.Thread.Sleep(200);
+
+ if (form.Blocked)
+ {
+ contact.Blocked = true;
+ }
+ }
+ else if (form.Blocked)
+ {
+ contact.Blocked = true;
+ }
+ else
+ {
+ contact.OnAllowedList = true;
+ }
+
+ System.Threading.Thread.Sleep(200);
+ contact.OnPendingList = false;
+ }
+ return;
+ };
+ form.Show(this);
+ }
+ else
+ {
+ MessageBox.Show(contact.Mail + " accepted your invitation and added you their contact list.");
+ }
+ }
+ }
+
+
+ ///
+ /// A delegate passed to Invoke in order to create the conversation form in the thread of the main form.
+ ///
+ private delegate void SetStatusDelegate(string status);
+
+ private void SetStatusSynchronized(string status)
+ {
+ statusBar.Text = status;
+ }
+
+ private void SetStatus(string status)
+ {
+ if (InvokeRequired)
+ {
+ this.Invoke(new SetStatusDelegate(SetStatusSynchronized), new object[] { status });
+ }
+ else
+ {
+ SetStatusSynchronized(status);
+ }
+ }
+
+ ///
+ /// Sign into the messenger network. Disconnect first if a connection has already been established.
+ ///
+ ///
+ ///
+ private void loginButton_Click(object sender, System.EventArgs e)
+ {
+ switch (Convert.ToInt32(loginButton.Tag))
+ {
+ case 0: // not connected -> connect
+ {
+ if (messenger.Connected)
+ {
+ SetStatus("Disconnecting from server");
+ messenger.Disconnect();
+ }
+
+ // set the credentials, this is ofcourse something every MSNPSharp program will need to implement.
+ messenger.Credentials = new Credentials(accountTextBox.Text, passwordTextBox.Text, MsnProtocol.MSNP18);
+
+ // inform the user what is happening and try to connecto to the messenger network.
+ SetStatus("Connecting to server");
+ messenger.Connect();
+
+ displayImageBox.Image = global::MSNPSharpClient.Properties.Resources.loading;
+
+ loginButton.Tag = 1;
+ loginButton.Text = "Cancel";
+ initialExpand = true;
+
+ // note that Messenger.Connect() will run in a seperate thread and return immediately.
+ // it will fire events that informs you about the status of the connection attempt.
+ // these events are registered in the constructor.
+
+ }
+ break;
+
+ case 1: // connecting -> cancel
+ {
+ if (messenger.Connected)
+ messenger.Disconnect();
+
+ if (toolStripSortByStatus.Checked)
+ SortByStatus(null);
+ else
+ SortByGroup(null);
+
+ displayImageBox.Image = null;
+ loginButton.Tag = 0;
+ loginButton.Text = "> Sign in";
+ pnlNameAndPM.Visible = false;
+ comboPlaces.Visible = false;
+ initialExpand = true;
+
+ }
+ break;
+
+ case 2: // connected -> disconnect
+ {
+ if (messenger.Connected)
+ messenger.Disconnect();
+
+ if (toolStripSortByStatus.Checked)
+ SortByStatus(null);
+ else
+ SortByGroup(null);
+
+ displayImageBox.Image = null;
+ loginButton.Tag = 0;
+ loginButton.Text = "> Sign in";
+ pnlNameAndPM.Visible = true;
+ comboPlaces.Visible = true;
+ initialExpand = true;
+
+ }
+ break;
+ }
+ }
+
+ private void login_KeyPress(object sender, KeyPressEventArgs e)
+ {
+ if ((e.KeyChar == '\r') || (e.KeyChar == '\r'))
+ {
+ loginButton.PerformClick();
+ }
+ }
+
+ void Owner_StatusChanged(object sender, StatusChangedEventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ BeginInvoke(new EventHandler(Owner_StatusChanged), new object[] { sender, e });
+ return;
+ }
+
+ if (messenger.Nameserver.IsSignedIn)
+ {
+ comboStatus.SelectedIndex = comboStatus.FindString(GetStatusString(Messenger.ContactList.Owner.Status));
+ }
+ }
+
+ private string GetStatusString(PresenceStatus status)
+ {
+ switch (status)
+ {
+ case PresenceStatus.Away:
+ case PresenceStatus.BRB:
+ case PresenceStatus.Lunch:
+ case PresenceStatus.Idle:
+ return "Away";
+ case PresenceStatus.Online:
+ return "Online";
+ case PresenceStatus.Offline:
+ return "Offline";
+ case PresenceStatus.Hidden:
+ return "Hidden";
+ case PresenceStatus.Busy:
+ case PresenceStatus.Phone:
+ return "Busy";
+
+ }
+
+ return "Offline";
+ }
+
+ private void comboStatus_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new EventHandler(comboStatus_SelectedIndexChanged), sender, e);
+ return;
+ }
+
+ PresenceStatus newstatus = (PresenceStatus)Enum.Parse(typeof(PresenceStatus), comboStatus.Text);
+
+ if (messenger.Connected)
+ {
+ if (newstatus == PresenceStatus.Offline)
+ {
+ PresenceStatus old = Messenger.ContactList.Owner.Status;
+
+ foreach (ConversationForm convform in ConversationForms)
+ {
+ if (convform.Visible == true)
+ {
+ if (MessageBox.Show("You are signing out from example client. All windows will be closed.", "Sign out", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
+ {
+ return;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ Messenger.Disconnect();
+ comboStatus.SelectedIndex = 0;
+ }
+ else
+ {
+ Messenger.ContactList.Owner.Status = newstatus;
+ }
+ }
+ else if (newstatus == PresenceStatus.Offline)
+ {
+ comboStatus.SelectedIndex = 0;
+ }
+ }
+
+ private void comboStatus_DrawItem(object sender, DrawItemEventArgs e)
+ {
+ if (e.Index == -1)
+ return;
+
+ e.Graphics.FillRectangle(Brushes.White, e.Bounds);
+ if ((e.State & DrawItemState.Selected) != DrawItemState.None)
+ e.DrawBackground();
+
+ PresenceStatus newstatus = (PresenceStatus)Enum.Parse(typeof(PresenceStatus), comboStatus.Items[e.Index].ToString());
+ Brush brush = Brushes.Green;
+
+ switch (newstatus)
+ {
+ case PresenceStatus.Online:
+ brush = Brushes.Green;
+ break;
+
+ case PresenceStatus.Busy:
+ brush = Brushes.Red;
+ break;
+
+ case PresenceStatus.Away:
+ brush = Brushes.Orange;
+ break;
+
+ case PresenceStatus.Hidden:
+ brush = Brushes.Gray;
+ break;
+
+ case PresenceStatus.Offline:
+ brush = Brushes.Black;
+ break;
+ }
+
+ Point imageLocation = new Point(e.Bounds.X + 2, e.Bounds.Y + 2);
+ e.Graphics.FillRectangle(brush, new Rectangle(imageLocation, new Size(12, 12)));
+
+ PointF textLocation = new PointF(imageLocation.X + 16, imageLocation.Y);
+ e.Graphics.DrawString(newstatus.ToString(), PARENT_NODE_FONT, Brushes.Black, textLocation);
+ }
+
+ private void comboPlaces_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ if (comboPlaces.SelectedIndex > 0)
+ {
+ string place = comboPlaces.Text.Split(' ')[comboPlaces.Text.Split(' ').Length - 1];
+ if (comboPlaces.SelectedIndex == 1)
+ {
+ Messenger.ContactList.Owner.Status = PresenceStatus.Offline;
+ comboPlaces.Visible = false;
+ }
+ else if (comboPlaces.SelectedIndex >= 1)
+ {
+ Guid placeId = places[comboPlaces.SelectedIndex - 2];
+ if (placeId == Guid.Empty)
+ {
+ comboPlaces.Visible = false;
+ Messenger.ContactList.Owner.SignoutFromEverywhere();
+ }
+ else
+ {
+ Messenger.ContactList.Owner.SignoutFrom(placeId); //places does not contain the current places.
+ }
+ }
+ }
+ }
+
+ void cbRobotMode_CheckedChanged(object sender, EventArgs e)
+ {
+ ComboBox cbBotMode = sender as ComboBox;
+ messenger.Nameserver.BotMode = cbRobotMode.Checked;
+ }
+
+ List places = new List(0);
+
+ private void Owner_PlacesChanged(object sender, EventArgs e)
+ {
+ if (comboPlaces.InvokeRequired)
+ {
+ comboPlaces.BeginInvoke(new EventHandler(Owner_PlacesChanged), new object[] { sender, e });
+ return;
+ }
+
+ // if (Messenger.ContactList.Owner.Places.Count > 1)
+ {
+ comboPlaces.BeginUpdate();
+ comboPlaces.Items.Clear();
+ comboPlaces.Items.Add("(" + Messenger.ContactList.Owner.PlaceCount + ") Places");
+ comboPlaces.Items.Add("Signout from here (" + Messenger.ContactList.Owner.EpName + ")");
+
+ foreach (KeyValuePair keyvalue in Messenger.ContactList.Owner.EndPointData)
+ {
+ if (keyvalue.Key != NSMessageHandler.MachineGuid)
+ {
+ comboPlaces.Items.Add("Signout from " + (keyvalue.Value as PrivateEndPointData).Name);
+ places.Add(keyvalue.Key);
+ }
+ }
+
+ comboPlaces.SelectedIndex = 0;
+ comboPlaces.Visible = true;
+ comboPlaces.EndUpdate();
+ }
+ }
+
+ private void NameserverProcessor_ConnectionEstablished(object sender, EventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new EventHandler(NameserverProcessor_ConnectionEstablished), sender, e);
+ return;
+ }
+
+ messenger.Nameserver.AutoSynchronize = !cbRobotMode.Checked;
+
+ SetStatus("Connected to server");
+ }
+
+ private void Nameserver_SignedIn(object sender, EventArgs e)
+ {
+
+ if (InvokeRequired)
+ {
+ BeginInvoke(new EventHandler(Nameserver_SignedIn), sender, e);
+ return;
+ }
+
+ SetStatus("Signed into the messenger network as " + Messenger.ContactList.Owner.Name);
+
+ // set our presence status
+ loginButton.Tag = 2;
+ loginButton.Text = "Sign off";
+ pnlNameAndPM.Visible = true;
+ comboPlaces.Visible = true;
+
+ Messenger.ContactList.Owner.Status = (PresenceStatus)Enum.Parse(typeof(PresenceStatus), comboStatus.Text);
+
+ propertyGrid.SelectedObject = Messenger.ContactList.Owner;
+ displayImageBox.Image = Messenger.ContactList.Owner.DisplayImage.Image;
+ displayImageBox.SizeMode = PictureBoxSizeMode.Zoom;
+
+ UpdateContactlist(sender, e);
+ }
+
+ private void Nameserver_SignedOff(object sender, SignedOffEventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new EventHandler(Nameserver_SignedOff), sender, e);
+ return;
+ }
+
+ SetStatus("Signed off from the messenger network");
+ ResetAll();
+ }
+
+ private void ResetAll()
+ {
+ tmrKeepOnLine.Enabled = false;
+ tmrNews.Enabled = false;
+
+ displayImageBox.Image = null;
+ displayImageBox.SizeMode = PictureBoxSizeMode.CenterImage;
+
+ loginButton.Tag = 0;
+ loginButton.Text = "> Sign in";
+ pnlNameAndPM.Visible = false;
+ comboPlaces.Visible = false;
+ propertyGrid.SelectedObject = null;
+
+ treeViewFavoriteList.Nodes.Clear();
+ treeViewFilterList.Nodes.Clear();
+
+ if (toolStripSortByStatus.Checked)
+ SortByStatus(null);
+ else
+ SortByGroup(null);
+
+ places.Clear();
+
+ List convFormsClone = new List(ConversationForms);
+ foreach(ConversationForm convForm in convFormsClone)
+ {
+ convForm.Close();
+ }
+ }
+
+ private void Nameserver_ExceptionOccurred(object sender, ExceptionEventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new EventHandler(Nameserver_ExceptionOccurred), new object[] { sender, e });
+ }
+ else
+ {
+
+ // ignore the unauthorized exception, since we're handling that error in another method.
+ if (e.Exception is UnauthorizedException)
+ return;
+
+ MessageBox.Show(e.Exception.ToString(), "Nameserver exception");
+ }
+ }
+
+ private void NameserverProcessor_ConnectingException(object sender, ExceptionEventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new EventHandler(Nameserver_ExceptionOccurred), new object[] { sender, e });
+ }
+ else
+ {
+ MessageBox.Show(e.Exception.ToString(), "Connecting exception");
+ SetStatus("Connecting failed");
+ }
+ }
+
+ private void Nameserver_AuthenticationError(object sender, ExceptionEventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new EventHandler(Nameserver_ExceptionOccurred), new object[] { sender, e });
+ }
+ else
+ {
+ MessageBox.Show("Authentication failed, check your account or password.\r\n Error detail:\r\n " + e.Exception.InnerException.Message + "\r\n"
+ + " StackTrace:\r\n " + e.Exception.InnerException.StackTrace
+ , "Authentication Error");
+ SetStatus("Authentication failed");
+ }
+ }
+
+ ///
+ /// Updates the treeView.
+ ///
+ private void UpdateContactlist(object sender, EventArgs e)
+ {
+ if (messenger.Connected == false)
+ return;
+
+ if (toolStripSortByStatus.Checked)
+ SortByStatus(null);
+ else
+ SortByGroup(null);
+
+ tmrKeepOnLine.Enabled = true;
+ }
+
+
+ ///
+ /// Notifies the user of errors which are send by the MSN server.
+ ///
+ ///
+ ///
+ private void Nameserver_ServerErrorReceived(object sender, MSNErrorEventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new EventHandler(Nameserver_ServerErrorReceived), new object[] { sender, e });
+ }
+ else
+ {
+ // when the MSN server sends an error code we want to be notified.
+ MessageBox.Show(e.MSNError.ToString(), "Server error received");
+ SetStatus("Server error received");
+ }
+ }
+
+ ///
+ /// A delegate passed to Invoke in order to create the conversation form in the thread of the main form.
+ ///
+ private delegate ConversationForm CreateConversationDelegate(Contact remote, ConversationID cid);
+
+ private ConversationForm CreateConversationForm(Contact remote, ConversationID cid)
+ {
+
+ // create a new conversation. However do not show the window untill a message is received.
+ // for example, a conversation will be created when the remote client sends wants to send
+ // you a file. You don't want to show the conversation form in that case.
+ ConversationForm conversationForm = new ConversationForm(Messenger, remote, cid);
+ // do this to create the window handle. Otherwise we are not able to call Invoke() on the
+ // conversation form later.
+ conversationForm.Handle.ToInt32();
+ ConversationForms.Add(conversationForm);
+
+ conversationForm.FormClosing += delegate
+ {
+ ConversationForms.Remove(conversationForm);
+ };
+
+ return conversationForm;
+ }
+
+
+ ///
+ /// Asks the user to accept or deny the incoming filetransfer invitation.
+ ///
+ ///
+ ///
+ private void messenger_TransferInvitationReceived(object sender, MSNSLPInvitationEventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new EventHandler(messenger_TransferInvitationReceived), sender, e);
+ return;
+ }
+
+ if (e.TransferProperties.DataType == DataTransferType.File)
+ {
+ e.DelayProcess = true;
+
+ FileTransferForm ftf = new FileTransferForm(e);
+ ftf.Show(this);
+
+ }
+ else if (e.TransferProperties.DataType == DataTransferType.Activity)
+ {
+ if (MessageBox.Show(
+ e.TransferProperties.RemoteContact.Name +
+ " wants to invite you to join an activity.\r\nActivity name: " +
+ e.Activity.ActivityName + "\r\nAppID: " + e.Activity.AppID,
+ "Activity invitation",
+ MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
+ {
+ e.TransferSession.DataStream = new MemoryStream();
+ e.Accept = true;
+ e.TransferSession.AutoCloseStream = true;
+ }
+ }
+ }
+
+ private int nextPing = 50;
+ private void tmrKeepOnLine_Tick(object sender, EventArgs e)
+ {
+ if (nextPing > 0)
+ nextPing--;
+ if (nextPing == 0)
+ {
+ nextPing--;
+ messenger.Nameserver.SendPing();
+ }
+ }
+
+
+
+ private static Font PARENT_NODE_FONT = new Font("Tahoma", 8f, FontStyle.Bold);
+ private static Font PARENT_NODE_FONT_BANNED = new Font("Tahoma", 8f, FontStyle.Bold | FontStyle.Strikeout);
+ private static Font USER_NODE_FONT = new Font("Tahoma", 8f);
+ private static Font USER_NODE_FONT_BANNED = new Font("Tahoma", 8f, FontStyle.Strikeout);
+ public class StatusSorter : IComparer
+ {
+ public static StatusSorter Default = new StatusSorter();
+ private StatusSorter()
+ {
+ }
+ public int Compare(object x, object y)
+ {
+ TreeNode node = x as TreeNode;
+ TreeNode node2 = y as TreeNode;
+
+ if (node.Tag is string && node2.Tag is string)
+ {
+ // Online (0), Offline (1)
+ return node.Tag.ToString().CompareTo(node2.Tag.ToString());
+ }
+ else if (node.Tag is Circle && node2.Tag is Circle)
+ {
+
+ return ((Circle)node.Tag).AddressBookId.CompareTo(((Circle)node2.Tag).AddressBookId);
+
+ }
+ else if (node.Tag is Contact && node2.Tag is Contact)
+ {
+ if (((Contact)node.Tag).Online == ((Contact)node2.Tag).Online)
+ {
+ return string.Compare(((Contact)node.Tag).Name, ((Contact)node2.Tag).Name, StringComparison.CurrentCultureIgnoreCase);
+ }
+ if (((Contact)node.Tag).Online)
+ return -1;
+ else if (((Contact)node2.Tag).Online)
+ return 1;
+ }
+ else if (node.Tag is ContactGroup && node2.Tag is ContactGroup)
+ {
+ return string.Compare(((ContactGroup)node.Tag).Name, ((ContactGroup)node2.Tag).Name, StringComparison.CurrentCultureIgnoreCase);
+ }
+ return 0;
+ }
+ }
+
+ private void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
+ {
+ if ((e.Button == MouseButtons.Left) && (e.Node.Level != 0))
+ {
+ Contact selectedContact = treeViewFavoriteList.SelectedNode.Tag as Contact;
+
+ if (selectedContact != null)
+ {
+ propertyGrid.SelectedObject = selectedContact;
+
+ if (selectedContact.Online && (!(selectedContact is Circle)))
+ {
+ sendIMMenuItem.PerformClick();
+ }
+ }
+ }
+ }
+
+ private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
+ {
+ if (e.Button == MouseButtons.Left)
+ {
+ if (e.Node.Level == 0)
+ {
+ if (e.Node.IsExpanded || (e.Node.ImageIndex == ImageIndexes.Open))
+ {
+ e.Node.Collapse();
+ e.Node.ImageIndex = e.Node.SelectedImageIndex = (e.Node.Tag is Circle) ? ImageIndexes.Circle : ImageIndexes.Closed;
+ }
+ else if (e.Node.Nodes.Count > 0)
+ {
+ e.Node.Expand();
+ e.Node.ImageIndex = e.Node.SelectedImageIndex = (e.Node.Tag is Circle) ? ImageIndexes.Circle : ImageIndexes.Open;
+ }
+ if (e.Node.Tag is ContactGroup || e.Node.Tag is Circle)
+ {
+ propertyGrid.SelectedObject = e.Node.Tag;
+ }
+ }
+ else
+ {
+ Contact selectedContact = (Contact)e.Node.Tag;
+
+ if (selectedContact is Circle)
+ {
+ if (e.Node.IsExpanded)
+ {
+ e.Node.Collapse();
+ }
+ else
+ {
+ e.Node.Expand();
+ }
+ }
+
+ propertyGrid.SelectedObject = selectedContact;
+ }
+ }
+ else if (e.Button == MouseButtons.Right)
+ {
+ if (e.Node.Tag is Contact && e.Node.Level > 0)
+ {
+ treeViewFavoriteList.SelectedNode = e.Node;
+ Contact contact = (Contact)treeViewFavoriteList.SelectedNode.Tag;
+
+ if (contact.Blocked)
+ {
+ blockMenuItem.Visible = false;
+ unblockMenuItem.Visible = true;
+ }
+ else
+ {
+ blockMenuItem.Visible = true;
+ unblockMenuItem.Visible = false;
+ }
+
+ if (contact.Online)
+ {
+ sendIMMenuItem.Visible = true;
+ sendOIMMenuItem.Visible = false;
+
+ toolStripMenuItem2.Visible = true;
+ }
+ else
+ {
+ sendIMMenuItem.Visible = false;
+ sendOIMMenuItem.Visible = true;
+
+ toolStripMenuItem2.Visible = false;
+ }
+
+ deleteMenuItem.Visible = contact.Guid != Guid.Empty;
+
+ Point point = treeViewFavoriteList.PointToScreen(new Point(e.X, e.Y));
+ userMenuStrip.Show(point.X - userMenuStrip.Width, point.Y);
+ }
+ else if (e.Node.Tag is ContactGroup)
+ {
+ treeViewFavoriteList.SelectedNode = e.Node;
+
+ Point point = treeViewFavoriteList.PointToScreen(new Point(e.X, e.Y));
+ groupContextMenu.Show(point.X - groupContextMenu.Width, point.Y);
+ }
+ }
+ }
+
+ private void blockToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ ((Contact)treeViewFavoriteList.SelectedNode.Tag).Blocked = true;
+ treeViewFavoriteList.SelectedNode.NodeFont = USER_NODE_FONT_BANNED;
+ }
+
+ private void unblockMenuItem_Click(object sender, EventArgs e)
+ {
+ ((Contact)treeViewFavoriteList.SelectedNode.Tag).Blocked = false;
+ treeViewFavoriteList.SelectedNode.NodeFont = USER_NODE_FONT;
+ }
+
+ private void deleteMenuItem_Click(object sender, EventArgs e)
+ {
+ Contact contact = (Contact)treeViewFavoriteList.SelectedNode.Tag;
+ RemoveContactForm form = new RemoveContactForm();
+ form.FormClosed += delegate(object f, FormClosedEventArgs fce)
+ {
+ form = f as RemoveContactForm;
+ if (DialogResult.OK == form.DialogResult)
+ {
+ if (form.Block)
+ {
+ contact.Blocked = true;
+ }
+
+ if (form.RemoveFromAddressBook)
+ {
+ messenger.ContactService.RemoveContact(contact);
+ }
+ else
+ {
+ contact.IsMessengerUser = false;
+ }
+ }
+ };
+ form.ShowDialog(this);
+ }
+
+ private void sendMessageToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ Contact contact = treeViewFavoriteList.SelectedNode.Tag as Contact;
+ if (!contact.IsMessengerUser) return;
+
+ if (!contact.OnForwardList)
+ {
+ AddContactForm acf = new AddContactForm(contact.Mail);
+
+ if (DialogResult.OK == acf.ShowDialog(this) &&
+ acf.Account != String.Empty)
+ {
+ messenger.ContactService.AddNewContact(acf.Account, acf.InvitationMessage);
+ }
+
+ return;
+ }
+
+ bool activate = false;
+ ConversationForm activeForm = null;
+
+ if (contact.ClientType != ClientType.EmailMember)
+ {
+ foreach (ConversationForm conv in ConversationForms)
+ {
+ if (contact.IsSibling(conv.ConversationID.RemoteOwner))
+ {
+ activeForm = conv;
+ activate = true;
+ }
+ }
+ }
+
+ if (activate)
+ {
+ if (activeForm.WindowState == FormWindowState.Minimized || activeForm.Visible == false)
+ activeForm.Show();
+
+ activeForm.Activate();
+ return;
+ }
+
+ //Get the conversation identifier, then you can use:
+ // conversationIdentifier = _messenger.MessageManager.SendTextMessage(ConversationID, message);
+ //To send a message.
+ ConversationID conversationIdentifier = Messenger.MessageManager.GetID(contact);
+ ConversationForm form = CreateConversationForm(contact, conversationIdentifier);
+
+ form.Show();
+ }
+
+ private void sendOfflineMessageToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ Contact selectedContact = (Contact)treeViewFavoriteList.SelectedNode.Tag;
+ this.propertyGrid.SelectedObject = selectedContact;
+ messenger.OIMService.SendOIMMessage(selectedContact, new TextMessage("MSNPSharp offline message test."));
+
+ }
+
+ private void sendMIMMenuItem_Click(object sender, EventArgs e)
+ {
+ Contact selectedContact = (Contact)treeViewFavoriteList.SelectedNode.Tag;
+ this.propertyGrid.SelectedObject = selectedContact;
+
+ if (selectedContact.MobileAccess || selectedContact.ClientType == ClientType.PhoneMember)
+ {
+ messenger.Nameserver.SendMobileMessage(selectedContact, "MSNP mobile message");
+ }
+ else
+ MessageBox.Show("This contact is not able to receive mobile messages");
+ }
+
+
+ private void btnSortBy_Click(object sender, EventArgs e)
+ {
+ Button sortByButton = sender as Button;
+ int x = ((base.Location.X + splitContainer1.Panel1.Width + sortByButton.Left)) + 15;
+ int y = (base.Location.Y + tableLayoutPanel3.Height + sortByButton.Top) + 3 * btnSortBy.Height;
+ sortContextMenu.Show(x, y);
+ sortContextMenu.Focus();
+ }
+
+ private void toolStripSortByStatus_Click(object sender, EventArgs e)
+ {
+ if (this.toolStripSortByStatus.Checked)
+ {
+ treeViewFavoriteList.Nodes.RemoveByKey(ImageIndexes.NoGroupNodeKey);
+ foreach (ContactGroup cg in messenger.ContactGroups)
+ {
+ treeViewFavoriteList.Nodes.RemoveByKey(cg.Guid);
+ }
+
+ SortByStatus(null);
+ }
+ else
+ {
+ this.toolStripSortByStatus.Checked = true;
+ }
+ }
+
+ private bool initialExpand = true;
+
+ private string GetCircleDisplayName(Circle circle)
+ {
+ if (circle == null)
+ return string.Empty;
+
+ return circle.Name + " (" + circle.ContactList.Values.Count.ToString() + " members)";
+ }
+
+
+ private void SortByFavAndCircle(Contact contactToUpdate)
+ {
+ TreeNode favoritesNode = null; // (0/0)
+ TreeNode circlesNode = null; // (0/0)
+
+ if (treeViewFavoriteList.Nodes.ContainsKey(ImageIndexes.FavoritesNodeKey))
+ {
+ favoritesNode = treeViewFavoriteList.Nodes[ImageIndexes.FavoritesNodeKey];
+ }
+ else
+ {
+ favoritesNode = treeViewFavoriteList.Nodes.Add(ImageIndexes.FavoritesNodeKey, "Favorites", ImageIndexes.Closed, ImageIndexes.Closed);
+ favoritesNode.NodeFont = PARENT_NODE_FONT;
+ favoritesNode.Tag = ImageIndexes.FavoritesNodeKey;
+ }
+
+ if (treeViewFavoriteList.Nodes.ContainsKey(ImageIndexes.CircleNodeKey))
+ {
+ circlesNode = treeViewFavoriteList.Nodes[ImageIndexes.CircleNodeKey];
+ }
+ else
+ {
+ circlesNode = treeViewFavoriteList.Nodes.Add(ImageIndexes.CircleNodeKey, "Circles", ImageIndexes.Closed, ImageIndexes.Closed);
+ circlesNode.NodeFont = PARENT_NODE_FONT;
+ circlesNode.Tag = ImageIndexes.CircleNodeKey;
+ }
+
+ if (contactToUpdate == null)
+ {
+ // Initial sort
+ favoritesNode.Nodes.Clear();
+ circlesNode.Nodes.Clear();
+
+ foreach (Circle circle in Messenger.CircleList)
+ {
+ TreeNode circleNode = circlesNode.Nodes.Add(circle.Hash, GetCircleDisplayName(circle), ImageIndexes.Circle, ImageIndexes.Circle);
+ circleNode.NodeFont = circle.Blocked ? PARENT_NODE_FONT_BANNED : PARENT_NODE_FONT;
+ circleNode.Tag = circle;
+
+ foreach (Contact contact in circle.ContactList.All)
+ {
+ // Get real passport contact to chat with... If this contact isn't on our forward list, show add contact form...
+ string text = contact.Name;
+ if (contact.PersonalMessage != null && !String.IsNullOrEmpty(contact.PersonalMessage.Message))
+ {
+ text += " - " + contact.PersonalMessage.Message;
+ }
+ if (contact.Name != contact.Mail)
+ {
+ text += " (" + contact.Mail + ")";
+ }
+
+ TreeNode newnode = circleNode.Nodes.Add(contact.Hash, text);
+ newnode.NodeFont = contact.Blocked ? USER_NODE_FONT_BANNED : USER_NODE_FONT;
+ newnode.ImageIndex = newnode.SelectedImageIndex = ImageIndexes.GetStatusIndex(contact.Status);
+ newnode.Tag = contact;
+ }
+ }
+
+ ContactGroup favGroup = messenger.ContactGroups.FavoriteGroup;
+ if (favGroup != null)
+ {
+ foreach (Contact c in messenger.ContactList.Forward)
+ {
+ if (c.HasGroup(favGroup))
+ {
+ string text = c.Name;
+ if (c.PersonalMessage != null && !String.IsNullOrEmpty(c.PersonalMessage.Message))
+ {
+ text += " - " + c.PersonalMessage.Message;
+ }
+ if (c.Name != c.Mail)
+ {
+ text += " (" + c.Mail + ")";
+ }
+
+ TreeNode newnode = favoritesNode.Nodes.ContainsKey(c.Hash) ?
+ favoritesNode.Nodes[c.Hash] : favoritesNode.Nodes.Add(c.Hash, text);
+
+ newnode.NodeFont = c.Blocked ? USER_NODE_FONT_BANNED : USER_NODE_FONT;
+ newnode.ImageIndex = newnode.SelectedImageIndex = ImageIndexes.GetStatusIndex(c.Status);
+ newnode.Tag = c;
+ }
+ }
+ }
+ }
+ else if (contactToUpdate is Circle)
+ {
+ // Circle event
+ Circle circle = contactToUpdate as Circle;
+ bool isDeleted = (Messenger.CircleList[circle.AddressBookId, circle.HostDomain] == null);
+
+ if (!isDeleted)
+ {
+ TreeNode circlenode = circlesNode.Nodes.ContainsKey(circle.Hash) ?
+ circlesNode.Nodes[circle.Hash] : circlesNode.Nodes.Add(circle.Hash, GetCircleDisplayName(circle), ImageIndexes.Circle, ImageIndexes.Circle);
+
+ circlenode.NodeFont = circle.Blocked ? PARENT_NODE_FONT_BANNED : PARENT_NODE_FONT;
+ circlenode.Tag = circle;
+
+ foreach (Contact contact in circle.ContactList.All)
+ {
+ // Get real passport contact to chat with... If this contact isn't on our forward list, show add contact form...
+ string text2 = contact.Name;
+ if (contact.PersonalMessage != null && !String.IsNullOrEmpty(contact.PersonalMessage.Message))
+ {
+ text2 += " - " + contact.PersonalMessage.Message;
+ }
+ if (contact.Name != contact.Mail)
+ {
+ text2 += " (" + contact.Mail + ")";
+ }
+
+ TreeNode newnode = circlenode.Nodes.ContainsKey(contact.Hash) ?
+ circlenode.Nodes[contact.Hash] : circlenode.Nodes.Add(contact.Hash, text2);
+
+ newnode.Text = text2;
+ newnode.ImageIndex = newnode.SelectedImageIndex = ImageIndexes.GetStatusIndex(contact.Status);
+ newnode.NodeFont = contact.Blocked ? USER_NODE_FONT_BANNED : USER_NODE_FONT;
+ newnode.Tag = contact;
+ }
+
+ circlenode.Text = GetCircleDisplayName(circle);
+ }
+ else
+ {
+ circlesNode.Nodes.RemoveByKey(circle.Hash);
+ }
+ }
+ else
+ {
+ // Contact event... Contact is not null.
+ // Favorite
+ ContactGroup favGroup = messenger.ContactGroups.FavoriteGroup;
+ if (favGroup != null && contactToUpdate.HasGroup(favGroup))
+ {
+ Contact contact = messenger.ContactList[contactToUpdate.Mail, contactToUpdate.ClientType];
+ string text = contact.Name;
+ if (contact.PersonalMessage != null && !String.IsNullOrEmpty(contact.PersonalMessage.Message))
+ {
+ text += " - " + contact.PersonalMessage.Message;
+ }
+ if (contact.Name != contact.Mail)
+ {
+ text += " (" + contact.Mail + ")";
+ }
+
+ TreeNode contactNode = favoritesNode.Nodes.ContainsKey(contactToUpdate.Hash) ?
+ favoritesNode.Nodes[contactToUpdate.Hash] : favoritesNode.Nodes.Add(contactToUpdate.Hash, text);
+
+ contactNode.NodeFont = contact.Blocked ? USER_NODE_FONT_BANNED : USER_NODE_FONT;
+ contactNode.ImageIndex = contactNode.SelectedImageIndex = ImageIndexes.GetStatusIndex(contactToUpdate.Status);
+ contactNode.Tag = contactToUpdate;
+ }
+ }
+
+ int onlineCount = 0;
+ foreach (TreeNode nodeFav in favoritesNode.Nodes)
+ {
+ if (nodeFav.Tag is Contact && (((Contact)nodeFav.Tag).Online))
+ {
+ onlineCount++;
+ }
+ }
+ string newText = "Favorites (" + onlineCount + "/" + favoritesNode.Nodes.Count + ")";
+ if (favoritesNode.Text != newText)
+ favoritesNode.Text = newText;
+
+ onlineCount = 0;
+ foreach (TreeNode nodeCircle in circlesNode.Nodes)
+ {
+ if (nodeCircle.Tag is Circle && (((Circle)nodeCircle.Tag).Online))
+ {
+ onlineCount++;
+ }
+ }
+
+ newText = "Circles (" + onlineCount + "/" + circlesNode.Nodes.Count + ")";
+ if (circlesNode.Text != newText)
+ circlesNode.Text = newText;
+ }
+
+ private void SortByStatus(Contact contactToUpdate)
+ {
+ TreeNode selectedNode = treeViewFavoriteList.SelectedNode;
+ bool isExpanded = (selectedNode != null && selectedNode.IsExpanded);
+
+ //treeViewFavoriteList.BeginUpdate();
+
+ if (toolStripSortBygroup.Checked)
+ toolStripSortBygroup.Checked = false;
+
+ SortByFavAndCircle(contactToUpdate);
+
+ TreeNode onlineNode = null; // (0)
+ TreeNode mobileNode = null; // (0)
+ TreeNode offlineNode = null; // (0)
+
+ if (treeViewFavoriteList.Nodes.ContainsKey(ImageIndexes.OnlineNodeKey))
+ {
+ onlineNode = treeViewFavoriteList.Nodes[ImageIndexes.OnlineNodeKey];
+ }
+ else
+ {
+ onlineNode = treeViewFavoriteList.Nodes.Add(ImageIndexes.OnlineNodeKey, "Online", ImageIndexes.Closed, ImageIndexes.Closed);
+ onlineNode.NodeFont = contactToUpdate == null ? PARENT_NODE_FONT : (contactToUpdate.Blocked ? PARENT_NODE_FONT_BANNED : PARENT_NODE_FONT);
+ onlineNode.Tag = ImageIndexes.OnlineNodeKey;
+ }
+
+ if (treeViewFavoriteList.Nodes.ContainsKey(ImageIndexes.MobileNodeKey))
+ {
+ mobileNode = treeViewFavoriteList.Nodes[ImageIndexes.MobileNodeKey];
+ }
+ else
+ {
+ mobileNode = treeViewFavoriteList.Nodes.Add(ImageIndexes.MobileNodeKey, "Mobile", ImageIndexes.Closed, ImageIndexes.Closed);
+ mobileNode.NodeFont = PARENT_NODE_FONT;
+ mobileNode.Tag = ImageIndexes.MobileNodeKey;
+ }
+
+ if (treeViewFavoriteList.Nodes.ContainsKey(ImageIndexes.OfflineNodeKey))
+ {
+ offlineNode = treeViewFavoriteList.Nodes[ImageIndexes.OfflineNodeKey];
+ }
+ else
+ {
+ offlineNode = treeViewFavoriteList.Nodes.Add(ImageIndexes.OfflineNodeKey, "Offline", ImageIndexes.Closed, ImageIndexes.Closed);
+ offlineNode.NodeFont = PARENT_NODE_FONT;
+ offlineNode.Tag = ImageIndexes.OfflineNodeKey;
+ }
+
+ // Re-sort all
+ if (contactToUpdate == null)
+ {
+ mobileNode.Nodes.Clear();
+ onlineNode.Nodes.Clear();
+ offlineNode.Nodes.Clear();
+
+ foreach (Contact contact in messenger.ContactList.All)
+ {
+ string text = contact.Name;
+ if (contact.PersonalMessage != null && !String.IsNullOrEmpty(contact.PersonalMessage.Message))
+ {
+ text += " - " + contact.PersonalMessage.Message;
+ }
+ if (contact.Name != contact.Mail)
+ {
+ text += " (" + contact.Mail + ")";
+ }
+
+ TreeNode newnode = contact.Online ? onlineNode.Nodes.Add(contact.Hash, text) : offlineNode.Nodes.Add(contact.Hash, text);
+ newnode.ImageIndex = newnode.SelectedImageIndex = ImageIndexes.GetStatusIndex(contact.Status);
+ newnode.NodeFont = contact.Blocked ? USER_NODE_FONT_BANNED : USER_NODE_FONT;
+ newnode.Tag = contact;
+
+ if (contact.MobileAccess || contact.ClientType == ClientType.PhoneMember)
+ {
+ TreeNode newnode2 = mobileNode.Nodes.Add(contact.Hash, text);
+ newnode2.ImageIndex = newnode2.SelectedImageIndex = ImageIndexes.GetStatusIndex(contact.Status);
+ newnode2.NodeFont = contact.Blocked ? USER_NODE_FONT_BANNED : USER_NODE_FONT;
+ newnode2.Tag = contact;
+ }
+ }
+ }
+ else if ((contactToUpdate is Circle) == false)
+ {
+ TreeNode contactNode = null;
+
+ if (contactToUpdate.Online)
+ {
+ if (offlineNode.Nodes.ContainsKey(contactToUpdate.Hash))
+ {
+ offlineNode.Nodes.RemoveByKey(contactToUpdate.Hash);
+ }
+ if (onlineNode.Nodes.ContainsKey(contactToUpdate.Hash))
+ {
+ contactNode = onlineNode.Nodes[contactToUpdate.Hash];
+ }
+ }
+ else
+ {
+ if (onlineNode.Nodes.ContainsKey(contactToUpdate.Hash))
+ {
+ onlineNode.Nodes.RemoveByKey(contactToUpdate.Hash);
+ }
+ if (offlineNode.Nodes.ContainsKey(contactToUpdate.Hash))
+ {
+ contactNode = offlineNode.Nodes[contactToUpdate.Hash];
+ }
+ }
+
+ string text = contactToUpdate.Name;
+ if (contactToUpdate.PersonalMessage != null && !String.IsNullOrEmpty(contactToUpdate.PersonalMessage.Message))
+ {
+ text += " - " + contactToUpdate.PersonalMessage.Message;
+ }
+ if (contactToUpdate.Name != contactToUpdate.Mail)
+ {
+ text += " (" + contactToUpdate.Mail + ")";
+ }
+
+ if (contactNode == null)
+ {
+ contactNode = contactToUpdate.Online ? onlineNode.Nodes.Add(contactToUpdate.Hash, text) : offlineNode.Nodes.Add(contactToUpdate.Hash, text);
+ }
+
+ if (contactNode.Text != text)
+ contactNode.Text = text;
+
+ contactNode.ImageIndex = contactNode.SelectedImageIndex = ImageIndexes.GetStatusIndex(contactToUpdate.Status);
+ contactNode.NodeFont = contactToUpdate.Blocked ? USER_NODE_FONT_BANNED : USER_NODE_FONT;
+ contactNode.Tag = contactToUpdate;
+
+ if (contactToUpdate.MobileAccess || contactToUpdate.ClientType == ClientType.PhoneMember)
+ {
+ TreeNode newnode2 = mobileNode.Nodes.ContainsKey(contactToUpdate.Hash) ?
+ mobileNode.Nodes[contactToUpdate.Hash] : mobileNode.Nodes.Add(contactToUpdate.Hash, text);
+
+ newnode2.ImageIndex = newnode2.SelectedImageIndex = ImageIndexes.GetStatusIndex(contactToUpdate.Status);
+ newnode2.NodeFont = contactToUpdate.Blocked ? USER_NODE_FONT_BANNED : USER_NODE_FONT;
+ newnode2.Tag = contactToUpdate;
+ }
+ }
+
+ string newText = "Online (" + onlineNode.Nodes.Count.ToString() + ")";
+ if (onlineNode.Text != newText)
+ onlineNode.Text = newText;
+
+ newText = "Offline (" + offlineNode.Nodes.Count.ToString() + ")";
+ if (offlineNode.Text != newText)
+ offlineNode.Text = newText;
+
+ newText = "Mobile (" + mobileNode.Nodes.Count.ToString() + ")";
+ if (mobileNode.Text != newText)
+ mobileNode.Text = newText;
+
+ treeViewFavoriteList.Sort();
+
+ if (selectedNode != null)
+ {
+ treeViewFavoriteList.SelectedNode = selectedNode;
+
+ if (isExpanded && treeViewFavoriteList.SelectedNode != null)
+ {
+ treeViewFavoriteList.SelectedNode.Expand();
+ }
+ }
+ else
+ {
+ if (initialExpand && onlineNode.Nodes.Count > 0)
+ {
+ onlineNode.Expand();
+ onlineNode.ImageIndex = ImageIndexes.Open;
+
+ initialExpand = false;
+ }
+ }
+
+ //treeViewFavoriteList.EndUpdate();
+ treeViewFavoriteList.AllowDrop = false;
+ }
+
+ private void toolStripSortBygroup_Click(object sender, EventArgs e)
+ {
+ if (this.toolStripSortBygroup.Checked)
+ {
+ treeViewFavoriteList.Nodes.RemoveByKey(ImageIndexes.OnlineNodeKey);
+ treeViewFavoriteList.Nodes.RemoveByKey(ImageIndexes.MobileNodeKey);
+ treeViewFavoriteList.Nodes.RemoveByKey(ImageIndexes.OfflineNodeKey);
+
+ SortByGroup(null);
+ }
+ else
+ {
+ this.toolStripSortBygroup.Checked = true;
+ }
+ }
+
+ private void SortByGroup(Contact contactToUpdate)
+ {
+ this.treeViewFavoriteList.BeginUpdate();
+ this.toolStripSortByStatus.Checked = false;
+
+ SortByFavAndCircle(contactToUpdate);
+
+ foreach (ContactGroup group in this.messenger.ContactGroups)
+ {
+ if (group.IsFavorite == false)
+ {
+ TreeNode node = treeViewFavoriteList.Nodes.ContainsKey(group.Guid) ?
+ treeViewFavoriteList.Nodes[group.Guid] : treeViewFavoriteList.Nodes.Add(group.Guid, group.Name, ImageIndexes.Closed, ImageIndexes.Closed);
+
+ node.ImageIndex = ImageIndexes.Closed;
+ node.NodeFont = PARENT_NODE_FONT;
+ node.Tag = group;
+ node.Text = "0";
+ }
+ }
+
+ TreeNode common = treeViewFavoriteList.Nodes.ContainsKey(ImageIndexes.NoGroupNodeKey) ?
+ treeViewFavoriteList.Nodes[ImageIndexes.NoGroupNodeKey] : treeViewFavoriteList.Nodes.Add(ImageIndexes.NoGroupNodeKey, "Others", 0, 0);
+
+ common.ImageIndex = ImageIndexes.Closed;
+ common.NodeFont = PARENT_NODE_FONT;
+ common.Tag = ImageIndexes.NoGroupNodeKey;
+ common.Text = "0";
+
+ foreach (Contact contact in messenger.ContactList.All)
+ {
+ string text = contact.Name;
+ if (contact.PersonalMessage != null && !String.IsNullOrEmpty(contact.PersonalMessage.Message))
+ {
+ text += " - " + contact.PersonalMessage.Message;
+ }
+ if (contact.Name != contact.Mail)
+ {
+ text += " (" + contact.Mail + ")";
+ }
+
+ if (contact.ContactGroups.Count == 0)
+ {
+ TreeNode newnode = common.Nodes.ContainsKey(contact.Hash) ?
+ common.Nodes[contact.Hash] : common.Nodes.Add(contact.Hash, text);
+
+ newnode.ImageIndex = newnode.SelectedImageIndex = ImageIndexes.GetStatusIndex(contact.Status);
+ newnode.NodeFont = contact.Blocked ? USER_NODE_FONT_BANNED : USER_NODE_FONT;
+ newnode.Tag = contact;
+ newnode.Text = text;
+
+ if (contact.Online)
+ common.Text = (Convert.ToInt32(common.Text) + 1).ToString();
+ }
+ else
+ {
+ foreach (ContactGroup group in contact.ContactGroups)
+ {
+ if (group.IsFavorite == false)
+ {
+ TreeNode found = treeViewFavoriteList.Nodes[group.Guid];
+ TreeNode newnode = found.Nodes.Add(contact.Hash, contact.Name);
+ newnode.ImageIndex = newnode.SelectedImageIndex = ImageIndexes.GetStatusIndex(contact.Status);
+ newnode.NodeFont = contact.Blocked ? USER_NODE_FONT_BANNED : USER_NODE_FONT;
+ newnode.Tag = contact;
+
+ if (contact.Online)
+ found.Text = (Convert.ToInt32(found.Text) + 1).ToString();
+ }
+ }
+ }
+ }
+
+ foreach (TreeNode nodeGroup in treeViewFavoriteList.Nodes)
+ {
+ if (nodeGroup.Tag is ContactGroup)
+ {
+ nodeGroup.Text = ((ContactGroup)nodeGroup.Tag).Name + "(" + nodeGroup.Text + "/" + nodeGroup.Nodes.Count + ")";
+ }
+ }
+
+ common.Text = "Others (" + common.Text + "/" + common.Nodes.Count + ")";
+
+ treeViewFavoriteList.Sort();
+ treeViewFavoriteList.EndUpdate();
+ treeViewFavoriteList.AllowDrop = true;
+ }
+
+ private void treeViewFavoriteList_DragEnter(object sender, DragEventArgs e)
+ {
+ if (e.Data.GetDataPresent("System.Windows.Forms.TreeNode", false))
+ {
+ e.Effect = DragDropEffects.Move;
+ }
+ else
+ {
+ e.Effect = DragDropEffects.None;
+ }
+ }
+
+ private void treeViewFavoriteList_ItemDrag(object sender, ItemDragEventArgs e)
+ {
+ if ((e.Item is TreeNode)/* && (((TreeNode)e.Item).Level > 0)*/)
+ {
+ base.DoDragDrop(e.Item, DragDropEffects.Move);
+ }
+ }
+
+ private void treeViewFavoriteList_DragOver(object sender, DragEventArgs e)
+ {
+ Point pt = ((TreeView)sender).PointToClient(new Point(e.X, e.Y));
+ TreeNode nodeAt = ((TreeView)sender).GetNodeAt(pt);
+ TreeNode data = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode");
+ if (((data.Level == 0) || (data.Parent == nodeAt)) || (nodeAt.Parent == data.Parent))
+ {
+ e.Effect = DragDropEffects.None;
+ }
+ else
+ {
+ e.Effect = DragDropEffects.Move;
+ }
+ }
+
+ private void treeViewFavoriteList_DragDrop(object sender, DragEventArgs e)
+ {
+ if (e.Data.GetDataPresent("System.Windows.Forms.TreeNode", false))
+ {
+ TreeNode contactNode = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode");
+ if (contactNode.Level != 0)
+ {
+ Point pt = ((TreeView)sender).PointToClient(new Point(e.X, e.Y));
+ TreeNode newgroupNode = (((TreeView)sender).GetNodeAt(pt).Level == 0) ? ((TreeView)sender).GetNodeAt(pt) : ((TreeView)sender).GetNodeAt(pt).Parent;
+ TreeNode oldgroupNode = contactNode.Parent;
+ Contact contact = (Contact)contactNode.Tag;
+ bool flag = true;
+ try
+ {
+ if (newgroupNode.Tag is ContactGroup)
+ {
+ messenger.ContactService.AddContactToGroup(contact, (ContactGroup)newgroupNode.Tag);
+ }
+ if (oldgroupNode.Tag is ContactGroup)
+ {
+ messenger.ContactService.RemoveContactFromGroup(contact, (ContactGroup)oldgroupNode.Tag);
+ }
+ }
+ catch (Exception)
+ {
+ flag = false;
+ }
+
+ if (flag)
+ {
+ treeViewFavoriteList.BeginUpdate();
+ TreeNode node3 = (TreeNode)contactNode.Clone();
+ newgroupNode.Nodes.Add(node3);
+ contactNode.Remove();
+ treeViewFavoriteList.EndUpdate();
+
+ newgroupNode.Text = newgroupNode.Text.Split(new char[] { '/' })[0] + "/" + newgroupNode.Nodes.Count + ")";
+ oldgroupNode.Text = oldgroupNode.Text.Split(new char[] { '/' })[0] + "/" + oldgroupNode.Nodes.Count + ")";
+ }
+ }
+ }
+ }
+
+ private void toolStripDeleteGroup_Click(object sender, EventArgs e)
+ {
+ ContactGroup selectedGroup = (ContactGroup)treeViewFavoriteList.SelectedNode.Tag;
+ this.propertyGrid.SelectedObject = selectedGroup;
+
+ messenger.ContactGroups.Remove(selectedGroup);
+
+ System.Threading.Thread.Sleep(500);
+ Application.DoEvents();
+ System.Threading.Thread.Sleep(500);
+
+ SortByGroup(null);
+ }
+
+ private void btnAddNew_Click(object sender, EventArgs e)
+ {
+ if (this.loginButton.Tag.ToString() != "2")
+ {
+ MessageBox.Show("Please sign in first.");
+ return;
+ }
+
+ AddContactForm acf = new AddContactForm(String.Empty);
+ if (DialogResult.OK == acf.ShowDialog(this) && acf.Account != String.Empty)
+ {
+ messenger.ContactService.AddNewContact(acf.Account, acf.InvitationMessage);
+ }
+ }
+
+ private void createCircleMenuItem_Click(object sender, EventArgs e)
+ {
+ //This is a demostration to tell you how to use MSNPSharp to create, block, and unblock Circle.
+ messenger.ContactService.CreateCircle("test wp circle");
+ messenger.ContactService.CreateCircleCompleted += new EventHandler(ContactService_TestingCircleAdded);
+ }
+
+ void ContactService_TestingCircleAdded(object sender, CircleEventArgs e)
+ {
+ //Circle created, then show you how to block.
+ ////if (!e.Circle.OnBlockedList)
+ ////{
+ //// messenger.ContactService.BlockCircle(e.Circle);
+ //// e.Circle.ContactBlocked += new EventHandler(Circle_ContactBlocked);
+ //// Trace.WriteLine("Circle blocked: " + e.Circle.ToString());
+ ////}
+
+ ////Trace.WriteLine("Circle created: " + e.Circle.ToString());
+ }
+
+ void Circle_ContactBlocked(object sender, EventArgs e)
+ {
+ //Circle blocked, show you how to unblock.
+ Circle circle = sender as Circle;
+ if (circle != null)
+ {
+ messenger.ContactService.UnBlockCircle(circle);
+ circle.ContactUnBlocked += new EventHandler(circle_ContactUnBlocked);
+ Trace.WriteLine("Circle unblocked: " + circle.ToString());
+ }
+ }
+
+ void circle_ContactUnBlocked(object sender, EventArgs e)
+ {
+ //This demo shows you how to invite a contact to your circle.
+ if (messenger.ContactList.HasContact("freezingsoft@hotmail.com", ClientType.PassportMember))
+ {
+ messenger.ContactService.InviteCircleMember(sender as Circle, messenger.ContactList["freezingsoft@hotmail.com", ClientType.PassportMember], "hello");
+ messenger.ContactService.InviteCircleMemberCompleted += new EventHandler(ContactService_CircleMemberInvited);
+ }
+ }
+
+ void ContactService_CircleMemberInvited(object sender, CircleMemberEventArgs e)
+ {
+ Trace.WriteLine("Invited: " + e.Member.Hash);
+ }
+
+ private void importContactsMenuItem_Click(object sender, EventArgs e)
+ {
+ ImportContacts ic = new ImportContacts();
+ if (ic.ShowDialog(this) == DialogResult.OK)
+ {
+ string invitation = ic.InvitationMessage;
+ foreach (String account in ic.Contacts)
+ {
+ messenger.ContactService.AddNewContact(account, invitation);
+ }
+ }
+ }
+
+ private void txtSearch_TextChanged(object sender, EventArgs e)
+ {
+ if (txtSearch.Text == String.Empty || txtSearch.Text == "Search contacts")
+ {
+ treeViewFilterList.Nodes.Clear();
+ treeViewFavoriteList.Visible = true;
+ treeViewFilterList.Visible = false;
+ }
+ else
+ {
+ treeViewFilterList.Nodes.Clear();
+ treeViewFavoriteList.Visible = false;
+ treeViewFilterList.Visible = true;
+ TreeNode foundnode = treeViewFilterList.Nodes.Add("0", "Search Results:");
+
+ foreach (Contact contact in messenger.ContactList.All)
+ {
+ if (contact.Mail.IndexOf(txtSearch.Text, StringComparison.CurrentCultureIgnoreCase) != -1
+ ||
+ contact.Name.IndexOf(txtSearch.Text, StringComparison.CurrentCultureIgnoreCase) != -1)
+ {
+ TreeNode newnode = foundnode.Nodes.Add(contact.Hash, contact.Name);
+ newnode.NodeFont = contact.Blocked ? USER_NODE_FONT_BANNED : USER_NODE_FONT;
+ newnode.Tag = contact;
+ }
+ }
+ foundnode.Text = "Search Results: " + foundnode.Nodes.Count;
+ foundnode.Expand();
+ }
+ }
+
+ private void txtSearch_Enter(object sender, EventArgs e)
+ {
+ if (txtSearch.Text == "Search contacts")
+ {
+ txtSearch.Text = String.Empty;
+ }
+ }
+
+ private void txtSearch_Leave(object sender, EventArgs e)
+ {
+ if (txtSearch.Text == String.Empty)
+ {
+ txtSearch.Text = "Search contacts";
+ }
+ }
+
+ private void lblName_Leave(object sender, EventArgs e)
+ {
+ string dn = lblName.Text;
+ string pm = lblPM.Text;
+
+ List lstPersonalMessage = new List(new string[] { "", "" });
+
+ if (dn != messenger.ContactList.Owner.Name)
+ {
+
+ lstPersonalMessage[0] = dn;
+ }
+
+ if (messenger.ContactList.Owner.PersonalMessage == null || pm != messenger.ContactList.Owner.PersonalMessage.Message)
+ {
+ lstPersonalMessage[1] = pm;
+
+ }
+
+ Thread updateThread = new Thread(new ParameterizedThreadStart(UpdateProfile));
+ updateThread.Start(lstPersonalMessage);
+ }
+
+ private void comboStatus_KeyPress(object sender, KeyPressEventArgs e)
+ {
+ if (!messenger.Connected)
+ {
+ login_KeyPress(sender, e);
+ }
+ }
+
+ private void displayImageBox_Click(object sender, EventArgs e)
+ {
+ if (messenger.Connected)
+ {
+ if (openImageDialog.ShowDialog() == DialogResult.OK)
+ {
+ Image newImage = Image.FromFile(openImageDialog.FileName, true);
+ Thread updateThread = new Thread(new ParameterizedThreadStart(UpdateProfile));
+ updateThread.Start(newImage);
+ }
+ }
+ }
+
+ private void UpdateProfile(object profileObject)
+ {
+ Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "Updating owner profile, please wait....");
+
+ if (profileObject is Image)
+ {
+ bool updateResult = messenger.StorageService.UpdateProfile(profileObject as Image, "MyPhoto");
+ Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "Update displayimage completed. Result = " + updateResult);
+ }
+
+ if (profileObject is List)
+ {
+ List lstPersonalMessage = profileObject as List;
+ if (lstPersonalMessage[0] != "")
+ {
+ messenger.ContactList.Owner.Name = lstPersonalMessage[0];
+ }
+
+ if (lstPersonalMessage[1] != "")
+ {
+ messenger.ContactList.Owner.PersonalMessage = new PersonalMessage(lstPersonalMessage[1], MediaType.None, null, NSMessageHandler.MachineGuid);
+ }
+
+ Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "Update personal message completed.");
+ }
+ }
+
+ private void btnSetMusic_Click(object sender, EventArgs e)
+ {
+ MusicForm musicForm = new MusicForm();
+ if (musicForm.ShowDialog() == DialogResult.OK)
+ {
+ Messenger.ContactList.Owner.PersonalMessage = new PersonalMessage(
+ Messenger.ContactList.Owner.PersonalMessage.Message,
+ MediaType.Music,
+ new string[] { musicForm.Artist, musicForm.Song, musicForm.Album, "" },
+ NSMessageHandler.MachineGuid);
+ }
+ }
+
+
+ }
+}
diff --git a/Example/DotMSNClient.csproj b/Example/DotMSNClient.csproj
new file mode 100644
index 0000000..b9b26b0
--- /dev/null
+++ b/Example/DotMSNClient.csproj
@@ -0,0 +1,257 @@
+
+
+
+ Local
+ 8.0.50727
+ 2.0
+ {BDF3E472-EFE8-44D6-AFB6-062DD929D56F}
+ Debug
+ AnyCPU
+ MSNPSharp_logo.ico
+
+
+ DotMSNClient
+ JScript
+ Grid
+ IE50
+ false
+ WinExe
+ MSNPSharpClient
+ OnBuildSuccess
+ MSNPSharpClient.ClientForm
+
+
+
+
+ v2.0
+ 2.0
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+ bin\Debug\
+ 285212672
+
+
+ TRACE;DEBUG
+
+
+ true
+ 4096
+ false
+ false
+ false
+ 4
+ full
+ prompt
+ AllRules.ruleset
+
+
+ bin\Release\
+ 285212672
+
+
+ TRACE
+
+
+ 4096
+ true
+ false
+ false
+ 4
+ none
+ prompt
+ AllRules.ruleset
+
+
+
+ System
+
+
+ System.Data
+
+
+ System.Drawing
+
+
+
+
+ System.Windows.Forms
+
+
+ System.XML
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ AddContactForm.cs
+
+
+ Form
+
+
+ Form
+
+
+ FileTransferForm.cs
+
+
+ Form
+
+
+ DotMSNClient.cs
+
+
+ Form
+
+
+ ImportContacts.cs
+
+
+ Form
+
+
+ MusicForm.cs
+
+
+
+ True
+ True
+ Resources.resx
+
+
+ Form
+
+
+ RemoveContactForm.cs
+
+
+ Form
+
+
+ ReverseAddedForm.cs
+
+
+ Component
+
+
+ Form
+
+
+ TraceForm.cs
+
+
+ Designer
+ AddContactForm.cs
+
+
+ ConversationForm.cs
+ Designer
+
+
+ FileTransferForm.cs
+ Designer
+
+
+ DotMSNClient.cs
+ Designer
+
+
+ Designer
+ ImportContacts.cs
+
+
+ Designer
+ MusicForm.cs
+
+
+ Designer
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+ Designer
+ RemoveContactForm.cs
+
+
+ Designer
+ ReverseAddedForm.cs
+
+
+ Designer
+ TraceForm.cs
+
+
+
+
+ {97CB2DC7-2FE8-4AF5-84D0-6B9872A5E960}
+ MSNPSharp
+
+
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ true
+
+
+ False
+ Windows Installer 3.1
+ true
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Example/DotMSNClient.csproj.user b/Example/DotMSNClient.csproj.user
new file mode 100644
index 0000000..6f23531
--- /dev/null
+++ b/Example/DotMSNClient.csproj.user
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+ en-US
+ false
+
+
\ No newline at end of file
diff --git a/Example/DotMSNClient.resx b/Example/DotMSNClient.resx
new file mode 100644
index 0000000..19a2329
--- /dev/null
+++ b/Example/DotMSNClient.resx
@@ -0,0 +1,150 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 118, 17
+
+
+ 776, 17
+
+
+ 506, 17
+
+
+ 228, 17
+
+
+ 639, 17
+
+
+ 17, 17
+
+
+ 17, 56
+
+
+ 163, 56
+
+
+ 322, 56
+
+
+ 76
+
+
\ No newline at end of file
diff --git a/Example/FileTransferForm.Designer.cs b/Example/FileTransferForm.Designer.cs
new file mode 100644
index 0000000..da2292e
--- /dev/null
+++ b/Example/FileTransferForm.Designer.cs
@@ -0,0 +1,164 @@
+namespace MSNPSharpClient
+{
+ partial class FileTransferForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.lblFile = new System.Windows.Forms.Label();
+ this.txtFilePath = new System.Windows.Forms.TextBox();
+ this.btnOK = new System.Windows.Forms.Button();
+ this.btnCancel = new System.Windows.Forms.Button();
+ this.progressBar = new System.Windows.Forms.ProgressBar();
+ this.button1 = new System.Windows.Forms.Button();
+ this.saveFileDialog = new System.Windows.Forms.SaveFileDialog();
+ this.label1 = new System.Windows.Forms.Label();
+ this.lblSize = new System.Windows.Forms.Label();
+ this.SuspendLayout();
+ //
+ // lblFile
+ //
+ this.lblFile.AutoSize = true;
+ this.lblFile.Location = new System.Drawing.Point(18, 8);
+ this.lblFile.Name = "lblFile";
+ this.lblFile.Size = new System.Drawing.Size(29, 12);
+ this.lblFile.TabIndex = 0;
+ this.lblFile.Text = "File";
+ //
+ // txtFilePath
+ //
+ this.txtFilePath.Location = new System.Drawing.Point(64, 6);
+ this.txtFilePath.Name = "txtFilePath";
+ this.txtFilePath.Size = new System.Drawing.Size(270, 21);
+ this.txtFilePath.TabIndex = 3;
+ this.txtFilePath.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
+ //
+ // btnOK
+ //
+ this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.btnOK.Location = new System.Drawing.Point(64, 94);
+ this.btnOK.Name = "btnOK";
+ this.btnOK.Size = new System.Drawing.Size(164, 37);
+ this.btnOK.TabIndex = 6;
+ this.btnOK.Tag = "OK";
+ this.btnOK.Text = "OK";
+ this.btnOK.UseVisualStyleBackColor = true;
+ this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
+ //
+ // btnCancel
+ //
+ this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.btnCancel.Location = new System.Drawing.Point(237, 94);
+ this.btnCancel.Name = "btnCancel";
+ this.btnCancel.Size = new System.Drawing.Size(97, 37);
+ this.btnCancel.TabIndex = 7;
+ this.btnCancel.Text = "Cancel";
+ this.btnCancel.UseVisualStyleBackColor = true;
+ this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
+ //
+ // progressBar
+ //
+ this.progressBar.Location = new System.Drawing.Point(64, 56);
+ this.progressBar.Name = "progressBar";
+ this.progressBar.Size = new System.Drawing.Size(270, 21);
+ this.progressBar.Step = 1;
+ this.progressBar.TabIndex = 8;
+ this.progressBar.Visible = false;
+ //
+ // button1
+ //
+ this.button1.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.button1.Location = new System.Drawing.Point(254, 30);
+ this.button1.Name = "button1";
+ this.button1.Size = new System.Drawing.Size(80, 21);
+ this.button1.TabIndex = 9;
+ this.button1.Text = "Browse...";
+ this.button1.UseVisualStyleBackColor = true;
+ this.button1.Click += new System.EventHandler(this.button1_Click);
+ //
+ // saveFileDialog
+ //
+ this.saveFileDialog.Filter = "*.*|*.*";
+ this.saveFileDialog.RestoreDirectory = true;
+ this.saveFileDialog.Title = "Save as...";
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(18, 34);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(29, 12);
+ this.label1.TabIndex = 10;
+ this.label1.Text = "Size";
+ //
+ // lblSize
+ //
+ this.lblSize.AutoSize = true;
+ this.lblSize.Location = new System.Drawing.Point(61, 34);
+ this.lblSize.Name = "lblSize";
+ this.lblSize.Size = new System.Drawing.Size(35, 12);
+ this.lblSize.TabIndex = 11;
+ this.lblSize.Text = "bytes";
+ //
+ // FileTransferForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.CancelButton = this.btnCancel;
+ this.ClientSize = new System.Drawing.Size(345, 142);
+ this.ControlBox = false;
+ this.Controls.Add(this.lblSize);
+ this.Controls.Add(this.label1);
+ this.Controls.Add(this.button1);
+ this.Controls.Add(this.progressBar);
+ this.Controls.Add(this.btnCancel);
+ this.Controls.Add(this.btnOK);
+ this.Controls.Add(this.txtFilePath);
+ this.Controls.Add(this.lblFile);
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "FileTransferForm";
+ this.Text = "File Transfer";
+ this.Load += new System.EventHandler(this.FileTransferForm_Load);
+ this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FileTransferForm_FormClosing);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Label lblFile;
+ private System.Windows.Forms.TextBox txtFilePath;
+ private System.Windows.Forms.Button btnOK;
+ private System.Windows.Forms.Button btnCancel;
+ private System.Windows.Forms.ProgressBar progressBar;
+ private System.Windows.Forms.Button button1;
+ private System.Windows.Forms.SaveFileDialog saveFileDialog;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Label lblSize;
+ }
+}
\ No newline at end of file
diff --git a/Example/FileTransferForm.cs b/Example/FileTransferForm.cs
new file mode 100644
index 0000000..cad3cb0
--- /dev/null
+++ b/Example/FileTransferForm.cs
@@ -0,0 +1,172 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Diagnostics;
+
+namespace MSNPSharpClient
+{
+ using MSNPSharp;
+ using MSNPSharp.Core;
+ using MSNPSharp.DataTransfer;
+
+
+ public partial class FileTransferForm : Form
+ {
+ MSNSLPInvitationEventArgs invite;
+ private bool transferFinished;
+
+ public FileTransferForm(MSNSLPInvitationEventArgs invite)
+ {
+ this.invite = invite;
+ InitializeComponent();
+ }
+
+ private void FileTransferForm_Load(object sender, EventArgs e)
+ {
+ string appPath = Path.GetFullPath(".");
+
+ Text = "File Transfer: " + invite.TransferProperties.RemoteContact.Mail;
+ txtFilePath.Text = Path.Combine(appPath, invite.Filename);
+ lblSize.Text = invite.FileSize.ToString() + " bytes";
+
+ invite.TransferSession.TransferStarted += (TransferSession_TransferStarted);
+ invite.TransferSession.TransferProgressed += (TransferSession_TransferProgressed);
+ invite.TransferSession.TransferAborted += (TransferSession_TransferAborted);
+ invite.TransferSession.TransferFinished += (TransferSession_TransferFinished);
+ }
+
+ void TransferSession_TransferStarted(object sender, EventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new EventHandler(TransferSession_TransferStarted), sender, e);
+ return;
+ }
+
+ progressBar.Visible = true;
+ lblSize.Text = "Transfer started";
+ }
+
+ void TransferSession_TransferProgressed(object sender, P2PTransferProgressedEventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new EventHandler(TransferSession_TransferProgressed), sender, e);
+ return;
+ }
+ progressBar.Visible = true;
+ progressBar.Value = e.Percent;
+ lblSize.Text = "Transferred: " + e.Transferred + " / " + e.TotalSize;
+ }
+
+ void TransferSession_TransferFinished(object sender, EventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new EventHandler(TransferSession_TransferFinished), sender, e);
+ return;
+ }
+
+ transferFinished = true;
+
+ btnOK.Text = "Open File";
+ btnOK.Tag = "OPENFILE";
+ btnCancel.Visible = true;
+
+ lblSize.Text = "Transfer finished";
+ progressBar.Visible = false;
+ progressBar.Value = 0;
+ }
+
+ void TransferSession_TransferAborted(object sender, EventArgs e)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new EventHandler(TransferSession_TransferAborted), sender, e);
+ return;
+ }
+
+ btnOK.Text = "Close";
+ btnOK.Tag = "CLOSE";
+ lblSize.Text = "Transfer aborted";
+
+ progressBar.Visible = false;
+ progressBar.Value = 0;
+
+ }
+
+ private void button1_Click(object sender, EventArgs e)
+ {
+ if (saveFileDialog.ShowDialog() == DialogResult.OK)
+ {
+ txtFilePath.Text = saveFileDialog.FileName;
+ }
+ }
+
+ private void btnCancel_Click(object sender, EventArgs e)
+ {
+ if (transferFinished)
+ {
+ Close();
+ }
+ else
+ {
+ invite.Accept = false;
+ invite.TransferHandler.RejectTransfer(invite);
+
+ btnCancel.Visible = false;
+ Close();
+ }
+ }
+
+ private void btnOK_Click(object sender, EventArgs e)
+ {
+ switch (btnOK.Tag.ToString())
+ {
+ case "OK":
+
+ invite.TransferSession.DataStream = new FileStream(txtFilePath.Text, FileMode.Create, FileAccess.Write);
+ invite.TransferSession.AutoCloseStream = true;
+ invite.Accept = true;
+ invite.TransferHandler.AcceptTransfer(invite);
+
+ btnCancel.Visible = false;
+
+ lblSize.Text = "Waiting to start...";
+
+ btnOK.Text = "Abort Transfer";
+ btnOK.Tag = "ABORT";
+ break;
+
+ case "ABORT":
+ invite.TransferHandler.CloseSession(invite.TransferSession);
+ btnOK.Text = "Close";
+ btnOK.Tag = "CLOSE";
+ break;
+
+ case "OPENFILE":
+ Process.Start(txtFilePath.Text);
+ Close();
+ break;
+
+ case "CLOSE":
+ Close();
+ break;
+ }
+ }
+
+ private void FileTransferForm_FormClosing(object sender, FormClosingEventArgs e)
+ {
+ invite.TransferSession.TransferStarted -= (TransferSession_TransferStarted);
+ invite.TransferSession.TransferProgressed -= (TransferSession_TransferProgressed);
+ invite.TransferSession.TransferAborted -= (TransferSession_TransferAborted);
+ invite.TransferSession.TransferFinished -= (TransferSession_TransferFinished);
+ }
+
+ }
+};
\ No newline at end of file
diff --git a/Example/FileTransferForm.resx b/Example/FileTransferForm.resx
new file mode 100644
index 0000000..d957dca
--- /dev/null
+++ b/Example/FileTransferForm.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/Example/ImportContacts.Designer.cs b/Example/ImportContacts.Designer.cs
new file mode 100644
index 0000000..f3e9914
--- /dev/null
+++ b/Example/ImportContacts.Designer.cs
@@ -0,0 +1,120 @@
+namespace MSNPSharpClient
+{
+ partial class ImportContacts
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
+ this.lblInvitation = new System.Windows.Forms.Label();
+ this.txtInvitation = new System.Windows.Forms.TextBox();
+ this.browseFile = new System.Windows.Forms.Button();
+ this.button1 = new System.Windows.Forms.Button();
+ this.button2 = new System.Windows.Forms.Button();
+ this.SuspendLayout();
+ //
+ // openFileDialog
+ //
+ this.openFileDialog.DefaultExt = "ctt";
+ this.openFileDialog.Filter = "Messenger Contact List|*.ctt";
+ this.openFileDialog.Title = "Select Contact File";
+ //
+ // lblInvitation
+ //
+ this.lblInvitation.AutoSize = true;
+ this.lblInvitation.Location = new System.Drawing.Point(12, 20);
+ this.lblInvitation.Name = "lblInvitation";
+ this.lblInvitation.Size = new System.Drawing.Size(96, 13);
+ this.lblInvitation.TabIndex = 0;
+ this.lblInvitation.Text = "Invitation Message";
+ //
+ // txtInvitation
+ //
+ this.txtInvitation.Location = new System.Drawing.Point(114, 17);
+ this.txtInvitation.Name = "txtInvitation";
+ this.txtInvitation.Size = new System.Drawing.Size(342, 20);
+ this.txtInvitation.TabIndex = 1;
+ this.txtInvitation.Text = "Accept me :)";
+ //
+ // browseFile
+ //
+ this.browseFile.Location = new System.Drawing.Point(114, 43);
+ this.browseFile.Name = "browseFile";
+ this.browseFile.Size = new System.Drawing.Size(134, 23);
+ this.browseFile.TabIndex = 2;
+ this.browseFile.Text = "Browse Contact File...";
+ this.browseFile.UseVisualStyleBackColor = true;
+ this.browseFile.Click += new System.EventHandler(this.browseFile_Click);
+ //
+ // button1
+ //
+ this.button1.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.button1.Location = new System.Drawing.Point(283, 73);
+ this.button1.Name = "button1";
+ this.button1.Size = new System.Drawing.Size(84, 23);
+ this.button1.TabIndex = 3;
+ this.button1.Text = "OK";
+ this.button1.UseVisualStyleBackColor = true;
+ this.button1.Click += new System.EventHandler(this.button_Click);
+ //
+ // button2
+ //
+ this.button2.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.button2.Location = new System.Drawing.Point(373, 73);
+ this.button2.Name = "button2";
+ this.button2.Size = new System.Drawing.Size(83, 23);
+ this.button2.TabIndex = 4;
+ this.button2.Text = "Cancel";
+ this.button2.UseVisualStyleBackColor = true;
+ this.button2.Click += new System.EventHandler(this.button_Click);
+ //
+ // ImportContacts
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(466, 108);
+ this.Controls.Add(this.button2);
+ this.Controls.Add(this.button1);
+ this.Controls.Add(this.browseFile);
+ this.Controls.Add(this.txtInvitation);
+ this.Controls.Add(this.lblInvitation);
+ this.Name = "ImportContacts";
+ this.Text = "Import Contacts";
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.OpenFileDialog openFileDialog;
+ private System.Windows.Forms.Label lblInvitation;
+ private System.Windows.Forms.TextBox txtInvitation;
+ private System.Windows.Forms.Button browseFile;
+ private System.Windows.Forms.Button button1;
+ private System.Windows.Forms.Button button2;
+ }
+}
\ No newline at end of file
diff --git a/Example/ImportContacts.cs b/Example/ImportContacts.cs
new file mode 100644
index 0000000..8df59d5
--- /dev/null
+++ b/Example/ImportContacts.cs
@@ -0,0 +1,73 @@
+using System;
+using System.IO;
+using System.Xml;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using MSNPSharp;
+
+namespace MSNPSharpClient
+{
+ public partial class ImportContacts : Form
+ {
+ public ImportContacts()
+ {
+ InitializeComponent();
+ }
+
+
+ private string invitationMessage = String.Empty;
+ public string InvitationMessage
+ {
+ get
+ {
+ return invitationMessage;
+ }
+ }
+
+ private List _contacts = new List();
+ public List Contacts
+ {
+ get
+ {
+ return _contacts;
+ }
+ }
+
+ private void browseFile_Click(object sender, EventArgs e)
+ {
+ if (DialogResult.OK == openFileDialog.ShowDialog(this))
+ {
+ Contacts.Clear();
+ invitationMessage = txtInvitation.Text;
+ try
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(File.ReadAllText(openFileDialog.FileName));
+
+ XmlNodeList contacts = doc.GetElementsByTagName("contact");
+ foreach (XmlNode contactNode in contacts)
+ {
+ if (ClientType.PassportMember == (ClientType)Convert.ToInt32(contactNode.Attributes["type"].Value))
+ {
+ Contacts.Add(contactNode.InnerText.ToLower(System.Globalization.CultureInfo.InvariantCulture));
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message);
+ }
+ MessageBox.Show(Contacts.Count.ToString() + " contacts to be imported.");
+ }
+ }
+
+ private void button_Click(object sender, EventArgs e)
+ {
+ Close();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Example/ImportContacts.resx b/Example/ImportContacts.resx
new file mode 100644
index 0000000..f901ebb
--- /dev/null
+++ b/Example/ImportContacts.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/Example/MSNPSharp_logo.ico b/Example/MSNPSharp_logo.ico
new file mode 100644
index 0000000..7ba3fdb
Binary files /dev/null and b/Example/MSNPSharp_logo.ico differ
diff --git a/Example/MusicForm.Designer.cs b/Example/MusicForm.Designer.cs
new file mode 100644
index 0000000..1de16ea
--- /dev/null
+++ b/Example/MusicForm.Designer.cs
@@ -0,0 +1,142 @@
+namespace MSNPSharpClient
+{
+ partial class MusicForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.lblArtist = new System.Windows.Forms.Label();
+ this.lblSong = new System.Windows.Forms.Label();
+ this.lblAlbum = new System.Windows.Forms.Label();
+ this.txtArtist = new System.Windows.Forms.TextBox();
+ this.txtSong = new System.Windows.Forms.TextBox();
+ this.txtAlbum = new System.Windows.Forms.TextBox();
+ this.btnOK = new System.Windows.Forms.Button();
+ this.btnCancel = new System.Windows.Forms.Button();
+ this.SuspendLayout();
+ //
+ // lblArtist
+ //
+ this.lblArtist.AutoSize = true;
+ this.lblArtist.Location = new System.Drawing.Point(18, 9);
+ this.lblArtist.Name = "lblArtist";
+ this.lblArtist.Size = new System.Drawing.Size(30, 13);
+ this.lblArtist.TabIndex = 0;
+ this.lblArtist.Text = "Artist";
+ //
+ // lblSong
+ //
+ this.lblSong.AutoSize = true;
+ this.lblSong.Location = new System.Drawing.Point(16, 35);
+ this.lblSong.Name = "lblSong";
+ this.lblSong.Size = new System.Drawing.Size(32, 13);
+ this.lblSong.TabIndex = 1;
+ this.lblSong.Text = "Song";
+ //
+ // lblAlbum
+ //
+ this.lblAlbum.AutoSize = true;
+ this.lblAlbum.Location = new System.Drawing.Point(12, 59);
+ this.lblAlbum.Name = "lblAlbum";
+ this.lblAlbum.Size = new System.Drawing.Size(36, 13);
+ this.lblAlbum.TabIndex = 2;
+ this.lblAlbum.Text = "Album";
+ //
+ // txtArtist
+ //
+ this.txtArtist.Location = new System.Drawing.Point(64, 6);
+ this.txtArtist.Name = "txtArtist";
+ this.txtArtist.Size = new System.Drawing.Size(297, 20);
+ this.txtArtist.TabIndex = 3;
+ //
+ // txtSong
+ //
+ this.txtSong.Location = new System.Drawing.Point(64, 32);
+ this.txtSong.Name = "txtSong";
+ this.txtSong.Size = new System.Drawing.Size(297, 20);
+ this.txtSong.TabIndex = 4;
+ //
+ // txtAlbum
+ //
+ this.txtAlbum.Location = new System.Drawing.Point(64, 56);
+ this.txtAlbum.Name = "txtAlbum";
+ this.txtAlbum.Size = new System.Drawing.Size(297, 20);
+ this.txtAlbum.TabIndex = 5;
+ //
+ // btnOK
+ //
+ this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.btnOK.Location = new System.Drawing.Point(204, 82);
+ this.btnOK.Name = "btnOK";
+ this.btnOK.Size = new System.Drawing.Size(75, 23);
+ this.btnOK.TabIndex = 6;
+ this.btnOK.Text = "OK";
+ this.btnOK.UseVisualStyleBackColor = true;
+ //
+ // btnCancel
+ //
+ this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.btnCancel.Location = new System.Drawing.Point(285, 82);
+ this.btnCancel.Name = "btnCancel";
+ this.btnCancel.Size = new System.Drawing.Size(76, 23);
+ this.btnCancel.TabIndex = 7;
+ this.btnCancel.Text = "Cancel";
+ this.btnCancel.UseVisualStyleBackColor = true;
+ //
+ // MusicForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(374, 113);
+ this.Controls.Add(this.btnCancel);
+ this.Controls.Add(this.btnOK);
+ this.Controls.Add(this.txtAlbum);
+ this.Controls.Add(this.txtSong);
+ this.Controls.Add(this.txtArtist);
+ this.Controls.Add(this.lblAlbum);
+ this.Controls.Add(this.lblSong);
+ this.Controls.Add(this.lblArtist);
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "MusicForm";
+ this.Text = "I am Listening...";
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Label lblArtist;
+ private System.Windows.Forms.Label lblSong;
+ private System.Windows.Forms.Label lblAlbum;
+ private System.Windows.Forms.TextBox txtArtist;
+ private System.Windows.Forms.TextBox txtSong;
+ private System.Windows.Forms.TextBox txtAlbum;
+ private System.Windows.Forms.Button btnOK;
+ private System.Windows.Forms.Button btnCancel;
+ }
+}
\ No newline at end of file
diff --git a/Example/MusicForm.cs b/Example/MusicForm.cs
new file mode 100644
index 0000000..b4b177d
--- /dev/null
+++ b/Example/MusicForm.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+
+namespace MSNPSharpClient
+{
+ public partial class MusicForm : Form
+ {
+ public MusicForm()
+ {
+ InitializeComponent();
+ }
+
+
+ public string Artist
+ {
+ get
+ {
+ return txtArtist.Text;
+ }
+ }
+
+ public string Song
+ {
+ get
+ {
+ return txtSong.Text;
+ }
+ }
+
+ public string Album
+ {
+ get
+ {
+ return txtSong.Text;
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Example/MusicForm.resx b/Example/MusicForm.resx
new file mode 100644
index 0000000..19dc0dd
--- /dev/null
+++ b/Example/MusicForm.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Example/Properties/AssemblyInfo.cs b/Example/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..2d78b1d
--- /dev/null
+++ b/Example/Properties/AssemblyInfo.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: ComVisibleAttribute(false)]
+[assembly: CLSCompliantAttribute(false)]
+[assembly: AssemblyTitleAttribute("MSNPSharp Example Client")]
+[assembly: AssemblyDescriptionAttribute(".NET MSN Messenger library Example Client")]
+[assembly: AssemblyCopyrightAttribute("Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions (http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice.")]
+[assembly: AssemblyProductAttribute("MSNPSharp")]
+[assembly: AssemblyDelaySignAttribute(false)]
+[assembly: GuidAttribute("FAE04EC0-301F-11D3-BF4B-00C04F79EFBC")]
+
+// Version information for an assembly consists of the following four values:
+// Major.Minor.Build.SVNRevision
+[assembly: AssemblyVersionAttribute("3.2.1.2668")]
+[assembly: AssemblyFileVersionAttribute("3.2.1.2668")]
+[assembly: AssemblyCompanyAttribute("MSNPSharp")]
+[assembly: AssemblyTrademarkAttribute("MSNPSharp")]
diff --git a/Example/Properties/Resources.Designer.cs b/Example/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..4eaef34
--- /dev/null
+++ b/Example/Properties/Resources.Designer.cs
@@ -0,0 +1,303 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace MSNPSharpClient.Properties {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MSNPSharpClient.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap app_banner {
+ get {
+ object obj = ResourceManager.GetObject("app_banner", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap away {
+ get {
+ object obj = ResourceManager.GetObject("away", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap biggrin {
+ get {
+ object obj = ResourceManager.GetObject("biggrin", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap busy {
+ get {
+ object obj = ResourceManager.GetObject("busy", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap circle {
+ get {
+ object obj = ResourceManager.GetObject("circle", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap closed {
+ get {
+ object obj = ResourceManager.GetObject("closed", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap Color_fontHS {
+ get {
+ object obj = ResourceManager.GetObject("Color_fontHS", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap file {
+ get {
+ object obj = ResourceManager.GetObject("file", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap hidden {
+ get {
+ object obj = ResourceManager.GetObject("hidden", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap idle {
+ get {
+ object obj = ResourceManager.GetObject("idle", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap inner_emoticon {
+ get {
+ object obj = ResourceManager.GetObject("inner_emoticon", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap loading {
+ get {
+ object obj = ResourceManager.GetObject("loading", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
+ ///
+ internal static System.Drawing.Icon msn_ico {
+ get {
+ object obj = ResourceManager.GetObject("msn_ico", resourceCulture);
+ return ((System.Drawing.Icon)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
+ ///
+ internal static System.Drawing.Icon MSNPSharp_logo_small_ico {
+ get {
+ object obj = ResourceManager.GetObject("MSNPSharp_logo_small_ico", resourceCulture);
+ return ((System.Drawing.Icon)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap nudge {
+ get {
+ object obj = ResourceManager.GetObject("nudge", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap offline {
+ get {
+ object obj = ResourceManager.GetObject("offline", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap online {
+ get {
+ object obj = ResourceManager.GetObject("online", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap open {
+ get {
+ object obj = ResourceManager.GetObject("open", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap sad {
+ get {
+ object obj = ResourceManager.GetObject("sad", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap smiley {
+ get {
+ object obj = ResourceManager.GetObject("smiley", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap tongueout {
+ get {
+ object obj = ResourceManager.GetObject("tongueout", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap wink {
+ get {
+ object obj = ResourceManager.GetObject("wink", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
+ ///
+ internal static System.Drawing.Icon yahoo_ico {
+ get {
+ object obj = ResourceManager.GetObject("yahoo_ico", resourceCulture);
+ return ((System.Drawing.Icon)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap YahooMessenger_logo {
+ get {
+ object obj = ResourceManager.GetObject("YahooMessenger_logo", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+ }
+}
diff --git a/Example/Properties/Resources.resx b/Example/Properties/Resources.resx
new file mode 100644
index 0000000..fe10750
--- /dev/null
+++ b/Example/Properties/Resources.resx
@@ -0,0 +1,193 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+ ..\Resources\yahoo_ico.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\smileys\sad.gif;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\nudge.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\MSNPSharp_logo_small.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\smileys\biggrin.gif;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\status\away.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\msn_ico.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\status\idle.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\loading.gif;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\smileys\wink.gif;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\status\busy.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\status\hidden.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\status\online.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\file.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\status\offline.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\status\circle.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\status\closed.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\YahooMessenger_logo.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\status\open.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\smileys\tongueout.gif;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\smileys\smiley.gif;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\inner_emoicon.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\app_banner.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\Color_fontHS.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
\ No newline at end of file
diff --git a/Example/RemoveContactForm.Designer.cs b/Example/RemoveContactForm.Designer.cs
new file mode 100644
index 0000000..56e6e8c
--- /dev/null
+++ b/Example/RemoveContactForm.Designer.cs
@@ -0,0 +1,102 @@
+namespace MSNPSharpClient
+{
+ partial class RemoveContactForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.cbRemove = new System.Windows.Forms.CheckBox();
+ this.cbBlock = new System.Windows.Forms.CheckBox();
+ this.btnRemove = new System.Windows.Forms.Button();
+ this.btnCancel = new System.Windows.Forms.Button();
+ this.SuspendLayout();
+ //
+ // cbRemove
+ //
+ this.cbRemove.AutoSize = true;
+ this.cbRemove.Location = new System.Drawing.Point(12, 21);
+ this.cbRemove.Name = "cbRemove";
+ this.cbRemove.Size = new System.Drawing.Size(201, 17);
+ this.cbRemove.TabIndex = 0;
+ this.cbRemove.Text = "Remove this user from my contact list";
+ this.cbRemove.UseVisualStyleBackColor = true;
+ //
+ // cbBlock
+ //
+ this.cbBlock.AutoSize = true;
+ this.cbBlock.Location = new System.Drawing.Point(12, 44);
+ this.cbBlock.Name = "cbBlock";
+ this.cbBlock.Size = new System.Drawing.Size(75, 17);
+ this.cbBlock.TabIndex = 1;
+ this.cbBlock.Text = "Also block";
+ this.cbBlock.UseVisualStyleBackColor = true;
+ //
+ // btnRemove
+ //
+ this.btnRemove.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.btnRemove.Location = new System.Drawing.Point(24, 76);
+ this.btnRemove.Name = "btnRemove";
+ this.btnRemove.Size = new System.Drawing.Size(99, 23);
+ this.btnRemove.TabIndex = 2;
+ this.btnRemove.Text = "Remove contact";
+ this.btnRemove.UseVisualStyleBackColor = true;
+ this.btnRemove.Click += new System.EventHandler(this.btn_Click);
+ //
+ // btnCancel
+ //
+ this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.btnCancel.Location = new System.Drawing.Point(129, 76);
+ this.btnCancel.Name = "btnCancel";
+ this.btnCancel.Size = new System.Drawing.Size(75, 23);
+ this.btnCancel.TabIndex = 3;
+ this.btnCancel.Text = "Cancel";
+ this.btnCancel.UseVisualStyleBackColor = true;
+ this.btnCancel.Click += new System.EventHandler(this.btn_Click);
+ //
+ // RemoveContactForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(217, 113);
+ this.Controls.Add(this.btnCancel);
+ this.Controls.Add(this.btnRemove);
+ this.Controls.Add(this.cbBlock);
+ this.Controls.Add(this.cbRemove);
+ this.Name = "RemoveContactForm";
+ this.Text = "Remove Contact";
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.CheckBox cbRemove;
+ private System.Windows.Forms.CheckBox cbBlock;
+ private System.Windows.Forms.Button btnRemove;
+ private System.Windows.Forms.Button btnCancel;
+ }
+}
\ No newline at end of file
diff --git a/Example/RemoveContactForm.cs b/Example/RemoveContactForm.cs
new file mode 100644
index 0000000..2892ab5
--- /dev/null
+++ b/Example/RemoveContactForm.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+
+namespace MSNPSharpClient
+{
+ public partial class RemoveContactForm : Form
+ {
+
+ public bool RemoveFromAddressBook
+ {
+ get
+ {
+ return cbRemove.Checked;
+ }
+ }
+
+ public bool Block
+ {
+ get
+ {
+ return cbBlock.Checked;
+ }
+ }
+
+ public RemoveContactForm()
+ {
+ InitializeComponent();
+ }
+
+ private void btn_Click(object sender, EventArgs e)
+ {
+ Close();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Example/RemoveContactForm.resx b/Example/RemoveContactForm.resx
new file mode 100644
index 0000000..19dc0dd
--- /dev/null
+++ b/Example/RemoveContactForm.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Example/Resources/Color_fontHS.png b/Example/Resources/Color_fontHS.png
new file mode 100644
index 0000000..0a7695d
Binary files /dev/null and b/Example/Resources/Color_fontHS.png differ
diff --git a/Example/Resources/MSNPSharp_logo.ico b/Example/Resources/MSNPSharp_logo.ico
new file mode 100644
index 0000000..7ba3fdb
Binary files /dev/null and b/Example/Resources/MSNPSharp_logo.ico differ
diff --git a/Example/Resources/MSNPSharp_logo_small.ico b/Example/Resources/MSNPSharp_logo_small.ico
new file mode 100644
index 0000000..47a55c5
Binary files /dev/null and b/Example/Resources/MSNPSharp_logo_small.ico differ
diff --git a/Example/Resources/YahooMessenger_logo.png b/Example/Resources/YahooMessenger_logo.png
new file mode 100644
index 0000000..3ca721d
Binary files /dev/null and b/Example/Resources/YahooMessenger_logo.png differ
diff --git a/Example/Resources/app_banner.png b/Example/Resources/app_banner.png
new file mode 100644
index 0000000..c4b38d8
Binary files /dev/null and b/Example/Resources/app_banner.png differ
diff --git a/Example/Resources/file.png b/Example/Resources/file.png
new file mode 100644
index 0000000..c07f629
Binary files /dev/null and b/Example/Resources/file.png differ
diff --git a/Example/Resources/inner_emoicon.png b/Example/Resources/inner_emoicon.png
new file mode 100644
index 0000000..ed88b96
Binary files /dev/null and b/Example/Resources/inner_emoicon.png differ
diff --git a/Example/Resources/loading.gif b/Example/Resources/loading.gif
new file mode 100644
index 0000000..3288d10
Binary files /dev/null and b/Example/Resources/loading.gif differ
diff --git a/Example/Resources/msn_ico.ico b/Example/Resources/msn_ico.ico
new file mode 100644
index 0000000..b0047c8
Binary files /dev/null and b/Example/Resources/msn_ico.ico differ
diff --git a/Example/Resources/nudge.png b/Example/Resources/nudge.png
new file mode 100644
index 0000000..a18c944
Binary files /dev/null and b/Example/Resources/nudge.png differ
diff --git a/Example/Resources/smileys/biggrin.gif b/Example/Resources/smileys/biggrin.gif
new file mode 100644
index 0000000..5e490d1
Binary files /dev/null and b/Example/Resources/smileys/biggrin.gif differ
diff --git a/Example/Resources/smileys/sad.gif b/Example/Resources/smileys/sad.gif
new file mode 100644
index 0000000..cb59b62
Binary files /dev/null and b/Example/Resources/smileys/sad.gif differ
diff --git a/Example/Resources/smileys/smiley.gif b/Example/Resources/smileys/smiley.gif
new file mode 100644
index 0000000..46bafcd
Binary files /dev/null and b/Example/Resources/smileys/smiley.gif differ
diff --git a/Example/Resources/smileys/tongueout.gif b/Example/Resources/smileys/tongueout.gif
new file mode 100644
index 0000000..b96d15d
Binary files /dev/null and b/Example/Resources/smileys/tongueout.gif differ
diff --git a/Example/Resources/smileys/wink.gif b/Example/Resources/smileys/wink.gif
new file mode 100644
index 0000000..dfc35cc
Binary files /dev/null and b/Example/Resources/smileys/wink.gif differ
diff --git a/Example/Resources/status/away.png b/Example/Resources/status/away.png
new file mode 100644
index 0000000..5966f74
Binary files /dev/null and b/Example/Resources/status/away.png differ
diff --git a/Example/Resources/status/busy.png b/Example/Resources/status/busy.png
new file mode 100644
index 0000000..1fdf421
Binary files /dev/null and b/Example/Resources/status/busy.png differ
diff --git a/Example/Resources/status/circle.png b/Example/Resources/status/circle.png
new file mode 100644
index 0000000..2840701
Binary files /dev/null and b/Example/Resources/status/circle.png differ
diff --git a/Example/Resources/status/closed.png b/Example/Resources/status/closed.png
new file mode 100644
index 0000000..614a23e
Binary files /dev/null and b/Example/Resources/status/closed.png differ
diff --git a/Example/Resources/status/hidden.png b/Example/Resources/status/hidden.png
new file mode 100644
index 0000000..a41b641
Binary files /dev/null and b/Example/Resources/status/hidden.png differ
diff --git a/Example/Resources/status/idle.png b/Example/Resources/status/idle.png
new file mode 100644
index 0000000..ecd3b4d
Binary files /dev/null and b/Example/Resources/status/idle.png differ
diff --git a/Example/Resources/status/offline.png b/Example/Resources/status/offline.png
new file mode 100644
index 0000000..854fe7f
Binary files /dev/null and b/Example/Resources/status/offline.png differ
diff --git a/Example/Resources/status/online.png b/Example/Resources/status/online.png
new file mode 100644
index 0000000..1efefd3
Binary files /dev/null and b/Example/Resources/status/online.png differ
diff --git a/Example/Resources/status/open.png b/Example/Resources/status/open.png
new file mode 100644
index 0000000..d2d9210
Binary files /dev/null and b/Example/Resources/status/open.png differ
diff --git a/Example/Resources/yahoo_ico.ico b/Example/Resources/yahoo_ico.ico
new file mode 100644
index 0000000..b51c74b
Binary files /dev/null and b/Example/Resources/yahoo_ico.ico differ
diff --git a/Example/ReverseAddedForm.Designer.cs b/Example/ReverseAddedForm.Designer.cs
new file mode 100644
index 0000000..a330ba6
--- /dev/null
+++ b/Example/ReverseAddedForm.Designer.cs
@@ -0,0 +1,151 @@
+namespace MSNPSharpClient
+{
+ partial class ReverseAddedForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.lblAdded = new System.Windows.Forms.Label();
+ this.gbMembership = new System.Windows.Forms.GroupBox();
+ this.rbBlock = new System.Windows.Forms.RadioButton();
+ this.rbAllow = new System.Windows.Forms.RadioButton();
+ this.cbContactList = new System.Windows.Forms.CheckBox();
+ this.btnOK = new System.Windows.Forms.Button();
+ this.btnCancel = new System.Windows.Forms.Button();
+ this.gbMembership.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // lblAdded
+ //
+ this.lblAdded.AutoSize = true;
+ this.lblAdded.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(162)));
+ this.lblAdded.Location = new System.Drawing.Point(12, 9);
+ this.lblAdded.Name = "lblAdded";
+ this.lblAdded.Size = new System.Drawing.Size(226, 13);
+ this.lblAdded.TabIndex = 0;
+ this.lblAdded.Text = "{0} has added you to their contact list.";
+ //
+ // gbMembership
+ //
+ this.gbMembership.Controls.Add(this.rbBlock);
+ this.gbMembership.Controls.Add(this.rbAllow);
+ this.gbMembership.Location = new System.Drawing.Point(15, 36);
+ this.gbMembership.Name = "gbMembership";
+ this.gbMembership.Size = new System.Drawing.Size(441, 74);
+ this.gbMembership.TabIndex = 1;
+ this.gbMembership.TabStop = false;
+ this.gbMembership.Text = "Add contact to:";
+ //
+ // rbBlock
+ //
+ this.rbBlock.AutoSize = true;
+ this.rbBlock.Location = new System.Drawing.Point(15, 42);
+ this.rbBlock.Name = "rbBlock";
+ this.rbBlock.Size = new System.Drawing.Size(421, 17);
+ this.rbBlock.TabIndex = 1;
+ this.rbBlock.Text = "Blocked List (User can not see my online status and can not send instant messages" +
+ ")";
+ this.rbBlock.UseVisualStyleBackColor = true;
+ this.rbBlock.CheckedChanged += new System.EventHandler(this.rbBlock_CheckedChanged);
+ //
+ // rbAllow
+ //
+ this.rbAllow.AutoSize = true;
+ this.rbAllow.Checked = true;
+ this.rbAllow.Location = new System.Drawing.Point(15, 19);
+ this.rbAllow.Name = "rbAllow";
+ this.rbAllow.Size = new System.Drawing.Size(352, 17);
+ this.rbAllow.TabIndex = 0;
+ this.rbAllow.TabStop = true;
+ this.rbAllow.Text = "Allowed List (User can see my status and can send instant messages)";
+ this.rbAllow.UseVisualStyleBackColor = true;
+ //
+ // cbContactList
+ //
+ this.cbContactList.AutoSize = true;
+ this.cbContactList.Checked = true;
+ this.cbContactList.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.cbContactList.Location = new System.Drawing.Point(30, 125);
+ this.cbContactList.Name = "cbContactList";
+ this.cbContactList.Size = new System.Drawing.Size(169, 17);
+ this.cbContactList.TabIndex = 2;
+ this.cbContactList.Text = "Add this user to my contact list";
+ this.cbContactList.UseVisualStyleBackColor = true;
+ //
+ // btnOK
+ //
+ this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.btnOK.Location = new System.Drawing.Point(302, 125);
+ this.btnOK.Name = "btnOK";
+ this.btnOK.Size = new System.Drawing.Size(75, 23);
+ this.btnOK.TabIndex = 3;
+ this.btnOK.Text = "OK";
+ this.btnOK.UseVisualStyleBackColor = true;
+ this.btnOK.Click += new System.EventHandler(this.btn_Click);
+ //
+ // btnCancel
+ //
+ this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.btnCancel.Location = new System.Drawing.Point(381, 125);
+ this.btnCancel.Name = "btnCancel";
+ this.btnCancel.Size = new System.Drawing.Size(75, 23);
+ this.btnCancel.TabIndex = 4;
+ this.btnCancel.Text = "Cancel";
+ this.btnCancel.UseVisualStyleBackColor = true;
+ this.btnCancel.Click += new System.EventHandler(this.btn_Click);
+ //
+ // ReverseAddedForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(470, 156);
+ this.Controls.Add(this.btnCancel);
+ this.Controls.Add(this.btnOK);
+ this.Controls.Add(this.cbContactList);
+ this.Controls.Add(this.gbMembership);
+ this.Controls.Add(this.lblAdded);
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "ReverseAddedForm";
+ this.Text = "Pending Contact {0}";
+ this.gbMembership.ResumeLayout(false);
+ this.gbMembership.PerformLayout();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Label lblAdded;
+ private System.Windows.Forms.GroupBox gbMembership;
+ private System.Windows.Forms.RadioButton rbAllow;
+ private System.Windows.Forms.RadioButton rbBlock;
+ private System.Windows.Forms.CheckBox cbContactList;
+ private System.Windows.Forms.Button btnOK;
+ private System.Windows.Forms.Button btnCancel;
+ }
+}
\ No newline at end of file
diff --git a/Example/ReverseAddedForm.cs b/Example/ReverseAddedForm.cs
new file mode 100644
index 0000000..b5d1a48
--- /dev/null
+++ b/Example/ReverseAddedForm.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using MSNPSharp;
+
+namespace MSNPSharpClient
+{
+ public partial class ReverseAddedForm : Form
+ {
+ public ReverseAddedForm(Contact contact)
+ {
+ InitializeComponent();
+
+ Text = String.Format(Text, contact.Mail);
+ lblAdded.Text = String.Format(lblAdded.Text, contact.Name + " (" + contact.Mail + ")");
+ }
+
+ public bool Blocked
+ {
+ get
+ {
+ return rbBlock.Checked;
+ }
+ }
+
+ public bool AddToContactList
+ {
+ get
+ {
+ return cbContactList.Checked;
+ }
+ }
+
+ private void rbBlock_CheckedChanged(object sender, EventArgs e)
+ {
+ if (rbBlock.Checked)
+ {
+ cbContactList.Checked = false;
+ }
+ }
+
+ private void btn_Click(object sender, EventArgs e)
+ {
+ Close();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Example/ReverseAddedForm.resx b/Example/ReverseAddedForm.resx
new file mode 100644
index 0000000..19dc0dd
--- /dev/null
+++ b/Example/ReverseAddedForm.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Example/RtfRichTextBox.cs b/Example/RtfRichTextBox.cs
new file mode 100644
index 0000000..343626e
--- /dev/null
+++ b/Example/RtfRichTextBox.cs
@@ -0,0 +1,427 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+using System.Runtime.InteropServices;
+
+namespace MSNPSharpClient
+{
+ using MSNPSharp;
+
+ public class RtfRichTextBox : RichTextBox
+ {
+ [DllImport("gdiplus.dll")]
+ private static extern uint GdipEmfToWmfBits(IntPtr _hEmf, uint _bufferSize, byte[] _buffer, int _mappingMode, EmfToWmfBitsFlags _flags);
+
+ #region .cctor
+ static bool hasGdiPlus = false;
+ static RtfRichTextBox()
+ {
+ try
+ {
+ if(!Settings.IsMono)
+ {
+ //We are in M$ Windows!
+ GdipEmfToWmfBits(IntPtr.Zero, 0, null, 0, 0);
+ hasGdiPlus = true;
+ }
+ }
+ catch (Exception)
+ {
+ }
+ }
+ #endregion
+
+
+ private float xDpi;
+ private float yDpi;
+
+ private RtfColor textColor = RtfColor.Black;
+ private RtfColor highlightColor = RtfColor.White;
+ private Dictionary emotions = new Dictionary();
+ private Dictionary rtfColor = new Dictionary();
+ private Dictionary rtfFontFamily = new Dictionary();
+
+ public RtfRichTextBox()
+ {
+ rtfColor.Add(RtfColor.Aqua, @"\red0\green255\blue255");
+ rtfColor.Add(RtfColor.Black, @"\red0\green0\blue0");
+ rtfColor.Add(RtfColor.Blue, @"\red0\green0\blue255");
+ rtfColor.Add(RtfColor.Fuchsia, @"\red255\green0\blue255");
+ rtfColor.Add(RtfColor.Gray, @"\red128\green128\blue128");
+ rtfColor.Add(RtfColor.Green, @"\red0\green128\blue0");
+ rtfColor.Add(RtfColor.Lime, @"\red0\green255\blue0");
+ rtfColor.Add(RtfColor.Maroon, @"\red128\green0\blue0");
+ rtfColor.Add(RtfColor.Navy, @"\red0\green0\blue128");
+ rtfColor.Add(RtfColor.Olive, @"\red128\green128\blue0");
+ rtfColor.Add(RtfColor.Purple, @"\red128\green0\blue128");
+ rtfColor.Add(RtfColor.Red, @"\red255\green0\blue0");
+ rtfColor.Add(RtfColor.Silver, @"\red192\green192\blue192");
+ rtfColor.Add(RtfColor.Teal, @"\red0\green128\blue128");
+ rtfColor.Add(RtfColor.White, @"\red255\green255\blue255");
+ rtfColor.Add(RtfColor.Yellow, @"\red255\green255\blue0");
+
+ rtfFontFamily.Add(FontFamily.GenericMonospace.Name, @"\fmodern");
+ rtfFontFamily.Add(FontFamily.GenericSansSerif.Name, @"\fswiss");
+ rtfFontFamily.Add(FontFamily.GenericSerif.Name, @"\froman");
+ rtfFontFamily.Add("UNKNOWN", @"\fnil");
+
+ using (Graphics graphics = CreateGraphics())
+ {
+ xDpi = graphics.DpiX;
+ yDpi = graphics.DpiY;
+ }
+ }
+
+ public RtfRichTextBox(RtfColor _textColor)
+ : this()
+ {
+ textColor = _textColor;
+ }
+
+ public RtfRichTextBox(RtfColor _textColor, RtfColor _highlightColor)
+ : this()
+ {
+ textColor = _textColor;
+ highlightColor = _highlightColor;
+ }
+
+ public void AppendRtf(string _rtf)
+ {
+ Select(TextLength, 0);
+ SelectionColor = Color.Black;
+ SelectedRtf = _rtf;
+ }
+
+ public void AppendTextAsRtf(string _text)
+ {
+ AppendTextAsRtf(_text, Font);
+ }
+
+ public void AppendTextAsRtf(string _text, Font _font)
+ {
+ AppendTextAsRtf(_text, _font, textColor);
+ }
+
+ public void AppendTextAsRtf(string _text, Font _font, RtfColor _textColor)
+ {
+ AppendTextAsRtf(_text, _font, _textColor, highlightColor);
+ }
+
+ public void AppendTextAsRtf(string _text, Font _font, RtfColor _textColor, RtfColor _backColor)
+ {
+ Select(TextLength, 0);
+ InsertTextAsRtf(_text, _font, _textColor, _backColor);
+ }
+
+ private string GetColorTable(RtfColor _textColor, RtfColor _backColor)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.Append(@"{\colortbl ;");
+ builder.Append(rtfColor[_textColor]);
+ builder.Append(";");
+ builder.Append(rtfColor[_backColor]);
+ builder.Append(@";}\n");
+ return builder.ToString();
+ }
+
+ private string GetDocumentArea(string _text, Font _font)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.Append(@"\viewkind4\uc1\pard\cf1\f0\fs20");
+ builder.Append(@"\highlight2");
+ if (_font.Bold)
+ {
+ builder.Append(@"\b");
+ }
+ if (_font.Italic)
+ {
+ builder.Append(@"\i");
+ }
+ if (_font.Strikeout)
+ {
+ builder.Append(@"\strike");
+ }
+ if (_font.Underline)
+ {
+ builder.Append(@"\ul");
+ }
+ builder.Append(@"\f0");
+ builder.Append(@"\fs");
+ builder.Append((int)Math.Round((double)(2f * _font.SizeInPoints)));
+ builder.Append(" ");
+ builder.Append(_text.Replace("\n", @"\par "));
+ builder.Append(@"\highlight0");
+ if (_font.Bold)
+ {
+ builder.Append(@"\b0");
+ }
+ if (_font.Italic)
+ {
+ builder.Append(@"\i0");
+ }
+ if (_font.Strikeout)
+ {
+ builder.Append(@"\strike0");
+ }
+ if (_font.Underline)
+ {
+ builder.Append(@"\ulnone");
+ }
+ builder.Append(@"\f0");
+ builder.Append(@"\fs20");
+ builder.Append(@"\cf0\fs17}");
+ return builder.ToString();
+ }
+
+ private string GetFontTable(Font _font)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.Append(@"{\fonttbl{\f0");
+ builder.Append(@"\");
+ if (rtfFontFamily.ContainsKey(_font.FontFamily.Name))
+ {
+ builder.Append(rtfFontFamily[_font.FontFamily.Name]);
+ }
+ else
+ {
+ builder.Append(rtfFontFamily["UNKNOWN"]);
+ }
+ builder.Append(@"\fcharset0 ");
+ builder.Append(_font.Name);
+ builder.Append(";}}");
+ return builder.ToString();
+ }
+
+ private string GetImagePrefix(Image _image)
+ {
+ StringBuilder builder = new StringBuilder();
+ int picw = (int)Math.Round((double)((((float)_image.Width) / xDpi) * 2540f));
+ int pich = (int)Math.Round((double)((((float)_image.Height) / yDpi) * 2540f));
+ int picwgoal = (int)Math.Round((double)((((float)_image.Width) / xDpi) * 1440f));
+ int pichgoal = (int)Math.Round((double)((((float)_image.Height) / yDpi) * 1440f));
+ builder.Append(@"{\pict\wmetafile8");
+ builder.Append(@"\picw");
+ builder.Append(picw);
+ builder.Append(@"\pich");
+ builder.Append(pich);
+ builder.Append(@"\picwgoal");
+ builder.Append(picwgoal);
+ builder.Append(@"\pichgoal");
+ builder.Append(pichgoal);
+ builder.Append(" ");
+ return builder.ToString();
+ }
+
+ private string GetRtfImage(Image _image)
+ {
+ MemoryStream stream = null;
+ Graphics graphics = null;
+ Metafile image = null;
+ string ret;
+ try
+ {
+ stream = new MemoryStream();
+ using (graphics = CreateGraphics())
+ {
+ IntPtr hdc = graphics.GetHdc();
+ image = new Metafile(stream, hdc);
+ graphics.ReleaseHdc(hdc);
+ }
+ using (graphics = Graphics.FromImage(image))
+ {
+ graphics.DrawImage(_image, new Rectangle(0, 0, _image.Width, _image.Height));
+ }
+ IntPtr henhmetafile = image.GetHenhmetafile();
+ uint num = GdipEmfToWmfBits(henhmetafile, 0, null, 1, EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault);
+ byte[] buffer = new byte[num];
+ GdipEmfToWmfBits(henhmetafile, num, buffer, 1, EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault);
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < buffer.Length; i++)
+ {
+ builder.Append(string.Format("{0:X2}", buffer[i]));
+ }
+ ret = builder.ToString();
+ }
+ finally
+ {
+ if (graphics != null)
+ {
+ graphics.Dispose();
+ }
+ if (image != null)
+ {
+ image.Dispose();
+ }
+ if (stream != null)
+ {
+ stream.Close();
+ }
+ }
+ return ret;
+ }
+
+ public void InsertEmotion()
+ {
+ if (hasGdiPlus)
+ {
+ foreach (string emoticon in emotions.Keys)
+ {
+ int start = Find(emoticon, RichTextBoxFinds.None);
+ if (start > -1)
+ {
+ Select(start, emoticon.Length);
+ InsertImage(emotions[emoticon]);
+ }
+ }
+ }
+ }
+
+ public void InsertImage(Image _image)
+ {
+ if (hasGdiPlus)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.Append(@"{\rtf1\ansi\ansicpg1252\deff0\deflang1033");
+ builder.Append(GetFontTable(Font));
+ builder.Append(GetImagePrefix(_image));
+ builder.Append(GetRtfImage(_image));
+ builder.Append(@"}");
+
+ SelectedRtf = builder.ToString();
+ }
+ }
+
+ public void InsertRtf(string _rtf)
+ {
+ SelectedRtf = _rtf;
+ }
+
+ public void InsertTextAsRtf(string _text)
+ {
+ InsertTextAsRtf(_text, Font);
+ }
+
+ public void InsertTextAsRtf(string _text, Font _font)
+ {
+ InsertTextAsRtf(_text, _font, textColor);
+ }
+
+ public void InsertTextAsRtf(string _text, Font _font, RtfColor _textColor)
+ {
+ InsertTextAsRtf(_text, _font, _textColor, highlightColor);
+ }
+
+ public void InsertTextAsRtf(string _text, Font _font, RtfColor _textColor, RtfColor _backColor)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.Append(@"{\rtf1\ansi\ansicpg1252\deff0\deflang1033");
+ builder.Append(GetFontTable(_font));
+ builder.Append(GetColorTable(_textColor, _backColor));
+ builder.Append(GetDocumentArea(_text, _font));
+
+ SelectedRtf = builder.ToString();
+ }
+
+ private string RemoveBadChars(string _originalRtf)
+ {
+ return _originalRtf.Replace("\0", "");
+ }
+
+ public Dictionary Emotions
+ {
+ get
+ {
+ return emotions;
+ }
+ }
+
+ public bool HasEmotion
+ {
+ get
+ {
+ if (hasGdiPlus)
+ {
+ foreach (string emoticon in emotions.Keys)
+ {
+ if (Text.IndexOf(emoticon, StringComparison.CurrentCultureIgnoreCase) > -1)
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+ public RtfColor HiglightColor
+ {
+ get
+ {
+ return highlightColor;
+ }
+ set
+ {
+ highlightColor = value;
+ }
+ }
+
+ public new string Rtf
+ {
+ get
+ {
+ return RemoveBadChars(base.Rtf);
+ }
+ set
+ {
+ base.Rtf = value;
+ }
+ }
+
+ public RtfColor TextColor
+ {
+ get
+ {
+ return textColor;
+ }
+ set
+ {
+ textColor = value;
+ }
+ }
+
+ [Flags]
+ private enum EmfToWmfBitsFlags
+ {
+ EmfToWmfBitsFlagsDefault = 0,
+ EmfToWmfBitsFlagsEmbedEmf = 1,
+ EmfToWmfBitsFlagsIncludePlaceable = 2,
+ EmfToWmfBitsFlagsNoXORClip = 4
+ }
+
+ public enum RtfColor
+ {
+ Black,
+ Maroon,
+ Green,
+ Olive,
+ Navy,
+ Purple,
+ Teal,
+ Gray,
+ Silver,
+ Red,
+ Lime,
+ Yellow,
+ Blue,
+ Fuchsia,
+ Aqua,
+ White
+ }
+ }
+};
diff --git a/Example/TraceForm.Designer.cs b/Example/TraceForm.Designer.cs
new file mode 100644
index 0000000..1fa1e92
--- /dev/null
+++ b/Example/TraceForm.Designer.cs
@@ -0,0 +1,165 @@
+namespace MSNPSharpClient
+{
+ partial class TraceForm
+ {
+ ///
+ /// 必需的设计器变量。
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// 清理所有正在使用的资源。
+ ///
+ /// 如果应释放托管资源,为 true;否则为 false。
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows 窗体设计器生成的代码
+
+ ///
+ /// 设计器支持所需的方法 - 不要
+ /// 使用代码编辑器修改此方法的内容。
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TraceForm));
+ this.tsbStart = new System.Windows.Forms.ToolStripButton();
+ this.tsbStop = new System.Windows.Forms.ToolStripButton();
+ this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
+ this.tsbClear = new System.Windows.Forms.ToolStripButton();
+ this.toolStrip1 = new System.Windows.Forms.ToolStrip();
+ this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
+ this.toolStripLabelLevel = new System.Windows.Forms.ToolStripLabel();
+ this.toolStripComboBoxLevel = new System.Windows.Forms.ToolStripComboBox();
+ this.rtbTrace = new System.Windows.Forms.RichTextBox();
+ this.toolStrip1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // tsbStart
+ //
+ this.tsbStart.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
+ this.tsbStart.Enabled = false;
+ this.tsbStart.Image = ((System.Drawing.Image)(resources.GetObject("tsbStart.Image")));
+ this.tsbStart.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.tsbStart.Name = "tsbStart";
+ this.tsbStart.Size = new System.Drawing.Size(35, 22);
+ this.tsbStart.Text = "Start";
+ this.tsbStart.ToolTipText = "Start Tracing";
+ this.tsbStart.Click += new System.EventHandler(this.tsbStart_Click);
+ //
+ // tsbStop
+ //
+ this.tsbStop.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
+ this.tsbStop.Image = ((System.Drawing.Image)(resources.GetObject("tsbStop.Image")));
+ this.tsbStop.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.tsbStop.Name = "tsbStop";
+ this.tsbStop.Size = new System.Drawing.Size(35, 22);
+ this.tsbStop.Text = "Stop";
+ this.tsbStop.ToolTipText = "Stop Tracing";
+ this.tsbStop.Click += new System.EventHandler(this.tsbStop_Click);
+ //
+ // toolStripSeparator1
+ //
+ this.toolStripSeparator1.Name = "toolStripSeparator1";
+ this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25);
+ //
+ // tsbClear
+ //
+ this.tsbClear.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
+ this.tsbClear.Image = ((System.Drawing.Image)(resources.GetObject("tsbClear.Image")));
+ this.tsbClear.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.tsbClear.Name = "tsbClear";
+ this.tsbClear.Size = new System.Drawing.Size(38, 22);
+ this.tsbClear.Text = "Clear";
+ this.tsbClear.ToolTipText = "Clear All";
+ this.tsbClear.Click += new System.EventHandler(this.tsbClear_Click);
+ //
+ // toolStrip1
+ //
+ this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.tsbStart,
+ this.tsbStop,
+ this.toolStripSeparator1,
+ this.tsbClear,
+ this.toolStripSeparator2,
+ this.toolStripLabelLevel,
+ this.toolStripComboBoxLevel});
+ this.toolStrip1.Location = new System.Drawing.Point(0, 0);
+ this.toolStrip1.Name = "toolStrip1";
+ this.toolStrip1.Size = new System.Drawing.Size(661, 25);
+ this.toolStrip1.TabIndex = 1;
+ this.toolStrip1.Text = "toolStrip1";
+ //
+ // toolStripSeparator2
+ //
+ this.toolStripSeparator2.Name = "toolStripSeparator2";
+ this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25);
+ //
+ // toolStripLabelLevel
+ //
+ this.toolStripLabelLevel.Name = "toolStripLabelLevel";
+ this.toolStripLabelLevel.Size = new System.Drawing.Size(40, 22);
+ this.toolStripLabelLevel.Text = "Level: ";
+ //
+ // toolStripComboBoxLevel
+ //
+ this.toolStripComboBoxLevel.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.toolStripComboBoxLevel.Items.AddRange(new object[] {
+ "Verbose",
+ "Info",
+ "Warning",
+ "Error",
+ "Off"});
+ this.toolStripComboBoxLevel.Name = "toolStripComboBoxLevel";
+ this.toolStripComboBoxLevel.Size = new System.Drawing.Size(121, 25);
+ this.toolStripComboBoxLevel.SelectedIndexChanged += new System.EventHandler(this.toolStripComboBoxLevel_SelectedIndexChanged);
+ //
+ // rtbTrace
+ //
+ this.rtbTrace.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.rtbTrace.Location = new System.Drawing.Point(0, 30);
+ this.rtbTrace.Name = "rtbTrace";
+ this.rtbTrace.Size = new System.Drawing.Size(661, 457);
+ this.rtbTrace.TabIndex = 0;
+ this.rtbTrace.Text = "";
+ //
+ // TraceForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(661, 488);
+ this.Controls.Add(this.toolStrip1);
+ this.Controls.Add(this.rtbTrace);
+ this.Name = "TraceForm";
+ this.Text = "TraceForm";
+ this.Load += new System.EventHandler(this.TraceForm_Load);
+ this.toolStrip1.ResumeLayout(false);
+ this.toolStrip1.PerformLayout();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.ToolStripButton tsbStart;
+ private System.Windows.Forms.ToolStripButton tsbStop;
+ private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
+ private System.Windows.Forms.ToolStripButton tsbClear;
+ private System.Windows.Forms.ToolStrip toolStrip1;
+ private System.Windows.Forms.RichTextBox rtbTrace;
+ private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
+ private System.Windows.Forms.ToolStripLabel toolStripLabelLevel;
+ private System.Windows.Forms.ToolStripComboBox toolStripComboBoxLevel;
+
+
+ }
+}
\ No newline at end of file
diff --git a/Example/TraceForm.cs b/Example/TraceForm.cs
new file mode 100644
index 0000000..bbe7cee
--- /dev/null
+++ b/Example/TraceForm.cs
@@ -0,0 +1,291 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Threading;
+using System.Windows.Forms;
+using System.IO;
+using System.Diagnostics;
+using System.Security.Permissions;
+
+namespace MSNPSharpClient
+{
+ using MSNPSharp;
+
+ public partial class TraceForm : Form
+ {
+ RichTextBoxTraceListener rtbTraceListener = null;
+ public TraceForm()
+ {
+ InitializeComponent();
+ this.Icon = Properties.Resources.MSNPSharp_logo_small_ico;
+ rtbTraceListener = new RichTextBoxTraceListener(rtbTrace);
+ Trace.Listeners.Add(rtbTraceListener);
+
+ FormClosing += new FormClosingEventHandler(TraceForm_FormClosing);
+ }
+
+ void TraceForm_FormClosing(object sender, FormClosingEventArgs e)
+ {
+ rtbTraceListener.Close();
+ Trace.Listeners.Remove(rtbTraceListener);
+ }
+
+ private void tsbClear_Click(object sender, EventArgs e)
+ {
+ rtbTrace.Clear();
+ }
+
+ private void tsbStop_Click(object sender, EventArgs e)
+ {
+ rtbTraceListener.Stop();
+ tsbStart.Enabled = true;
+ tsbStop.Enabled = false;
+ }
+
+ private void tsbStart_Click(object sender, EventArgs e)
+ {
+ rtbTraceListener.Resume();
+ tsbStart.Enabled = false;
+ tsbStop.Enabled = true;
+ }
+
+ private void TraceForm_Load(object sender, EventArgs e)
+ {
+ toolStripComboBoxLevel.SelectedItem = "Verbose";
+ }
+
+ private void toolStripComboBoxLevel_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ MSNPSharp.Settings.TraceSwitch.Level = (TraceLevel)Enum.Parse(typeof(TraceLevel), toolStripComboBoxLevel.SelectedItem.ToString());
+ }
+ }
+
+
+ public class TraceWriter : TextWriter
+ {
+ private RichTextBox richTextBox = null;
+ private delegate void WriteHandler(string buffer, RichTextBox rtb);
+ private const int MaxBufferLen = 1024;
+ private StringBuilder buffer = new StringBuilder(MaxBufferLen);
+ private DateTime lastInputTime = DateTime.Now;
+ private Thread writeThread = null;
+ private Queue messageQueue = new Queue(MaxBufferLen);
+ private bool canClose = false;
+ private bool userClick = false;
+ private int selectionStart = 0;
+ private int selectionLength = 0;
+
+ protected virtual void WriteBuffer()
+ {
+ StringBuilder trace = new StringBuilder(MaxBufferLen);
+ while (!canClose)
+ {
+ lock (messageQueue)
+ {
+
+ while (messageQueue.Count > 0)
+ {
+ trace.EnsureCapacity(buffer.Length < MaxBufferLen ? MaxBufferLen : MaxBufferLen + 2);
+ trace.Append(messageQueue.Dequeue());
+ }
+ }
+
+ if (trace.Length > 0)
+ {
+ try
+ {
+ richTextBox.BeginInvoke(new WriteHandler(OutPut), new object[] { trace.ToString(), richTextBox });
+ }
+ catch (Exception)
+ {
+ return;
+ }
+
+ trace.Remove(0, trace.Length);
+ }
+
+ Thread.Sleep(Settings.IsMono ? 5000 : 100);
+ }
+ }
+
+ protected virtual void OutPut(string buffer, RichTextBox rtb)
+ {
+ if (selectionStart == rtb.Text.Length)
+ userClick = false;
+
+ rtb.AppendText(buffer);
+ if (userClick)
+ {
+ rtb.Select(selectionStart, selectionLength);
+ rtb.ScrollToCaret();
+ }
+ }
+
+ public TraceWriter(RichTextBox outputRTB)
+ {
+ richTextBox = outputRTB;
+ richTextBox.Click += new EventHandler(richTextBox_Click);
+ richTextBox.KeyDown += new KeyEventHandler(richTextBox_KeyDown);
+ writeThread = new Thread(new ThreadStart(WriteBuffer));
+ writeThread.Start();
+ }
+
+ void richTextBox_KeyDown(object sender, KeyEventArgs e)
+ {
+ userClick = true;
+ selectionStart = richTextBox.SelectionStart;
+ selectionLength = richTextBox.SelectionLength;
+ }
+
+ void richTextBox_Click(object sender, EventArgs e)
+ {
+ userClick = true;
+ selectionStart = richTextBox.SelectionStart;
+ selectionLength = richTextBox.SelectionLength;
+ }
+
+ public override void Write(char value)
+ {
+ if (richTextBox != null && buffer != null)
+ {
+ lock (messageQueue)
+ {
+ messageQueue.Enqueue(value);
+ }
+ }
+ }
+
+ public override void Close()
+ {
+ canClose = true;
+ base.Close();
+ }
+
+ public override Encoding Encoding
+ {
+ get { return Encoding.Default; }
+ }
+ }
+
+ [HostProtection(SecurityAction.LinkDemand, Synchronization = true)]
+ public class RichTextBoxTraceListener : TraceListener
+ {
+ // Fields
+ private TraceWriter writer = null;
+ private object syncObject = new object();
+ private bool stop = false;
+
+ // Methods
+ public RichTextBoxTraceListener()
+ : base()
+ {
+ }
+
+ public RichTextBoxTraceListener(RichTextBox rtb)
+ : base(string.Empty)
+ {
+ writer = new TraceWriter(rtb);
+ }
+
+
+ public override void Close()
+ {
+ if (this.writer != null)
+ {
+ this.writer.Close();
+ }
+ this.writer = null;
+ this.stop = true;
+ }
+
+ private bool EnsureWriter()
+ {
+ lock (syncObject)
+ {
+ if (writer == null || stop == true) return false;
+ return true;
+ }
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ this.Close();
+ }
+ }
+
+ public override void Flush()
+ {
+ if (!EnsureWriter()) return;
+ this.writer.Flush();
+ }
+
+ private static Encoding GetEncodingWithFallback(Encoding encoding)
+ {
+ Encoding encoding2 = (Encoding)encoding.Clone();
+ encoding2.EncoderFallback = EncoderFallback.ReplacementFallback;
+ encoding2.DecoderFallback = DecoderFallback.ReplacementFallback;
+ return encoding2;
+ }
+
+ public override void Write (string message)
+ {
+ if (!EnsureWriter ())
+ return;
+ if (base.NeedIndent)
+ {
+ this.WriteIndent ();
+ }
+
+ if (!Settings.IsMono)
+ {
+ this.writer.Write ("[" + DateTime.Now.ToString ("u") + "] " + message);
+ }
+ }
+
+ public override void WriteLine(string message)
+ {
+ if (!EnsureWriter()) return;
+ if (base.NeedIndent)
+ {
+ this.WriteIndent();
+ }
+ this.writer.WriteLine("[" + DateTime.Now.ToString("u") + "] " + message);
+ base.NeedIndent = true;
+ }
+
+ public void Stop()
+ {
+ lock (syncObject)
+ {
+ stop = true;
+ }
+ }
+
+ public void Resume()
+ {
+ lock (syncObject)
+ {
+ stop = false;
+ }
+ }
+
+ // Properties
+ public TraceWriter Writer
+ {
+ get
+ {
+ return this.writer;
+ }
+ set
+ {
+ this.writer = value;
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/Example/TraceForm.resx b/Example/TraceForm.resx
new file mode 100644
index 0000000..ab988b1
--- /dev/null
+++ b/Example/TraceForm.resx
@@ -0,0 +1,169 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAgxJREFUOE+lkvtL
+ U2EYx+0PEbtpFwnBKPGKiJImGP0gYhIYs1E5GF5gIxkpA00JRSmMEF0ohMh+GaRWYlqabMVcNdS2QpaI
+ VqiDIYhk397vA6fXhCjyhYdzeM/5fp7vczkAdeL2cwho7v/wWzT1zcN+Pwhr51uY2/y41PQaF+wzKKiZ
+ QvaN58g0jyLd5KEUcQbg+84P/Cm2tncQjW3j68YWIqubCC3FcOJc478BAuGoZM6zvoRnakXEruEIjhc4
+ /g5gZop9c+voGAyLbQIfeBZxLL9BA1jzXvuGbWamuKh+GmmVbswE19A59FEBbmoAG7YbsLtm2mZmiml9
+ cvabNDwpz6YB7LYBoMXCumkJr7LOmnnHzBQ/9X2Bo2cOibm1GsBREbAQiYmw/8lnuCeWkVzcgnZlnw1j
+ 3HV/wuNXK6i/9x5Hc6wawDlTXHbLJ+LZUBQPRyKwdQdxutwl1h+NLXHh5Ht1ewBHsiwawCW57HyDAfWR
+ dvl0uhZQ1eqX8aVc7EKLqrum651ATLf9OJx5XQM4KmY0xPzZ0hFAiQJnXB0WwME0E3IsL5B17ZlADqWb
+ NYDrOepdlcysmTWWOrxqbceRWtaLk0VO1XW72D5Vckd2gMBfq8zdpmUG62NJvKM4+XyziDk24xmfWoGE
+ s1c0gHPmbrPTpHNJKOCo2G1mZs20zcwUJ5yp1AB5+8/zEwgF5GMVDxh4AAAAAElFTkSuQmCC
+
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAgxJREFUOE+lkvtL
+ U2EYx+0PEbtpFwnBKPGKiJImGP0gYhIYs1E5GF5gIxkpA00JRSmMEF0ohMh+GaRWYlqabMVcNdS2QpaI
+ VqiDIYhk397vA6fXhCjyhYdzeM/5fp7vczkAdeL2cwho7v/wWzT1zcN+Pwhr51uY2/y41PQaF+wzKKiZ
+ QvaN58g0jyLd5KEUcQbg+84P/Cm2tncQjW3j68YWIqubCC3FcOJc478BAuGoZM6zvoRnakXEruEIjhc4
+ /g5gZop9c+voGAyLbQIfeBZxLL9BA1jzXvuGbWamuKh+GmmVbswE19A59FEBbmoAG7YbsLtm2mZmiml9
+ cvabNDwpz6YB7LYBoMXCumkJr7LOmnnHzBQ/9X2Bo2cOibm1GsBREbAQiYmw/8lnuCeWkVzcgnZlnw1j
+ 3HV/wuNXK6i/9x5Hc6wawDlTXHbLJ+LZUBQPRyKwdQdxutwl1h+NLXHh5Ht1ewBHsiwawCW57HyDAfWR
+ dvl0uhZQ1eqX8aVc7EKLqrum651ATLf9OJx5XQM4KmY0xPzZ0hFAiQJnXB0WwME0E3IsL5B17ZlADqWb
+ NYDrOepdlcysmTWWOrxqbceRWtaLk0VO1XW72D5Vckd2gMBfq8zdpmUG62NJvKM4+XyziDk24xmfWoGE
+ s1c0gHPmbrPTpHNJKOCo2G1mZs20zcwUJ5yp1AB5+8/zEwgF5GMVDxh4AAAAAElFTkSuQmCC
+
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAgxJREFUOE+lkvtL
+ U2EYx+0PEbtpFwnBKPGKiJImGP0gYhIYs1E5GF5gIxkpA00JRSmMEF0ohMh+GaRWYlqabMVcNdS2QpaI
+ VqiDIYhk397vA6fXhCjyhYdzeM/5fp7vczkAdeL2cwho7v/wWzT1zcN+Pwhr51uY2/y41PQaF+wzKKiZ
+ QvaN58g0jyLd5KEUcQbg+84P/Cm2tncQjW3j68YWIqubCC3FcOJc478BAuGoZM6zvoRnakXEruEIjhc4
+ /g5gZop9c+voGAyLbQIfeBZxLL9BA1jzXvuGbWamuKh+GmmVbswE19A59FEBbmoAG7YbsLtm2mZmiml9
+ cvabNDwpz6YB7LYBoMXCumkJr7LOmnnHzBQ/9X2Bo2cOibm1GsBREbAQiYmw/8lnuCeWkVzcgnZlnw1j
+ 3HV/wuNXK6i/9x5Hc6wawDlTXHbLJ+LZUBQPRyKwdQdxutwl1h+NLXHh5Ht1ewBHsiwawCW57HyDAfWR
+ dvl0uhZQ1eqX8aVc7EKLqrum651ATLf9OJx5XQM4KmY0xPzZ0hFAiQJnXB0WwME0E3IsL5B17ZlADqWb
+ NYDrOepdlcysmTWWOrxqbceRWtaLk0VO1XW72D5Vckd2gMBfq8zdpmUG62NJvKM4+XyziDk24xmfWoGE
+ s1c0gHPmbrPTpHNJKOCo2G1mZs20zcwUJ5yp1AB5+8/zEwgF5GMVDxh4AAAAAElFTkSuQmCC
+
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/MSNPSharp.sln b/MSNPSharp.sln
new file mode 100644
index 0000000..2e660ca
--- /dev/null
+++ b/MSNPSharp.sln
@@ -0,0 +1,60 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotMSNClient", "Example\DotMSNClient.csproj", "{BDF3E472-EFE8-44D6-AFB6-062DD929D56F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProxyServer", "ProxyServer\ProxyServer.csproj", "{EB773C85-DDF7-4031-A993-102B9C8ED02C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MSNPSharp", "MSNPSharp\MSNPSharp.csproj", "{97CB2DC7-2FE8-4AF5-84D0-6B9872A5E960}"
+EndProject
+Global
+ GlobalSection(TestCaseManagementSettings) = postSolution
+ CategoryFile = MSNPSharp.vsmdi
+ EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|Mixed Platforms = Debug|Mixed Platforms
+ Debug|Win32 = Debug|Win32
+ Release|Any CPU = Release|Any CPU
+ Release|Mixed Platforms = Release|Mixed Platforms
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {BDF3E472-EFE8-44D6-AFB6-062DD929D56F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BDF3E472-EFE8-44D6-AFB6-062DD929D56F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BDF3E472-EFE8-44D6-AFB6-062DD929D56F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {BDF3E472-EFE8-44D6-AFB6-062DD929D56F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {BDF3E472-EFE8-44D6-AFB6-062DD929D56F}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {BDF3E472-EFE8-44D6-AFB6-062DD929D56F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BDF3E472-EFE8-44D6-AFB6-062DD929D56F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BDF3E472-EFE8-44D6-AFB6-062DD929D56F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {BDF3E472-EFE8-44D6-AFB6-062DD929D56F}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {BDF3E472-EFE8-44D6-AFB6-062DD929D56F}.Release|Win32.ActiveCfg = Release|Any CPU
+ {EB773C85-DDF7-4031-A993-102B9C8ED02C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EB773C85-DDF7-4031-A993-102B9C8ED02C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EB773C85-DDF7-4031-A993-102B9C8ED02C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {EB773C85-DDF7-4031-A993-102B9C8ED02C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {EB773C85-DDF7-4031-A993-102B9C8ED02C}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {EB773C85-DDF7-4031-A993-102B9C8ED02C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EB773C85-DDF7-4031-A993-102B9C8ED02C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EB773C85-DDF7-4031-A993-102B9C8ED02C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {EB773C85-DDF7-4031-A993-102B9C8ED02C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {EB773C85-DDF7-4031-A993-102B9C8ED02C}.Release|Win32.ActiveCfg = Release|Any CPU
+ {97CB2DC7-2FE8-4AF5-84D0-6B9872A5E960}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {97CB2DC7-2FE8-4AF5-84D0-6B9872A5E960}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {97CB2DC7-2FE8-4AF5-84D0-6B9872A5E960}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {97CB2DC7-2FE8-4AF5-84D0-6B9872A5E960}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {97CB2DC7-2FE8-4AF5-84D0-6B9872A5E960}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {97CB2DC7-2FE8-4AF5-84D0-6B9872A5E960}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {97CB2DC7-2FE8-4AF5-84D0-6B9872A5E960}.Release|Any CPU.Build.0 = Release|Any CPU
+ {97CB2DC7-2FE8-4AF5-84D0-6B9872A5E960}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {97CB2DC7-2FE8-4AF5-84D0-6B9872A5E960}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {97CB2DC7-2FE8-4AF5-84D0-6B9872A5E960}.Release|Win32.ActiveCfg = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(MonoDevelopProperties) = preSolution
+ StartupItem = Example\DotMSNClient.csproj
+ EndGlobalSection
+EndGlobal
diff --git a/MSNPSharp/Circle.Obsolete.cs b/MSNPSharp/Circle.Obsolete.cs
new file mode 100644
index 0000000..72306f6
--- /dev/null
+++ b/MSNPSharp/Circle.Obsolete.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using MSNPSharp.MSNWS.MSNABSharingService;
+
+namespace MSNPSharp
+{
+ public partial class Circle
+ {
+ private ContactType hiddenRepresentative = null;
+
+ ///
+ /// Circle constructor
+ ///
+ /// The "Me Contact" in the addressbook.
+ ///
+ ///
+ ///
+ [Obsolete("No hidden representative is needed anymore.", true)]
+ public Circle(ContactType me, ContactType hidden, CircleInverseInfoType circleInfo, NSMessageHandler handler)
+ : base(circleInfo.Content.Handle.Id.ToLowerInvariant(), circleInfo.Content.Handle.Id.ToLowerInvariant() + "@" + circleInfo.Content.Info.HostedDomain.ToLowerInvariant(), ClientType.CircleMember, me.contactInfo.CID, handler)
+ {
+ hostDomain = circleInfo.Content.Info.HostedDomain.ToLowerInvariant();
+ hiddenRepresentative = hidden;
+
+ CircleRole = (CirclePersonalMembershipRole)Enum.Parse(typeof(CirclePersonalMembershipRole), circleInfo.PersonalInfo.MembershipInfo.CirclePersonalMembership.Role);
+
+ SetName(circleInfo.Content.Info.DisplayName);
+ SetNickName(Name);
+
+ meContact = me;
+
+ if (hidden != null)
+ {
+ Guid = new Guid(hidden.contactId);
+
+ if (hidden.contactInfo != null && hidden.contactInfo.CIDSpecified)
+ CID = hidden.contactInfo.CID;
+ }
+
+ contactList = new ContactList(AddressBookId, new Owner(AddressBookId, me.contactInfo.passportName, me.contactInfo.CID, NSMessageHandler), NSMessageHandler);
+ Initialize();
+ }
+ }
+}
diff --git a/MSNPSharp/Circle.cs b/MSNPSharp/Circle.cs
new file mode 100644
index 0000000..a853e6c
--- /dev/null
+++ b/MSNPSharp/Circle.cs
@@ -0,0 +1,438 @@
+#region Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions (http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice
+/*
+Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions
+(http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice.
+All rights reserved. http://code.google.com/p/msnp-sharp/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the names of Bas Geertsema or Xih Solutions nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Diagnostics;
+using MSNPSharp.MSNWS.MSNABSharingService;
+
+namespace MSNPSharp
+{
+ using MSNPSharp.Core;
+
+ ///
+ /// A new type of group introduces with WLM2009.
+ ///
+ [Serializable()]
+ public partial class Circle : Contact
+ {
+ private ContactList contactList = null;
+ private string hostDomain = CircleString.DefaultHostDomain;
+ private long segmentCounter = 0;
+
+ private ContactType meContact = null;
+
+ private ABFindContactsPagedResultTypeAB abinfo = null;
+
+
+ public string HostDomain
+ {
+ get { return hostDomain; }
+ }
+
+ public ContactList ContactList
+ {
+ get
+ {
+ return contactList;
+ }
+ }
+
+ ///
+ /// The last change time of circle's addressbook.
+ ///
+ public string LastChanged
+ {
+ get
+ {
+ if (abinfo == null)
+ return WebServiceConstants.ZeroTime;
+
+ return abinfo.lastChange;
+ }
+ }
+
+ ///
+ /// Circle constructor
+ ///
+ /// The "Me Contact" in the addressbook.
+ ///
+ ///
+ public Circle(ContactType me, CircleInverseInfoType circleInfo, NSMessageHandler handler)
+ : base(circleInfo.Content.Handle.Id.ToLowerInvariant(), circleInfo.Content.Handle.Id.ToLowerInvariant() + "@" + circleInfo.Content.Info.HostedDomain.ToLowerInvariant(), ClientType.CircleMember, me.contactInfo.CID, handler)
+ {
+ hostDomain = circleInfo.Content.Info.HostedDomain.ToLowerInvariant();
+
+ CircleRole = (CirclePersonalMembershipRole)Enum.Parse(typeof(CirclePersonalMembershipRole), circleInfo.PersonalInfo.MembershipInfo.CirclePersonalMembership.Role);
+
+ SetName(circleInfo.Content.Info.DisplayName);
+ SetNickName(Name);
+
+ meContact = me;
+
+ CID = 0;
+
+ contactList = new ContactList(AddressBookId, new Owner(AddressBookId, me.contactInfo.passportName, me.contactInfo.CID, NSMessageHandler), NSMessageHandler);
+ Initialize();
+ }
+
+ private void CheckValidation()
+ {
+ if (NSMessageHandler == null)
+ throw new MSNPSharpException("NSMessagehandler is null");
+ if (!NSMessageHandler.IsSignedIn)
+ throw new InvalidOperationException("Cannot send a message without signning in to the server. Please sign in first.");
+
+ if (NSMessageHandler.ContactList.Owner.Status == PresenceStatus.Hidden)
+ throw new InvalidOperationException("Cannot send a message when you are in 'Hidden' status.");
+ }
+
+ private string ConstructSDGScheme()
+ {
+ string from = ((int)NSMessageHandler.ContactList.Owner.ClientType).ToString() + ":" +
+ NSMessageHandler.ContactList.Owner.Mail +
+ ";epid=" + NSMessageHandler.ContactList.Owner.MachineGuid.ToString("B").ToLowerInvariant();
+
+
+ string to = ((int)ClientType).ToString() + ":" + Mail + ";path=IM";
+
+ string routingInfo = CircleString.RoutingScheme.Replace(CircleString.ToReplacementTag, to);
+ routingInfo = routingInfo.Replace(CircleString.FromReplacementTag, from);
+
+ string reliabilityInfo = CircleString.ReliabilityScheme.Replace(CircleString.StreamReplacementTag, "0");
+ reliabilityInfo = reliabilityInfo.Replace(CircleString.SegmentReplacementTag, IncreaseSegmentCounter().ToString());
+
+ string putCommandString = CircleString.CircleMessageScheme;
+ putCommandString = putCommandString.Replace(CircleString.RoutingSchemeReplacementTag, routingInfo);
+ putCommandString = putCommandString.Replace(CircleString.ReliabilitySchemeReplacementTag, reliabilityInfo);
+
+ return putCommandString;
+ }
+
+ ///
+ /// Send nudge to all members in this circle.
+ ///
+ /// NSMessageHandler is null
+ /// Not sign in to the server, or in status.
+ public void SendNudge()
+ {
+ CheckValidation();
+ string scheme = ConstructSDGScheme();
+
+ scheme = scheme.Replace(CircleString.MessageSchemeReplacementTag, CircleString.NudgeMessageScheme);
+
+ NSPayLoadMessage nspayload = new NSPayLoadMessage("SDG", scheme);
+ NSMessageHandler.MessageProcessor.SendMessage(nspayload);
+ }
+
+ ///
+ /// Send a text message to all members in this circle.
+ ///
+ ///
+ /// NSMessageHandler is null
+ /// Not sign in to the server, or in status.
+ public void SendMessage(TextMessage textMessage)
+ {
+ CheckValidation();
+
+ string scheme = ConstructSDGScheme();
+
+ textMessage.PrepareMessage();
+
+ string content = MimeHeaderStrings.X_MMS_IM_Format + ": " + textMessage.GetStyleString() + "\r\n\r\n" + textMessage.Text;
+ string textMessageScheme = CircleString.TextMessageScheme.Replace(CircleString.TextMessageContentReplacementTag, content);
+ textMessageScheme = textMessageScheme.Replace(CircleString.ContentLengthReplacementTag, textMessage.Text.Length.ToString());
+
+ scheme = scheme.Replace(CircleString.MessageSchemeReplacementTag, textMessageScheme);
+
+ NSPayLoadMessage nspayload = new NSPayLoadMessage("SDG", scheme);
+ NSMessageHandler.MessageProcessor.SendMessage(nspayload);
+
+ }
+
+ ///
+ /// Send a typing message indicates that you are typing to all members in this circle.
+ ///
+ /// NSMessageHandler is null
+ /// Not sign in to the server, or in status.
+ public void SendTypingMessage()
+ {
+ CheckValidation();
+ string scheme = ConstructSDGScheme();
+
+ string typingScheme = CircleString.TypingMessageScheme.Replace(CircleString.OwnerReplacementTag, NSMessageHandler.ContactList.Owner.Mail);
+ scheme = scheme.Replace(CircleString.MessageSchemeReplacementTag, typingScheme);
+
+ NSPayLoadMessage nspayload = new NSPayLoadMessage("SDG", scheme);
+ NSMessageHandler.MessageProcessor.SendMessage(nspayload);
+ }
+
+ internal long IncreaseSegmentCounter()
+ {
+ return segmentCounter++;
+ }
+
+ ///
+ /// Get a specific contact from circle's contact list by the information provided.
+ ///
+ /// The contact information
+ /// The parse option for the account parameter
+ ///
+ internal Contact GetMember(string account, AccountParseOption option)
+ {
+ string lowerAccount = account.ToLowerInvariant();
+ try
+ {
+ switch (option)
+ {
+ case AccountParseOption.ParseAsClientTypeAndAccount:
+ {
+ string[] typeAccount = lowerAccount.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
+ if (typeAccount.Length >= 2)
+ {
+ ClientType type = (ClientType)(int.Parse(typeAccount[0]));
+ string mail = typeAccount[1];
+ if (HasMember(mail, type))
+ {
+ return ContactList.GetContact(mail, type);
+ }
+
+ return null;
+
+ }
+ }
+ break;
+ case AccountParseOption.ParseAsFullCircleAccount:
+ {
+ string[] sp = lowerAccount.Split(new string[] { CircleString.ViaCircleGroupSplitter }, StringSplitOptions.RemoveEmptyEntries);
+ if (sp.Length < 2)
+ {
+ return null;
+ }
+
+ string[] idDomain = sp[1].Split(new char[] { '@' }, StringSplitOptions.RemoveEmptyEntries);
+ if (idDomain.Length < 2)
+ return null;
+ string[] typeAccount = sp[0].Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
+ if (typeAccount.Length < 2)
+ return null;
+ Guid abid = new Guid(idDomain[0]);
+ if (abid != AddressBookId || idDomain[1].ToLowerInvariant() != HostDomain) //Is it the correct circle selected?
+ return null;
+
+ ClientType type = (ClientType)(int.Parse(typeAccount[0]));
+ string mail = typeAccount[1];
+ if (HasMember(mail, type))
+ {
+ return ContactList.GetContact(mail, type);
+ }
+
+ return null;
+ }
+
+ }
+ }
+ catch (Exception ex)
+ {
+ Trace.WriteLineIf(Settings.TraceSwitch.TraceError, "Get contact from circle error: account: " + account +
+ " in " + ToString() + "\r\nError Message: " + ex.Message);
+ }
+
+ return null;
+ }
+
+ ///
+ /// Remove a specific contact from circle's contact list by the information provided.
+ ///
+ /// The contact information
+ /// The parse option for the account parameter
+ ///
+ internal bool RemoveMember(string account, AccountParseOption option)
+ {
+ string lowerAccount = account.ToLowerInvariant();
+ try
+ {
+ switch (option)
+ {
+ case AccountParseOption.ParseAsClientTypeAndAccount:
+ {
+ string[] typeAccount = lowerAccount.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
+ if (typeAccount.Length >= 2)
+ {
+ ClientType type = (ClientType)(int.Parse(typeAccount[0]));
+ string mail = typeAccount[1];
+ if (HasMember(mail, type))
+ {
+ ContactList.Remove(account, type);
+ return true;
+ }
+
+ return false;
+
+ }
+ }
+ break;
+ case AccountParseOption.ParseAsFullCircleAccount:
+ {
+ string[] sp = lowerAccount.Split(new string[] { CircleString.ViaCircleGroupSplitter }, StringSplitOptions.RemoveEmptyEntries);
+ if (sp.Length < 2)
+ {
+ return false;
+ }
+
+ string[] idDomain = sp[1].Split(new char[] { '@' }, StringSplitOptions.RemoveEmptyEntries);
+ if (idDomain.Length < 2)
+ return false;
+ string[] typeAccount = sp[0].Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
+ if (typeAccount.Length < 2)
+ return false;
+ Guid abid = new Guid(idDomain[0]);
+ if (abid != AddressBookId || idDomain[1].ToLowerInvariant() != HostDomain) //Is it the correct circle selected?
+ return false;
+
+ ClientType type = (ClientType)(int.Parse(typeAccount[0]));
+ string mail = typeAccount[1];
+ if (HasMember(mail, type))
+ {
+ ContactList.Remove(account, type);
+ return true;
+ }
+
+ return false;
+ }
+
+ }
+ }
+ catch (Exception ex)
+ {
+ Trace.WriteLineIf(Settings.TraceSwitch.TraceError, "Remove contact from circle error: account: " + account +
+ " in " + ToString() + "\r\nError Message: " + ex.Message);
+ }
+
+ return false;
+ }
+
+
+ ///
+ /// Check whether a specific contact exists in circle's contact list by the information provided.
+ ///
+ /// The contact information
+ /// The parse option for the account parameter
+ ///
+ internal bool HasMember(string account, AccountParseOption option)
+ {
+ string lowerAccount = account.ToLowerInvariant();
+ try
+ {
+ switch (option)
+ {
+ case AccountParseOption.ParseAsClientTypeAndAccount:
+ {
+ string[] typeAccount = lowerAccount.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
+ if (typeAccount.Length >= 2)
+ {
+ ClientType type = (ClientType)(int.Parse(typeAccount[0]));
+ string mail = typeAccount[1];
+ return HasMember(mail, type);
+ }
+ }
+ break;
+ case AccountParseOption.ParseAsFullCircleAccount:
+ {
+ string[] sp = lowerAccount.Split(new string[] { CircleString.ViaCircleGroupSplitter }, StringSplitOptions.RemoveEmptyEntries);
+ if (sp.Length < 2)
+ {
+ return false;
+ }
+
+ string[] idDomain = sp[1].Split(new char[] { '@' }, StringSplitOptions.RemoveEmptyEntries);
+ if (idDomain.Length < 2)
+ return false;
+ string[] typeAccount = sp[0].Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
+ if (typeAccount.Length < 2)
+ return false;
+ Guid abid = new Guid(idDomain[0]);
+ if (abid != AddressBookId || idDomain[1].ToLowerInvariant() != HostDomain) //Is it the correct circle selected?
+ return false;
+
+ ClientType type = (ClientType)(int.Parse(typeAccount[0]));
+ string mail = typeAccount[1];
+ return HasMember(mail, type);
+ }
+
+ }
+ }
+ catch (Exception ex)
+ {
+ Trace.WriteLineIf(Settings.TraceSwitch.TraceError, "Verifying membership error: account: " + account +
+ " in " + ToString() + "\r\nError Message: " + ex.Message);
+ }
+
+ return false;
+ }
+
+
+ internal bool HasMember(string account, ClientType type)
+ {
+ lock (ContactList)
+ return ContactList.HasContact(account, type);
+ }
+
+ internal bool HasMember(Guid contactId)
+ {
+ lock (ContactList)
+ return (ContactList.GetContactByGuid(contactId) != null);
+
+ }
+
+ internal bool HasMember(long CID)
+ {
+ lock (ContactList)
+ return (ContactList.GetContactByCID(CID) != null);
+ }
+
+ internal void SetAddressBookInfo(ABFindContactsPagedResultTypeAB abInfo)
+ {
+ abinfo = abInfo;
+ }
+
+ #region Protected
+ protected virtual void Initialize()
+ {
+ ContactType = MessengerContactType.Circle;
+ Lists = MSNLists.AllowedList | MSNLists.ForwardList;
+ }
+
+ #endregion
+ }
+}
diff --git a/MSNPSharp/CircleInviter.cs b/MSNPSharp/CircleInviter.cs
new file mode 100644
index 0000000..073cab6
--- /dev/null
+++ b/MSNPSharp/CircleInviter.cs
@@ -0,0 +1,76 @@
+#region
+/*
+Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions
+(http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice, Andy Phan.
+All rights reserved. http://code.google.com/p/msnp-sharp/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the names of Bas Geertsema or Xih Solutions nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#endregion
+
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using MSNPSharp.MSNWS.MSNABSharingService;
+
+namespace MSNPSharp
+{
+ ///
+ /// The who send a join contact invitation.
+ ///
+ [Obsolete("Inviter is no more supported by Microsoft.")]
+ [Serializable()]
+ public class CircleInviter : Contact
+ {
+ private string message = string.Empty;
+
+ ///
+ /// Invitation message send via the email.
+ ///
+ public string Message
+ {
+ get
+ {
+ return message;
+ }
+ }
+
+
+ internal CircleInviter(ContactType inviter, string inviterMessage)
+ : base(WebServiceConstants.MessengerIndividualAddressBookId, inviter.contactInfo.passportName, ClientType.PassportMember, inviter.contactInfo.CID, null)
+ {
+ if (inviterMessage != null)
+ message = inviterMessage;
+ }
+
+ internal CircleInviter(string inviterEmail, string inviterName, string inviterMessage)
+ : base(WebServiceConstants.MessengerIndividualAddressBookId, inviterEmail, ClientType.PassportMember, 0, null)
+ {
+ if (inviterMessage != null)
+ message = inviterMessage;
+ }
+ }
+}
diff --git a/MSNPSharp/CircleList.cs b/MSNPSharp/CircleList.cs
new file mode 100644
index 0000000..1ff7b08
--- /dev/null
+++ b/MSNPSharp/CircleList.cs
@@ -0,0 +1,168 @@
+#region Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions (http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice
+/*
+Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions
+(http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice.
+All rights reserved. http://code.google.com/p/msnp-sharp/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the names of Bas Geertsema or Xih Solutions nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Collections;
+using System.Threading;
+
+namespace MSNPSharp
+{
+ [Serializable()]
+ public class CircleList : IEnumerable
+ {
+ private Dictionary list = new Dictionary();
+
+ [NonSerialized]
+ private NSMessageHandler nsMessageHandler = null;
+
+ [NonSerialized]
+ private object syncRoot;
+
+ public object SyncRoot
+ {
+ get
+ {
+ if (syncRoot == null)
+ {
+ object newobj = new object();
+ Interlocked.CompareExchange(ref syncRoot, newobj, null);
+ }
+ return syncRoot;
+ }
+ }
+
+ internal bool AddCircle(Circle circle)
+ {
+ if (this[circle.Mail] == null)
+ {
+ lock (SyncRoot)
+ list.Add(circle.Mail, circle);
+ return true;
+ }
+ else
+ {
+ lock (SyncRoot)
+ {
+ circle.Lists = list[circle.Mail].Lists;
+ list[circle.Mail] = circle;
+ }
+ }
+
+ return false;
+ }
+
+ ///
+ /// Remove a circle from circle list.
+ ///
+ ///
+ internal void RemoveCircle(Circle circle)
+ {
+ lock (SyncRoot)
+ {
+ list.Remove(circle.Mail);
+ }
+ }
+
+ ///
+ /// Remove a circle from circle list, by providing addressbook Id and Host Domain.
+ ///
+ /// The addressbook Id for circle's addressbook page.
+ /// The host domain of a circle.
+ internal void RemoveCircle(Guid abId, string hostDomain)
+ {
+ lock (SyncRoot)
+ {
+ string identifier = abId.ToString().ToLowerInvariant() + "@" + hostDomain.ToLowerInvariant();
+ list.Remove(identifier);
+ }
+ }
+
+ internal CircleList(NSMessageHandler handler)
+ {
+ nsMessageHandler = handler;
+ }
+
+
+ ///
+ /// Find by circle Id and host domain if circle not found, return null.
+ ///
+ /// Circle id
+ /// Circle host domain.
+ ///
+ public Circle this[Guid abId, string hostDomain]
+ {
+ get
+ {
+ string identifier = abId.ToString().ToLowerInvariant() + "@" + hostDomain.ToLowerInvariant();
+ if (list.ContainsKey(identifier))
+ return list[identifier];
+
+ return null;
+ }
+ }
+
+ ///
+ /// Find by circle Id and host domain, if circle not found, return null.
+ ///
+ /// Via Id: guid@hostdomain
+ ///
+ public Circle this[string idAndHostDomain]
+ {
+ get
+ {
+ string identifier = idAndHostDomain.ToLowerInvariant();
+ if (list.ContainsKey(identifier))
+ return list[identifier];
+
+ return null;
+ }
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return list.Values.GetEnumerator();
+ }
+
+ public void Clear()
+ {
+ lock (SyncRoot)
+ list.Clear();
+ }
+
+ public int Count
+ {
+ get { return list.Count; }
+ }
+ }
+}
diff --git a/MSNPSharp/ClassDiagram1.cd b/MSNPSharp/ClassDiagram1.cd
new file mode 100644
index 0000000..19c6950
--- /dev/null
+++ b/MSNPSharp/ClassDiagram1.cd
@@ -0,0 +1,923 @@
+
+
+
+
+
+
+ Configuration.cs
+ AABAAAAAAAAAAAAAAAAAAAAAAAAgAAoAAABAIAAACAA=
+
+
+
+
+
+ ConnectivityException.cs
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ ConnectivitySettings.cs
+ AAQAAACEAAAAoAAEACAAAgAACAIACAwCAAgEAgAAAAA=
+
+
+
+
+
+ Contact.cs
+ AAAAAAAAAAAAAAAACAAAAAgIAAAACAAAAAAAAAAAAAA=
+
+
+
+
+
+ Contact.cs
+ AAAAAAAAAAAAAAAACAAAAAgAAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ Contact.cs
+ AAAAAAAAAAAAAAAAAAAAAAAIAAAACAAAAAAAAAAAAAA=
+
+
+
+
+
+ Contact.cs
+ UFVJQQQEoQJFgSQgwLFkVFSFQUxOFekEUgDAQRFAAmU=
+
+
+
+
+
+ ContactGroup.cs
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQ=
+
+
+
+
+
+ ContactGroup.cs
+ EAAAAAAAAAAAAAAAgAAAABQEAAAEBIAAEAAAQBAAAAA=
+
+
+
+
+
+ ContactGroupList.cs
+ AAIAAgAAAAAAABAACAAABAAAAAAgAAAAEAAAAABAAAg=
+
+
+
+
+
+
+ ContactList.cs
+ AAAAAAAgACAACAAQKAAAFAAAAAABAAAAgoACIAAIIAI=
+
+
+
+
+
+ Conversation.cs
+ BEIQRCKCFZVEgCWg0EACpBMQBg0FwBSxg4QGIAUUYQA=
+
+
+
+
+
+ Credentials.cs
+ AAAAAAAgAAIAAAAAAAAAAAAgAAAAAAACAAAAQgAAAEA=
+
+
+
+
+
+ DisplayImage.cs
+ AAAAAAAAAAAAAAAAAAAAAAAAEAAACBAAEAAAAAAAAAA=
+
+
+
+
+
+ Emoticon.cs
+ AAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ EmoticonMessage.cs
+ AACAAAAAACAACCAkAAAABAAAAAQAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ EventArgs.cs
+ AAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAA=
+
+
+
+
+
+ EventArgs.cs
+ AAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAIACA=
+
+
+
+
+
+ EventArgs.cs
+ AAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAIIAA=
+
+
+
+
+
+ EventArgs.cs
+ AAgAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAIAAA=
+
+
+
+
+
+ MailEventArgs.cs
+ SAAAAUgAEAEgAAAAIAAAAAAAEAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ MailEventArgs.cs
+ AAgAAAAAAAAAQAAABAAAAAQABAAAAAAAAAAEAAAIAAA=
+
+
+
+
+
+ MailEventArgs.cs
+ AgACAQIAAAEARAAAAIQAAACEAAAABAAAAAAEAAAAAgA=
+
+
+
+
+
+ Messenger.cs
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAQQAIAAAAAAAAgAAA=
+
+
+
+
+
+ Messenger.cs
+ ECRAAACAAAABQAAIAAAAgIAAAEAEKEgAHECQAlACAgA=
+
+
+
+
+
+ MobileMessage.cs
+ AACAAAAgAAAAKCAEACAAAAAgAAAEAAAIBAAACAAAAAA=
+
+
+
+
+
+ MSNObject.cs
+ AAEIAEAABgVAgoQEgIIAQAIKBAARAIAAEISAAgAABiI=
+
+
+
+
+
+ MSNObject.cs
+ AAIAAAAAAACAABBAAAAAFAQABABAAAAAAAAAAAAAICA=
+
+
+
+
+
+
+ MSNPSharpException.cs
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ EventArgs.cs
+ AAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ EventArgs.cs
+ AAAAAAAAAgAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ EventArgs.cs
+ AAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ EventArgs.cs
+ AAAAAAAAAAAAAAAACQAAAAkAAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ EventArgs.cs
+ AAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ NSMessageHandler.cs
+ PAjnFUTGC1CprQGioUBgIigmEHAEXPRCnELxJspflPU=
+
+
+
+
+
+
+ NSMessageProcessor.cs
+ AAQAAAAgCAAAAAAAACAAAIAoAAAAAAAAAAAAAAAAAgA=
+
+
+
+
+
+ Owner.cs
+ gAFAAHDFIABITGWAIMwNoSwBKKdIdWkGBOABIYhAQSE=
+
+
+
+
+
+ PersonalMessage.cs
+ ACACAAAAAAAAUAgEAEAYCAAAQAqAAAIAAQAAIAAwAAA=
+
+
+
+
+
+ QRYFactory.cs
+ AAAAARAAAAAAAAAAAACAAEAIAAAAAAAAAAAAAAAAgAA=
+
+
+
+
+
+ SBMessageHandler.cs
+ AAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ SBMessageHandler.cs
+ AAAQAAAAEAAAAAAAAAAAAAQAAAAEAAABACAAQQAgAEA=
+
+
+
+
+
+ SBMessageHandler.cs
+ FEABzQZCGIBQCABusUggIDGaFoAAeBSQHAAAIBGE4BA=
+
+
+
+
+
+
+ SBMessageProcessor.cs
+ AAQAAAAgCAAAAAAAACACAIAoAAAAAAAAAAAAAAAAAgA=
+
+
+
+
+
+ StrDictionary.cs
+ AAAAAIAAAAAAAAQAAAAEAAAAAAAAAAAAAAAgAAAAAAA=
+
+
+
+
+
+ StrDictionary.cs
+ AAICAAAAAAAEABAACAAAAAAAAAAAAAAAAAAAAABAAAA=
+
+
+
+
+
+
+ TextMessage.cs
+ IAKAAAAAQAAACCAEAAQAAAAMABABCACYAAQAiAAGABA=
+
+
+
+
+
+
+ UnauthorizedException.cs
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Wink.cs
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ Core\Factory.cs
+ ECAAIAAAABAFABAICAEACAhAgQAFYCAgYBAABAQAAAQ=
+
+
+
+
+
+ Core\MessagePool.cs
+ AAAAAAAAAAECAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ Core\MSNMessage.cs
+ AACAAYAgAAGgCCAMAAAABAAgAAQAAAAAAQgAAAAAAAA=
+
+
+
+
+
+
+ Core\NetworkMessage.cs
+ AACAAAAAQgAACiAAAIIEAAAABgAAAABAgQAAAAAAAAA=
+
+
+
+
+
+ Core\NotificationMessage.cs
+ AACQkAAwAACALAgEIIAAABAAAgAEAQgIAAAABAEAAgE=
+
+
+
+
+
+ Core\NSMessage.cs
+ AACAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+
+ Core\NSMessagePool.cs
+ AAAAAAAAACECEAQAIFCAAAAAAAAAEgAAABIAAAAAAAA=
+
+
+
+
+
+
+ Core\SBMessage.cs
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ Core\SBMessagePool.cs
+ AAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ Core\SBMSGMessage.cs
+ AACAQAAIAEAACAAEAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ Core\SocketMessageProcessor.cs
+ CARgAAIBAAAAQQAAACBBQJAQQUAAIEICAAEAAgAYAkA=
+
+
+
+
+
+
+ DataTransfer\MSNSLPHandler.cs
+ EAgKIhAAAgIAEABAABgAIkCIACJAgAAAAAAAAAAICEA=
+
+
+
+
+
+ DataTransfer\MSNSLPHandler.cs
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAA=
+
+
+
+
+
+ DataTransfer\MSNSLPHandler.cs
+ AIAAAQDUAUEAQAFAAAgAAAAAAAAAAVAAAAEAAAAIAAA=
+
+
+
+
+
+ DataTransfer\MSNSLPHandler.cs
+ CQAAgQBGECAgAAgAQBJgAIQVEAEAOCAAAFAAQ4AAgCA=
+
+
+
+
+
+
+ DataTransfer\MSNSLPMessage.cs
+ IgiAACIAAAAAiAAEAIAhBAoAkQAYCJgAEAgQACAIAAA=
+
+
+
+
+
+ DataTransfer\P2PDCPool.cs
+ AAAAAAAAAAECAAAAAEAAAAAAAAAAAAABAAAQAAAAABA=
+
+
+
+
+
+ DataTransfer\P2PDirectProcessor.cs
+ AAQAAAAAAAEAAEAAACCAAAAAgAAAAAAAAQAAAAAAAgA=
+
+
+
+
+
+ DataTransfer\P2PHandler.cs
+ AAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ DataTransfer\P2PHandler.cs
+ GAgoAABAQAQgAxkACAAgAAA0ECEAKQAAEAAAIAAIEIA=
+
+
+
+
+
+
+ DataTransfer\P2PMessage.cs
+ BBCgBAQAAIIgCKAGIAiAAAAIBAAAAARAACAAQAAghAQ=
+
+
+
+
+
+ DataTransfer\P2PMessage.cs
+ AAAAAAAABAAAAAAEAAAAAAAAQAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ DataTransfer\P2PMessage.cs
+ AACAAAAAAAAACAAEAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ DataTransfer\P2PMessage.cs
+ AACgAAAAAAAAAAAEAAAAAAAEAAAABAAAAAAAAAAAAAA=
+
+
+
+
+
+ DataTransfer\P2PMessagePool.cs
+ AAAAAAAAAAAAAAAAAEgAAAAAAAAAAQAAAAACQAAAAAA=
+
+
+
+
+
+ DataTransfer\P2PMessageSession.cs
+ S9AkKABIECQADwAECDGgIgkiUDASagBAGEACIUIAhAA=
+
+
+
+
+
+
+ DataTransfer\P2PTransferSession.cs
+ CBgYCYBIAKEEEQDEBDjgUDAoICAAKEBIAAEQAhAYGAM=
+
+
+
+
+
+
+ ProxySocket\AuthMethod.cs
+ AAAAAAQBAAAAAEAAAAAAAAIAAAAACAAgAAAAAgAAQAA=
+
+
+
+
+
+ ProxySocket\AuthNone.cs
+ AAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAgAAAAAAAAAAA=
+
+
+
+
+
+ ProxySocket\AuthUserPass.cs
+ AAAAAAAAAAAQAAAAAQAABQIBAAAAAAAiAAAAAAAABAA=
+
+
+
+
+
+ ProxySocket\IAsyncProxyResult.cs
+ AAAAAAIAAAAABAAAAAAAECAAAAAAABAQEAACAAAAAAA=
+
+
+
+
+
+
+ ProxySocket\ProxyException.cs
+ AAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ ProxySocket\ProxySocket.cs
+ AAAQAAAEICCJAEgAAAQAIICACAQFACAGAAAARAAgAEA=
+
+
+
+
+
+ ProxySocket\Socks4Handler.cs
+ AAAAABAAAAASAAAAAAAAAAABAAEEAAAAAAAAAAAAAAg=
+
+
+
+
+
+ ProxySocket\Socks5Handler.cs
+ AAAAABAAAAASAAAAAEAAAQKBAAEEAAACAEAABEAQEAg=
+
+
+
+
+
+ ProxySocket\SocksHandler.cs
+ AAAAABQBACAAAAAAEQAABAAACAAACEAAAAAQAgAAQAg=
+
+
+
+
+
+ Core\YIMMessage.cs
+ AACAAAAAAAEAAGAAAAAABAAgBAAAAIAAAQAAAAAAAAA=
+
+
+
+
+
+ YIMMessageHandler.cs
+ AAAAAABAAAAAAAAsAAAAAAECAgAAABwACAAAAAKAAAA=
+
+
+
+
+
+ Core\IMessageHandler.cs
+ AAAAAABAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAA=
+
+
+
+
+
+ Core\MessageProcessor.cs
+ CAAAAAAAAAAAAQAAACAAAAAAAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ enums.cs
+ AAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAEAAAA=
+
+
+
+
+
+ enums.cs
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEAAAAAAAAAAI=
+
+
+
+
+
+ enums.cs
+ AAAAAABABAAAAAAAAAgAEAAAAABAAAAAAAAAIAAEgFA=
+
+
+
+
+
+ enums.cs
+ AAcpAoEqohACAGQAgEYgAIaHBAoURRIJAUFQACGBAJA=
+
+
+
+
+
+ enums.cs
+ AAQAAAQAAAAAAAAAAAAAAAAAAAQAAAAAQAAAAAEIAAA=
+
+
+
+
+
+ enums.cs
+ AAAAAAAAAAAIAAAAAgAAAAAAAAAAAAAAAAAAAAAAABA=
+
+
+
+
+
+ enums.cs
+ AAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAEAAAAAAABA=
+
+
+
+
+
+ enums.cs
+ AABACAAIAJNIJAIAAAAFAAGAAEBgAEAAjAAIAQkYCAA=
+
+
+
+
+
+ enums.cs
+ AAAAAAAAAAAAACAAAIAAAAAAAAACAAAAAAAAAAEAAAE=
+
+
+
+
+
+ enums.cs
+ QAAAAAEAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAEAAAA=
+
+
+
+
+
+ enums.cs
+ AAAIAQAAABCABEACAEAAICAQABAAACAAAIAAEAIIiAA=
+
+
+
+
+
+ MSNObject.cs
+ IACAAAAAEAAAAAAAAAYABAAAAABCAAFAAAAiAIAAABA=
+
+
+
+
+
+ enums.cs
+ AAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAABA=
+
+
+
+
+
+ DataTransfer\MSNSLPHandler.cs
+ AAAAAAAAAAAAAAAAAIAABAAAAAAEAAAAAAAAAEAAABA=
+
+
+
+
+
+ DataTransfer\P2PMessage.cs
+ AgAAAAIIAgCAAAAAAAgAAAAAAAAMQACAAAAAAAAAAAA=
+
+
+
+
+
+ ProxySocket\ProxySocket.cs
+ AAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAEAAAA=
+
+
+
+
+
+ Messenger.cs
+ AAAAAAAgAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ NSMessageHandler.cs
+ EAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ NSMessageHandler.cs
+ AAAgAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ NSMessageHandler.cs
+ ABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ NSMessageHandler.cs
+ AAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQ=
+
+
+
+
+
+ NSMessageHandler.cs
+ AAAAAAAAAAAAAAAAAAgAAAAQAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ NSMessageHandler.cs
+ AAAAAAAACAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ NSMessageHandler.cs
+ AAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAIA=
+
+
+
+
+
+ NSMessageHandler.cs
+ AAAAAAAAAAAAAAAAAAAAAAAQAACAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ NSMessageHandler.cs
+ AAAAAAAAAAAAAAAAAAAAAAAQAAAEAAAAAAAAAAAAAAA=
+
+
+
+
+
+ NSMessageHandler.cs
+ AAAAAAAAAAAAAAAAAAAAAAAQAAAAAgAAAAAAAAAAAAA=
+
+
+
+
+
+ NSMessageHandler.cs
+ AAAAAAAAAAAAAAAgAAAAAAAQAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ SBMessageHandler.cs
+ AAAAAAAAAAAAAAAAAACAAAAQAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ SBMessageHandler.cs
+ AAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAQAAAA=
+
+
+
+
+
+ SBMessageHandler.cs
+ AAAAAACAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ SBMessageHandler.cs
+ AAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAEAAAAA=
+
+
+
+
+
+ SBMessageHandler.cs
+ EAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ IMessageHandler.cs
+ AAAAAAAAAAAAAACAAAAAAAAQAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ IMessageHandler.cs
+ AAAAAAAAAQAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ MessageProcessor.cs
+ AAAAAAAAAQAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ MSNSLPHandler.cs
+ AAAAAAAAAAAIAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ MSNSLPHandler.cs
+ AAAACAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ P2PHandler.cs
+ CAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA=
+
+
+
+
+
+ ProxySocket\SocksHandler.cs
+ AAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAA=
+
+
+
\ No newline at end of file
diff --git a/MSNPSharp/Comparers.cs b/MSNPSharp/Comparers.cs
new file mode 100644
index 0000000..74b0526
--- /dev/null
+++ b/MSNPSharp/Comparers.cs
@@ -0,0 +1,85 @@
+#region Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions (http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice
+/*
+Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions
+(http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice.
+All rights reserved. http://code.google.com/p/msnp-sharp/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the names of Bas Geertsema or Xih Solutions nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#endregion
+
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MSNPSharp
+{
+ ///
+ /// A comparer which treat siblings as the same contact.
+ ///
+ ///
+ public class SiblingComparer : IEqualityComparer
+ {
+ #region IEqualityComparer Members
+
+ public bool Equals(TKey x, TKey y)
+ {
+ return GetHashCode(x) == GetHashCode(y);
+ }
+
+ public int GetHashCode(TKey obj)
+ {
+ if (obj is Contact)
+ {
+ return (obj as Contact).SiblingString.GetHashCode();
+ }
+
+ return obj.GetHashCode();
+ }
+
+ #endregion
+ }
+
+ namespace Utilities
+ {
+ public class ConversationIDComparer : IEqualityComparer
+ {
+ #region IEqualityComparer Members
+
+ public bool Equals(ConversationID x, ConversationID y)
+ {
+ return x == y;
+ }
+
+ public int GetHashCode(ConversationID obj)
+ {
+ return obj.GetHashCode();
+ }
+
+ #endregion
+ }
+ }
+}
diff --git a/MSNPSharp/Configuration.cs b/MSNPSharp/Configuration.cs
new file mode 100644
index 0000000..703371b
--- /dev/null
+++ b/MSNPSharp/Configuration.cs
@@ -0,0 +1,237 @@
+#region Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions (http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice
+/*
+Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions
+(http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice.
+All rights reserved. http://code.google.com/p/msnp-sharp/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the names of Bas Geertsema or Xih Solutions nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#endregion
+
+using System;
+using System.IO;
+using System.Diagnostics;
+
+namespace MSNPSharp
+{
+ using MSNPSharp.IO;
+ using MSNPSharp.Core;
+
+ [Serializable]
+ public enum PublicPortPriority
+ {
+ None = 0,
+ First = 1,
+ Last = 9
+ }
+
+ ///
+ /// General configuration options.
+ ///
+ [Serializable()]
+ public static class Settings
+ {
+ ///
+ /// Defines the verbosity of the trace messages.
+ ///
+ public static TraceSwitch TraceSwitch = new TraceSwitch("MSNPSharp", "MSNPSharp switch");
+
+ ///
+ /// Ports for DC to try bind. These ports aren't firewalled by ISS.
+ ///
+ public static readonly ushort[] PublicPorts = new ushort[]
+ {
+ 80, // http
+ 21, // ftp
+ 25, // smtp
+ 110, // pop3
+ 443, // https
+ 8080 // webcache
+ };
+
+
+
+ ///
+ /// Constructor.
+ ///
+ static Settings()
+ {
+ isMono = (null != Type.GetType("Mono.Runtime")); // http://www.mono-project.com/FAQ:_Technical
+
+ TraceSwitch.Level = TraceLevel.Verbose;
+#if DEBUG
+ serializationType = MclSerialization.Compression | MclSerialization.Cryptography;
+#else
+ serializationType = MclSerialization.Compression;
+#endif
+ enableGzipCompressionForWebServices = (isMono == false);
+ }
+
+ private static PublicPortPriority publicPortPriority = PublicPortPriority.First;
+ private static string savepath = Path.GetFullPath(".");
+ private static bool enableGzipCompressionForWebServices;
+ private static MclSerialization serializationType;
+ private static int msnTicketsCleanupInterval = 5;
+ private static int msnTicketLifeTime = 20;
+ private static bool noSave;
+ private static bool isMono;
+
+ public static PublicPortPriority PublicPortPriority
+ {
+ get
+ {
+ return publicPortPriority;
+ }
+ set
+ {
+ publicPortPriority = value;
+ }
+ }
+
+ ///
+ /// Indicates whether the runtime framework is currently mono or not.
+ ///
+ public static bool IsMono
+ {
+ get
+ {
+ return isMono;
+ }
+ }
+
+ ///
+ /// File serialization type when saving.
+ /// Compression saves spaces on disk, Encrypt protects your addressbook but eats some cpu
+ ///
+ public static MclSerialization SerializationType
+ {
+ get
+ {
+ return serializationType;
+ }
+ set
+ {
+ serializationType = value;
+ }
+ }
+
+ ///
+ /// Don't save addressbook files.
+ ///
+ public static bool NoSave
+ {
+ get
+ {
+ return noSave;
+ }
+ set
+ {
+ noSave = value;
+ }
+ }
+
+ ///
+ /// Save directory
+ ///
+ public static string SavePath
+ {
+ get
+ {
+ return savepath;
+ }
+ set
+ {
+ savepath = value;
+ }
+ }
+
+ /// MSNTicket lifetime in minutes for the internal cache. Default is 20 minutes.
+ /// Keep small if the client will connect to the msn network for the short time.
+ public static int MSNTicketLifeTime
+ {
+ get
+ {
+ return msnTicketLifeTime;
+ }
+ set
+ {
+ if (value <= 0)
+ value = 20;
+
+ msnTicketLifeTime = value;
+ }
+ }
+
+ ///
+ /// Run clean up code for the MSNTickets in every x minutes. Default is 5 minutes.
+ ///
+ public static int MSNTicketsCleanupInterval
+ {
+ get
+ {
+ return msnTicketsCleanupInterval;
+ }
+ set
+ {
+ if (value <= 0)
+ value = 5;
+
+ msnTicketsCleanupInterval = value;
+ }
+ }
+
+ ///
+ /// Use Gzip compression for web services to save bandwidth.
+ ///
+ /// Don't use this if you run .net framework on mono
+ public static bool EnableGzipCompressionForWebServices
+ {
+ get
+ {
+ return enableGzipCompressionForWebServices;
+ }
+ set
+ {
+ enableGzipCompressionForWebServices = value;
+ }
+ }
+
+ ///
+ /// Don't use compression when saving addressbook files.
+ ///
+ [Obsolete("Please use SerializationType", false)]
+ public static bool NoCompress
+ {
+ get
+ {
+ return (serializationType == MclSerialization.None);
+ }
+ set
+ {
+ serializationType = value ? MclSerialization.None : MclSerialization.Compression;
+ }
+ }
+ }
+};
\ No newline at end of file
diff --git a/MSNPSharp/ConnectivityException.cs b/MSNPSharp/ConnectivityException.cs
new file mode 100644
index 0000000..1de5072
--- /dev/null
+++ b/MSNPSharp/ConnectivityException.cs
@@ -0,0 +1,83 @@
+#region Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions (http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice
+/*
+Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions
+(http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice.
+All rights reserved. http://code.google.com/p/msnp-sharp/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the names of Bas Geertsema or Xih Solutions nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#endregion
+
+using System;
+using System.Runtime.Serialization;
+
+namespace MSNPSharp
+{
+ using MSNPSharp.Core;
+
+ ///
+ /// Specifies an exception when a connection is setup.
+ ///
+ [Serializable()]
+ public class ConnectivityException : MSNPSharpException
+ {
+ ///
+ /// Basic constructor.
+ ///
+ public ConnectivityException()
+ {
+ }
+
+ ///
+ /// Specifies a ConnectivityException.
+ ///
+ /// A textual presentation of the exception message
+ public ConnectivityException(string message)
+ : base(message)
+ {
+ }
+
+ ///
+ /// Specifies a ConnectivityException which originates from another exception.
+ ///
+ /// A textual presentation of the exception message
+ /// The (inner)exception which caused this exception. For example a SocketException
+ public ConnectivityException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+
+ ///
+ /// Serialization constructor.
+ ///
+ ///
+ ///
+ protected ConnectivityException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+
+ }
+};
diff --git a/MSNPSharp/ConnectivitySettings.cs b/MSNPSharp/ConnectivitySettings.cs
new file mode 100644
index 0000000..5c45ce1
--- /dev/null
+++ b/MSNPSharp/ConnectivitySettings.cs
@@ -0,0 +1,502 @@
+#region Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions (http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice
+/*
+Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions
+(http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice.
+All rights reserved. http://code.google.com/p/msnp-sharp/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the names of Bas Geertsema or Xih Solutions nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#endregion
+
+using System;
+using System.Net;
+using System.Web;
+using System.Net.Security;
+using System.Security.Cryptography.X509Certificates;
+
+namespace MSNPSharp
+{
+ using MSNPSharp.Core;
+
+ public class MSNServiceCertificatePolicy : ICertificatePolicy
+ {
+ public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem)
+ {
+ return true;
+ }
+ }
+
+ ///
+ /// Defines the way how connections must be set up.
+ ///
+ ///
+ /// Via ConnectivitySettings the client can specify to which MSN server must be connected,
+ /// whether or not proxy servers are used for internet connections and whether
+ /// web proxys are used for accessing HTTP resources. The most common HTTP resource
+ /// is the authentication with Passport.com during the login phase.
+ ///
+ [Serializable()]
+ public class ConnectivitySettings
+ {
+ #region Constructors
+
+ static ConnectivitySettings()
+ {
+ try
+ {
+ ServicePointManager.ServerCertificateValidationCallback += delegate(object sender, X509Certificate certificate,
+ X509Chain chain, SslPolicyErrors sslPolicyErrors)
+ {
+ return true;
+ };
+ }
+ catch (Exception)
+ {
+#pragma warning disable 0618
+ ServicePointManager.CertificatePolicy = new MSNServiceCertificatePolicy();
+#pragma warning restore 0618
+ }
+ }
+
+ ///
+ /// Constructor to instantiate a ConnectivitySettings object.
+ ///
+ public ConnectivitySettings()
+ {
+ }
+
+ ///
+ /// Copy constructor.
+ ///
+ ///
+ public ConnectivitySettings(ConnectivitySettings x)
+ : this(x.LocalHost, x.LocalPort, x.Host, x.Port, x.ProxyHost, x.Port, x.ProxyUsername, x.ProxyPassword, x.ProxyType, x.WebProxy)
+ {
+ }
+
+
+ ///
+ /// Constructs a ConnectivitySettings which uses a socks proxy in all direct TCP communications with the messenger servers. HTTP resources are accessed via the supplied WebProxy.
+ ///
+ /// Host endpoint of messenger server. Standard is msnmsgr.escargot.chat:1863
+ public ConnectivitySettings(IPEndPoint remoteEndPoint)
+ : this(remoteEndPoint.Address.ToString(), remoteEndPoint.Port)
+ {
+ }
+
+ ///
+ /// Constructs a ConnectivitySettings which uses a socks proxy in all direct TCP communications with the messenger servers. HTTP resources are accessed via the supplied WebProxy.
+ ///
+ /// Local endpoint you want to bind to.
+ /// Host endpoint of messenger server. Standard is msnmsgr.escargot.chat:1863
+ public ConnectivitySettings(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint)
+ : this(localEndPoint.Address.ToString(), localEndPoint.Port, remoteEndPoint.Address.ToString(), remoteEndPoint.Port)
+ {
+ }
+
+
+ ///
+ /// Constructs a ConnectivitySettings with custom host and port.
+ ///
+ /// Host of messenger server. Standard is msnmsgr.escargot.chat
+ /// Port of messenger server. Standard is 1863
+ public ConnectivitySettings(string host, int port)
+ : this(host, port, string.Empty, 0, string.Empty, string.Empty, ProxyType.None, null)
+ {
+ }
+
+ ///
+ /// Constructs a ConnectivitySettings with custom host and port.
+ ///
+ /// The local address you want to bind to.
+ /// The local port you want to bind to.
+ /// Host of messenger server. Standard is msnmsgr.escargot.chat
+ /// Port of messenger server. Standard is 1863
+ public ConnectivitySettings(string localHost, int localPort, string host, int port)
+ : this(localHost, localPort, host, port, string.Empty, 0, string.Empty, string.Empty, ProxyType.None, null)
+ {
+ }
+
+ ///
+ /// Constructs a ConnectivitySettings which uses a socks proxy in all direct TCP communications with the messenger servers. HTTP resources are accessed via the supplied WebProxy.
+ ///
+ /// Host endpoint of messenger server. Standard is msnmsgr.escargot.chat:1863
+ /// Webproxy to be used when accessing HTTP resources
+ public ConnectivitySettings(IPEndPoint remoteEndPoint, WebProxy webProxy)
+ : this(remoteEndPoint.Address.ToString(), remoteEndPoint.Port, webProxy)
+ {
+ }
+
+ ///
+ /// Constructs a ConnectivitySettings which uses a socks proxy in all direct TCP communications with the messenger servers. HTTP resources are accessed via the supplied WebProxy.
+ ///
+ /// Local endpoint you want to bind to.
+ /// Host endpoint of messenger server. Standard is msnmsgr.escargot.chat:1863
+ /// Webproxy to be used when accessing HTTP resources
+ public ConnectivitySettings(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, WebProxy webProxy)
+ : this(localEndPoint.Address.ToString(), localEndPoint.Port, remoteEndPoint.Address.ToString(), remoteEndPoint.Port, webProxy)
+ {
+ }
+
+
+ ///
+ /// Constructs a ConnectivitySettings which uses a Web proxy for all HTTP connections made.
+ ///
+ /// Host of messenger server. Standard is msnmsgr.escargot.chat
+ /// Port of messenger server. Standard is 1863
+ /// Webproxy to be used when accessing HTTP resources
+ public ConnectivitySettings(string host, int port, WebProxy webProxy)
+ : this(host, port, string.Empty, 0, string.Empty, string.Empty, ProxyType.None, webProxy)
+ {
+ }
+
+ ///
+ /// Constructs a ConnectivitySettings which uses a Web proxy for all HTTP connections made.
+ ///
+ /// The local address you want to bind to.
+ /// The local port you want to bind to.
+ /// Host of messenger server. Standard is msnmsgr.escargot.chat
+ /// Port of messenger server. Standard is 1863
+ /// Webproxy to be used when accessing HTTP resources
+ public ConnectivitySettings(string localHost, int localPort, string host, int port, WebProxy webProxy)
+ : this(localHost, localPort, host, port, string.Empty, 0, string.Empty, string.Empty, ProxyType.None, webProxy)
+ {
+ }
+
+
+
+ ///
+ /// Constructs a ConnectivitySettings which uses a socks proxy in all direct TCP communications with the messenger servers. HTTP resources are accessed via the supplied WebProxy.
+ ///
+ /// Host endpoint of messenger server. Standard is msnmsgr.escargot.chat:1863
+ /// Host endpoint of the proxy server
+ /// Username, if any, used when accessing the proxyserver
+ /// Password, if any, used when accessing the proxyserver
+ /// The proxy version, Socks4 or Socks5
+ public ConnectivitySettings(IPEndPoint remoteEndPoint, IPEndPoint proxyEndPoint, string proxyUsername, string proxyPassword, ProxyType proxyType)
+ : this(remoteEndPoint.Address.ToString(), remoteEndPoint.Port, proxyEndPoint.Address.ToString(), proxyEndPoint.Port, proxyUsername, proxyPassword, proxyType, null)
+ {
+ }
+
+ ///
+ /// Constructs a ConnectivitySettings which uses a socks proxy in all direct TCP communications with the messenger servers. HTTP resources are accessed via the supplied WebProxy.
+ ///
+ /// Local endpoint you want to bind to.
+ /// Host endpoint of messenger server. Standard is msnmsgr.escargot.chat:1863
+ /// Host endpoint of the proxy server
+ /// Username, if any, used when accessing the proxyserver
+ /// Password, if any, used when accessing the proxyserver
+ /// The proxy version, Socks4 or Socks5
+ public ConnectivitySettings(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, IPEndPoint proxyEndPoint, string proxyUsername, string proxyPassword, ProxyType proxyType)
+ : this(localEndPoint, remoteEndPoint, proxyUsername, proxyPassword, proxyType, null)
+ {
+ }
+
+ ///
+ /// Constructs a ConnectivitySettings which uses a proxy in all direct TCP communications with the messenger servers. This means HTTP resources for authenticating the user with Passport.com are accessed directly.
+ ///
+ /// Host of messenger server. Standard is msnmsgr.escargot.chat
+ /// Port of messenger server. Standard is 1863
+ /// Host of the proxy server
+ /// Port of the proxy server
+ /// Username, if any, used when accessing the proxyserver
+ /// Password, if any, used when accessing the proxyserver
+ /// The proxy version, Socks4 or Socks5
+ public ConnectivitySettings(string host, int port, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, ProxyType proxyType)
+ : this(host, port, proxyHost, proxyPort, proxyUsername, proxyPassword, proxyType, null)
+ {
+
+ }
+
+ ///
+ /// Constructs a ConnectivitySettings which uses a socks proxy in all direct TCP communications with the messenger servers. HTTP resources are accessed via the supplied WebProxy.
+ ///
+ /// The local address you want to bind to.
+ /// The local port you want to bind to.
+ /// Host of messenger server. Standard is msnmsgr.escargot.chat
+ /// Port of messenger server. Standard is 1863
+ /// Host of the proxy server
+ /// Port of the proxy server
+ /// Username, if any, used when accessing the proxyserver
+ /// Password, if any, used when accessing the proxyserver
+ /// The proxy version, Socks4 or Socks5
+ public ConnectivitySettings(string localHost, int localPort, string host, int port, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, ProxyType proxyType)
+ : this(localHost, localPort, host, port, proxyHost, proxyPort, proxyUsername, proxyPassword, proxyType, null)
+ {
+ }
+
+
+ ///
+ /// Constructs a ConnectivitySettings which uses a socks proxy in all direct TCP communications with the messenger servers. HTTP resources are accessed via the supplied WebProxy.
+ ///
+ /// Host endpoint of messenger server. Standard is msnmsgr.escargot.chat:1863
+ /// Host endpoint of the proxy server
+ /// Username, if any, used when accessing the proxyserver
+ /// Password, if any, used when accessing the proxyserver
+ /// The proxy version, Socks4 or Socks5
+ /// Webproxy to be used when accessing HTTP resources
+ public ConnectivitySettings(IPEndPoint remoteEndPoint, IPEndPoint proxyEndPoint, string proxyUsername, string proxyPassword, ProxyType proxyType, WebProxy webProxy)
+ : this(remoteEndPoint.Address.ToString(), remoteEndPoint.Port, proxyEndPoint.Address.ToString(), proxyEndPoint.Port, proxyUsername, proxyPassword, proxyType, webProxy)
+ {
+ }
+
+ ///
+ /// Constructs a ConnectivitySettings which uses a socks proxy in all direct TCP communications with the messenger servers. HTTP resources are accessed via the supplied WebProxy.
+ ///
+ /// Local endpoint you want to bind to.
+ /// Host endpoint of messenger server. Standard is msnmsgr.escargot.chat:1863
+ /// Host endpoint of the proxy server
+ /// Username, if any, used when accessing the proxyserver
+ /// Password, if any, used when accessing the proxyserver
+ /// The proxy version, Socks4 or Socks5
+ /// Webproxy to be used when accessing HTTP resources
+ public ConnectivitySettings(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, IPEndPoint proxyEndPoint, string proxyUsername, string proxyPassword, ProxyType proxyType, WebProxy webProxy)
+ : this(localEndPoint.Address.ToString(), localEndPoint.Port, remoteEndPoint.Address.ToString(), remoteEndPoint.Port, proxyEndPoint.Address.ToString(), proxyEndPoint.Port, proxyUsername, proxyPassword, proxyType, webProxy)
+ {
+ }
+
+ ///
+ /// Constructs a ConnectivitySettings which uses a socks proxy in all direct TCP communications with the messenger servers. HTTP resources are accessed via the supplied WebProxy.
+ ///
+ /// Host of messenger server. Standard is msnmsgr.escargot.chat
+ /// Port of messenger server. Standard is 1863
+ /// Host of the proxy server
+ /// Port of the proxy server
+ /// Username, if any, used when accessing the proxyserver
+ /// Password, if any, used when accessing the proxyserver
+ /// The proxy version, Socks4 or Socks5
+ /// Webproxy to be used when accessing HTTP resources
+ public ConnectivitySettings(string host, int port, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, ProxyType proxyType, WebProxy webProxy)
+ :this(string.Empty, 0, host, port, proxyHost, proxyPort, proxyUsername, proxyPassword, proxyType, webProxy)
+ {
+ }
+
+ ///
+ /// Constructs a ConnectivitySettings which uses a socks proxy in all direct TCP communications with the messenger servers. HTTP resources are accessed via the supplied WebProxy.
+ ///
+ /// The local address you want to bind to.
+ /// The local port you want to bind to.
+ /// Host of messenger server. Standard is msnmsgr.escargot.chat
+ /// Port of messenger server. Standard is 1863
+ /// Host of the proxy server
+ /// Port of the proxy server
+ /// Username, if any, used when accessing the proxyserver
+ /// Password, if any, used when accessing the proxyserver
+ /// The proxy version, Socks4 or Socks5
+ /// Webproxy to be used when accessing HTTP resources
+ public ConnectivitySettings(string localHost, int localPort, string host, int port, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, ProxyType proxyType, WebProxy webProxy)
+ {
+ this.localHost = localHost;
+ this.localPort = localPort;
+ this.host = host;
+ this.port = port;
+ this.proxyHost = proxyHost;
+ this.proxyPort = proxyPort;
+ this.proxyUsername = proxyUsername;
+ this.proxyPassword = proxyPassword;
+ this.proxyType = proxyType;
+ this.webProxy = webProxy;
+ }
+
+ #endregion
+
+ #region Private members
+
+ private string host = "msnmsgr.escargot.chat";
+ private int port = 1863;
+ private string localHost = string.Empty;
+ private int localPort = 0;
+ private string proxyHost = string.Empty;
+ private int proxyPort = 0;
+ private string proxyUsername = string.Empty;
+ private string proxyPassword = string.Empty;
+ private ProxyType proxyType = ProxyType.None;
+ private WebProxy webProxy = null;
+
+ #endregion
+
+ #region Public properties
+
+ ///
+ /// Hostname of the MSN server. Defaults is msnmsgr.escargot.chat
+ ///
+ public string Host
+ {
+ get
+ {
+ return host;
+ }
+ set
+ {
+ host = value;
+ }
+ }
+
+ ///
+ /// Port of the MSN server. Default is 1863.
+ ///
+ public int Port
+ {
+ get
+ {
+ return port;
+ }
+ set
+ {
+ port = value;
+ }
+ }
+
+ ///
+ /// The local ip you want to bind.
+ ///
+ public string LocalHost
+ {
+ get
+ {
+ return localHost;
+ }
+ set
+ {
+ localHost = value;
+ }
+ }
+
+ ///
+ /// The local port you want to bind, default is 0 (which means the system will assign it automatically).
+ ///
+ public int LocalPort
+ {
+ get
+ {
+ return localPort;
+ }
+ set
+ {
+ localPort = value;
+ }
+ }
+
+ ///
+ /// The host of the proxy. This must be filled in when ProxyType is set to something else than ProxyType.None.
+ ///
+ public string ProxyHost
+ {
+ get
+ {
+ return proxyHost;
+ }
+ set
+ {
+ proxyHost = value;
+ }
+ }
+
+ ///
+ /// The port used to access the proxy. This must be filled in when ProxyType is set to something else than ProxyType.None.
+ ///
+ public int ProxyPort
+ {
+ get
+ {
+ return proxyPort;
+ }
+ set
+ {
+ proxyPort = value;
+ }
+ }
+
+ ///
+ /// The username used when accessing the proxy. This must be filled in when ProxyType is set to something else than ProxyType.None.
+ ///
+ public string ProxyUsername
+ {
+ get
+ {
+ return proxyUsername;
+ }
+ set
+ {
+ proxyUsername = value;
+ }
+ }
+
+ ///
+ /// The username used when accessing the proxy. This must be filled in when ProxyType is set to something else than ProxyType.None.
+ ///
+ public string ProxyPassword
+ {
+ get
+ {
+ return proxyPassword;
+ }
+ set
+ {
+ proxyPassword = value;
+ }
+ }
+
+ ///
+ /// The ProxyType used. If ProxyType is set to something else than ProxyType.None a proxy server is used, using Socks4 or Socks 5 depending on the type. Read-only.
+ ///
+ public ProxyType ProxyType
+ {
+ get
+ {
+ return proxyType;
+ }
+ set
+ {
+ proxyType = value;
+ }
+ }
+
+ ///
+ /// If this is not null a webproxy is used in all HTTP request in the library. An important HTTP request is the authentication with Passport.com.
+ ///
+ public WebProxy WebProxy
+ {
+ get
+ {
+ return webProxy;
+ }
+ set
+ {
+ webProxy = value;
+ }
+ }
+
+ ///
+ /// A string that shows the current host and port.
+ ///
+ ///
+ public override string ToString()
+ {
+ return "{Host=" + Host + ", Port=" + Port + "}";
+ }
+ #endregion
+ }
+};
diff --git a/MSNPSharp/Contact.cs b/MSNPSharp/Contact.cs
new file mode 100644
index 0000000..11013f8
--- /dev/null
+++ b/MSNPSharp/Contact.cs
@@ -0,0 +1,1380 @@
+#region Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions (http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice
+/*
+Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions
+(http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice.
+All rights reserved. http://code.google.com/p/msnp-sharp/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the names of Bas Geertsema or Xih Solutions nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#endregion
+
+using System;
+using System.Net;
+using System.Reflection;
+using System.Collections;
+using System.Collections.Generic;
+using System.Drawing;
+using System.IO;
+using System.Diagnostics;
+
+namespace MSNPSharp
+{
+ using MSNPSharp.Core;
+ using MSNPSharp.MSNWS.MSNABSharingService;
+
+
+ ///
+ /// User in roster list.
+ ///
+ [Serializable()]
+ public class Contact
+ {
+ #region Fields
+
+ protected Guid guid = Guid.Empty;
+ protected Guid addressBookId = Guid.Empty;
+ private long cId = 0;
+ private string mail = string.Empty;
+ private string name = string.Empty;
+ private string nickName = string.Empty;
+
+ private Dictionary phoneNumbers = new Dictionary();
+ private string contactType = string.Empty;
+ private string comment = string.Empty;
+ private string siblingString = string.Empty;
+ private string hash = string.Empty;
+
+ private bool hasSpace = false;
+ private bool mobileDevice = false;
+ private bool mobileAccess = false;
+ private bool isMessengerUser = false;
+ private bool hasInitialized = false;
+
+ private PresenceStatus status = PresenceStatus.Offline;
+ private ClientType clientType = ClientType.PassportMember;
+ private CirclePersonalMembershipRole circleRole = CirclePersonalMembershipRole.None;
+
+ private List contactGroups = new List(0);
+ private MSNLists lists = MSNLists.None;
+
+ private DisplayImage displayImage = null;
+ private PersonalMessage personalMessage = null;
+
+
+ private Dictionary emoticons = new Dictionary(0);
+ private Dictionary siblings = new Dictionary(0);
+ protected Dictionary endPointData = new Dictionary(0);
+
+ private ulong oimCount = 1;
+ private int adlCount = 1;
+ private object clientData = null;
+
+ private List activities = new List(0);
+ private Uri userTile = null;
+ private string userTileLocation = string.Empty;
+
+ private object syncObject = new object();
+
+ private NSMessageHandler nsMessageHandler = null;
+
+ #endregion
+
+ private Contact()
+ {
+ }
+
+ protected internal Contact(string abId, string account, ClientType cliType, long cid, NSMessageHandler handler)
+ {
+ Initialized(new Guid(abId), account, cliType, cid, handler);
+ }
+
+ protected internal Contact(Guid abId, string account, ClientType cliType, long cid, NSMessageHandler handler)
+ {
+ Initialized(abId, account, cliType, cid, handler);
+ }
+
+ protected virtual void Initialized(Guid abId, string account, ClientType cliType, long cid, NSMessageHandler handler)
+ {
+ if (hasInitialized)
+ return;
+
+ NSMessageHandler = handler;
+ addressBookId = abId;
+ mail = account.ToLowerInvariant();
+ clientType = cliType;
+ cId = cid;
+
+ SetName(account);
+ siblingString = ClientType.ToString() + ":" + account.ToLowerInvariant();
+ hash = MakeHash(Mail, ClientType, AddressBookId);
+ EndPointData[Guid.Empty] = new EndPointData(account, Guid.Empty);
+
+ if (NSMessageHandler != null)
+ {
+ NSMessageHandler.Manager.Add(this);
+ }
+
+ displayImage = DisplayImage.CreateDefaultImage(Mail);
+
+ hasInitialized = true;
+ }
+
+ #region Events
+ ///
+ /// Fired when contact's display name changed.
+ ///
+ public event EventHandler ScreenNameChanged;
+
+ public event EventHandler PersonalMessageChanged;
+
+ ///
+ /// Fired after contact's display image has been changed.
+ ///
+ public event EventHandler DisplayImageChanged;
+
+ ///
+ /// Fired after received contact's display image changed notification.
+ ///
+ public event EventHandler DisplayImageContextChanged;
+ public event EventHandler ContactGroupAdded;
+ public event EventHandler ContactGroupRemoved;
+ public event EventHandler ContactBlocked;
+ public event EventHandler ContactUnBlocked;
+ public event EventHandler ContactOnline;
+ public event EventHandler ContactOffline;
+ public event EventHandler StatusChanged;
+
+ #endregion
+
+ #region Contact Properties
+
+ internal object SyncObject
+ {
+ get
+ {
+ return syncObject;
+ }
+ }
+
+ internal string SiblingString
+ {
+ get
+ {
+ return siblingString;
+ }
+ }
+
+ internal NSMessageHandler NSMessageHandler
+ {
+ get
+ {
+ return nsMessageHandler;
+ }
+
+ set
+ {
+ nsMessageHandler = value;
+ }
+ }
+
+ ///
+ /// The display image url from the webside.
+ ///
+ public Uri UserTileURL
+ {
+ get
+ {
+ return userTile;
+ }
+
+ internal set
+ {
+ userTile = value;
+ }
+ }
+
+ ///
+ /// The displayimage context.
+ ///
+ public string UserTileLocation
+ {
+ //I create this property because I don't want to play tricks with display image's OriginalContext and Context any more.
+
+ get
+ {
+ return userTileLocation;
+ }
+
+ internal set
+ {
+ userTileLocation = MSNObject.GetDecodeString(value);
+ }
+ }
+
+ ///
+ /// Get the Guid of contact, NOT CID.
+ ///
+ public Guid Guid
+ {
+ get
+ {
+ return guid;
+ }
+
+ internal set
+ {
+ guid = value;
+ }
+ }
+
+ ///
+ /// The identifier of addressbook this contact belongs to.
+ ///
+ public Guid AddressBookId
+ {
+ get
+ {
+ return addressBookId;
+ }
+ }
+
+ ///
+ /// Machine ID, this may be different from the endpoint id.
+ ///
+ public Guid MachineGuid
+ {
+ get
+ {
+ if (PersonalMessage != null)
+ {
+ if (PersonalMessage.MachineGuid != null)
+ {
+ if (PersonalMessage.MachineGuid != Guid.Empty)
+ return PersonalMessage.MachineGuid;
+ }
+ }
+ return Guid.Empty;
+ }
+ }
+
+ ///
+ /// The contact id of contact, only PassportMembers have CID.
+ ///
+ public long CID
+ {
+ get
+ {
+ return cId;
+ }
+ internal set
+ {
+ cId = value;
+ }
+ }
+
+ ///
+ /// The email account of contact.
+ ///
+ public string Mail
+ {
+ get
+ {
+ return mail;
+ }
+ }
+
+ ///
+ /// The display name of contact.
+ ///
+ public virtual string Name
+ {
+ get
+ {
+ return name;
+ }
+
+ set
+ {
+ throw new NotImplementedException("Must be override in subclass.");
+ }
+ }
+
+ public string HomePhone
+ {
+ get
+ {
+ return phoneNumbers.ContainsKey(ContactPhoneTypes.ContactPhonePersonal) ?
+ phoneNumbers[ContactPhoneTypes.ContactPhonePersonal] : string.Empty;
+ }
+ }
+
+ public string WorkPhone
+ {
+ get
+ {
+ return phoneNumbers.ContainsKey(ContactPhoneTypes.ContactPhoneBusiness) ?
+ phoneNumbers[ContactPhoneTypes.ContactPhoneBusiness] : string.Empty;
+ }
+ }
+
+ public string MobilePhone
+ {
+ get
+ {
+ return phoneNumbers.ContainsKey(ContactPhoneTypes.ContactPhoneMobile) ?
+ phoneNumbers[ContactPhoneTypes.ContactPhoneMobile] : string.Empty;
+ }
+ }
+
+ public Dictionary PhoneNumbers
+ {
+ get
+ {
+ return phoneNumbers;
+ }
+ }
+
+ public bool MobileDevice
+ {
+ get
+ {
+ return mobileDevice;
+ }
+ }
+
+ public bool MobileAccess
+ {
+ get
+ {
+ return mobileAccess;
+ }
+ }
+
+ ///
+ /// Indicates whether this contact has MSN Space.
+ ///
+ public bool HasSpace
+ {
+ get
+ {
+ return hasSpace;
+ }
+
+ internal set
+ {
+ hasSpace = value;
+ NSMessageHandler.ContactService.UpdateContact(this, AddressBookId, null);
+ }
+ }
+
+ public Dictionary EndPointData
+ {
+ get
+ {
+ return endPointData;
+ }
+ }
+
+ public bool HasSignedInWithMultipleEndPoints
+ {
+ get
+ {
+ //One for Guid.Empty added when calling the constructor, another for contact's own end point.
+ return EndPointData.Count > 2;
+ }
+ }
+
+ public int PlaceCount
+ {
+ get
+ {
+ return HasSignedInWithMultipleEndPoints ? EndPointData.Count - 1 : 1;
+ }
+ }
+
+ ///
+ /// The online status of contact.
+ ///
+ public virtual PresenceStatus Status
+ {
+ get
+ {
+ return status;
+ }
+
+ set
+ {
+ throw new NotImplementedException("This property is real-only for base class. Must be override in subclass.");
+ }
+ }
+
+ ///
+ /// Indicates whether the contact is online.
+ ///
+ public bool Online
+ {
+ get
+ {
+ return status != PresenceStatus.Offline;
+ }
+ }
+
+ ///
+ /// The type of contact's email account.
+ ///
+ public ClientType ClientType
+ {
+ get
+ {
+ return clientType;
+ }
+ }
+
+ ///
+ /// The role of contact in the addressbook.
+ ///
+ public string ContactType
+ {
+ get
+ {
+ return contactType;
+ }
+ internal set
+ {
+ contactType = value;
+ }
+ }
+
+ public List ContactGroups
+ {
+ get
+ {
+ return contactGroups;
+ }
+ }
+
+ public Dictionary Siblings
+ {
+ get
+ {
+ return siblings;
+ }
+ }
+
+ public virtual DisplayImage DisplayImage
+ {
+ get
+ {
+
+ LoadDisplayImageFromDeltas();
+ return displayImage;
+ }
+
+ //Calling this will not fire DisplayImageChanged event.
+ internal set
+ {
+ if (displayImage != value)
+ {
+ displayImage = value;
+ SaveDisplayImage(displayImage);
+ }
+ }
+ }
+
+ public PersonalMessage PersonalMessage
+ {
+ get
+ {
+ return personalMessage;
+ }
+ }
+
+ ///
+ /// Emoticons[sha]
+ ///
+ public Dictionary Emoticons
+ {
+ get
+ {
+ return emoticons;
+ }
+ }
+
+ public List Activities
+ {
+ get
+ {
+ return activities;
+ }
+ }
+
+ ///
+ /// The string representation info of contact.
+ ///
+ public virtual string Hash
+ {
+ get
+ {
+ return hash;
+ }
+ }
+
+ public object ClientData
+ {
+ get
+ {
+ return clientData;
+ }
+ set
+ {
+ clientData = value;
+ }
+ }
+
+ ///
+ /// Receive updated contact information automatically.
+ /// Contact details like address and phone numbers are automatically downloaded to your Address Book.
+ ///
+ public bool AutoSubscribeToUpdates
+ {
+ get
+ {
+ return (contactType == MessengerContactType.Live || contactType == MessengerContactType.LivePending);
+ }
+ set
+ {
+ if (NSMessageHandler != null && Guid != Guid.Empty && ClientType == ClientType.PassportMember)
+ {
+ if (value)
+ {
+ if (!AutoSubscribeToUpdates)
+ {
+ contactType = MessengerContactType.LivePending;
+ NSMessageHandler.ContactService.UpdateContact(this, AddressBookId, null);
+ }
+ }
+ else
+ {
+ if (contactType != MessengerContactType.Regular)
+ {
+ contactType = MessengerContactType.Regular;
+ NSMessageHandler.ContactService.UpdateContact(this, AddressBookId, null);
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// Indicates whether the contact can receive MSN message.
+ ///
+ public bool IsMessengerUser
+ {
+ get
+ {
+ return isMessengerUser;
+ }
+
+
+ set
+ {
+ if (NSMessageHandler != null && Guid != Guid.Empty && IsMessengerUser != value)
+ {
+ isMessengerUser = value;
+ NSMessageHandler.ContactService.UpdateContact(this, AddressBookId,
+ delegate //If you don't add this, you can't see the contact online until your next login
+ {
+ Dictionary hashlist = new Dictionary(2);
+ hashlist.Add(Hash, Lists ^ MSNLists.ReverseList);
+ string payload = ContactService.ConstructLists(hashlist, false)[0];
+ NSMessageHandler.MessageProcessor.SendMessage(new NSPayLoadMessage("ADL", payload));
+ });
+ }
+
+ NotifyManager();
+ }
+ }
+
+
+ public string Comment
+ {
+ get
+ {
+ return comment;
+ }
+ set
+ {
+ if (NSMessageHandler != null && Guid != Guid.Empty && Comment != value)
+ {
+ comment = value;
+ NSMessageHandler.ContactService.UpdateContact(this, AddressBookId, null);
+ }
+ }
+ }
+
+ ///
+ /// The name provide by the owner.
+ ///
+ public string NickName
+ {
+ get
+ {
+ return nickName;
+ }
+ set
+ {
+ if (NSMessageHandler != null && Guid != Guid.Empty && NickName != value)
+ {
+ nickName = value;
+ NSMessageHandler.ContactService.UpdateContact(this, AddressBookId, null);
+ }
+ }
+ }
+
+
+ ///
+ /// The amount of OIMs sent in a session.
+ ///
+ internal ulong OIMCount
+ {
+ get
+ {
+ return oimCount;
+ }
+ set
+ {
+ if (value < 1)
+ {
+ value = 1;
+ }
+ oimCount = value;
+ }
+ }
+
+ ///
+ /// The amount of ADL commands send for this contact.
+ ///
+ internal int ADLCount
+ {
+ get { return adlCount; }
+ set
+ {
+ if (value < 0)
+ {
+ value = 0;
+ }
+
+ adlCount = value;
+ }
+ }
+
+ internal string LocalContactString
+ {
+ get
+ {
+ return GetLocalContactString();
+
+ }
+ }
+
+ ///
+ /// The role of a contact in the addressbook.
+ ///
+ public CirclePersonalMembershipRole CircleRole
+ {
+ get
+ {
+ return circleRole;
+ }
+
+ internal set
+ {
+ circleRole = value;
+ }
+ }
+
+ #endregion
+
+ #region List Properties
+
+ public bool OnForwardList
+ {
+ get
+ {
+ return ((lists & MSNLists.ForwardList) == MSNLists.ForwardList);
+ }
+ set
+ {
+ if (value != OnForwardList)
+ {
+ if (value)
+ {
+ NSMessageHandler.ContactService.AddContactToList(this, MSNLists.ForwardList, null);
+ }
+ else
+ {
+ NSMessageHandler.ContactService.RemoveContactFromList(this, MSNLists.ForwardList, null);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Blocks/unblocks this contact. If blocked, will be placed in your BL and removed
+ /// from your AL; otherwise, will be removed from your BL and placed in your AL.
+ /// If this contact is not in ReverseList and you want to delete forever,
+ /// set the or to false.
+ ///
+ public bool Blocked
+ {
+ get
+ {
+ return OnBlockedList;
+ }
+ set
+ {
+ if (NSMessageHandler != null)
+ {
+ if (value)
+ NSMessageHandler.ContactService.BlockContact(this);
+ else
+ NSMessageHandler.ContactService.UnBlockContact(this);
+ }
+ }
+ }
+
+ ///
+ /// Adds or removes this contact into/from your AL.
+ /// If this contact is not in ReverseList and you want to delete forever,
+ /// set this property to false.
+ ///
+ public bool OnAllowedList
+ {
+ get
+ {
+ return ((lists & MSNLists.AllowedList) == MSNLists.AllowedList);
+ }
+ set
+ {
+ if (value != OnAllowedList)
+ {
+ if (value)
+ {
+ Blocked = false;
+ }
+ else if (!OnReverseList)
+ {
+ NSMessageHandler.ContactService.RemoveContactFromList(this, MSNLists.AllowedList, null);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Adds or removes this contact into/from your BL.
+ /// If this contact is not in ReverseList and you want to delete forever,
+ /// set this property to false.
+ ///
+ public bool OnBlockedList
+ {
+ get
+ {
+ return ((lists & MSNLists.BlockedList) == MSNLists.BlockedList);
+ }
+ set
+ {
+ if (value != OnBlockedList)
+ {
+ if (value)
+ {
+ Blocked = true;
+ }
+ else if (!OnReverseList)
+ {
+ NSMessageHandler.ContactService.RemoveContactFromList(this, MSNLists.BlockedList, null);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Indicates whether the contact have you on their contact list.
+ ///
+ public bool OnReverseList
+ {
+ get
+ {
+ return ((lists & MSNLists.ReverseList) == MSNLists.ReverseList);
+ }
+ }
+
+ ///
+ /// Indicates whether the contact have you on their contact list and pending your approval.
+ ///
+ public bool OnPendingList
+ {
+ get
+ {
+ return ((lists & MSNLists.PendingList) == MSNLists.PendingList);
+ }
+ set
+ {
+ if (value != OnPendingList && value == false)
+ {
+ NSMessageHandler.ContactService.RemoveContactFromList(this, MSNLists.PendingList, null);
+ }
+ }
+ }
+
+ ///
+ /// The msn lists this contact has.
+ ///
+ public MSNLists Lists
+ {
+ get
+ {
+ return lists;
+ }
+
+ protected internal set
+ {
+ lists = value;
+ NotifyManager();
+ }
+ }
+
+ #endregion
+
+ #region Internal setters
+
+ internal void SetComment(string note)
+ {
+ comment = note;
+ }
+
+ internal void SetIsMessengerUser(bool isMessengerEnabled)
+ {
+ isMessengerUser = isMessengerEnabled;
+ NotifyManager();
+ }
+
+ internal void SetList(MSNLists msnLists)
+ {
+ lists = msnLists;
+ NotifyManager();
+ }
+
+ internal void SetMobileAccess(bool enabled)
+ {
+ mobileAccess = enabled;
+ }
+
+ internal void SetMobileDevice(bool enabled)
+ {
+ mobileDevice = enabled;
+ }
+
+ internal void SetName(string newName)
+ {
+ if (name != newName)
+ {
+ string oldName = name;
+ name = newName;
+
+ // notify all of our buddies we changed our name
+ OnScreenNameChanged(oldName);
+ }
+ }
+
+
+
+ internal void SetHasSpace(bool hasSpaceValue)
+ {
+ hasSpace = hasSpaceValue;
+ }
+
+ internal void SetNickName(string newNick)
+ {
+ nickName = newNick;
+ }
+
+ internal void SetPersonalMessage(PersonalMessage newpmessage)
+ {
+ if (personalMessage != newpmessage)
+ {
+ personalMessage = newpmessage;
+ // notify the user we changed our display message
+ OnPersonalMessageChanged(newpmessage);
+ }
+ }
+
+ internal void SetStatus(PresenceStatus newStatus)
+ {
+ //Becareful deadlock!
+
+ PresenceStatus currentStatus = PresenceStatus.Unknown;
+
+ lock (syncObject)
+ {
+ currentStatus = status;
+ }
+
+ if (currentStatus != newStatus)
+ {
+ PresenceStatus oldStatus = currentStatus;
+
+ lock (syncObject)
+ {
+
+ status = newStatus;
+ }
+
+ // raise an event
+ OnStatusChanged(oldStatus);
+
+ // raise the online/offline events
+ if (oldStatus == PresenceStatus.Offline)
+ OnContactOnline(oldStatus);
+
+ if (newStatus == PresenceStatus.Offline)
+ OnContactOffline(oldStatus);
+ }
+
+ }
+
+ ///
+ /// This method will lead to fire event if the DisplayImage.Sha has been changed.
+ ///
+ ///
+ ///
+ /// false: No event was fired.
+ /// true: The was fired.
+ ///
+ internal bool FireDisplayImageContextChangedEvent(string updatedImageContext)
+ {
+ if (DisplayImage == updatedImageContext)
+ return false;
+
+ OnDisplayImageContextChanged(new DisplayImageChangedEventArgs(null, DisplayImageChangedType.UpdateTransmissionRequired));
+ return true;
+ }
+
+ ///
+ /// This method will lead to fire event if the DisplayImage.Image has been changed.
+ ///
+ ///
+ ///
+ /// false: No event was fired.
+ /// true: The event was fired.
+ ///
+ internal bool SetDisplayImageAndFireDisplayImageChangedEvent(DisplayImage image)
+ {
+ if (image == null) return false;
+
+
+ DisplayImageChangedEventArgs displayImageChangedArg = null;
+ //if ((displayImage != null && displayImage.Sha != image.Sha && displayImage.IsDefaultImage && image.Image != null) || //Transmission completed. default Image -> new Image
+ // (displayImage != null && displayImage.Sha != image.Sha && !displayImage.IsDefaultImage && image.Image != null) || //Transmission completed. old Image -> new Image.
+ // (displayImage != null && object.ReferenceEquals(displayImage, image) && displayImage.Image != null) || //Transmission completed. old Image -> updated old Image.
+ // (displayImage == null))
+ {
+
+ displayImageChangedArg = new DisplayImageChangedEventArgs(image, DisplayImageChangedType.TransmissionCompleted, false);
+ }
+
+ if (!object.ReferenceEquals(displayImage, image))
+ {
+ displayImage = image;
+ }
+
+ SaveOriginalDisplayImageAndFireDisplayImageChangedEvent(displayImageChangedArg);
+
+ return true;
+ }
+
+ internal void SaveOriginalDisplayImageAndFireDisplayImageChangedEvent(DisplayImageChangedEventArgs arg)
+ {
+ SaveDisplayImage(displayImage);
+ OnDisplayImageChanged(arg);
+ }
+
+ internal void NotifyManager()
+ {
+ if (AddressBookId != new Guid(WebServiceConstants.MessengerIndividualAddressBookId))
+ return;
+
+ if (NSMessageHandler == null)
+ return;
+
+ NSMessageHandler.Manager.SyncProperties(this);
+ }
+
+ #region Protected
+
+ protected virtual string GetLocalContactString()
+ {
+ if (MachineGuid == Guid.Empty)
+ return Mail.ToLowerInvariant();
+
+ return Mail.ToLowerInvariant() + ";" + MachineGuid.ToString("B");
+ }
+
+ protected virtual void OnScreenNameChanged(string oldName)
+ {
+ if (ScreenNameChanged != null)
+ {
+ ScreenNameChanged(this, EventArgs.Empty);
+ }
+ }
+
+ protected virtual void OnPersonalMessageChanged(PersonalMessage newmessage)
+ {
+ if (PersonalMessageChanged != null)
+ {
+ PersonalMessageChanged(this, EventArgs.Empty);
+ }
+ }
+
+ protected virtual void OnStatusChanged(PresenceStatus oldStatus)
+ {
+ if (StatusChanged != null)
+ StatusChanged(this, new StatusChangedEventArgs(oldStatus));
+ }
+
+ protected virtual void OnContactOnline(PresenceStatus oldStatus)
+ {
+ if (ContactOnline != null)
+ ContactOnline(this, new StatusChangedEventArgs(oldStatus));
+ }
+
+ protected virtual void OnContactOffline(PresenceStatus oldStatus)
+ {
+ if (ContactOffline != null)
+ {
+ ContactOffline(this, new StatusChangedEventArgs(oldStatus));
+ }
+ }
+
+ protected virtual void OnDisplayImageChanged(DisplayImageChangedEventArgs arg)
+ {
+ if (DisplayImageChanged != null)
+ {
+ DisplayImageChanged(this, arg);
+ }
+ }
+
+ protected virtual void OnDisplayImageContextChanged(DisplayImageChangedEventArgs arg)
+ {
+ if (DisplayImageContextChanged != null)
+ {
+ DisplayImageContextChanged(this, arg);
+ }
+ }
+
+ protected virtual void LoadDisplayImageFromDeltas()
+ {
+ if (NSMessageHandler.ContactService.Deltas == null)
+ return;
+
+ if (displayImage != null && !displayImage.IsDefaultImage) //Not default, no need to restore.
+ return;
+
+ string Sha = string.Empty;
+ byte[] rawImageData = NSMessageHandler.ContactService.Deltas.GetRawImageDataBySiblingString(SiblingString, out Sha);
+ if (rawImageData != null)
+ {
+ displayImage = new DisplayImage(Mail, new MemoryStream(rawImageData));
+ Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose, "User " + ToString() + "'s displayimage restored.\r\n " +
+ "Old SHA: " + Sha + "\r\n " +
+ "Current SHA: " + displayImage.Sha + "\r\n");
+ }
+ }
+
+ protected virtual void SaveDisplayImage(DisplayImage dispImage)
+ {
+ if (NSMessageHandler.ContactService.Deltas == null || dispImage == null)
+ return;
+
+ if (dispImage.Image == null || string.IsNullOrEmpty(dispImage.Sha))
+ return;
+
+ if (NSMessageHandler.ContactService.Deltas.SaveImageAndRelationship(SiblingString, dispImage.Sha, dispImage.GetRawData()))
+ {
+ NSMessageHandler.ContactService.Deltas.Save(true);
+ }
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Internal contact operations
+
+ protected virtual void OnContactGroupAdded(ContactGroup group)
+ {
+ if (ContactGroupAdded != null)
+ ContactGroupAdded(this, new ContactGroupEventArgs(group));
+ }
+
+ protected virtual void OnContactGroupRemoved(ContactGroup group)
+ {
+ if (ContactGroupRemoved != null)
+ ContactGroupRemoved(this, new ContactGroupEventArgs(group));
+ }
+
+ protected virtual void OnContactBlocked()
+ {
+ if (ContactBlocked != null)
+ ContactBlocked(this, new EventArgs());
+ }
+
+ protected virtual void OnContactUnBlocked()
+ {
+ if (ContactUnBlocked != null)
+ ContactUnBlocked(this, new EventArgs());
+ }
+
+
+ internal void AddContactToGroup(ContactGroup group)
+ {
+ if (!contactGroups.Contains(group))
+ {
+ contactGroups.Add(group);
+
+ OnContactGroupAdded(group);
+ }
+ }
+
+ internal void RemoveContactFromGroup(ContactGroup group)
+ {
+ if (contactGroups.Contains(group))
+ {
+ contactGroups.Remove(group);
+
+ OnContactGroupRemoved(group);
+ }
+ }
+
+ ///
+ /// Add a membership list for this contact.
+ ///
+ ///
+ /// Since AllowList and BlockList are mutally exclusive, adding a member to AllowList will lead to the remove of BlockList, revese is as the same.
+ internal void AddToList(MSNLists list)
+ {
+ if ((lists & list) == MSNLists.None)
+ {
+ lists |= list;
+
+ if ((list & MSNLists.BlockedList) == MSNLists.BlockedList)
+ {
+ OnContactBlocked();
+ }
+
+ NotifyManager();
+ }
+
+ }
+
+ internal void AddSibling(Contact contact)
+ {
+ lock (syncObject)
+ Siblings[contact.Hash] = contact;
+ }
+
+ internal void AddSibling(Contact[] contacts)
+ {
+ if (contacts == null)
+ return;
+
+ lock (syncObject)
+ {
+ foreach (Contact sibling in contacts)
+ {
+ Siblings[sibling.Hash] = sibling;
+ }
+ }
+ }
+
+ internal void RemoveFromList(MSNLists list)
+ {
+ if ((lists & list) != MSNLists.None)
+ {
+ lists ^= list;
+
+ // set this contact to offline when it is neither on the allow list or on the forward list
+ if (!(OnForwardList || OnAllowedList))
+ {
+ status = PresenceStatus.Offline;
+ //also clear the groups, becase msn loose them when removed from the two lists
+ contactGroups.Clear();
+ }
+
+ if ((list & MSNLists.BlockedList) == MSNLists.BlockedList)
+ {
+ OnContactUnBlocked();
+ }
+
+ NotifyManager();
+ }
+
+
+ }
+
+ internal void RemoveFromList()
+ {
+ if (NSMessageHandler != null)
+ {
+ OnAllowedList = false;
+ OnForwardList = false;
+
+ NotifyManager();
+ }
+ }
+
+ internal static MSNLists GetConflictLists(MSNLists currentLists, MSNLists newLists)
+ {
+ MSNLists conflictLists = MSNLists.None;
+
+ if ((currentLists & MSNLists.AllowedList) != MSNLists.None && (newLists & MSNLists.BlockedList) != MSNLists.None)
+ {
+ conflictLists |= MSNLists.AllowedList;
+ }
+
+ if ((currentLists & MSNLists.BlockedList) != MSNLists.None && (newLists & MSNLists.AllowedList) != MSNLists.None)
+ {
+ conflictLists |= MSNLists.BlockedList;
+ }
+
+ return conflictLists;
+ }
+
+ internal Guid SelectRandomEPID()
+ {
+ foreach (Guid epId in EndPointData.Keys)
+ {
+ if (epId != Guid.Empty)
+ return epId;
+ }
+
+ return Guid.Empty;
+ }
+
+ internal static string MakeHash(string account, ClientType type, Guid abId)
+ {
+ if (account == null)
+ throw new ArgumentNullException("account");
+
+ return type.ToString() + ":" + account.ToLowerInvariant() + ";via=" + abId.ToString("D").ToLowerInvariant();
+ }
+
+ internal static string MakeHash(string account, ClientType type, string abId)
+ {
+ return type.ToString() + ":" + account.ToLowerInvariant() + ";via=" + abId.ToLowerInvariant();
+ }
+
+ internal bool HasLists(MSNLists msnlists)
+ {
+ return ((lists & msnlists) == msnlists);
+ }
+
+ internal static MSNLists GetListForADL(MSNLists currentContactList)
+ {
+ if ((currentContactList & MSNLists.ReverseList) == MSNLists.ReverseList)
+ {
+ return currentContactList ^ MSNLists.ReverseList;
+ }
+
+ return currentContactList;
+ }
+
+
+ #endregion
+
+ public bool HasGroup(ContactGroup group)
+ {
+ return contactGroups.Contains(group);
+ }
+
+ public void UpdateScreenName()
+ {
+ if (NSMessageHandler == null)
+ throw new MSNPSharpException("No valid message handler object");
+
+ NSMessageHandler.RequestScreenName(this);
+ }
+
+ public override int GetHashCode()
+ {
+ return Hash.GetHashCode();
+ }
+
+ public static bool operator ==(Contact contact1, Contact contact2)
+ {
+ if (((object)contact1) == null && ((object)contact2) == null)
+ return true;
+ if (((object)contact1) == null || ((object)contact2) == null)
+ return false;
+ return contact1.GetHashCode() == contact2.GetHashCode();
+ }
+
+ public static bool operator !=(Contact contact1, Contact contact2)
+ {
+ return !(contact1 == contact2);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj == null || obj.GetType() != GetType())
+ return false;
+
+ if (ReferenceEquals(this, obj))
+ return true;
+
+ return obj.GetHashCode() == GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return Hash;
+ }
+
+ ///
+ /// Check whether two contacts represent the same user (Have the same passport account).
+ ///
+ ///
+ ///
+ public virtual bool IsSibling(Contact contact)
+ {
+ if (contact == null)
+ return false;
+ if (ClientType == contact.ClientType && Mail.ToLowerInvariant() == contact.Mail.ToLowerInvariant())
+ return true;
+
+ return false;
+ }
+
+ }
+};
diff --git a/MSNPSharp/ContactGroup.cs b/MSNPSharp/ContactGroup.cs
new file mode 100644
index 0000000..851b396
--- /dev/null
+++ b/MSNPSharp/ContactGroup.cs
@@ -0,0 +1,210 @@
+#region Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions (http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice
+/*
+Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions
+(http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice.
+All rights reserved. http://code.google.com/p/msnp-sharp/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the names of Bas Geertsema or Xih Solutions nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#endregion
+
+using System;
+
+namespace MSNPSharp
+{
+ using MSNPSharp.Core;
+
+ ///
+ /// Used as event argument when a contactgroup is affected.
+ ///
+ [Serializable()]
+ public class ContactGroupEventArgs : EventArgs
+ {
+ private ContactGroup contactGroup;
+
+ ///
+ /// The affected contact group
+ ///
+ public ContactGroup ContactGroup
+ {
+ get
+ {
+ return contactGroup;
+ }
+ set
+ {
+ contactGroup = value;
+ }
+ }
+
+ ///
+ /// Constructor, mostly used internal by the library.
+ ///
+ ///
+ public ContactGroupEventArgs(ContactGroup contactGroup)
+ {
+ ContactGroup = contactGroup;
+ }
+ }
+
+ ///
+ /// Defines a single contact group.
+ ///
+ [Serializable()]
+ public class ContactGroup
+ {
+ #region Private
+
+ private string name;
+ private string guid;
+ private object clientData;
+ private bool isFavorite;
+
+ [NonSerialized]
+ private NSMessageHandler nsMessageHandler = null;
+
+ #endregion
+
+ #region Internal
+
+ ///
+ /// Constructor, used internally by the library.
+ ///
+ ///
+ ///
+ ///
+ ///
+ internal ContactGroup(string name, string guid, NSMessageHandler nsMessageHandler, bool isFavorite)
+ {
+ this.name = name;
+ this.guid = guid;
+ this.isFavorite = isFavorite;
+ this.nsMessageHandler = nsMessageHandler;
+ }
+
+ private ContactGroup()
+ : this(String.Empty, System.Guid.NewGuid().ToString(), null, false)
+ {
+ }
+
+ ///
+ /// Used by nameserver.
+ ///
+ ///
+ internal void SetName(string name)
+ {
+ this.name = name;
+ }
+ #endregion
+
+ #region Public
+
+ ///
+ /// The notification message handler which controls this contact object
+ ///
+ internal NSMessageHandler NSMessageHandler
+ {
+ get
+ {
+ return nsMessageHandler;
+ }
+ }
+
+ ///
+ /// The custom data specified by the client programmer
+ ///
+ /// The application programmer can define it's own data here. It is not used by MSNPSharp.
+ public object ClientData
+ {
+ get
+ {
+ return clientData;
+ }
+ set
+ {
+ clientData = value;
+ }
+ }
+
+ ///
+ /// Name of the contactgroup
+ ///
+ public string Name
+ {
+ get
+ {
+ return name;
+ }
+ set
+ {
+ if (NSMessageHandler != null)
+ {
+ NSMessageHandler.ContactService.RenameGroup(this, value);
+ }
+ }
+ }
+
+ ///
+ /// The unique contactgroup ID assigned by MSN
+ ///
+ public string Guid
+ {
+ get
+ {
+ return guid;
+ }
+ }
+
+ public bool IsFavorite
+ {
+ get
+ {
+ return isFavorite;
+ }
+ }
+
+ ///
+ /// Returns the ID field as hashcode. This is necessary to compare contactgroups.
+ ///
+ ///
+ override public int GetHashCode()
+ {
+ return guid.GetHashCode();
+ }
+
+ ///
+ /// Equals two contacgroups based on their ID
+ ///
+ ///
+ ///
+ public override bool Equals(object obj)
+ {
+ ContactGroup cg = obj as ContactGroup;
+ return cg != null && cg.Guid == guid;
+ }
+
+ #endregion
+ }
+};
diff --git a/MSNPSharp/ContactGroupList.cs b/MSNPSharp/ContactGroupList.cs
new file mode 100644
index 0000000..5ed1843
--- /dev/null
+++ b/MSNPSharp/ContactGroupList.cs
@@ -0,0 +1,131 @@
+#region Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions (http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice
+/*
+Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions
+(http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice.
+All rights reserved. http://code.google.com/p/msnp-sharp/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the names of Bas Geertsema or Xih Solutions nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#endregion
+
+using System;
+using System.Collections;
+using System.Globalization;
+using System.Collections.Generic;
+
+namespace MSNPSharp
+{
+ [Serializable()]
+ public class ContactGroupList : IEnumerable
+ {
+ List list = new List();
+
+ [NonSerialized]
+ NSMessageHandler nsMessageHandler = null;
+
+ internal void AddGroup(ContactGroup group)
+ {
+ if (this[group.Guid] == null)
+ list.Add(group);
+ else
+ this[group.Guid].SetName(group.Name);
+ }
+ internal void RemoveGroup(ContactGroup group)
+ {
+ list.Remove(group);
+ }
+
+ internal ContactGroupList(NSMessageHandler handler)
+ {
+ nsMessageHandler = handler;
+ }
+
+ public virtual void Add(string name)
+ {
+ if (nsMessageHandler == null)
+ throw new MSNPSharpException("No nameserver handler defined");
+
+ nsMessageHandler.ContactService.AddContactGroup(name);
+ }
+
+ public virtual void Remove(ContactGroup group)
+ {
+ if (nsMessageHandler == null)
+ throw new MSNPSharpException("No nameserver handler defined");
+
+ if (this[group.Guid] != null)
+ nsMessageHandler.ContactService.RemoveContactGroup(group);
+ else
+ throw new MSNPSharpException("Contactgroup not defined in this list");
+ }
+
+ public ContactGroup GetByName(string name)
+ {
+ foreach (ContactGroup group in list)
+ {
+ if (group.Name == name)
+ return group;
+ }
+
+ return null;
+ }
+
+ public ContactGroup this[string guid]
+ {
+ get
+ {
+ foreach (ContactGroup group in list)
+ {
+ if (group.Guid.ToLower(CultureInfo.InvariantCulture) == guid.ToLower(CultureInfo.InvariantCulture))
+ return group;
+ }
+ return null;
+ }
+ }
+
+ public ContactGroup FavoriteGroup
+ {
+ get
+ {
+ foreach (ContactGroup group in list)
+ {
+ if (group.IsFavorite)
+ return group;
+ }
+ return null;
+ }
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return list.GetEnumerator();
+ }
+
+ public void Clear()
+ {
+ list.Clear();
+ }
+ }
+};
diff --git a/MSNPSharp/ContactList.cs b/MSNPSharp/ContactList.cs
new file mode 100644
index 0000000..6a44daf
--- /dev/null
+++ b/MSNPSharp/ContactList.cs
@@ -0,0 +1,545 @@
+#region Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions (http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice
+/*
+Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions
+(http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice.
+All rights reserved. http://code.google.com/p/msnp-sharp/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the names of Bas Geertsema or Xih Solutions nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#endregion
+
+using System;
+using System.Threading;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+
+namespace MSNPSharp
+{
+ using MSNPSharp.Core;
+
+ [Serializable()]
+ public class ContactList : Dictionary
+ {
+ private static ClientType[] clientTypes = (ClientType[])Enum.GetValues(typeof(ClientType));
+
+ [NonSerialized]
+ private NSMessageHandler nsMessageHandler;
+ [NonSerialized]
+ private object syncRoot;
+
+ private Guid addressBookId = Guid.Empty;
+ private Owner owner = null;
+
+ private ContactList()
+ {
+ }
+
+ private void Initialize(NSMessageHandler handler, Owner owner)
+ {
+ nsMessageHandler = handler;
+ this.owner = owner;
+ }
+
+ public ContactList(NSMessageHandler handler)
+ {
+ addressBookId = new Guid(WebServiceConstants.MessengerIndividualAddressBookId);
+ nsMessageHandler = handler;
+ }
+
+ public ContactList(string abId, Owner owner, NSMessageHandler handler)
+ {
+ addressBookId = new Guid(abId);
+ Initialize(handler, owner);
+ }
+
+ public ContactList(Guid abId, Owner owner, NSMessageHandler handler)
+ {
+ addressBookId = abId;
+ Initialize(handler, owner);
+ }
+
+ #region ListEnumerators
+
+ public class ListEnumerator : IEnumerator
+ {
+ private Enumerator baseEnum;
+ private MSNLists listFilter;
+
+ public ListEnumerator(Enumerator listEnum, MSNLists filter)
+ {
+ baseEnum = listEnum;
+ listFilter = filter;
+ }
+
+ public virtual bool MoveNext()
+ {
+ if (listFilter == MSNLists.None)
+ {
+ return baseEnum.MoveNext();
+ }
+ else
+ {
+ while (baseEnum.MoveNext())
+ {
+ if (Current.HasLists(listFilter))
+ return true;
+ }
+ return false;
+ }
+ }
+
+ object IEnumerator.Current
+ {
+ get
+ {
+ return baseEnum.Current;
+ }
+ }
+
+ public Contact Current
+ {
+ get
+ {
+ return baseEnum.Current.Value;
+ }
+ }
+
+ public void Reset()
+ {
+ }
+
+ public void Dispose()
+ {
+ baseEnum.Dispose();
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return this;
+ }
+ }
+
+ public class EmailListEnumerator : ContactList.ListEnumerator
+ {
+ public EmailListEnumerator(Enumerator listEnum)
+ : base(listEnum, MSNLists.None)
+ {
+ }
+
+ public override bool MoveNext()
+ {
+ while (base.MoveNext())
+ {
+ if (Current.Guid != Guid.Empty && Current.IsMessengerUser == false)
+ return true;
+ }
+ return false;
+ }
+ }
+
+ #endregion
+
+ #region Lists
+
+ public ContactList.ListEnumerator Forward
+ {
+ get
+ {
+ return new ContactList.ListEnumerator(GetEnumerator(), MSNLists.ForwardList);
+ }
+ }
+
+ public ContactList.ListEnumerator Allowed
+ {
+ get
+ {
+ return new ContactList.ListEnumerator(GetEnumerator(), MSNLists.AllowedList);
+ }
+ }
+
+ public ContactList.ListEnumerator BlockedList
+ {
+ get
+ {
+ return new ContactList.ListEnumerator(GetEnumerator(), MSNLists.BlockedList);
+ }
+ }
+
+ public ContactList.ListEnumerator Reverse
+ {
+ get
+ {
+ return new ContactList.ListEnumerator(GetEnumerator(), MSNLists.ReverseList);
+ }
+ }
+
+ public ContactList.ListEnumerator Pending
+ {
+ get
+ {
+ return new ContactList.ListEnumerator(GetEnumerator(), MSNLists.PendingList);
+ }
+ }
+
+ public ContactList.ListEnumerator All
+ {
+ get
+ {
+ return new ContactList.ListEnumerator(GetEnumerator(), MSNLists.None);
+ }
+ }
+
+ public ContactList.ListEnumerator Email
+ {
+ get
+ {
+ return new ContactList.EmailListEnumerator(GetEnumerator());
+ }
+ }
+
+ #endregion
+
+ public object SyncRoot
+ {
+ get
+ {
+ if (syncRoot == null)
+ {
+ object newobj = new object();
+ Interlocked.CompareExchange(ref syncRoot, newobj, null);
+ }
+ return syncRoot;
+ }
+ }
+
+ ///
+ /// The addressbook identifier of this addressbook.
+ ///
+ public Guid AddressBookId
+ {
+ get
+ {
+ return addressBookId;
+ }
+ }
+
+ ///
+ /// The owner of the contactlist. This is the identity that logged into the messenger network.
+ ///
+ public Owner Owner
+ {
+ get
+ {
+ return owner;
+ }
+ }
+
+ ///
+ /// Get the specified contact.
+ /// If the contact does not exist, return null
+ ///
+ ///
+ ///
+ /// If the contact does not exist, return null.
+ /// If the specified account has multi-clienttype, the contact with type
+ /// will be returned first.
+ /// If there's no PassportMember with the specified account, the contact with type
+ /// will be returned. Then the next is
+ /// , and so on...
+ ///
+ public Contact GetContact(string account)
+ {
+ if (HasContact(account, ClientType.PassportMember))
+ return GetContact(account, ClientType.PassportMember);
+
+ if (HasContact(account, ClientType.EmailMember))
+ return GetContact(account, ClientType.EmailMember);
+
+ if (HasContact(account, ClientType.PhoneMember))
+ return GetContact(account, ClientType.PhoneMember);
+
+ if (HasContact(account, ClientType.LCS))
+ return GetContact(account, ClientType.LCS);
+
+ return null;
+ }
+
+ ///
+ /// Get the specified contact.
+ /// This overload will set the contact name to a specified value (if the contact exists.).
+ /// If the contact does not exist, return null
+ ///
+ ///
+ ///
+ ///
+ /// If the contact does not exist, return null.
+ /// If the specified account has multi-clienttype, the contact with type
+ /// will be returned first.
+ /// If there's no PassportMember with the specified account, the contact with type
+ /// will be returned.Then the next is
+ /// , and so on...
+ ///
+ internal Contact GetContact(string account, string name)
+ {
+ Contact contact = GetContact(account);
+ if (contact != null)
+ lock (SyncRoot)
+ contact.SetName(name);
+
+ return contact;
+ }
+
+ ///
+ /// Get a contact with specified account and client type, if the contact does not exist, create it.
+ /// This overload will set the contact name to a specified value.
+ ///
+ ///
+ /// The new name you want to set.
+ ///
+ ///
+ /// A object.
+ /// If the contact does not exist, create it.
+ ///
+ internal Contact GetContact(string account, string name, ClientType type)
+ {
+ Contact contact = GetContact(account, type);
+
+ lock (SyncRoot)
+ contact.SetName(name);
+
+ return contact;
+ }
+
+ ///
+ /// Get a contact with specified account and client type, if the contact does not exist, create it.
+ ///
+ /// Account (Mail) of a contact
+ /// Contact type.
+ ///
+ /// A object.
+ /// If the contact does not exist, create it.
+ ///
+ internal Contact GetContact(string account, ClientType type)
+ {
+ int hash = Contact.MakeHash(account, type, AddressBookId.ToString("D")).GetHashCode();
+
+ lock (SyncRoot)
+ {
+ if (ContainsKey(hash))
+ {
+ return this[hash];
+ }
+
+ Contact tmpContact = new Contact(AddressBookId, account, type, 0, nsMessageHandler);
+
+
+ Add(hash, tmpContact);
+ }
+
+ return GetContact(account, type);
+ }
+
+ public Contact GetContactByGuid(Guid guid)
+ {
+ if (guid != Guid.Empty)
+ {
+ lock (SyncRoot)
+ {
+ foreach (Contact contact in Values)
+ {
+ if (contact.Guid == guid)
+ return contact;
+ }
+ }
+ }
+ return null;
+ }
+
+ public Contact GetContactByCID(long cid)
+ {
+ if (cid != 0)
+ {
+ lock (SyncRoot)
+ {
+ foreach (Contact contact in Values)
+ {
+ if (contact.CID == cid)
+ return contact;
+ }
+ }
+ }
+ return null;
+ }
+
+ public Contact this[string account]
+ {
+ get
+ {
+ return GetContact(account);
+ }
+ set
+ {
+ this[account, value.ClientType] = value;
+ }
+ }
+
+ public Contact this[string account, ClientType type]
+ {
+ get
+ {
+ return GetContact(account, type);
+ }
+ set
+ {
+ this[account, type] = value;
+ }
+ }
+
+ ///
+ /// Check whether the specified account is in the contact list.
+ ///
+ ///
+ ///
+ public bool HasContact(string account)
+ {
+ foreach (ClientType ct in clientTypes)
+ {
+ if (HasContact(account, ct))
+ return true;
+ }
+ return false;
+ }
+
+ ///
+ /// Check whether the account with specified client type is in the contact list.
+ ///
+ ///
+ ///
+ ///
+ public bool HasContact(string account, ClientType type)
+ {
+ return ContainsKey(Contact.MakeHash(account, type, AddressBookId.ToString("D")).GetHashCode());
+ }
+
+ public void CopyTo(Contact[] array, int index)
+ {
+ lock (SyncRoot)
+ Values.CopyTo(array, index);
+ }
+
+ ///
+ /// Copy the whole contact list out.
+ ///
+ ///
+ public Contact[] ToArray()
+ {
+ lock (SyncRoot)
+ {
+ Contact[] array = new Contact[Values.Count];
+ CopyTo(array, 0);
+ return array;
+ }
+ }
+
+ ///
+ /// Remove all the contacts with the specified account.
+ ///
+ ///
+ internal void Remove(string account)
+ {
+ foreach (ClientType ct in clientTypes)
+ {
+ if (HasContact(account, ct))
+ Remove(account, ct);
+ }
+ }
+
+ ///
+ /// Remove a contact with specified account and client type.
+ ///
+ ///
+ ///
+ internal void Remove(string account, ClientType type)
+ {
+ lock (SyncRoot)
+ {
+ Remove(Contact.MakeHash(account, type, AddressBookId.ToString("D")).GetHashCode());
+ }
+ }
+
+ ///
+ /// Set the owner for default addressbook. This funcation can be only called once.
+ ///
+ ///
+ internal void SetOwner(Owner owner)
+ {
+ if (AddressBookId != new Guid(WebServiceConstants.MessengerIndividualAddressBookId))
+ {
+ throw new InvalidOperationException("Only default addressbook can call this function.");
+ }
+
+ if (Owner != null)
+ {
+ throw new InvalidOperationException("Owner already set.");
+ }
+
+ if (owner.AddressBookId != new Guid(WebServiceConstants.MessengerIndividualAddressBookId))
+ {
+ throw new InvalidOperationException("Invalid owner: This is not the owner for default addressbook.");
+ }
+
+ this.owner = owner;
+ }
+
+ public bool HasMultiType(string account)
+ {
+ int typecount = 0;
+ foreach (ClientType ct in clientTypes)
+ {
+ if (HasContact(account, ct) && ++typecount > 1)
+ return true;
+ }
+ return false;
+ }
+
+ ///
+ /// Reset the contact list and clear the owner.
+ ///
+ public void Reset()
+ {
+ if (Owner != null)
+ {
+ Owner.Emoticons.Clear();
+ Owner.EndPointData.Clear();
+ Owner.LocalEndPointClientCapacities = ClientCapacities.None;
+ Owner.LocalEndPointClientCapacitiesEx = ClientCapacitiesEx.None;
+ }
+
+ Clear();
+ owner = null;
+ }
+ }
+};
\ No newline at end of file
diff --git a/MSNPSharp/ContactManager.cs b/MSNPSharp/ContactManager.cs
new file mode 100644
index 0000000..80d2337
--- /dev/null
+++ b/MSNPSharp/ContactManager.cs
@@ -0,0 +1,244 @@
+#region Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions (http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice
+/*
+Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions
+(http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice.
+All rights reserved. http://code.google.com/p/msnp-sharp/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the names of Bas Geertsema or Xih Solutions nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MSNPSharp
+{
+ internal sealed class ContactManager
+ {
+ #region Fields
+ private NSMessageHandler nsMessageHandler = null;
+
+ private Dictionary defaultContactPage = new Dictionary();
+ private Dictionary otherContactPage = new Dictionary();
+
+ #endregion
+
+ #region Properties
+
+ internal NSMessageHandler NSMessageHandler
+ {
+ get { return nsMessageHandler; }
+ }
+
+ #endregion
+
+ #region Constructors
+
+ public ContactManager(NSMessageHandler handler)
+ {
+ nsMessageHandler = handler;
+ }
+
+ #endregion
+
+ #region Private functions
+
+ private string AddToDefaultContactPage(Contact contact)
+ {
+ string key = GetContactKey(contact);
+ if (contact.AddressBookId == new Guid(WebServiceConstants.MessengerIndividualAddressBookId))
+ {
+
+ lock (defaultContactPage)
+ defaultContactPage[key] = contact;
+ }
+
+ return key;
+ }
+
+ private void DisplayImageChanged(object sender, EventArgs e)
+ {
+ Contact contact = sender as Contact;
+ if (contact == null)
+ return;
+
+ SyncDisplayImage(contact);
+ }
+
+ private string AddToOtherContactPage(Contact contact)
+ {
+ string key = GetContactKey(contact);
+ if (contact.AddressBookId != new Guid(WebServiceConstants.MessengerIndividualAddressBookId))
+ {
+
+ lock (otherContactPage)
+ {
+ if (!otherContactPage.ContainsKey(key))
+ {
+ otherContactPage[key] = contact;
+ }
+ else
+ {
+ otherContactPage[key].AddSibling(contact);
+ }
+ }
+
+ if (NeedSync(key))
+ {
+ lock (defaultContactPage)
+ {
+ if (contact != defaultContactPage[key])
+ defaultContactPage[key].AddSibling(contact);
+ }
+ }
+ }
+
+ return key;
+ }
+
+ private bool NeedSync(Contact contact)
+ {
+ return NeedSync(GetContactKey(contact));
+ }
+
+ private bool NeedSync(string key)
+ {
+ lock (defaultContactPage)
+ return defaultContactPage.ContainsKey(key);
+ }
+
+ private bool Sync(string key)
+ {
+ lock (defaultContactPage)
+ {
+ if (!NeedSync(key))
+ return false;
+
+ Contact root = defaultContactPage[key];
+
+ if (root.Siblings.Count > 0)
+ {
+ SyncProperties(root);
+ }
+
+ }
+
+ return true;
+ }
+
+ #endregion
+
+ #region Public functions
+
+ public void SyncProperties(Contact root)
+ {
+ lock (root.SyncObject)
+ {
+ foreach (Contact sibling in root.Siblings.Values)
+ {
+ if (sibling == root)
+ continue;
+
+ sibling.SetList(root.Lists);
+ sibling.SetIsMessengerUser(root.IsMessengerUser);
+
+ }
+ }
+ }
+
+ public void SyncDisplayImage(Contact initator)
+ {
+ if (initator.AddressBookId == new Guid(WebServiceConstants.MessengerIndividualAddressBookId))
+ {
+
+ if (initator.Siblings.Count > 0)
+ {
+ lock (initator.SyncObject)
+ {
+ foreach (Contact sibling in initator.Siblings.Values)
+ {
+ if (sibling != initator)
+ sibling.DisplayImage = initator.DisplayImage;
+ }
+ }
+ }
+ }
+ else
+ {
+ string key = GetContactKey(initator);
+
+ Contact root = null;
+ lock (otherContactPage)
+ {
+ if (!otherContactPage.ContainsKey(key))
+ return;
+
+ root = otherContactPage[key];
+ }
+
+ if (root.Siblings.Count > 0)
+ {
+ lock (root.SyncObject)
+ {
+ foreach (Contact sibling in root.Siblings.Values)
+ {
+ if (sibling != root)
+ sibling.DisplayImage = root.DisplayImage;
+ }
+ }
+ }
+ }
+ }
+
+ public void Add(Contact contact)
+ {
+ string key = AddToDefaultContactPage(contact);
+ AddToOtherContactPage(contact);
+ contact.DisplayImageChanged += new EventHandler(DisplayImageChanged);
+ if (!NeedSync(key))
+ {
+ return;
+ }
+
+ Sync(key);
+
+ }
+
+ public string GetContactKey(Contact contact)
+ {
+ return contact.ClientType.ToString().ToLowerInvariant() + ":" + contact.Mail.ToLowerInvariant();
+ }
+
+ public void Reset()
+ {
+ lock (defaultContactPage)
+ defaultContactPage.Clear();
+ lock (otherContactPage)
+ otherContactPage.Clear();
+ }
+ #endregion
+ }
+}
diff --git a/MSNPSharp/Conversation.cs b/MSNPSharp/Conversation.cs
new file mode 100644
index 0000000..a3e359e
--- /dev/null
+++ b/MSNPSharp/Conversation.cs
@@ -0,0 +1,1179 @@
+#region Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions (http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice
+/*
+Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions
+(http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice.
+All rights reserved. http://code.google.com/p/msnp-sharp/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the names of Bas Geertsema or Xih Solutions nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#endregion
+
+using System;
+using System.IO;
+using System.Threading;
+using System.Collections;
+using System.Diagnostics;
+using System.Collections.Generic;
+
+namespace MSNPSharp
+{
+ using MSNPSharp.Core;
+ using MSNPSharp.DataTransfer;
+
+ internal abstract class MessageObject
+ {
+ protected object innerObject = null;
+
+ public object InnerObject
+ {
+ get { return innerObject; }
+ }
+ }
+
+ internal class UserTypingObject : MessageObject
+ {
+
+ }
+
+ internal class NudgeObject : MessageObject { }
+ internal class TextMessageObject : MessageObject
+ {
+ public TextMessageObject(TextMessage message)
+ {
+ innerObject = message;
+ }
+ }
+
+ internal class EmoticonObject : MessageObject
+ {
+ private EmoticonType type;
+
+ public EmoticonType Type
+ {
+ get { return type; }
+ }
+ public EmoticonObject(List iconlist, EmoticonType icontype)
+ {
+ innerObject = iconlist;
+ type = icontype;
+ }
+ }
+
+ ///
+ /// A facade to the underlying switchboard and YIM session.
+ ///
+ ///
+ /// Conversation implements a few features for the ease of the application programmer. It provides
+ /// directly basic common functionality. However, if you need to perform more advanced actions, or catch
+ /// other events you have to directly use the underlying switchboard handler, or switchboard processor.
+ /// Conversation automatically requests emoticons used by remote contacts.
+ ///
+ public class Conversation
+ {
+ #region Private
+
+ #region Members
+
+ private Messenger _messenger = null;
+ private SBMessageHandler _switchboard = null;
+ private bool ended = false;
+ private bool ending = false;
+ private ConversationState conversationState = ConversationState.None;
+
+ private bool autoRequestEmoticons = true;
+ private bool autoKeepAlive = false;
+
+ private List _pendingInviteContacts = new List(0);
+ private List _contacts = new List(0);
+ private Contact _firstContact = null;
+ private object _syncObject = new object();
+
+ private Queue _messageQueues = new Queue(0);
+ private ConversationType _type = ConversationType.None;
+ private int keepalivePeriod = 30000;
+
+ private Timer keepaliveTimer = null;
+ #endregion
+
+ private void transferSession_TransferAborted(object sender, EventArgs e)
+ {
+ Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "Emoticon aborted", GetType().Name);
+
+ P2PTransferSession session = sender as P2PTransferSession;
+ OnMSNObjectDataTransferCompleted(sender,
+ new MSNObjectDataTransferCompletedEventArgs(session.ClientData as MSNObject, true, session.TransferProperties.RemoteContact, session.TransferProperties.RemoteContactEndPointID));
+ }
+
+ private void transferSession_TransferFinished(object sender, EventArgs e)
+ {
+ Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "Emoticon received", GetType().Name);
+
+ P2PTransferSession session = sender as P2PTransferSession;
+ OnMSNObjectDataTransferCompleted(sender,
+ new MSNObjectDataTransferCompletedEventArgs(session.ClientData as MSNObject, false, session.TransferProperties.RemoteContact, session.TransferProperties.RemoteContactEndPointID));
+
+ }
+
+ private bool AddContact(Contact contact)
+ {
+ lock (_contacts)
+ {
+ if (_contacts.Contains(contact))
+ return false; ;
+ _contacts.Add(contact);
+ }
+
+ return true;
+ }
+
+ private bool RemoveContact(Contact contact)
+ {
+ lock (_contacts)
+ {
+ return _contacts.Remove(contact);
+ }
+ }
+
+ private void ClearContacts()
+ {
+ lock (_contacts)
+ _contacts.Clear();
+ }
+
+ private static void KeepAlive(object state)
+ {
+ Conversation convers = state as Conversation;
+ if (convers.AutoKeepAlive)
+ {
+ if ((convers.Type & ConversationType.SwitchBoard) == ConversationType.SwitchBoard)
+ {
+ if (convers.conversationState >= ConversationState.SwitchboardRequestSent &&
+ convers.conversationState < ConversationState.SwitchboardEnded)
+ {
+ convers._switchboard.SendKeepAliveMessage();
+ }
+ }
+ }
+ }
+
+ private void IniCommonSettings()
+ {
+ if (_switchboard == null)
+ {
+ _switchboard = new SBMessageHandler(Messenger.Nameserver);
+
+ }
+
+ //Must call after _switchboard and _yimHandler have been initialized.
+ AttachEvents(_switchboard);
+
+ conversationState = ConversationState.ConversationCreated;
+ }
+
+ private bool IsPendingContact(Contact contact)
+ {
+ lock (_pendingInviteContacts)
+ {
+ foreach (Contact pendingContact in _pendingInviteContacts)
+ {
+ if (pendingContact.IsSibling(contact))
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+ private void PendingContactEnqueue(Contact pendingContact)
+ {
+ lock (_pendingInviteContacts)
+ {
+ if (!_pendingInviteContacts.Contains(pendingContact))
+ _pendingInviteContacts.Add(pendingContact);
+ }
+ }
+
+ private void MessageEnqueue(MessageObject message)
+ {
+ lock (_messageQueues)
+ {
+ _messageQueues.Enqueue(message);
+ }
+ }
+
+ private void SwitchBoardInvitePendingContacts()
+ {
+ List pendingInviteContacts = new List(_pendingInviteContacts);
+ foreach (Contact contact in pendingInviteContacts)
+ {
+ if (contact.Status == PresenceStatus.Offline)
+ {
+ lock (_pendingInviteContacts)
+ {
+ _pendingInviteContacts.Remove(contact);
+ }
+ }
+ }
+
+ pendingInviteContacts = new List(_pendingInviteContacts);
+ foreach (Contact contact in pendingInviteContacts)
+ {
+ if (contact.Status != PresenceStatus.Offline)
+ {
+ _switchboard.Invite(contact);
+ Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "SwitchBoard " + _switchboard.SessionHash + " inviting user: " + contact.Mail);
+ }
+ }
+ }
+
+ private void AttachEvents(SBMessageHandler switchboard)
+ {
+ DetachEvents(switchboard);
+
+ switchboard.AllContactsLeft += new EventHandler(OnAllContactsLeft);
+ switchboard.ContactJoined += new EventHandler(OnContactJoined);
+ switchboard.ContactLeft += new EventHandler(OnContactLeft);
+ switchboard.EmoticonDefinitionReceived += new EventHandler(OnEmoticonDefinitionReceived);
+ switchboard.ExceptionOccurred += new EventHandler(OnExceptionOccurred);
+ switchboard.NudgeReceived += new EventHandler(OnNudgeReceived);
+ switchboard.ServerErrorReceived += new EventHandler(OnServerErrorReceived);
+ switchboard.SessionClosed += new EventHandler(OnSessionClosed);
+ switchboard.SessionEstablished += new EventHandler(OnSessionEstablished);
+ switchboard.TextMessageReceived += new EventHandler(OnTextMessageReceived);
+ switchboard.UserTyping += new EventHandler(OnUserTyping);
+ switchboard.WinkReceived += new EventHandler(OnWinkReceived);
+ }
+
+ private void DetachEvents(SBMessageHandler switchboard)
+ {
+ switchboard.AllContactsLeft -= (OnAllContactsLeft);
+ switchboard.ContactJoined -= (OnContactJoined);
+ switchboard.ContactLeft -= (OnContactLeft);
+ switchboard.EmoticonDefinitionReceived -= (OnEmoticonDefinitionReceived);
+ switchboard.ExceptionOccurred -= (OnExceptionOccurred);
+ switchboard.NudgeReceived -= (OnNudgeReceived);
+ switchboard.ServerErrorReceived -= (OnServerErrorReceived);
+ switchboard.SessionClosed -= (OnSessionClosed);
+ switchboard.SessionEstablished -= (OnSessionEstablished);
+ switchboard.TextMessageReceived -= (OnTextMessageReceived);
+ switchboard.UserTyping -= (OnUserTyping);
+ switchboard.WinkReceived -= (OnWinkReceived);
+ }
+
+
+ private void SwitchBoardEnd(object param)
+ {
+ try
+ {
+ if ((bool)param == false)
+ {
+ Switchboard.Close();
+ }
+
+ }
+ catch (Exception ex)
+ {
+ Trace.WriteLineIf(Settings.TraceSwitch.TraceError, "[SwitchBoardEnd] An error occured while ending the switchboard: " + Switchboard.SessionHash
+ + "\r\n Error Message: " + ex.Message);
+ }
+
+ conversationState = ConversationState.SwitchboardEnded;
+ }
+
+ private Contact GetFirstJoinedContact()
+ {
+ lock (Contacts)
+ {
+ foreach (Contact contact in Contacts)
+ {
+ if (!contact.IsSibling(Messenger.ContactList.Owner))
+ {
+ return contact;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private bool SetFirstJoinedContact(Contact firstJoinedContact)
+ {
+ lock (_syncObject)
+ {
+ if (RemoteOwner == null)
+ {
+ _firstContact = firstJoinedContact;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private bool SetNextRemoteOwner()
+ {
+ lock (_syncObject)
+ {
+ Contact oldOwner = RemoteOwner;
+
+ foreach (Contact contact in Contacts)
+ {
+ if (!contact.IsSibling(Messenger.Nameserver.ContactList.Owner))
+ {
+ if (!contact.IsSibling(oldOwner))
+ {
+ _firstContact = contact;
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+ }
+
+ #endregion
+
+
+ #region Protected
+
+ protected void OnMSNObjectDataTransferCompleted(object sender, MSNObjectDataTransferCompletedEventArgs e)
+ {
+ if (MSNObjectDataTransferCompleted != null)
+ MSNObjectDataTransferCompleted(this, new ConversationMSNObjectDataTransferCompletedEventArgs(sender as P2PTransferSession, e));
+ }
+
+
+ protected virtual void OnConversationEnded(Conversation conversation)
+ {
+ if (Ended) return;
+ Ended = true;
+
+ conversationState = ConversationState.ConversationEnded;
+ if (ending)
+ {
+ DetachEvents(_switchboard);
+ ending = false;
+ }
+
+ _messenger.Conversations.Remove(this);
+
+
+ ClearContacts();
+
+ lock (_pendingInviteContacts)
+ _pendingInviteContacts.Clear();
+
+ if (ConversationEnded != null)
+ {
+ ConversationEnded(this, new ConversationEndEventArgs(conversation));
+ }
+ }
+
+ #region Event operation
+
+
+ protected virtual void OnWinkReceived(object sender, WinkEventArgs e)
+ {
+ _type |= ConversationType.Chat;
+ if (WinkReceived != null)
+ WinkReceived(this, e);
+ }
+
+ protected virtual void OnUserTyping(object sender, ContactEventArgs e)
+ {
+ _type |= ConversationType.Chat;
+ if (UserTyping != null)
+ UserTyping(this, e);
+ }
+
+ protected virtual void OnTextMessageReceived(object sender, TextMessageEventArgs e)
+ {
+ _type |= ConversationType.Chat;
+
+ if (TextMessageReceived != null)
+ TextMessageReceived(this, e);
+ }
+
+ protected virtual void OnSessionEstablished(object sender, EventArgs e)
+ {
+ if ((_type & ConversationType.SwitchBoard) == ConversationType.SwitchBoard)
+ {
+ SwitchBoardInvitePendingContacts();
+ }
+
+ if (SessionEstablished != null)
+ SessionEstablished(this, e);
+ }
+
+ protected virtual void OnSessionClosed(object sender, EventArgs e)
+ {
+ if (sender.GetType() == typeof(SBMessageHandler))
+ {
+ conversationState = ConversationState.SwitchboardEnded;
+ }
+
+ Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, sender.GetType().ToString() + " session :" + _switchboard.SessionHash + " closed.");
+
+ if (SessionClosed != null)
+ SessionClosed(this, e);
+
+ Messenger.P2PHandler.RemoveSwitchboardSession(_switchboard);
+
+ OnConversationEnded(this);
+ }
+
+ protected virtual void OnServerErrorReceived(object sender, MSNErrorEventArgs e)
+ {
+ if (ServerErrorReceived != null)
+ ServerErrorReceived(this, e);
+ }
+
+ protected virtual void OnNudgeReceived(object sender, ContactEventArgs e)
+ {
+ _type |= ConversationType.Chat;
+ if (NudgeReceived != null)
+ NudgeReceived(this, e);
+ }
+
+ protected virtual void OnExceptionOccurred(object sender, ExceptionEventArgs e)
+ {
+ if (ExceptionOccurred != null)
+ ExceptionOccurred(this, e);
+ }
+
+ protected virtual void OnEmoticonDefinitionReceived(object sender, EmoticonDefinitionEventArgs e)
+ {
+ _type |= ConversationType.Chat;
+ if (AutoRequestEmoticons == false)
+ return;
+
+ MSNObject existing = MSNObjectCatalog.GetInstance().Get(e.Emoticon.CalculateChecksum());
+ if (existing == null)
+ {
+ e.Sender.Emoticons[e.Emoticon.Sha] = e.Emoticon;
+
+ // create a session and send the invitation
+ P2PMessageSession session = Messenger.P2PHandler.GetSession(Messenger.ContactList.Owner, Messenger.ContactList.Owner.MachineGuid, e.Sender, e.Sender.SelectRandomEPID());
+
+ MSNSLPHandler msnslpHandler = session.MasterSession;
+ if (msnslpHandler != null)
+ {
+ P2PTransferSession transferSession = msnslpHandler.SendInvitation(session.LocalContact, session.RemoteContact, e.Emoticon);
+ transferSession.DataStream = e.Emoticon.OpenStream();
+ transferSession.ClientData = e.Emoticon;
+
+ transferSession.TransferAborted += new EventHandler(transferSession_TransferAborted);
+ transferSession.TransferFinished += new EventHandler(transferSession_TransferFinished);
+
+ MSNObjectCatalog.GetInstance().Add(e.Emoticon);
+ }
+ else
+ throw new MSNPSharpException("No MSNSLPHandler was attached to the p2p message session. An emoticon invitation message could not be send.");
+ }
+ else
+ {
+ //If exists, fire the event.
+ OnMSNObjectDataTransferCompleted(sender, new MSNObjectDataTransferCompletedEventArgs(existing, false, e.Sender, Guid.Empty));
+ }
+
+
+ if (EmoticonDefinitionReceived != null)
+ EmoticonDefinitionReceived(this, e);
+ }
+
+ protected virtual void OnContactLeft(object sender, ContactConversationEventArgs e)
+ {
+ if (e.EndPoint != Guid.Empty)
+ return;
+
+ RemoveContact(e.Contact);
+
+ if (ContactLeft != null)
+ ContactLeft(this, e);
+
+ if (e.Contact.IsSibling(RemoteOwner))
+ {
+ Contact oldOwner = RemoteOwner;
+ if (SetNextRemoteOwner())
+ {
+ OnRemoteOwnerChanged(new ConversationRemoteOwnerChangedEventArgs(oldOwner, RemoteOwner));
+ }
+ }
+ }
+
+ protected virtual void OnContactJoined(object sender, ContactConversationEventArgs e)
+ {
+ if (e.EndPoint != Guid.Empty)
+ {
+ //Wait until contacts from all locations have joined.
+ return;
+ }
+
+ if (!AddContact(e.Contact))
+ return;
+
+ if (!_messenger.Conversations.Contains(this))
+ {
+ _messenger.Conversations.Add(this);
+ }
+
+ lock (_pendingInviteContacts)
+ _pendingInviteContacts.Remove(e.Contact);
+
+ conversationState = ConversationState.OneRemoteUserJoined;
+
+ if (!e.Contact.IsSibling(Messenger.ContactList.Owner))
+ {
+ SetFirstJoinedContact(e.Contact);
+ }
+
+ lock (_messageQueues)
+ {
+ while (_messageQueues.Count > 0)
+ {
+ MessageObject msgobj = _messageQueues.Dequeue();
+ if (msgobj is TextMessageObject)
+ {
+ SendTextMessage(msgobj.InnerObject as TextMessage);
+ }
+
+ if (msgobj is NudgeObject)
+ {
+ SendNudge();
+ }
+
+ if (msgobj is EmoticonObject)
+ {
+ SendEmoticonDefinitions(msgobj.InnerObject as List, (msgobj as EmoticonObject).Type);
+ }
+ }
+ }
+
+
+ if (ContactJoined != null)
+ ContactJoined(this, e);
+ }
+
+ protected virtual void OnAllContactsLeft(object sender, EventArgs e)
+ {
+ if (AllContactsLeft != null)
+ AllContactsLeft(this, e);
+ EndSwitchBoardSession(true);
+ }
+
+ ///
+ /// Create a new conversation which contains the same users as the expired one.
+ ///
+ /// A new conversation.
+ /// The current conversation is not expired.
+ protected virtual Conversation ReCreate()
+ {
+ if (conversationState == ConversationState.OneRemoteUserJoined ||
+ conversationState == ConversationState.SwitchboardRequestSent)
+ {
+ return this;
+ }
+
+ if (RemoteOwner.Status == PresenceStatus.Offline)
+ {
+ throw new InvalidOperationException("Contact " + RemoteOwner.Mail + " not online, please send offline message instead.");
+ }
+
+ if ((_type & ConversationType.SwitchBoard) == ConversationType.SwitchBoard)
+ {
+ Messenger.Nameserver.RequestSwitchboard(_switchboard, this);
+
+ conversationState = ConversationState.SwitchboardRequestSent;
+ }
+
+
+ Ended = false;
+
+
+ //This is a very important priciple:
+ //If all contacts left, we try to re-invite the first contact ONLY.
+ PendingContactEnqueue(RemoteOwner);
+
+ return this;
+ }
+
+ protected virtual void OnRemoteOwnerChanged(ConversationRemoteOwnerChangedEventArgs e)
+ {
+ if (RemoteOwnerChanged != null)
+ RemoteOwnerChanged(this, e);
+ }
+
+
+ #endregion
+
+ #endregion
+
+ #region Internal
+
+ #endregion
+
+ #region Public Events
+
+ ///
+ /// Fired when the owner is the only contact left. If the owner leaves too the connection is automatically closed by the server.
+ ///
+ public event EventHandler AllContactsLeft;
+
+ ///
+ /// Fired when the session is closed, either by the server or by the local client.
+ ///
+ public event EventHandler SessionClosed;
+
+ ///
+ /// Occurs when a switchboard connection has been made and the initial handshaking commands are send. This indicates that the session is ready to invite or accept other contacts.
+ ///
+ public event EventHandler SessionEstablished;
+
+ ///
+ /// Fired when a contact joins. In case of a conversation with two people in it this event is called with the remote contact specified in the event argument.
+ ///
+ public event EventHandler ContactJoined;
+ ///
+ /// Fired when a contact leaves the conversation.
+ ///
+ public event EventHandler ContactLeft;
+
+ ///
+ /// Fired when a message is received from any of the other contacts in the conversation.
+ ///
+ public event EventHandler TextMessageReceived;
+
+ ///
+ /// Fired when a contact sends a emoticon definition.
+ ///
+ public event EventHandler EmoticonDefinitionReceived;
+
+ public event EventHandler WinkReceived;
+
+ ///
+ /// Fired when a contact sends a nudge
+ ///
+ public event EventHandler NudgeReceived;
+
+ ///
+ /// Fired when any of the other contacts is typing a message.
+ ///
+ public event EventHandler UserTyping;
+
+ ///
+ /// Occurs when an exception is thrown while handling the incoming or outgoing messages.
+ ///
+ public event EventHandler ExceptionOccurred;
+
+ ///
+ /// Occurs when the MSN Switchboard Server sends us an error.
+ ///
+ public event EventHandler ServerErrorReceived;
+
+ ///
+ /// Occurs after the remote owner left a multiple user conversation.
+ ///
+ public event EventHandler RemoteOwnerChanged;
+
+ #endregion
+
+ #region Public
+ ///
+ /// Fired when the data transfer for a MSNObject finished or aborted.
+ ///
+ public event EventHandler MSNObjectDataTransferCompleted;
+
+ ///
+ /// Occurs when a new conversation is ended (all contacts in the conversation have left or is called).
+ ///
+ public event EventHandler ConversationEnded;
+
+ #region Properties
+
+ ///
+ /// Contacts once or currently in the conversation.
+ ///
+ public List Contacts
+ {
+ get
+ {
+ return _contacts;
+ }
+ }
+
+ ///
+ /// Indicates the type of current available switchboard in this conversation.
+ ///
+ public ConversationType Type
+ {
+ get { return _type; }
+ }
+
+ ///
+ /// Indicates whether the conversation is ended by user.
+ /// If a conversation is ended, it can't be used to send any message.
+ ///
+ public bool Ended
+ {
+ get
+ {
+ lock (_syncObject)
+ return ended;
+ }
+
+ internal set
+ {
+ lock (_syncObject)
+ ended = value;
+ }
+ }
+
+ ///
+ /// Indicates whether emoticons from remote contacts are automatically retrieved
+ ///
+ public bool AutoRequestEmoticons
+ {
+ get
+ {
+ return autoRequestEmoticons;
+ }
+ set
+ {
+ autoRequestEmoticons = value;
+ }
+ }
+
+ ///
+ /// Indicates whether the conversation will never expired until the owner close it.
+ /// If true, will never fired and a keep-alive message will send to the switchboard every seconds.
+ ///
+ /// Setting this property on an ended conversation.
+ /// Setting this property for a YIM conversation or an expired conversation.
+ public bool AutoKeepAlive
+ {
+ get
+ {
+ if ((_type & ConversationType.YIM) == ConversationType.YIM)
+ return true;
+
+ return autoKeepAlive;
+ }
+
+ set
+ {
+ if (Ended)
+ {
+ throw new InvalidOperationException("Conversation ended.");
+ }
+
+ if ((_type & ConversationType.YIM) == ConversationType.YIM)
+ {
+ //YIM handlers, expired handlers. Should I throw an exception here?
+ throw new NotSupportedException("Cannot set keep-alive property to true for this conversation type.");
+ }
+
+
+ if (value && autoKeepAlive != value)
+ {
+ if ((_type & ConversationType.SwitchBoard) == ConversationType.SwitchBoard || _type == ConversationType.None)
+ {
+ autoKeepAlive = value;
+ keepaliveTimer = new Timer(new TimerCallback(KeepAlive), this, keepalivePeriod, keepalivePeriod);
+ return;
+ }
+
+ }
+
+ if (!value && autoKeepAlive != value)
+ {
+ autoKeepAlive = value;
+ keepaliveTimer.Dispose();
+ keepaliveTimer = null;
+ }
+ }
+ }
+
+ ///
+ /// The period between two keep-alive messages sent (In second).
+ ///
+ public int KeepAliveMessagePeriod
+ {
+ get { return keepalivePeriod / 1000; }
+ set
+ {
+ keepalivePeriod = value * 1000;
+ if (keepaliveTimer != null)
+ keepaliveTimer.Change(keepalivePeriod, keepalivePeriod);
+ else
+ keepaliveTimer = new Timer(new TimerCallback(KeepAlive), this, keepalivePeriod, keepalivePeriod);
+ }
+ }
+
+ ///
+ /// Messenger that created the conversation
+ ///
+ public Messenger Messenger
+ {
+ get
+ {
+ return _messenger;
+ }
+ set
+ {
+ _messenger = value;
+ }
+ }
+
+ ///
+ /// The switchboard handler. Handles incoming/outgoing messages.
+ /// If the conversation ended, this property will be null.
+ ///
+ public SBMessageHandler Switchboard
+ {
+ get
+ {
+ if ((_type & ConversationType.SwitchBoard) != ConversationType.SwitchBoard)
+ {
+ return null;
+ }
+ else
+ {
+ return _switchboard;
+ }
+ }
+ }
+
+ ///
+ /// The remote owner of this conversation.
+ ///
+ public Contact RemoteOwner
+ {
+ get { return _firstContact; }
+ }
+
+ #endregion
+
+ ///
+ /// Constructor.
+ ///
+ /// The messenger object that requests the conversation.
+ /// The switchboard to interface to.
+ internal Conversation(Messenger parent, SBMessageHandler sbHandler)
+ {
+ _switchboard = sbHandler;
+ _type = ConversationType.SwitchBoard;
+ _messenger = parent;
+ IniCommonSettings();
+ conversationState = ConversationState.SwitchboardRequestSent;
+ }
+
+ ///
+ /// Constructor.
+ ///
+ /// The messenger object that requests the conversation.
+ internal Conversation(Messenger parent)
+ {
+ _messenger = parent;
+
+ _type = ConversationType.None;
+ IniCommonSettings();
+ }
+
+ ///
+ /// Invite a remote contact to join the conversation.
+ ///
+ /// Contact account
+ /// Contact type
+ /// Operating on an ended conversation.
+ /// Inviting mutiple YIM users into a YIM conversation, invite YIM users to a switchboard conversation, or passport members are invited into YIM conversation.
+ public SBMessageHandler Invite(string contactMail, ClientType type)
+ {
+ if ((_type & ConversationType.YIM) == ConversationType.YIM &&
+ type != ClientType.EmailMember)
+ {
+ throw new NotSupportedException("Only Yahoo messenger users can be invited in a YIM conversation.");
+ }
+
+
+ if ((_type & ConversationType.YIM) == ConversationType.YIM &&
+ type == ClientType.EmailMember)
+ {
+ if (_contacts.Count > 1)
+ throw new NotSupportedException("Mutiple user not supported in YIM conversation.");
+ }
+
+ if ((_type & ConversationType.SwitchBoard) == ConversationType.SwitchBoard &&
+ (type != ClientType.PassportMember &&
+ type != ClientType.LCS))
+ {
+ throw new NotSupportedException("Only Passport members can be invited in a switchboard conversation.");
+ }
+
+ if (_type == ConversationType.None)
+ {
+ switch (type)
+ {
+ case ClientType.EmailMember:
+ _type = ConversationType.YIM;
+ break;
+
+ case ClientType.LCS:
+ case ClientType.PassportMember:
+ _type = ConversationType.SwitchBoard;
+ break;
+ }
+ }
+
+ if (!Messenger.ContactList.HasContact(contactMail, type))
+ {
+ throw new MSNPSharpException("Contact not on your contact list.");
+ }
+
+ Contact contact = Messenger.ContactList.GetContact(contactMail, type); //Only contacts on default addressbook can join conversations.
+ if (contact.Status == PresenceStatus.Offline)
+ {
+ throw new InvalidOperationException("Contact " + contactMail + " not online, please send offline message instead.");
+ }
+
+ if (Ended)
+ {
+ ReCreate();
+ PendingContactEnqueue(contact); //Must added after recreate.
+ }
+ else
+ {
+ if (RemoteOwner == null)
+ {
+ _firstContact = contact;
+ }
+
+ #region Initialize SBMessageHandler and invite.
+
+ if ((_type & ConversationType.SwitchBoard) == ConversationType.SwitchBoard)
+ {
+
+ if (conversationState == ConversationState.ConversationCreated ||
+ conversationState == ConversationState.SwitchboardEnded ||
+ conversationState == ConversationState.ConversationEnded)
+ {
+ PendingContactEnqueue(contact); //Enqueue the contact if user send message before it join.
+ Messenger.Nameserver.RequestSwitchboard(_switchboard, this);
+
+ conversationState = ConversationState.SwitchboardRequestSent;
+ return _switchboard;
+ }
+
+ bool inviteResult = _switchboard.Invite(contact);
+ if (inviteResult && _switchboard.GetRosterUniqueUserCount() > 1)
+ {
+ _type |= ConversationType.MutipleUsers;
+ }
+
+
+ }
+ #endregion
+
+ }
+
+ return _switchboard;
+ }
+
+ ///
+ /// Invite a remote contact to join the conversation.
+ ///
+ /// The remote contact to invite.
+ /// Operating on an expired conversation will get this exception.
+ /// Inviting mutiple YIM users into a YIM conversation, invite YIM users to a switchboard conversation, or passport members are invited into YIM conversation.
+ public SBMessageHandler Invite(Contact contact)
+ {
+ return Invite(contact.Mail, contact.ClientType);
+ }
+
+ ///
+ /// End this conversation.
+ ///
+ public void End()
+ {
+ ending = true;
+ EndSwitchBoardSession(false);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ /// If all the contacts left the conversation, this should be true.
+ /// if the current user want to left, this should set to false.
+ private void EndSwitchBoardSession(bool remoteDisconnect)
+ {
+ if (conversationState >= ConversationState.SwitchboardRequestSent &&
+ conversationState < ConversationState.SwitchboardEnded)
+ {
+ Thread endthread = new Thread(new ParameterizedThreadStart(SwitchBoardEnd)); //Avoid blocking the UI thread.
+ endthread.Start(remoteDisconnect);
+ }
+
+ if (keepaliveTimer != null)
+ keepaliveTimer.Dispose();
+ }
+
+ ///
+ /// Whether the specified contact or its sibling is in the conversation.
+ ///
+ ///
+ ///
+ public bool HasContact(Contact contact)
+ {
+ if (_type == ConversationType.None)
+ return false;
+
+
+ if ((_type & ConversationType.SwitchBoard) == ConversationType.SwitchBoard)
+ {
+ if (_switchboard.HasContact(contact))
+ return true;
+
+ if (IsPendingContact(contact))
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Sends a plain text message to all other contacts in the conversation.
+ ///
+ ///
+ /// This method wraps the TextMessage object in a SBMessage object and sends it over the network.
+ ///
+ /// The message to send.
+ /// Sending messages from an ended conversation.
+ public void SendTextMessage(TextMessage message)
+ {
+ _type |= ConversationType.Chat;
+
+ if (Ended)
+ {
+ ReCreate();
+ }
+
+ if (conversationState != ConversationState.OneRemoteUserJoined)
+ {
+ MessageEnqueue(new TextMessageObject(message));
+ return;
+ }
+
+
+ if ((_type & ConversationType.SwitchBoard) == ConversationType.SwitchBoard)
+ {
+ _switchboard.SendTextMessage(message);
+ }
+ }
+
+ ///
+ /// Sends a 'user is typing..' message to the switchboard, and is received by all participants.
+ ///
+ /// Sending messages from an ended conversation.
+ public void SendTypingMessage()
+ {
+ _type |= ConversationType.Chat;
+
+ if (Ended)
+ {
+ return;
+ }
+
+
+ if ((_type & ConversationType.SwitchBoard) == ConversationType.SwitchBoard && conversationState == ConversationState.OneRemoteUserJoined)
+ {
+ _switchboard.SendTypingMessage();
+ }
+ }
+
+ ///
+ /// Sends a 'nudge' message to the switchboard, and is received by all participants.
+ ///
+ /// Sending messages from an ended conversation.
+ public void SendNudge()
+ {
+ _type |= ConversationType.Chat;
+
+ if (Ended)
+ {
+ ReCreate();
+ }
+
+ if (conversationState != ConversationState.OneRemoteUserJoined)
+ {
+ MessageEnqueue(new NudgeObject());
+ return;
+ }
+
+
+ if ((_type & ConversationType.SwitchBoard) == ConversationType.SwitchBoard)
+ {
+ _switchboard.SendNudge();
+ }
+ }
+
+ ///
+ /// Sends the definition for a list of emoticons to all other contacts in the conversation. The client-programmer must use this function if a text messages uses multiple emoticons in a single message.
+ ///
+ /// Use this function before sending text messages which include the emoticon text. You can only send one emoticon message before the textmessage. So make sure that all emoticons used in the textmessage are included.
+ /// A list of emoticon objects.
+ /// The type of current emoticons.
+ /// Operating on an ended conversation.
+ /// Sending custom emoticons from a YIM conversation.
+ public void SendEmoticonDefinitions(List emoticons, EmoticonType icontype)
+ {
+ _type |= ConversationType.Chat;
+ if (Ended)
+ {
+ ReCreate();
+ }
+
+ if (conversationState != ConversationState.OneRemoteUserJoined)
+ {
+ MessageEnqueue(new EmoticonObject(emoticons, icontype));
+ return;
+ }
+
+ if ((_type & ConversationType.YIM) == ConversationType.YIM)
+ {
+ throw new NotSupportedException("YIM conversation not support sending custom emoticons.");
+ }
+
+ if ((_type & ConversationType.SwitchBoard) == ConversationType.SwitchBoard)
+ {
+ _switchboard.SendEmoticonDefinitions(emoticons, icontype);
+ }
+ }
+
+ #endregion
+
+
+ }
+};
diff --git a/MSNPSharp/ConversationID.cs b/MSNPSharp/ConversationID.cs
new file mode 100644
index 0000000..0b73e84
--- /dev/null
+++ b/MSNPSharp/ConversationID.cs
@@ -0,0 +1,200 @@
+#region Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions (http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice
+/*
+Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions
+(http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice.
+All rights reserved. http://code.google.com/p/msnp-sharp/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the names of Bas Geertsema or Xih Solutions nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Diagnostics;
+
+namespace MSNPSharp.Utilities
+{
+ public class ConversationID
+ {
+ private Conversation conversation = null;
+ private Contact remoteOwner = null;
+
+ private string hashString = string.Empty;
+ private string compareString = string.Empty;
+ private int hashCode = 0;
+
+ public Contact RemoteOwner
+ {
+ get { return remoteOwner; }
+ }
+
+ internal Conversation Conversation
+ {
+ get
+ {
+ return conversation;
+ }
+ }
+
+ private object syncObject = new object();
+
+ internal void SetConversation(Conversation conv)
+ {
+ conversation = conv;
+ if (conversation != null)
+ {
+ if (conversation.RemoteOwner == null && RemoteOwner == null)
+ throw new ArgumentException("Invailid conversation.");
+
+ if (conversation.RemoteOwner != null)
+ remoteOwner = conversation.RemoteOwner;
+ }
+ }
+
+ public ClientType NetworkType
+ {
+ get
+ {
+ if (!remoteOwner.IsMessengerUser)
+ return ClientType.None;
+
+ return remoteOwner.ClientType;
+ }
+ }
+
+ public ConversationID(Conversation conversation)
+ {
+ if (conversation == null)
+ throw new ArgumentNullException("conversation is null.");
+
+ SetConversation(conversation);
+
+ hashString = ToString();
+ hashCode = hashString.GetHashCode();
+
+
+ conversation.ConversationEnded += delegate
+ {
+ lock (syncObject)
+ {
+ SetConversation(null);
+ }
+ };
+
+ conversation.RemoteOwnerChanged += delegate(object sender, ConversationRemoteOwnerChangedEventArgs args)
+ {
+ lock (syncObject)
+ {
+ try
+ {
+ SetConversation(conversation);
+ }
+ catch (Exception)
+ {
+ Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose, "Remote owner changed to null.");
+ }
+ }
+ };
+ }
+
+ public ConversationID(Contact remote)
+ {
+ if (remote == null)
+ throw new ArgumentNullException("remote is null.");
+
+ remoteOwner = remote;
+ hashString = ToString();
+ hashCode = hashString.GetHashCode();
+ }
+
+ ///
+ /// Whether the two conversation are logically equals.
+ ///
+ ///
+ ///
+ ///
+ public static bool operator ==(ConversationID id1, object other)
+ {
+ if (((object)id1 == null) && other == null)
+ return true;
+
+ if (((object)id1) == null || other == null)
+ return false;
+
+ if (other is ConversationID)
+ {
+ return id1.Equals(other);
+ }
+
+ if (other is Conversation)
+ {
+ if (id1.conversation == null) return false;
+ return object.ReferenceEquals(id1.conversation, other);
+ }
+
+
+ return false;
+ }
+
+ public static bool operator !=(ConversationID id1, object other)
+ {
+ return !(id1 == other);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (object.ReferenceEquals(this, obj))
+ return true;
+
+ if (obj == null)
+ return false;
+
+ if (!(obj is ConversationID))
+ return false;
+
+ return ToString() == obj.ToString();
+ }
+
+ public override int GetHashCode()
+ {
+ return hashCode;
+ }
+
+ public override string ToString()
+ {
+ string remoteOwnerString = (remoteOwner == null ? "null" : remoteOwner.Mail.ToLowerInvariant());
+ string conversationString = string.Empty;
+ if (conversation != null)
+ {
+ if ((conversation.Type & ConversationType.MutipleUsers) > 0)
+ {
+ conversationString = conversation.Switchboard.SessionHash;
+ }
+ }
+ return string.Join(";", new string[] { NetworkType.ToString().ToLowerInvariant(), remoteOwnerString, conversationString });
+ }
+ }
+}
diff --git a/MSNPSharp/Core/BitUtility.cs b/MSNPSharp/Core/BitUtility.cs
new file mode 100644
index 0000000..21bd571
--- /dev/null
+++ b/MSNPSharp/Core/BitUtility.cs
@@ -0,0 +1,267 @@
+#region Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions (http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice
+/*
+Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions
+(http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice.
+All rights reserved. http://code.google.com/p/msnp-sharp/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the names of Bas Geertsema or Xih Solutions nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MSNPSharp.Core
+{
+ public static class BitUtility
+ {
+ public static short ToInt16(byte[] data, int startIndex, bool dataIsLittleEndian)
+ {
+ if (BitConverter.IsLittleEndian == dataIsLittleEndian)
+ {
+ return BitConverter.ToInt16(data, startIndex);
+ }
+ else
+ {
+ return BitConverter.ToInt16(GetSwappedByteArray(data, startIndex, 2), 0);
+ }
+ }
+
+ public static ushort ToUInt16(byte[] data, int startIndex, bool dataIsLittleEndian)
+ {
+ if (BitConverter.IsLittleEndian == dataIsLittleEndian)
+ {
+ return BitConverter.ToUInt16(data, startIndex);
+ }
+ else
+ {
+ return BitConverter.ToUInt16(GetSwappedByteArray(data, startIndex, 2), 0);
+ }
+ }
+
+ public static int ToInt32(byte[] data, int startIndex, bool dataIsLittleEndian)
+ {
+ if (BitConverter.IsLittleEndian == dataIsLittleEndian)
+ {
+ return BitConverter.ToInt32(data, startIndex);
+ }
+ else
+ {
+ return BitConverter.ToInt32(GetSwappedByteArray(data, startIndex, 4), 0);
+ }
+ }
+
+ public static uint ToUInt32(byte[] data, int startIndex, bool dataIsLittleEndian)
+ {
+ if (BitConverter.IsLittleEndian == dataIsLittleEndian)
+ {
+ return BitConverter.ToUInt32(data, startIndex);
+ }
+ else
+ {
+ return BitConverter.ToUInt32(GetSwappedByteArray(data, startIndex, 4), 0);
+ }
+ }
+
+ public static long ToInt64(byte[] data, int startIndex, bool dataIsLittleEndian)
+ {
+ if (BitConverter.IsLittleEndian == dataIsLittleEndian)
+ {
+ return BitConverter.ToInt64(data, startIndex);
+ }
+ else
+ {
+ return BitConverter.ToInt64(GetSwappedByteArray(data, startIndex, 8), 0);
+ }
+ }
+
+ public static ulong ToUInt64(byte[] data, int startIndex, bool dataIsLittleEndian)
+ {
+ if (BitConverter.IsLittleEndian == dataIsLittleEndian)
+ {
+ return BitConverter.ToUInt64(data, startIndex);
+ }
+ else
+ {
+ return BitConverter.ToUInt64(GetSwappedByteArray(data, startIndex, 8), 0);
+ }
+ }
+
+
+ public static byte[] GetBytes(short val, bool littleEndian)
+ {
+ byte[] bytes = BitConverter.GetBytes(val);
+
+ if (BitConverter.IsLittleEndian == littleEndian)
+ return bytes;
+
+ return GetSwappedByteArray(bytes, 0, 2);
+ }
+
+ public static byte[] GetBytes(ushort val, bool littleEndian)
+ {
+ byte[] bytes = BitConverter.GetBytes(val);
+
+ if (BitConverter.IsLittleEndian == littleEndian)
+ return bytes;
+
+ return GetSwappedByteArray(bytes, 0, 2);
+ }
+
+ public static byte[] GetBytes(int val, bool littleEndian)
+ {
+ byte[] bytes = BitConverter.GetBytes(val);
+
+ if (BitConverter.IsLittleEndian == littleEndian)
+ return bytes;
+
+ return GetSwappedByteArray(bytes, 0, 4);
+ }
+
+ public static byte[] GetBytes(uint val, bool littleEndian)
+ {
+ byte[] bytes = BitConverter.GetBytes(val);
+
+ if (BitConverter.IsLittleEndian == littleEndian)
+ return bytes;
+
+ return GetSwappedByteArray(bytes, 0, 4);
+ }
+
+ public static byte[] GetBytes(long val, bool littleEndian)
+ {
+ byte[] bytes = BitConverter.GetBytes(val);
+
+ if (BitConverter.IsLittleEndian == littleEndian)
+ return bytes;
+
+ return GetSwappedByteArray(bytes, 0, 8);
+ }
+
+ public static byte[] GetBytes(ulong val, bool littleEndian)
+ {
+ byte[] bytes = BitConverter.GetBytes(val);
+
+ if (BitConverter.IsLittleEndian == littleEndian)
+ return bytes;
+
+ return GetSwappedByteArray(bytes, 0, 8);
+ }
+
+ private static byte[] GetSwappedByteArray(byte[] data, int startIndex, int length)
+ {
+ byte[] swap = new byte[length];
+ int endIndex = 0;
+ while (--length >= 0)
+ {
+ swap[length] = data[startIndex + endIndex];
+ endIndex++;
+ }
+ return swap;
+ }
+
+
+
+
+ public static ushort ToLittleEndian(ushort val)
+ {
+ if (BitConverter.IsLittleEndian)
+ return val;
+
+ return FlipEndian(val);
+ }
+
+ public static uint ToLittleEndian(uint val)
+ {
+ if (BitConverter.IsLittleEndian)
+ return val;
+
+ return FlipEndian(val);
+ }
+
+ public static ulong ToLittleEndian(ulong val)
+ {
+ if (BitConverter.IsLittleEndian)
+ return val;
+
+ return FlipEndian(val);
+ }
+
+ public static ushort ToBigEndian(ushort val)
+ {
+ if (!BitConverter.IsLittleEndian)
+ return val;
+
+ return FlipEndian(val);
+ }
+
+ public static uint ToBigEndian(uint val)
+ {
+ if (!BitConverter.IsLittleEndian)
+ return val;
+
+ return FlipEndian(val);
+ }
+
+ public static ulong ToBigEndian(ulong val)
+ {
+ if (!BitConverter.IsLittleEndian)
+ return val;
+
+ return FlipEndian(val);
+ }
+
+ private static ushort FlipEndian(ushort val)
+ {
+ return (ushort)
+ (((val & 0x00ff) << 8) +
+ ((val & 0xff00) >> 8));
+ }
+
+
+ private static uint FlipEndian(uint val)
+ {
+ return (uint)
+ (((val & 0x000000ff) << 24) +
+ ((val & 0x0000ff00) << 8) +
+ ((val & 0x00ff0000) >> 8) +
+ ((val & 0xff000000) >> 24));
+ }
+
+ private static ulong FlipEndian(ulong val)
+ {
+ return (ulong)
+ (((val & 0x00000000000000ff) << 56) +
+ ((val & 0x000000000000ff00) << 40) +
+ ((val & 0x0000000000ff0000) << 24) +
+ ((val & 0x00000000ff000000) << 8) +
+ ((val & 0x000000ff00000000) >> 8) +
+ ((val & 0x0000ff0000000000) >> 24) +
+ ((val & 0x00ff000000000000) >> 40) +
+ ((val & 0xff00000000000000) >> 56));
+ }
+ }
+};
diff --git a/MSNPSharp/Core/Converter.cs b/MSNPSharp/Core/Converter.cs
new file mode 100644
index 0000000..5b0ee78
--- /dev/null
+++ b/MSNPSharp/Core/Converter.cs
@@ -0,0 +1,458 @@
+#region Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions (http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice
+/*
+Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions
+(http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice.
+All rights reserved. http://code.google.com/p/msnp-sharp/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the names of Bas Geertsema or Xih Solutions nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#endregion
+
+using System;
+using System.Web;
+using System.Text;
+using System.Xml;
+using System.Security.Cryptography;
+
+namespace MSNPSharp.Core
+{
+ using MSNPSharp.DataTransfer;
+
+ internal enum EscapeType
+ {
+ EscapeAll,
+ EscapeExceptPlus
+ }
+
+ ///
+ /// Provides methods for encoding and decoding URLs when processing Web requests. This class cannot be inherited.
+ ///
+ public static class MSNHttpUtility
+ {
+ private enum UnSafe
+ {
+ ///
+ /// For url encode
+ ///
+ UrlEscape = 0x1,
+ ///
+ /// For XML encode
+ ///
+ XMLEscape = 0x2,
+ ///
+ /// For HTML encode
+ ///
+ HTMLEscape = 0x4
+ }
+
+ private static uint[] ASCII_CLASS;
+ private static string strUrlUnsafe = " \"#%&+,/:;<=>?@[\\]^`{|}";
+ private static string strXmlUnsafe = "&:;<=>?[]\\^{|}";
+ private static string strHtmlUnsafe = "&'<> ;\"";
+
+ static MSNHttpUtility()
+ {
+ ASCII_CLASS = new uint[256];
+ int c = 0;
+ for (c = 0; c < ASCII_CLASS.Length; c++)
+ {
+ if ((c >= 0 && c <= 32) || c >= 126)
+ {
+ ASCII_CLASS[c] |= (uint)UnSafe.UrlEscape;
+ }
+
+ if (c >= 0 && c <= 32)
+ {
+ ASCII_CLASS[c] |= (uint)UnSafe.XMLEscape;
+ }
+
+ if (strUrlUnsafe.IndexOf((char)c) != -1)
+ {
+ ASCII_CLASS[c] |= (uint)UnSafe.UrlEscape;
+ }
+ if (strXmlUnsafe.IndexOf((char)c) != -1)
+ {
+ ASCII_CLASS[c] |= (uint)UnSafe.XMLEscape;
+ }
+ if (strHtmlUnsafe.IndexOf((char)c) != -1)
+ {
+ ASCII_CLASS[c] |= (uint)UnSafe.HTMLEscape;
+ }
+ }
+
+ }
+
+ ///
+ /// Encodes a MSNObject description using UTF-8 encoding by default.
+ ///
+ /// The MSNObject description to encode.
+ /// An encoded string.
+ public static string MSNObjectUrlEncode(string str)
+ {
+ return UrlEncode(str, Encoding.UTF8, EscapeType.EscapeExceptPlus);
+ }
+
+ ///
+ /// Replace space into %20.
+ ///
+ /// The string to encode.
+ /// An encoded string.
+ public static string NSEncode(string str)
+ {
+ return str.Replace(" ", "%20");
+ }
+
+ ///
+ /// Encodes a URL string using UTF-8 encoding by default.
+ ///
+ /// The text to encode.
+ /// An encoded string.
+ public static string UrlEncode(string str)
+ {
+ return UrlEncode(str, Encoding.UTF8, EscapeType.EscapeAll);
+ }
+
+ ///
+ /// Encodes a URL string using the specified encoding object.
+ ///
+ /// The text to encode.
+ /// The object that specifies the encoding scheme.
+ /// An encoded string.
+ public static string UrlEncode(string str, Encoding e)
+ {
+ return UrlEncode(str, e, EscapeType.EscapeAll);
+ }
+
+ private static string UrlEncode(string str, Encoding e, EscapeType type)
+ {
+ if (str == null)
+ return string.Empty;
+ byte[] byt = e.GetBytes(str);
+ StringBuilder result = new StringBuilder(256);
+ for (int c = 0; c < byt.Length; c++)
+ {
+ byte chr = byt[c];
+ if ((ASCII_CLASS[chr] & (uint)UnSafe.UrlEscape) != 0)
+ {
+ switch (chr)
+ {
+ case (byte)'+':
+ if (type == EscapeType.EscapeAll)
+ {
+ result.Append("%20");
+ }
+ else if (type == EscapeType.EscapeExceptPlus)
+ {
+ result.Append("%2B");
+ }
+
+ break;
+ default:
+ result.Append("%" + ((int)chr).ToString("X2"));
+ break;
+
+ }
+ }
+ else
+ {
+ result.Append((char)chr);
+ }
+ }
+
+ return result.ToString();
+ }
+
+ ///
+ /// Decode an encoded .
+ ///
+ /// The encoded MSNObject description.
+ /// A decoded string.
+ public static string MSNObjectUrlDecode(string str)
+ {
+ return UrlDecode(str, Encoding.UTF8, EscapeType.EscapeExceptPlus);
+ }
+
+ ///
+ /// Converts a string that has been encoded for transmission in a URL into a decoded string using UTF-8 encoding by default.
+ ///
+ /// The string to decode.
+ /// A decoded string.
+ public static string UrlDecode(string str)
+ {
+ return UrlDecode(str, Encoding.UTF8, EscapeType.EscapeAll);
+ }
+
+ ///
+ /// Converts a URL-encoded string into a decoded string, using the specified encoding object.
+ ///
+ /// The string to decode.
+ /// The that specifies the decoding scheme.
+ /// A decoded string.
+ public static string UrlDecode(string str, Encoding e)
+ {
+ return UrlDecode(str, e, EscapeType.EscapeAll);
+ }
+
+ ///
+ /// Replace "%20" into space.
+ ///
+ /// The string to decode.
+ /// A decoded string.
+ public static string NSDecode(string str)
+ {
+ return str.Replace("%20", " ");
+ }
+
+ private static string UrlDecode(string str, Encoding e, EscapeType type)
+ {
+ if (type == EscapeType.EscapeExceptPlus)
+ {
+ return HttpUtility.UrlDecode(str.Replace("%2b", "+").Replace("%2B", "+"), e);
+ }
+
+ return HttpUtility.UrlDecode(str.Replace("%20", "+"), e);
+ }
+
+ ///
+ /// Encodes a Xml string.
+ ///
+ /// The string to decode.
+ /// A decoded string.
+ public static string XmlEncode(string str)
+ {
+ if (str == null)
+ return string.Empty;
+
+ char[] chrArr = str.ToCharArray();
+ char chr;
+ StringBuilder result = new StringBuilder(256);
+ for (int c = 0; c < chrArr.Length; c++)
+ {
+ chr = chrArr[c];
+
+ if (chr < 128)
+ {
+ if ((ASCII_CLASS[chr] & (uint)UnSafe.XMLEscape) != 0)
+ {
+ result.Append("" + ((int)chr).ToString("X2") + ";");
+ continue;
+ }
+ }
+
+ result.Append(chr);
+ }
+
+ return result.ToString();
+ }
+
+
+ ///
+ /// Decode the QP encoded string.
+ ///
+ /// The string to decode.
+ /// A decoded string.
+ public static string QPDecode(string str)
+ {
+ return QPDecode(str, Encoding.Default);
+ }
+
+ ///
+ /// Decode the QP encoded string using an encoding
+ ///
+ /// The string to decode.
+ /// The that specifies the decoding scheme.
+ /// A decoded string.
+ public static string QPDecode(string value, Encoding encode)
+ {
+ string inputString = value;
+ StringBuilder builder1 = new StringBuilder();
+ inputString = inputString.Replace("=\r\n", "");
+ for (int num1 = 0; num1 < inputString.Length; num1++)
+ {
+ if (inputString[num1] == '=')
+ {
+ try
+ {
+ if (HexToDec(inputString.Substring(num1 + 1, 2)) < 0x80)
+ {
+ if (HexToDec(inputString.Substring(num1 + 1, 2)) >= 0)
+ {
+ byte[] buffer1 = new byte[1] { (byte)HexToDec(inputString.Substring(num1 + 1, 2)) };
+ builder1.Append(encode.GetString(buffer1));
+ num1 += 2;
+ }
+ }
+ else if (inputString[num1 + 1] != '=')
+ {
+ byte[] buffer2 = new byte[2] { (byte)HexToDec(inputString.Substring(num1 + 1, 2)), (byte)HexToDec(inputString.Substring(num1 + 4, 2)) };
+ builder1.Append(encode.GetString(buffer2));
+ num1 += 5;
+ }
+ }
+ catch
+ {
+ builder1.Append(inputString.Substring(num1, 1));
+ }
+ }
+ else
+ {
+ builder1.Append(inputString.Substring(num1, 1));
+ }
+ }
+ return builder1.ToString();
+ }
+
+ private static int HexToDec(string hex)
+ {
+ int num1 = 0;
+ string text1 = "0123456789ABCDEF";
+ for (int num2 = 0; num2 < hex.Length; num2++)
+ {
+ if (text1.IndexOf(hex[num2]) == -1)
+ {
+ return -1;
+ }
+ num1 = (num1 * 0x10) + text1.IndexOf(hex[num2]);
+ }
+ return num1;
+ }
+
+
+ public static int IndexOf(byte[] input, byte[] pattern)
+ {
+ if (pattern.Length > input.Length)
+ return -1;
+
+ for (int i = 0; i <= input.Length - pattern.Length; i++)
+ {
+ bool found = true;
+
+ for (int j = 0; j < pattern.Length; j++)
+ {
+ if (input[i + j] != pattern[j])
+ {
+ found = false;
+ break;
+ }
+ }
+
+ if (found)
+ return i;
+ }
+
+ return -1;
+ }
+
+ public static int IndexOf(byte[] input, string pattern)
+ {
+ return IndexOf(input, Encoding.UTF8.GetBytes(pattern));
+ }
+ }
+
+ public static class WebServiceDateTimeConverter
+ {
+ ///
+ /// Convert the XML time to .net instance.
+ ///
+ ///
+ ///
+ public static DateTime ConvertToDateTime(string dateTime)
+ {
+ if (dateTime == null || dateTime == string.Empty)
+ dateTime = WebServiceConstants.ZeroTime;
+
+ return XmlConvert.ToDateTime(dateTime, WebServiceConstants.XmlDateTimeFormats);
+ }
+ }
+
+
+ public static class HashedNonceGenerator
+ {
+ ///
+ /// Creates handshake guid using SHA1 hash algorithm.
+ ///
+ ///
+ /// The output packed to handshake for direct connect
+ public static Guid HashNonce(Guid nonce)
+ {
+ // http://forums.fanatic.net.nz/index.php?showtopic=19372&view=findpost&p=108868
+ // {2B95F56D-9CA0-9A64-82CE-ADC1F3C55845} <-> [0x37,0x29,0x2d,0x12,0x86,0x5c,0x7b,0x4c,0x81,0xf5,0xe,0x5,0x1,0x78,0x80,0xc2]
+ // OUTPUT: 2b95f56d-9ca0-9a64-82ce-adc1f3c55845
+ // INPUT: 122d2937-5c86-4c7b-81f5-0e05017880c2
+
+ Guid handshakeNonce = Guid.Empty;
+
+ using (SHA1Managed sha1 = new SHA1Managed())
+ {
+ // Returns 20 bytes
+ byte[] hash = sha1.ComputeHash(nonce.ToByteArray());
+
+ handshakeNonce = CreateGuidFromData(P2PVersion.P2PV2, hash);
+ }
+
+ return handshakeNonce;
+ }
+
+
+ public static Guid CreateGuidFromData(P2PVersion ver, byte[] data)
+ {
+ Guid ret = Guid.Empty;
+
+ if (ver == P2PVersion.P2PV1)
+ {
+ P2PMessage message = new P2PMessage(ver);
+ message.ParseBytes(data);
+
+ ret = new Guid(
+ (int)message.V1Header.AckSessionId,
+
+ (short)(message.Header.AckIdentifier & 0x0000FFFF),
+ (short)((message.Header.AckIdentifier & 0xFFFF0000) >> 16),
+
+ (byte)((message.V1Header.AckTotalSize & 0x00000000000000FF)),
+ (byte)((message.V1Header.AckTotalSize & 0x000000000000FF00) >> 8),
+ (byte)((message.V1Header.AckTotalSize & 0x0000000000FF0000) >> 16),
+ (byte)((message.V1Header.AckTotalSize & 0x00000000FF000000) >> 24),
+ (byte)((message.V1Header.AckTotalSize & 0x000000FF00000000) >> 32),
+ (byte)((message.V1Header.AckTotalSize & 0x0000FF0000000000) >> 40),
+ (byte)((message.V1Header.AckTotalSize & 0x00FF000000000000) >> 48),
+ (byte)((message.V1Header.AckTotalSize & 0xFF00000000000000) >> 56)
+ );
+ }
+ else if (ver == P2PVersion.P2PV2)
+ {
+ Int32 a = BitUtility.ToInt32(data, 0, BitConverter.IsLittleEndian);
+ Int16 b = BitUtility.ToInt16(data, 4, BitConverter.IsLittleEndian);
+ Int16 c = BitUtility.ToInt16(data, 6, BitConverter.IsLittleEndian);
+ byte d = data[8], e = data[9], f = data[10], g = data[11];
+ byte h = data[12], i = data[13], j = data[14], k = data[15];
+
+ ret = new Guid(a, b, c, d, e, f, g, h, i, j, k);
+ }
+
+ return ret;
+ }
+ }
+};
\ No newline at end of file
diff --git a/MSNPSharp/Core/IMessageHandler.cs b/MSNPSharp/Core/IMessageHandler.cs
new file mode 100644
index 0000000..7d051d0
--- /dev/null
+++ b/MSNPSharp/Core/IMessageHandler.cs
@@ -0,0 +1,64 @@
+#region Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions (http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice
+/*
+Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions
+(http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice.
+All rights reserved. http://code.google.com/p/msnp-sharp/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the names of Bas Geertsema or Xih Solutions nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#endregion
+
+using System;
+
+namespace MSNPSharp.Core
+{
+ ///
+ /// IMessageHandler defines the methods required to handle incoming network messages.
+ ///
+ public interface IMessageHandler
+ {
+ ///
+ /// Gets or sets the processor of network messages.
+ /// Every message handler is associated with a single message processor.
+ /// This way the handler can initiate, or send, messages which are not a reply
+ /// on incoming messages.
+ ///
+ IMessageProcessor MessageProcessor
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// A IMessageProcessor calls this method. The handler can then process the
+ /// message.
+ ///
+ ///
+ ///
+ ///
+ ///
+ void HandleMessage(IMessageProcessor sender, NetworkMessage message);
+ }
+};
diff --git a/MSNPSharp/Core/MSNMessage.cs b/MSNPSharp/Core/MSNMessage.cs
new file mode 100644
index 0000000..4a70b78
--- /dev/null
+++ b/MSNPSharp/Core/MSNMessage.cs
@@ -0,0 +1,254 @@
+#region Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions (http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice
+/*
+Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions
+(http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice.
+All rights reserved. http://code.google.com/p/msnp-sharp/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the names of Bas Geertsema or Xih Solutions nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#endregion
+
+using System;
+using System.Text;
+using System.Collections;
+using System.Globalization;
+
+namespace MSNPSharp.Core
+{
+ using MSNPSharp;
+
+ [Serializable()]
+ public class MSNMessage : NetworkMessage, ICloneable
+ {
+ protected int transactionID = -1;
+ private string command = "MSG";
+ private ArrayList commandValues;
+ private const string noTransactionIDCommands = "OUT PNG QNG RNG";
+
+ public MSNMessage()
+ {
+ commandValues = new ArrayList();
+ }
+
+ public MSNMessage(string command, ArrayList commandValues)
+ {
+ Command = command;
+ CommandValues = commandValues;
+ }
+
+ public override void PrepareMessage()
+ {
+ base.PrepareMessage();
+ }
+
+
+ public int TransactionID
+ {
+ get
+ {
+ return transactionID;
+ }
+ set
+ {
+ transactionID = value;
+ }
+ }
+
+ public string Command
+ {
+ get
+ {
+ return command;
+ }
+ set
+ {
+ command = value;
+ }
+ }
+
+ public ArrayList CommandValues
+ {
+ get
+ {
+ return commandValues;
+ }
+ set
+ {
+ commandValues = value;
+ }
+ }
+
+ public override byte[] GetBytes()
+ {
+
+ StringBuilder builder = new StringBuilder(128);
+ builder.Append(Command);
+
+ if (noTransactionIDCommands.IndexOf(Command) == -1)
+ {
+ if (TransactionID != -1)
+ {
+ builder.Append(' ');
+ builder.Append(TransactionID.ToString(CultureInfo.InvariantCulture));
+ }
+ }
+
+ foreach (string val in CommandValues)
+ {
+ builder.Append(' ');
+ builder.Append(val);
+ }
+
+
+
+ if (InnerMessage != null)
+ {
+ builder.Append(' ');
+ builder.Append(InnerMessage.GetBytes().Length);
+ builder.Append("\r\n");
+ return AppendArray(System.Text.Encoding.UTF8.GetBytes(builder.ToString()), InnerMessage.GetBytes());
+ }
+ else
+ {
+ builder.Append("\r\n");
+ return System.Text.Encoding.UTF8.GetBytes(builder.ToString());
+ }
+ }
+
+ public override void ParseBytes(byte[] data)
+ {
+
+ int cnt = 0;
+ int bodyStart = 0;
+
+ while (data[cnt] != '\r')
+ {
+ cnt++;
+
+ // watch out for buffer overflow
+ if (cnt == data.Length)
+ throw new MSNPSharpException("Parsing of incoming command message failed. No newline was detected.");
+ }
+
+ bodyStart = cnt + 1;
+ while (bodyStart < data.Length && (data[bodyStart] == '\r' || data[bodyStart] == '\n'))
+ {
+ bodyStart++;
+ }
+
+ // get the command parameters
+ Command = System.Text.Encoding.UTF8.GetString(data, 0, 3);
+ string commandLine = Encoding.UTF8.GetString(data, 4, cnt - 4);
+ CommandValues = new ArrayList(commandLine.Split(new char[] { ' ' }));
+
+
+ //Filter those commands follow by a number but not transaction id.
+ if (noTransactionIDCommands.IndexOf(Command) == -1)
+ {
+ if (CommandValues.Count > 0)
+ {
+ if (!int.TryParse((string)CommandValues[0], out transactionID))
+ {
+ transactionID = -1; //if there's no transid, set to -1
+ }
+ else
+ {
+ CommandValues.RemoveAt(0);
+ }
+ }
+
+ }
+
+ // set the inner body contents, if it is available
+ if (bodyStart < data.Length)
+ {
+ if (CommandValues.Count > 0)
+ {
+ CommandValues.RemoveAt(CommandValues.Count - 1);
+ }
+
+ int startIndex = bodyStart;
+ int newLength = data.Length - startIndex;
+ InnerBody = new byte[newLength];
+ Array.Copy(data, startIndex, InnerBody, 0, newLength);
+ }
+
+
+ }
+
+ ///
+ /// Get the debug string representation of the message
+ ///
+ ///
+ ///
+ /// To futher developers:
+ /// You cannot simply apply Encoding.UTF8.GetString(GetByte()) in this function
+ /// since the InnerMessage of MSNMessage may contain binary data.
+ ///
+ public override string ToString()
+ {
+ StringBuilder builder = new StringBuilder(128);
+ builder.Append(Command);
+
+
+ if (noTransactionIDCommands.IndexOf(Command) == -1)
+ {
+ if (TransactionID != -1)
+ {
+ builder.Append(' ');
+ builder.Append(TransactionID.ToString(CultureInfo.InvariantCulture));
+ }
+ }
+
+
+ foreach (string val in CommandValues)
+ {
+ builder.Append(' ');
+ builder.Append(val);
+ }
+
+
+ if (InnerMessage != null)
+ {
+ builder.Append(' ');
+ builder.Append(InnerMessage.GetBytes().Length);
+ }
+
+ //For toString, we do not return the inner message's string.
+ return builder.ToString();
+ }
+
+ #region ICloneable Member
+
+ object ICloneable.Clone()
+ {
+ MSNMessage messageClone = new MSNMessage();
+ messageClone.ParseBytes(GetBytes());
+ return messageClone;
+ }
+
+ #endregion
+ }
+};
diff --git a/MSNPSharp/Core/MessagePool.cs b/MSNPSharp/Core/MessagePool.cs
new file mode 100644
index 0000000..0290d7f
--- /dev/null
+++ b/MSNPSharp/Core/MessagePool.cs
@@ -0,0 +1,78 @@
+#region Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions (http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice
+/*
+Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions
+(http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice.
+All rights reserved. http://code.google.com/p/msnp-sharp/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the names of Bas Geertsema or Xih Solutions nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#endregion
+
+using System;
+using System.IO;
+
+namespace MSNPSharp.Core
+{
+ using MSNPSharp;
+
+ ///
+ /// Stores incoming messages in a buffer and releases them only when all contents are received.
+ ///
+ ///
+ /// MessagePool buffers incoming raw byte data and releases this data only when the message is fully retrieved.
+ /// This supports when a single message is send in multiple packets.
+ /// The descendants of this class have simple knowledge of the used protocol to identify whether a message is fully retrieved or not.
+ ///
+ public abstract class MessagePool
+ {
+ ///
+ /// Constructor to instantiate a message pool.
+ ///
+ protected MessagePool()
+ {
+ }
+
+ ///
+ /// Defines whether there is a message available to retrieve.
+ ///
+ public abstract bool MessageAvailable
+ {
+ get;
+ }
+
+ ///
+ /// Buffers the incoming raw data internal. This method is often used after receiving incoming data from a socket or another source.
+ ///
+ ///
+ public abstract void BufferData(BinaryReader reader);
+
+
+ ///
+ /// Retrieves the next message data from the buffer.
+ ///
+ ///
+ public abstract byte[] GetNextMessageData();
+ }
+};
diff --git a/MSNPSharp/Core/MessageProcessor.cs b/MSNPSharp/Core/MessageProcessor.cs
new file mode 100644
index 0000000..b826156
--- /dev/null
+++ b/MSNPSharp/Core/MessageProcessor.cs
@@ -0,0 +1,69 @@
+#region Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions (http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice
+/*
+Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions
+(http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice.
+All rights reserved. http://code.google.com/p/msnp-sharp/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the names of Bas Geertsema or Xih Solutions nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#endregion
+
+using System;
+
+namespace MSNPSharp.Core
+{
+ using MSNPSharp;
+
+ ///
+ /// Defines methods to send network messages.
+ ///
+ ///
+ /// IMessageProcessor is the abstraction of an object which can send network messages.
+ /// Network messages can be any kind of messages: text messages, data messages.
+ /// By using this interface a de-coupling is established between the handling of messages
+ /// and the I/O of messages.
+ /// IMessageProcessor is mostly used internal.
+ ///
+ public interface IMessageProcessor
+ {
+ ///
+ /// Sends a message to be processed by the processor.
+ ///
+ ///
+ void SendMessage(NetworkMessage message);
+
+ ///
+ /// Registers a handler that wants to receive incoming messages.
+ ///
+ ///
+ void RegisterHandler(IMessageHandler handler);
+
+ ///
+ /// Unregisters (removes) a handler that no lange wants to receive incoming messages.
+ ///
+ ///
+ void UnregisterHandler(IMessageHandler handler);
+ }
+};
diff --git a/MSNPSharp/Core/MimeDictionary.cs b/MSNPSharp/Core/MimeDictionary.cs
new file mode 100644
index 0000000..4310595
--- /dev/null
+++ b/MSNPSharp/Core/MimeDictionary.cs
@@ -0,0 +1,236 @@
+#region Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions (http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice
+/*
+Copyright (c) 2002-2011, Bas Geertsema, Xih Solutions
+(http://www.xihsolutions.net), Thiago.Sayao, Pang Wu, Ethem Evlice.
+All rights reserved. http://code.google.com/p/msnp-sharp/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the names of Bas Geertsema or Xih Solutions nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MSNPSharp.Core
+{
+ public class MimeDictionary : SortedList
+ {
+ public new MimeValue this[string name]
+ {
+ get
+ {
+ if (!ContainsKey(name))
+ return new MimeValue();
+
+ return (MimeValue)base[name];
+ }
+ set
+ {
+ base[name] = value;
+ }
+ }
+
+ public MimeDictionary()
+ {
+ }
+
+ public MimeDictionary(byte[] data)
+ {
+ Parse(data);
+ }
+
+ public int Parse(byte[] data)
+ {
+ int end = MSNHttpUtility.IndexOf(data, "\r\n\r\n");
+ int ret = end;
+
+ if (end < 0)
+ ret = end = data.Length;
+ else
+ ret += 4;
+
+ byte[] mimeData = new byte[end];
+ Array.Copy(data, mimeData, end);
+
+ string mimeStr = Encoding.UTF8.GetString(mimeData);
+ string[] lines = mimeStr.Trim().Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
+
+ int i = 0;
+ while (i < lines.Length)
+ {
+ string line = lines[i];
+
+ while ((++i < lines.Length) && lines[i].StartsWith("\t"))
+ line += lines[i];
+
+ int nameEnd = line.IndexOf(":");
+
+ if (nameEnd < 0)
+ continue;
+
+ string name = line.Substring(0, nameEnd).Trim();
+ MimeValue val = line.Substring(nameEnd + 1).Trim();
+
+ this[name] = val;
+ }
+
+ return ret;
+ }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ foreach (KeyValuePair pair in this)
+ {
+ sb.Append(pair.Key).Append(": ").Append(pair.Value.ToString()).Append("\r\n");
+ }
+
+ return sb.ToString();
+ }
+ }
+
+ public class MimeValue
+ {
+ string _val;
+ SortedList