Commits

Ryan Stecker committed 1371500

Added SteamContext.
Todo: SkypeContext.

  • Participants
  • Parent commits 23d7f8d
  • Branches skypestatus

Comments (0)

Files changed (4)

File Projects/SkypeStatus/SkypeStatus/Contexts/SteamContext.cs

+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Steam4NET;
+using HSteamPipe = System.Int32;
+using HSteamUser = System.Int32;
+
+namespace SkypeStatus
+{
+    class SteamException : Exception
+    {
+        public SteamException( string msg )
+            : base( msg )
+        {
+        }
+    }
+
+    static class SteamContext
+    {
+        public static ISteamClient009 SteamClient { get; private set; }
+
+        public static HSteamPipe Pipe { get; private set; }
+        public static HSteamUser User { get; private set; }
+
+        public static ISteamUser015 SteamUser { get; private set; }
+        public static ISteamFriends009 SteamFriends { get; private set; }
+        public static ISteamApps001 SteamApps { get; private set; }
+
+        public static Callback<PersonaStateChange_t> PersonaStateChange = new Callback<PersonaStateChange_t>();
+
+        public static void Init()
+        {
+
+            if ( !Steamworks.Load() )
+            {
+                throw new SteamException( "Unable to load steamclient library." );
+            }
+
+            if ( SteamClient == null )
+            {
+                SteamClient = Steamworks.CreateInterface<ISteamClient009>();
+
+                if ( SteamClient == null )
+                {
+                    throw new SteamException( "Unable to get ISteamClient interface." );
+                }
+            }
+
+            if ( Pipe == 0 )
+            {
+                Pipe = SteamClient.CreateSteamPipe();
+
+                if ( Pipe == 0 )
+                {
+                    throw new SteamException( "Unable to create steam pipe." );
+                }
+            }
+
+            if ( User == 0 )
+            {
+                User = SteamClient.ConnectToGlobalUser( Pipe );
+
+                if ( User == 0 )
+                {
+                    throw new SteamException( "Unable to connect to global user." );
+                }
+            }
+
+            if ( SteamUser == null )
+            {
+                SteamUser = SteamClient.GetISteamUser<ISteamUser015>( User, Pipe );
+
+                if ( SteamUser == null )
+                {
+                    throw new SteamException( "Unable to get ISteamUser interface." );
+                }
+            }
+
+            if ( SteamFriends == null )
+            {
+                SteamFriends = SteamClient.GetISteamFriends<ISteamFriends009>( User, Pipe );
+
+                if ( SteamFriends == null )
+                {
+                    throw new SteamException( "Unable to get ISteamFriends interface." );
+                }
+            }
+
+            if ( SteamApps == null )
+            {
+                SteamApps = SteamClient.GetISteamApps<ISteamApps001>( User, Pipe );
+
+                if ( SteamApps == null )
+                {
+                    throw new SteamException( "Unable to get ISteamApps interface." );
+                }
+            }
+
+            CallbackDispatcher.SpawnDispatchThread( Pipe );
+
+        }
+
+        public static void Shutdown()
+        {
+
+            CallbackDispatcher.StopDispatchThread( Pipe );
+
+            if ( SteamClient != null && User != 0 )
+            {
+                SteamClient.ReleaseUser( Pipe, User );
+            }
+
+            if ( SteamClient != null && Pipe != 0 )
+            {
+                SteamClient.ReleaseSteamPipe( Pipe );
+            }
+
+        }
+    }
+}

File Projects/SkypeStatus/SkypeStatus/SkypeStatus.csproj

     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Contexts\SteamContext.cs" />
     <Compile Include="UI\MainForm.cs">
       <SubType>Form</SubType>
     </Compile>
       <Name>Steam4NET2 %282010%29</Name>
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup>
+    <COMReference Include="SKYPE4COMLib">
+      <Guid>{03282B5D-B38F-469D-849A-09B0A7F4881B}</Guid>
+      <VersionMajor>1</VersionMajor>
+      <VersionMinor>0</VersionMinor>
+      <Lcid>0</Lcid>
+      <WrapperTool>tlbimp</WrapperTool>
+      <Isolated>False</Isolated>
+      <EmbedInteropTypes>True</EmbedInteropTypes>
+    </COMReference>
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.

