///---------------------------------------------------------------------------- /// /// Copyright (c) 2007-2008, AOL LLC /// All rights reserved. /// 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 name of the AOL LLC 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. /// ///---------------------------------------------------------------------------- using System; using System.IO; using System.ComponentModel; using System.Windows.Forms; using System.Threading; using System.Runtime.InteropServices; using AccCoreLib; namespace acshbuddy { /// /// AIMCC C# client /// class AcshApp : Control { // add import dll code so we can call C++ Functions from // .net code. [DllImport("acccore.dll", EntryPoint="#111", PreserveSig=false)] private static extern void AccCreateSession( [MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IDispatch)] out object session); private static AcshApp a; private AccSession s; private int[] transIdMap = {0}; [STAThread] public static void Main(string[] args) { if (args.Length != 2) { Console.WriteLine("usage: acshbuddy screenname password"); return; } a = new AcshApp(); a.Run(args[0], args[1]); } private void Run(string username, string password) { try { // create control to allow invokes CreateControl(); // create and init session object o; AccCreateSession(typeof(IAccSession).GUID, out o); s = (AccSession)o; // create our preference hook and then pass it // to Open AIM PrefsHook prefs = new PrefsHook(); s.PrefsHook = prefs; // set up the listeners to AIM events. Visual Studio will help you with // adding these functions by auto completing the functions. s.OnStateChange += new DAccEvents_OnStateChangeEventHandler(s_OnStateChange); s.OnUserChange += new DAccEvents_OnUserChangeEventHandler(s_OnUserChange); s.OnSecondarySessionStateChange += new DAccEvents_OnSecondarySessionStateChangeEventHandler(s_OnSecondarySessionStateChange); s.OnImReceived += new DAccEvents_OnImReceivedEventHandler(s_OnImReceived); // we need to set up a listener for getting logged into the expressions web page s.OnRequestServiceResult += new DAccEvents_OnRequestServiceResultEventHandler(s_OnRequestServiceResult); // we need to set up a listener for getting a user's info s.OnUserRequestPropertyResult += new DAccEvents_OnUserRequestPropertyResultEventHandler(s_OnUserRequestPropertyResult); // here is where we put the name of our client and developer key. // you will replace 'acshbuddy' with your client name and replace // 'ju1yztKT86VJ0xj3' with your custom client key // get your key at http://dev.aol.com/openaim s.ClientInfo.set_Property(AccClientInfoProp.AccClientInfoProp_Description, "acshbuddy (key=ju1yztKT86VJ0xj3)"); // set the user name on the session s.Identity = username; // sign on to AIM s.SignOn(password); // start main loop Application.Run(); } catch (COMException e) { Console.WriteLine(e.Message); } } // this is the code that allows our example // application to handle commands from the // command window class InputEvent : System.EventArgs { public InputEvent(string incommand) { command = incommand; } public string Command { get { return command; } } private readonly string command; }; private delegate void InputHandler(object o, InputEvent e); private void WaitForCommand() { MethodInvoker mi = new MethodInvoker(GetCommand); mi.BeginInvoke(null, null); } private void GetCommand() { string command = Console.ReadLine(); InputEvent e = new InputEvent(command); object[] list = { this, e }; BeginInvoke(new InputHandler(HandleCommand), list); } private void HandleCommand(object o, InputEvent e) { string[] tokens = e.Command.Split(' '); string verb = tokens[0]; IAccBuddyList list = s.BuddyList; switch (verb) { case ":q": s.SignOff(); break; case "b:a": if (tokens.Length != 3) { Console.WriteLine("Usage... b:a buddy group"); break; } try { IAccGroup group = list.GetGroupByName(tokens[2]); try { IAccUser buddy = group.InsertBuddy(tokens[1], -1); Console.WriteLine("ok, {0} has been added to {1}", buddy.Name, group.Name); } catch(System.Runtime.InteropServices.COMException ex) { Console.WriteLine("Sorry, that user could not be added to {0}, hr= {1}", group.Name, ex.ErrorCode); Console.WriteLine("Usage... b:a buddy group"); } } catch(System.Runtime.InteropServices.COMException ex) { Console.WriteLine("That group does not exist, hr={0}.", ex.ErrorCode); Console.WriteLine("Usage... b:a buddy group"); } break; case "b:l": int lcount = list.GroupCount; for (int i = 0; i < lcount; i++) { IAccGroup group = list.GetGroupByIndex(i); Console.WriteLine("{0}", group.Name); int gcount = group.BuddyCount; for (int j = 0; j < gcount; j++) { IAccUser buddy = group.GetBuddyByIndex(j); Console.WriteLine(" {0}", buddy.Name); } } break; case ":m": if (tokens.Length != 3) { Console.WriteLine("Usage... :m buddy message"); break; } IAccImSession ims = s.CreateImSession(tokens[1], AccImSessionType.AccImSessionType_Im); IAccIm im = s.CreateIm(tokens[2], null); ims.SendIm(im); break; case "r:e": try { // request a token for the expressions chooser web page and append the dev key from above to the end of the url // as follows &k=ju1yztKT86VJ0xj3 int transId = s.RequestService("http://api.oscar.aol.com/aim/getExpressionsPage?f=html&language=en-us&k=ju1yztKT86VJ0xj3", (object)""); int i = transIdMap.Length; transIdMap[0] = transId; } catch (System.Runtime.InteropServices.COMException ex) { Console.WriteLine("There was an error getting the expressions page {0}.", ex.ErrorCode); } break; case "b:i": try { // create a user object then request the buddy info for the user IAccUser user = s.CreateUser(tokens[1]); int transId = user.RequestProperty(AccUserProp.AccUserProp_HtmlInfo); int i = transIdMap.Length; transIdMap[i] = transId; } catch (System.Runtime.InteropServices.COMException ex) { Console.WriteLine("There was an error getting the buddy info page {0}.", ex.ErrorCode); } break; case "s:p": if (tokens.Length != 3) { Console.WriteLine("Usage... s:p key value"); break; } try { PrefsHook.m_prefsHook.SetValue(tokens[1], tokens[2]); } catch (System.Runtime.InteropServices.COMException ex) { Console.WriteLine("Setting pref {0} returned the following error {1}.", tokens[1], ex.ErrorCode); } break; case "g:p": if (tokens.Length != 2) { Console.WriteLine("Usage... g:p key"); break; } try { string val = (string)PrefsHook.m_prefsHook.GetValue(tokens[1]); Console.WriteLine("Getting pref {0} returned the following result {1}.", tokens[1], val); } catch (System.Runtime.InteropServices.COMException ex) { Console.WriteLine("Getting pref {0} returned the following error {1}.", tokens[1], ex.ErrorCode); } break; case "o:v": Console.WriteLine("Client Version: acshbuddy 1.0"); break; case ":h": Console.WriteLine("b:a {buddy group} Add a buddy to group"); Console.WriteLine("b:l List all buddies and groups in the buddy list."); Console.WriteLine(":m {buddy message} Send a message to specified buddy"); Console.WriteLine("r:e Open the AIM Expressions Web Page by requesting an auth token to seemlessly log into Expression Web Page."); Console.WriteLine("b:i {buddy} Get buddy info for a user"); Console.WriteLine("s:p {spec value} Set a preference"); Console.WriteLine("g:p {spec} Get a preference"); Console.WriteLine("o:v Lists client version"); Console.WriteLine(":q signs off of AIM and quits the test application"); break; default: Console.WriteLine("Invalid command, use :h for list of commands"); break; } WaitForCommand(); } private void s_OnStateChange(AccSession session, AccSessionState state, AccResult hr) { if (state == AccSessionState.AccSessionState_Online) { Console.WriteLine("...Welcome to AOL Instant Messenger (SM)..."); WaitForCommand(); } else if (state == AccSessionState.AccSessionState_Offline) { Application.Exit(); } } private void s_OnUserChange(AccSession session, IAccUser oldUser, IAccUser newUser, AccUserProp property, AccResult hr) { AccUserState oldState = (AccUserState)oldUser.get_Property( AccUserProp.AccUserProp_State); AccUserState newState = (AccUserState)newUser.get_Property( AccUserProp.AccUserProp_State); if (newState >= AccUserState.AccUserState_Online) { if (oldState == AccUserState.AccUserState_Offline) Console.WriteLine("** {0} has signed on.", newUser.Name); } else { if (oldState >= AccUserState.AccUserState_Online) Console.WriteLine("** {0} has signed off.", oldUser.Name); } } private void s_OnSecondarySessionStateChange(AccSession session, IAccSecondarySession piSecSession, AccSecondarySessionState State, AccResult hr) { // accept all incoming IMs even if the user is not on the buddy list if ((AccSecondarySessionServiceId)piSecSession.get_Property((int)AccSecondarySessionProp.AccSecondarySessionProp_ServiceId) == AccSecondarySessionServiceId.AccSecondarySessionServiceId_Im) { if (State == AccSecondarySessionState.AccSecondarySessionState_ReceivedProposal) { Console.WriteLine("** acshbuddy has received an IM from {0}.", (string) piSecSession.get_Property((int)AccSecondarySessionProp.AccSecondarySessionProp_RemoteUserName)); piSecSession.Accept(); } } } private void s_OnImReceived(AccSession session, IAccImSession piImSession, IAccParticipant piSender, IAccIm piIm) { Console.WriteLine("<*{0}*> {1}", piSender.Name, piIm.Text); } private void s_OnRequestServiceResult(AccSession session, int transId, AccResult hr, string host, int port, object cookie) { // check the transId to make sure we made the request foreach (int i in transIdMap) { if (transId == i) { // we know we have our request, now load the URL in a new default browser // window using the host param. System.Diagnostics.Process.Start(host); } } } private void s_OnUserRequestPropertyResult(AccSession session, IAccUser user, AccUserProp Property, int transId, AccResult hr, object propertyValue) { // check the transId to make sure we made the request foreach (int i in transIdMap) { if (transId == i) { // take the propertyValue and typecast it to an IAccIm // get the html IAccIm im = (IAccIm) propertyValue; string text = im.GetConvertedText("text/html"); // take the string and display it in a browser // to keep the sample simple we will just write to file // and load file in the browser TextWriter tw = new StreamWriter("c:\buddyInfo.html"); // write a line of text to the file tw.WriteLine(text); // close the stream tw.Close(); System.Diagnostics.Process.Start("c:\buddyInfo.html"); } } } } }