//Copyright (c) 2007 Joshua R. Rodgers //Permission is hereby granted, free of charge, to any person obtaining a copy //of this software and associated documentation files (the "Software"), to deal //in the Software without restriction, including without limitation the rights //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell //copies of the Software, and to permit persons to whom the Software is //furnished to do so, subject to the following conditions: //The above copyright notice and this permission notice shall be included in //all copies or substantial portions of the Software. //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN //THE SOFTWARE. using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using Bone.CallbackArgs; namespace Bone { internal class StaticDestructor { public delegate void Handler(); private Handler doDestroy; public StaticDestructor(Handler method) { doDestroy = method; } ~StaticDestructor() { doDestroy(); } } //ar -x libbone.a; g++ -shared -lpthread *.o -o bone.so; /// /// Contains functions that pertain to Bone, but not to any specific Handle object. /// Several of these functions are important to the operation of bone, including initialization. /// public static class Utility { private static Importer.Callback_BadContact cBadContact = new Importer.Callback_BadContact(CallbackHandler.Callback_BadContact); private static Importer.CallBack_Broadcast cBroadcast = new Importer.CallBack_Broadcast(CallbackHandler.CallBack_Broadcast); private static Importer.Callback_ChangeEmail cChangeEmail = new Importer.Callback_ChangeEmail(CallbackHandler.Callback_ChangeEmail); private static Importer.Callback_ChannelAddUser cChanelAddUser = new Importer.Callback_ChannelAddUser(CallbackHandler.Callback_ChannelAddUser); private static Importer.Callback_ChannelAttributes cChannelAttributes = new Importer.Callback_ChannelAttributes(CallbackHandler.Callback_ChannelAttributes); private static Importer.Callback_ChannelDelUser cChannelDelUser = new Importer.Callback_ChannelDelUser(CallbackHandler.Callback_ChannelDelUser); private static Importer.Callback_ChannelList cChannelList = new Importer.Callback_ChannelList(CallbackHandler.Callback_ChannelList); private static Importer.Callback_ChannelSub cChannelSub = new Importer.Callback_ChannelSub(CallbackHandler.Callback_ChannelSub); private static Importer.Callback_ChannelText cChannelText = new Importer.Callback_ChannelText(CallbackHandler.Callback_ChannelText); private static Importer.Callback_ContactIsOnline cContactIsOnline = new Importer.Callback_ContactIsOnline(CallbackHandler.Callback_ContactIsOnline); private static Importer.Callback_CreateUser cCreateUser = new Importer.Callback_CreateUser(CallbackHandler.Callback_CreateUser); private static Importer.Callback_DelayedText cDelayedText = new Importer.Callback_DelayedText(CallbackHandler.Callback_DelayedText); private static Importer.Callback_Disconnect cDisconnect = new Importer.Callback_Disconnect(CallbackHandler.Callback_Disconnect); private static Importer.Callback_InviteNotify cInviteNotify = new Importer.Callback_InviteNotify(CallbackHandler.Callback_InviteNotify); private static Importer.Callback_InviteUser cInviteUser = new Importer.Callback_InviteUser(CallbackHandler.Callback_InviteUser); private static Importer.Callback_IsOnline cIsOnline = new Importer.Callback_IsOnline(CallbackHandler.Callback_IsOnline); private static Importer.Callback_Login cLogin = new Importer.Callback_Login(CallbackHandler.Callback_Login); private static Importer.Callback_ModifyUserProfile cModifyUserProfile = new Importer.Callback_ModifyUserProfile(CallbackHandler.Callback_ModifyUserProfile); private static Importer.Callback_Ping cPing = new Importer.Callback_Ping(CallbackHandler.Callback_Ping); private static Importer.Callback_ReqPassword cReqPassword = new Importer.Callback_ReqPassword(CallbackHandler.Callback_ReqPassword); private static Importer.Callback_ReqUserProfile cReqUserProfile = new Importer.Callback_ReqUserProfile(CallbackHandler.Callback_ReqUserProfile); private static Importer.Callback_SendText cSendText = new Importer.Callback_SendText(CallbackHandler.Callback_SendText); private static Importer.Callback_Text cText = new Importer.Callback_Text(CallbackHandler.Callback_Text); private static Importer.Callback_Welcome cWelcome = new Importer.Callback_Welcome(CallbackHandler.Callback_Welcome); /// /// Initializes the Bone SDK. Must be called before calling any other members. /// /// true if failure occurs. internal static bool Initialize() { bool failed = Importer.bone_init(14); if (failed == false) { Importer.bone_setcallback(Callbacks.BONE_CALLBACK_BADCONTACT, cBadContact); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_BROADCAST, cBroadcast); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_CHANGEEMAIL, cChangeEmail); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_CHANNELADDUSER, cChanelAddUser); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_CHANNELATTRIBUTES, cChannelAttributes); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_CHANNELDELUSER, cChannelDelUser); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_CHANNELLIST, cChannelList); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_CHANNELSUB, cChannelSub); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_CHANNELTEXT, cChannelText); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_CONTACTISONLINE, cContactIsOnline); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_CREATEUSER, cCreateUser); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_DELAYEDTEXT, cDelayedText); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_DISCONNECT, cDisconnect); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_INVITENOTIFY, cInviteNotify); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_INVITEUSER, cInviteUser); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_ISONLINE, cIsOnline); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_LOGIN, cLogin); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_MODIFYUSERPROFILE, cModifyUserProfile); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_PING, cPing); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_REQPASSWORD, cReqPassword); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_REQUSERPROFILE, cReqUserProfile); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_SENDTEXT, cSendText); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_TEXT, cText); Importer.bone_setcallback(Callbacks.BONE_CALLBACK_WELCOME, cWelcome); } return failed; } /// /// Terminates the Bone SDK /// internal static void Terminate() { Importer.bone_term(); } /// /// Generates a string explaining the error code passed in. /// /// /// A textual explaination of the error. public static string GetErrorText(int error) { return Marshal.PtrToStringAnsi(Importer.bone_geterrortext(error)); } /// /// Gets the last error to occur after a function has returned failure. /// /// An integer representing the last error. public static int GetLastError() { return Importer.bone_getlasterror(); } /// /// Call this in a loop to dispatch events in a console program. DO NOT USE WITH WinForms! /// public static void Dispatch() { Importer.Message msg; if (Importer.GetMessage(out msg, IntPtr.Zero, 0, 0)) { Importer.TranslateMessage(out msg); Importer.DispatchMessage(out msg); } } internal static Dictionary handleDictionary = new Dictionary(); } /// /// Represents a single handle instance. Includes all the appropriate functions required to operate on the handle. /// Each handle maintains it's own list of event handlers for each callback. So each callback must be set for each instance. /// public sealed partial class Handle { /// /// Delegate type for handling bone callback events. /// /// The type of event arguments to be used. /// The object sending the event. /// The event arguments of the event. public delegate void Callback(object sender, T e); /// /// Indicates that a contact does not exist. /// public event Callback Callback_BadContact; /// /// Indicates that a broadcast message was sent. /// public event Callback Callback_Broadcast; /// /// Indicates that a change email operation has completed. /// public event Callback Callback_ChangeEmail; /// /// Indicates the a new user has joined a channel. /// public event Callback Callback_ChannelAddUser; /// /// Indicates that a user has left a channel. /// public event Callback Callback_ChannelDeleteUser; /// /// Indicates that attributes were received for a channel. /// public event Callback Callback_ChannelAttributes; /// /// Indicates that an error occurred while joining a channel. /// public event Callback Callback_ChannelSubscribe; /// /// Indicates a specific channel while listing channels. A null channel name represents the end of the list. /// public event Callback Callback_ChannelList; /// /// Indicates that new text has arrived on a specific channel. /// public event Callback Callback_ChannelText; /// /// Indicates that a contact has come online. /// public event Callback Callback_ContactIsOnline; /// /// Indicates that a create user operation has completed. /// public event Callback Callback_CreateUser; /// /// Indicates that a dalyed message has been received. /// public event Callback Callback_DelayedText; /// /// Indicates that the handle has experienced a disconnect from the server. /// public event Callback Callback_Disconnect; /// /// Indicates that an invitation to a channel has occurred. /// public event Callback Callback_InviteNotify; /// /// Indicates that an InviteUser operation has completed. /// public event Callback Callback_InviteUser; /// /// Indicates that an IsOnline operation has completed. /// public event Callback Callback_IsOnline; /// /// Indicates that a Login operation has completed. /// public event Callback Callback_Login; /// /// Indicates that a ModifyUserProfile operation has completed. /// public event Callback Callback_ModifyUserProfile; /// /// Indicates that a Ping operation has completed. /// public event Callback Callback_Ping; /// /// Indicates that a RequestPassword operation has completed. /// public event Callback Callback_RequestPassword; /// /// Indicates that a RequestUserProfile operation has completed. /// public event Callback Callback_RequestUserProfile; /// /// Indicates that a SendText operation has failed. /// public event Callback Callback_SendText; /// /// Indicates that a new text message has been received. /// public event Callback Callback_Text; /// /// Indicates that the server welcome message has been received. /// public event Callback Callback_Welcome; private IntPtr bHandle; #region Static Constructors / Destructors /// /// Static destructor for handling when the final instance of the class is garbage collected. /// private static readonly StaticDestructor destructor = new StaticDestructor ( delegate() { Utility.Terminate(); } ); /// /// Static constructor. This initializes the SDK the first time an instance is created. /// static Handle() { bool rc = Utility.Initialize(); if (rc == true) throw new Exception(string.Format("Failed to initialize the SDK (Reason {0}).", Utility.GetLastError())); } #endregion /// /// Constructs a new Bone Handle. /// public Handle() { } internal void Raise_Callback_BadContact(BoneCallbackBadContactArgs e) { if (Callback_BadContact != null) Callback_BadContact(this, e); } internal void Raise_Callback_Broadcast(BoneCallbackBroadcastArgs e) { if (Callback_Broadcast != null) Callback_Broadcast(this, e); } internal void Raise_Callback_ChangeEmail(BoneCallbackChangeEmailArgs e) { if (Callback_ChangeEmail != null) Callback_ChangeEmail(this, e); } internal void Raise_Callback_ChannelAddUser(BoneCallbackChannelAddUserArgs e) { if (Callback_ChannelAddUser != null) Callback_ChannelAddUser(this, e); } internal void Raise_Callback_ChannelDeleteUser(BoneCallbackChannelDeleteUserArgs e) { if (Callback_ChannelDeleteUser != null) Callback_ChannelDeleteUser(this, e); } internal void Raise_Callback_ChannelAttributes(BoneCallbackChannelAttributesArgs e) { if (Callback_ChannelAttributes != null) Callback_ChannelAttributes(this, e); } internal void Raise_Callback_ChannelSubscribe(BoneCallbackChannelSubscribeArgs e) { if (Callback_ChannelSubscribe != null) Callback_ChannelSubscribe(this, e); } internal void Raise_Callback_ChannelList(BoneCallbackChannelListArgs e) { if (Callback_ChannelList != null) Callback_ChannelList(this, e); } internal void Raise_Callback_ChannelText(BoneCallbackChannelTextArgs e) { if (Callback_ChannelText != null) Callback_ChannelText(this, e); } internal void Raise_Callback_ContactIsOnline(BoneCallbackContactIsOnlineArgs e) { if (Callback_ContactIsOnline != null) Callback_ContactIsOnline(this, e); } internal void Raise_Callback_CreateUser(BoneCallbackCreateUserArgs e) { if (Callback_CreateUser != null) Callback_CreateUser(this, e); } internal void Raise_Callback_DelayedText(BoneCallbackDelayedTextArgs e) { if (Callback_DelayedText != null) Callback_DelayedText(this, e); } internal void Raise_Callback_Disconnect(BoneCallbackDisconnectArgs e) { if (Callback_Disconnect != null) Callback_Disconnect(this, e); } internal void Raise_Callback_InviteNotify(BoneCallbackInviteNotifyArgs e) { if (Callback_InviteNotify != null) Callback_InviteNotify(this, e); } internal void Raise_Callback_InviteUser(BoneCallbackInviteUserArgs e) { if (Callback_InviteUser != null) Callback_InviteUser(this, e); } internal void Raise_Callback_IsOnline(BoneCallbackIsOnlineArgs e) { if (Callback_IsOnline != null) Callback_IsOnline(this, e); } internal void Raise_Callback_Login(BoneCallbackLoginArgs e) { if (Callback_Login != null) Callback_Login(this, e); } internal void Raise_Callback_ModifyUserProfile(BoneCallbackModifyUserProfileArgs e) { if (Callback_ModifyUserProfile != null) Callback_ModifyUserProfile(this, e); } internal void Raise_Callback_Ping(BoneCallbackPingArgs e) { if (Callback_Ping != null) Callback_Ping(this, e); } internal void Raise_Callback_RequestPassword(BoneCallbackRequestPasswordArgs e) { if (Callback_RequestPassword != null) Callback_RequestPassword(this, e); } internal void Raise_Callback_RequestUserProfile(BoneCallbackRequestUserProfileArgs e) { if (Callback_RequestUserProfile != null) Callback_RequestUserProfile(this, e); } internal void Raise_Callback_SendText(BoneCallbackSendTextArgs e) { if (Callback_SendText != null) Callback_SendText(this, e); } internal void Raise_Callback_Text(BoneCallbackTextArgs e) { if (Callback_Text != null) Callback_Text(this, e); } internal void Raise_Callback_Welcome(BoneCallbackWelcomeArgs e) { if (Callback_Welcome != null) Callback_Welcome(this, e); } } namespace CallbackArgs { /// /// Base class for handling bone callbacks. /// public abstract class BoneCallbackArgs : EventArgs { private Handle _handle; /// /// The handle associated with the event. /// public Handle Handle { get { return _handle; } internal set { _handle = value; } } } /// /// Arguments associated with the bad contact callback. /// public sealed class BoneCallbackBadContactArgs : BoneCallbackArgs { private string _contact; /// /// The name of the contact. /// public string Contact { get { return _contact; } internal set { _contact = value; } } } /// /// Arguments associated with the broadcast callback. /// public sealed class BoneCallbackBroadcastArgs : BoneCallbackArgs { private string _origin; private string _message; /// /// Origin of the message. /// public string Origin { get { return _origin; } internal set { _origin = value; } } /// /// The actual message text. /// public string Message { get { return _message; } internal set { _message = value; } } } /// /// Arguments associated with the change email callback. /// public sealed class BoneCallbackChangeEmailArgs : BoneCallbackArgs { private int _error; /// /// Error that occured during changing an e-mail address. /// public int Error { get { return _error; } internal set { _error = value; } } } /// /// Arguments associated with the channel add user callback. /// public sealed class BoneCallbackChannelAddUserArgs : BoneCallbackArgs { private string _channel; private string _user; /// /// Name of the channel. /// public string Channel { get { return _channel; } internal set { _channel = value; } } /// /// Name of the user. /// public string User { get { return _user; } internal set { _user = value; } } } /// /// Arguments associated with the channel delete user callback. /// public sealed class BoneCallbackChannelDeleteUserArgs : BoneCallbackArgs { private string _channel; private string _user; /// /// Name of the channel. /// public string Channel { get { return _channel; } internal set { _channel = value; } } /// /// Name of the user. /// public string User { get { return _user; } internal set { _user = value; } } } /// /// Arguments associated with the channel attributes callback. /// public sealed class BoneCallbackChannelAttributesArgs : BoneCallbackArgs { private string _channel; private byte _channelType; private string _owner; private string _channelPassword; /// /// Name of the channel. /// public string Channel { get { return _channel; } internal set { _channel = value; } } /// /// The type of channel. /// public byte ChannelType { get { return _channelType; } internal set { _channelType = value; } } /// /// Owner of the channel. /// public string Owner { get { return _owner; } internal set { _owner = value; } } /// /// The password associated with the channel. /// public string ChannelPassword { get { return _channelPassword; } internal set { _channelPassword = value; } } } /// /// Arguments associated with the channel subscribe callback. /// public sealed class BoneCallbackChannelSubscribeArgs : BoneCallbackArgs { private string _channel; private int _error; /// /// Name of the channel. /// public string Channel { get { return _channel; } internal set { _channel = value; } } /// /// Error associated with subscribing to the channel. /// public int Error { get { return _error; } internal set { _error = value; } } } /// /// Arguments associated with the channel list callback. /// public sealed class BoneCallbackChannelListArgs : BoneCallbackArgs { private string _channel; private byte _type; private int _userCount; /// /// Name of the channel. /// public string Channel { get { return _channel; } internal set { _channel = value; } } /// /// Type of the channel. /// public byte Type { get { return _type; } internal set { _type = value; } } /// /// Number of users in the channel. /// public int UserCount { get { return _userCount; } internal set { _userCount = value; } } } /// /// Arguments associated with the channel text callback. /// public sealed class BoneCallbackChannelTextArgs : BoneCallbackArgs { private string _origin; private string _channel; private string _message; /// /// Name of the channel. /// public string Channel { get { return _channel; } internal set { _channel = value; } } /// /// Name of the user sending the message. /// public string Origin { get { return _origin; } internal set { _origin = value; } } /// /// Message sent to the channel. /// public string Message { get { return _message; } internal set { _message = value; } } } /// /// Arguments associated with the contact is online callback. /// public sealed class BoneCallbackContactIsOnlineArgs : BoneCallbackArgs { private string _contact; private int _onlineStatus; /// /// Name of the contact. /// public string Contact { get { return _contact; } internal set { _contact = value; } } /// /// Status of the contact. /// public int OnlineStatus { get { return _onlineStatus; } internal set { _onlineStatus = value; } } } /// /// Arguments associated with the create user callback. /// public sealed class BoneCallbackCreateUserArgs : BoneCallbackArgs { private int _error; /// /// Error code associated with the result of the callback. /// public int Error { get { return _error; } internal set { _error = value; } } } /// /// Arguments associated with the delayed text callback. /// public sealed class BoneCallbackDelayedTextArgs : BoneCallbackArgs { private string _origin; private int _sendTime; private string _message; /// /// User sending the message. /// public string Origin { get { return _origin; } internal set { _origin = value; } } /// /// Message sent. /// public string Message { get { return _message; } internal set { _message = value; } } /// /// Time the user sent the message in UNIX time. /// public int SendTime { get { return _sendTime; } internal set { _sendTime = value; } } } //This one has nothing to do. It's mostly for sexy purposes. /// /// No arguments associated with a disconnect callback. /// public sealed class BoneCallbackDisconnectArgs : BoneCallbackArgs { } /// /// Arguments associated with the invite notify callback. /// public sealed class BoneCallbackInviteNotifyArgs : BoneCallbackArgs { private string _user; private string _channel; /// /// Name of the user sending the invite. /// public string User { get { return _user; } internal set { _user = value; } } /// /// Name of the channel the invite is for. /// public string Channel { get { return _channel; } internal set { _channel = value; } } } /// /// Arguments associated with the invite user callback. /// public sealed class BoneCallbackInviteUserArgs : BoneCallbackArgs { private string _user; private int _error; /// /// Name of the user being invited. /// public string User { get { return _user; } internal set { _user = value; } } /// /// Error associated with the result of the callback. /// public int Error { get { return _error; } internal set { _error = value; } } } /// /// Arguments associated with the is online callback. /// public sealed class BoneCallbackIsOnlineArgs : BoneCallbackArgs { private string _user; private int _onlineStatus; /// /// Name of the user the callback was issued for. /// public string User { get { return _user; } internal set { _user = value; } } /// /// Online status of the user. /// public int OnlineStatus { get { return _onlineStatus; } internal set { _onlineStatus = value; } } } /// /// Arguments associated with the login callback. /// public sealed class BoneCallbackLoginArgs : BoneCallbackArgs { int _error; /// /// Error associated with the result of the callback. /// public int Error { get { return _error; } internal set { _error = value; } } } /// /// Arguments associated with the modify user callback. /// public sealed class BoneCallbackModifyUserProfileArgs : BoneCallbackArgs { private int _error; private string _user; /// /// Error associated with the result of the callback. /// public int Error { get { return _error; } internal set { _error = value; } } /// /// Name of the user profile being modified. /// public string User { get { return _user; } internal set { _user = value; } } } /// /// Arguments associated with the ping callback. /// public sealed class BoneCallbackPingArgs : BoneCallbackArgs { private string _user; private int _delay; /// /// Name of the user the ping is being sent to. /// public string User { get { return _user; } internal set { _user = value; } } /// /// The delay time between the current handle and the target user. /// public int Delay { get { return _delay; } internal set { _delay = value; } } } /// /// Arguments associated with the request password callback. /// public sealed class BoneCallbackRequestPasswordArgs : BoneCallbackArgs { int _error; /// /// Error associated with the callback result. /// public int Error { get { return _error; } internal set { _error = value; } } } /// /// Arguments associated with the request user profile callback. /// public sealed class BoneCallbackRequestUserProfileArgs : BoneCallbackArgs { private int _error; private string _user; private string _password; private string _email; private int _userType; private int _creation; private int _lastLogin; private int _selfCreated; private int _isDisabled; /// /// Error associated with the result of the callback. /// public int Error { get { return _error; } internal set { _error = value; } } /// /// Name of the user the profile has been requested for. /// public string User { get { return _user; } internal set { _user = value; } } /// /// Password associated with the profile. /// public string Password { get { return _password; } internal set { _password = value; } } /// /// Email address associated with the profile. /// public string Email { get { return _email; } internal set { _email = value; } } /// /// Type of user associated with the profile. /// public int UserType { get { return _userType; } internal set { _userType = value; } } /// /// Date and time the profile was created in UNIX time. /// public int Creation { get { return _creation; } internal set { _creation = value; } } /// /// Date and time of the user's last login in UNIX time. /// public int LastLogin { get { return _lastLogin; } internal set { _lastLogin = value; } } /// /// Indicates if the user profile was self created. /// public int SelfCreated { get { return _selfCreated; } internal set { _selfCreated = value; } } /// /// Indicates it the user profile is disabled. /// public int IsDisabled { get { return _isDisabled; } internal set { _isDisabled = value; } } } /// /// Arguments associated with the send text callback. /// public sealed class BoneCallbackSendTextArgs : BoneCallbackArgs { private int _error; private string _target; /// /// Error associated with the result of the callback. /// public int Error { get { return _error; } internal set { _error = value; } } /// /// Target channel or user of the callback. /// public string Target { get { return _target; } internal set { _target = value; } } } /// /// Arguments associated with the text callback. /// public sealed class BoneCallbackTextArgs : BoneCallbackArgs { private string _origin; private string _message; /// /// Name of the user the message originated from. /// public string Origin { get { return _origin; } internal set { _origin = value; } } /// /// The message sent to the handle. /// public string Message { get { return _message; } internal set { _message = value; } } } /// /// Arguments associated with the welcome callback. /// public sealed class BoneCallbackWelcomeArgs : BoneCallbackArgs { private string _message; /// /// The welcome message of the server. /// public string Message { get { return _message; } internal set { _message = value; } } } } }