File Projects/SkypeStatus/SkypeStatus/UI/MainForm.Designer.cs

         /// </summary>
         private void InitializeComponent()
         {
+            this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
+            this.panel1 = new System.Windows.Forms.Panel();
+            this.lblSteam = new System.Windows.Forms.Label();
+            this.lblSkype = new System.Windows.Forms.Label();
+            this.btnSteamAttach = new System.Windows.Forms.Button();
+            this.btnSkypeAttach = new System.Windows.Forms.Button();
+            this.txtLog = new System.Windows.Forms.TextBox();
+            this.tableLayoutPanel1.SuspendLayout();
+            this.panel1.SuspendLayout();
             this.SuspendLayout();
             // 
+            // tableLayoutPanel1
+            // 
+            this.tableLayoutPanel1.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.Single;
+            this.tableLayoutPanel1.ColumnCount = 2;
+            this.tableLayoutPanel1.ColumnStyles.Add( new System.Windows.Forms.ColumnStyle( System.Windows.Forms.SizeType.Percent, 50F ) );
+            this.tableLayoutPanel1.ColumnStyles.Add( new System.Windows.Forms.ColumnStyle( System.Windows.Forms.SizeType.Percent, 50F ) );
+            this.tableLayoutPanel1.Controls.Add( this.btnSkypeAttach, 1, 1 );
+            this.tableLayoutPanel1.Controls.Add( this.lblSteam, 0, 0 );
+            this.tableLayoutPanel1.Controls.Add( this.lblSkype, 0, 1 );
+            this.tableLayoutPanel1.Controls.Add( this.btnSteamAttach, 1, 0 );
+            this.tableLayoutPanel1.Controls.Add( this.txtLog, 0, 2 );
+            this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.tableLayoutPanel1.Location = new System.Drawing.Point( 3, 3 );
+            this.tableLayoutPanel1.Name = "tableLayoutPanel1";
+            this.tableLayoutPanel1.RowCount = 3;
+            this.tableLayoutPanel1.RowStyles.Add( new System.Windows.Forms.RowStyle( System.Windows.Forms.SizeType.Percent, 25F ) );
+            this.tableLayoutPanel1.RowStyles.Add( new System.Windows.Forms.RowStyle( System.Windows.Forms.SizeType.Percent, 25F ) );
+            this.tableLayoutPanel1.RowStyles.Add( new System.Windows.Forms.RowStyle( System.Windows.Forms.SizeType.Percent, 50F ) );
+            this.tableLayoutPanel1.Size = new System.Drawing.Size( 429, 275 );
+            this.tableLayoutPanel1.TabIndex = 0;
+            // 
+            // panel1
+            // 
+            this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+            this.panel1.Controls.Add( this.tableLayoutPanel1 );
+            this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.panel1.Location = new System.Drawing.Point( 0, 0 );
+            this.panel1.Name = "panel1";
+            this.panel1.Padding = new System.Windows.Forms.Padding( 3 );
+            this.panel1.Size = new System.Drawing.Size( 437, 283 );
+            this.panel1.TabIndex = 1;
+            // 
+            // lblSteam
+            // 
+            this.lblSteam.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.lblSteam.AutoSize = true;
+            this.lblSteam.Location = new System.Drawing.Point( 4, 1 );
+            this.lblSteam.Name = "lblSteam";
+            this.lblSteam.Size = new System.Drawing.Size( 207, 67 );
+            this.lblSteam.TabIndex = 0;
+            this.lblSteam.Text = "Steam Status: Unknown";
+            this.lblSteam.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            // 
+            // lblSkype
+            // 
+            this.lblSkype.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.lblSkype.AutoSize = true;
+            this.lblSkype.Location = new System.Drawing.Point( 4, 69 );
+            this.lblSkype.Name = "lblSkype";
+            this.lblSkype.Size = new System.Drawing.Size( 207, 67 );
+            this.lblSkype.TabIndex = 1;
+            this.lblSkype.Text = "Skype Status: Unknown";
+            this.lblSkype.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            // 
+            // btnSteamAttach
+            // 
+            this.btnSteamAttach.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.btnSteamAttach.Location = new System.Drawing.Point( 218, 4 );
+            this.btnSteamAttach.Name = "btnSteamAttach";
+            this.btnSteamAttach.Size = new System.Drawing.Size( 207, 61 );
+            this.btnSteamAttach.TabIndex = 2;
+            this.btnSteamAttach.Text = "Attach";
+            this.btnSteamAttach.UseVisualStyleBackColor = true;
+            // 
+            // btnSkypeAttach
+            // 
+            this.btnSkypeAttach.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.btnSkypeAttach.Location = new System.Drawing.Point( 218, 72 );
+            this.btnSkypeAttach.Name = "btnSkypeAttach";
+            this.btnSkypeAttach.Size = new System.Drawing.Size( 207, 61 );
+            this.btnSkypeAttach.TabIndex = 3;
+            this.btnSkypeAttach.Text = "Attach";
+            this.btnSkypeAttach.UseVisualStyleBackColor = true;
+            // 
+            // txtLog
+            // 
+            this.txtLog.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.tableLayoutPanel1.SetColumnSpan( this.txtLog, 2 );
+            this.txtLog.Location = new System.Drawing.Point( 4, 140 );
+            this.txtLog.Multiline = true;
+            this.txtLog.Name = "txtLog";
+            this.txtLog.Size = new System.Drawing.Size( 421, 131 );
+            this.txtLog.TabIndex = 4;
+            // 
             // MainForm
             // 
             this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 13F );
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.ClientSize = new System.Drawing.Size( 284, 262 );
+            this.ClientSize = new System.Drawing.Size( 437, 283 );
+            this.Controls.Add( this.panel1 );
             this.Name = "MainForm";
             this.Text = "Skype Status";
+            this.tableLayoutPanel1.ResumeLayout( false );
+            this.tableLayoutPanel1.PerformLayout();
+            this.panel1.ResumeLayout( false );
             this.ResumeLayout( false );
 
         }
 
         #endregion
+
+        private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
+        private System.Windows.Forms.Panel panel1;
+        private System.Windows.Forms.Button btnSkypeAttach;
+        private System.Windows.Forms.Label lblSteam;
+        private System.Windows.Forms.Label lblSkype;
+        private System.Windows.Forms.Button btnSteamAttach;
+        private System.Windows.Forms.TextBox txtLog;
     }
 }
 

File Projects/SkypeStatus/SkypeStatus/UI/MainForm.cs

 using System.Linq;
 using System.Text;
 using System.Windows.Forms;
+using Steam4NET;
 
 namespace SkypeStatus
 {
     public partial class MainForm : Form
     {
+        bool steamAttached, skypeAttached;
+
+
         public MainForm()
         {
+            SkypeContext.Denied += SkypeContext_Denied;
+            SkypeContext.Ready += SkypeContext_Ready;
+
+            SteamContext.PersonaStateChange.OnRun += PersonaStateChange_OnRun;
+
             InitializeComponent();
+
+            AttachSteam();
+            AttachSkype();
         }
+
+        void PersonaStateChange_OnRun( PersonaStateChange_t param )
+        {
+            if ( param.m_ulSteamID != SteamContext.SteamUser.GetSteamID() )
+            {
+                // we're only interested in our own persona changes
+                return;
+            }
+
+            if ( !SkypeContext.IsReady )
+            {
+                Log( "Warning: Detect game launch, but skype isn't attached!" );
+                return;
+            }
+
+            if ( ( param.m_nChangeFlags & EPersonaChange.k_EPersonaChangeGamePlayed ) != 0 )
+            {
+                this.Invoke( new MethodInvoker( () =>
+                {
+                    UpdateSkypeMood( param );
+                } ) );
+            }
+        }
+
+        private void UpdateSkypeMood( PersonaStateChange_t param )
+        {
+            FriendGameInfo_t gameInfo = new FriendGameInfo_t();
+
+            if ( !SteamContext.SteamFriends.GetFriendGamePlayed( param.m_ulSteamID, ref gameInfo ) )
+            {
+                // this happens when we stop playing a game
+                SetSkypeMood( "Stopped playing" );
+                return;
+            }
+
+            CGameID gameId = gameInfo.m_gameID;
+
+            if ( gameId.AppType != CGameID.EGameID.k_EGameIDTypeApp )
+            {
+                Log( "Info: Detected game launch, but wasn't steam game. Only official steam apps are supported!" );
+                return;
+            }
+
+            StringBuilder sb = new StringBuilder( 256 );
+            SteamContext.SteamApps.GetAppData( gameId.AppID, "name", sb );
+
+            string name = sb.ToString();
+
+            if ( string.IsNullOrEmpty( name ) )
+            {
+                Log( "Warning: Detect game launch, but wasn't able to get the name! AppID: {0}, GameID: {1}", gameId.AppID, gameId.ConvertToUint64() );
+                return;
+            }
+
+            SetSkypeMood( "Now Playing: ", name );
+        }
+
+        private void SetSkypeMood( string steamGame, params object[] args )
+        {
+            try
+            {
+                SkypeContext.Skype.CurrentUserProfile.MoodText = string.Format( "[Steam] {0}", string.Format( steamGame, args ) );
+            }
+            catch ( Exception ex )
+            {
+                Log( "Error: Unable to set skype mood! {0}", ex );
+            }
+        }
+
+
+        void AttachSteam()
+        {
+            Log( "Trying to attach Steam..." );
+
+            try
+            {
+
+                SteamContext.Init();
+
+                steamAttached = true;
+                lblSteam.Text = "Steam Status: Ready";
+                btnSteamAttach.Enabled = false;
+
+                Log( "Done!" );
+
+            }
+            catch ( SteamException ex )
+            {
+
+                steamAttached = false;
+                lblSteam.Text = string.Format( "Steam Status: Error: {0}", ex.Message );
+                btnSteamAttach.Enabled = true;
+
+                Log( "Error: {0}", ex );
+
+            }
+        }
+
+        void AttachSkype()
+        {
+            Log( "Trying to attach Skype..." );
+            SkypeContext.Init();
+        }
+
+        void Log( string msg, params object[] args )
+        {
+            string logText = string.Format
+            (
+                "[{0}] {1}\r\n",
+                DateTime.Now.ToShortTimeString(),
+                string.Format( msg, args )
+            );
+
+            txtLog.AppendText( logText );
+        }
+
+
+        private void SkypeContext_Ready( object sender, EventArgs e )
+        {
+            this.Invoke( new MethodInvoker( () =>
+            {
+                skypeAttached = true;
+                lblSkype.Text = "Skype Status: Ready";
+                btnSkypeAttach.Enabled = false;
+
+                Log( "Done!" );
+            } ) );
+        }
+
+        private void SkypeContext_Denied( object sender, EventArgs e )
+        {
+            this.Invoke( new MethodInvoker( () =>
+            {
+                skypeAttached = false;
+                lblSkype.Text = "Skype Status: Access Denied!";
+                btnSkypeAttach.Enabled = true;
+
+                Log( "Error: Access to Skype was denied. Please press the \"attach\" button and allow access." );
+            } ) );
+        }
+
+        private void btnSteamAttach_Click( object sender, EventArgs e )
+        {
+            AttachSteam();
+        }
+
+        private void btnSkypeAttach_Click( object sender, EventArgs e )
+        {
+            AttachSkype();
+        }
+
+        private void MainForm_FormClosing( object sender, FormClosingEventArgs e )
+        {
+            SteamContext.Shutdown();
+        }
+
     }
 }