csharp/00000vish/Steam-Two/Steam%20Two/SteamBotController.cs

SteamBotController.cs
using System;
using System.Collections;
using System.IO;
using System.Security.Cryptography;
using System.Threading;
using System.Windows;
using SteamKit2;
using SteamKit2.Internal;

namespace SteamTwo
{
    static clast SteamBotController
    { 
        private static bool isRunning;
        public static bool loggedIn = false;
        public static bool chatOpen = false;
        private static SteamUser steamUser;
        private static SteamClient steamClient;
        private static CallbackManager manager;
        private static SteamFriends steamFriends;
        private static string user, past;
        private static string authCode, twoFactorAuth;
        private static Thread workThread = null;       

        public static void steamLogin(String username, String pastword)
        {           
            workThread = new Thread(steamLogin);
            user = username;
            past = pastword;
            workThread.Start();
        }

        public static void logBotIn()
        {
            workThread = new Thread(steamLogin);
            workThread.Start();
        }

        public static void logBotOff()
        {
            steamUser.LogOff();
            workThread.Abort();
            loggedIn = false;
        }

        private static void steamLogin()
        {

            // create our steamclient instance
            var configuration = SteamConfiguration.Create(b => b.WithProtocolTypes(ProtocolTypes.Tcp));
            steamClient = new SteamClient();
            // create the callback manager which will route callbacks to function calls
            manager = new CallbackManager(steamClient);

            // get the steamuser handler, which is used for logging on after successfully connecting
            steamUser = steamClient.GetHandler();
            steamFriends = steamClient.GetHandler();
            // register a few callbacks we're interested in
            // these are registered upon creation to a callback manager, which will then route the callbacks
            // to the functions specified
            manager.Subscribe(OnConnected);
            manager.Subscribe(OnDisconnected);

            manager.Subscribe(OnLoggedOn);
            manager.Subscribe(OnLoggedOff);

            // this callback is triggered when the steam servers wish for the client to store the sentry file
            manager.Subscribe(OnMachineAuth);



            // we use the following callbacks for friends related activities
            manager.Subscribe(OnAccountInfo);
            manager.Subscribe(OnFriendsList);
            manager.Subscribe(OnPersonaState);
            manager.Subscribe(OnFriendAdded);
            manager.Subscribe(OnChatMessage);

            isRunning = true;

            Console.WriteLine("Connecting to Steam...");

            // initiate the connection
            steamClient.Connect();

            // create our callback handling loop
            while (isRunning)
            {
                // in order for the callbacks to get routed, they need to be handled by the manager
                manager.RunWaitCallbacks(TimeSpan.FromSeconds(1));
            }
        }

        static void OnConnected(SteamClient.ConnectedCallback callback)
        {
            Console.WriteLine("Connected to Steam! Logging in '{0}'...", user);

            byte[] sentryHash = null;
            if (File.Exists("sentry.bin"))
            {
                // if we have a saved sentry file, read and sha-1 hash it
                byte[] sentryFile = File.ReadAllBytes("sentry.bin");
                sentryHash = CryptoHelper.SHAHash(sentryFile);
            }

            steamUser.LogOn(new SteamUser.LogOnDetails
            {
                Username = user,
                Pastword = past,

                // in this sample, we past in an additional authcode
                // this value will be null (which is the default) for our first logon attempt
                AuthCode = authCode,

                // if the account is using 2-factor auth, we'll provide the two factor code instead
                // this will also be null on our first logon attempt
                TwoFactorCode = twoFactorAuth,

                // our subsequent logons use the hash of the sentry file as proof of ownership of the file
                // this will also be null for our first (no authcode) and second (authcode only) logon attempts
                SentryFileHash = sentryHash,
            });
        }



        static void OnDisconnected(SteamClient.DisconnectedCallback callback)
        {
            // after recieving an AccountLogonDenied, we'll be disconnected from steam
            // so after we read an authcode from the user, we need to reconnect to begin the logon flow again

            Console.WriteLine("Disconnected from Steam, reconnecting in 5...");

            Thread.Sleep(TimeSpan.FromSeconds(5));

            //means disconnect was not users request so we reconnect
            if (loggedIn)
            {
                steamClient.Connect();
            }
        }

        static void OnLoggedOn(SteamUser.LoggedOnCallback callback)
        {
            bool isSteamGuard = callback.Result == EResult.AccountLogonDenied;
            bool is2FA = callback.Result == EResult.AccountLoginDeniedNeedTwoFactor;

            if (isSteamGuard || is2FA)
            {
                Console.WriteLine("This account is SteamGuard protected!");

                if (is2FA)
                {
                    Application.Current.Dispatcher.Invoke((Action)delegate
                    {
                        //Console.Write("Please enter your 2 factor auth code from your authenticator app: ");
                        // MainWindow.currentHandle.Show();
                        GetInput GI = new GetInput();
                        twoFactorAuth = GI.Show("Authentication", "Please enter your 2 factor auth code from your authenticator app below", false);
                        GI.Close();
                    });
                }
                else
                {
                    Application.Current.Dispatcher.Invoke((Action)delegate
                    {
                        //Console.Write("Please enter the auth code sent to the email at {0}: ", callback.EmailDomain);
                        //MainWindow.currentHandle.Show();
                        GetInput GI = new GetInput();
                        authCode = GI.Show("Authentication", "Please enter the auth code sent to the email at " + callback.EmailDomain, false);
                        GI.Close();
                    });
                }

                return;
            }

            if (callback.Result != EResult.OK)
            {
                Console.WriteLine("Unable to logon to Steam: {0} / {1}", callback.Result, callback.ExtendedResult);

                isRunning = false;
                return;
            }

            Console.WriteLine("Successfully logged on!");
            loggedIn = true;
            // at this point, we'd be able to perform actions on Steam
        }

        static void OnLoggedOff(SteamUser.LoggedOffCallback callback)
        {            
            Console.WriteLine("Logged off of Steam: {0}", callback.Result);
        }

        static void OnMachineAuth(SteamUser.UpdateMachineAuthCallback callback)
        {
            Console.WriteLine("Updating sentryfile...");

            // write out our sentry file
            // ideally we'd want to write to the filename specified in the callback
            // but then this sample would require more code to find the correct sentry file to read during logon
            // for the sake of simplicity, we'll just use "sentry.bin"

            int fileSize;
            byte[] sentryHash;
            using (var fs = File.Open("sentry.bin", FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                fs.Seek(callback.Offset, SeekOrigin.Begin);
                fs.Write(callback.Data, 0, callback.BytesToWrite);
                fileSize = (int)fs.Length;

                fs.Seek(0, SeekOrigin.Begin);
                using (var sha = SHA1.Create())
                {
                    sentryHash = sha.ComputeHash(fs);
                }
            }

            // inform the steam servers that we're accepting this sentry file
            steamUser.SendMachineAuthResponse(new SteamUser.MachineAuthDetails
            {
                JobID = callback.JobID,

                FileName = callback.FileName,

                BytesWritten = callback.BytesToWrite,
                FileSize = fileSize,
                Offset = callback.Offset,

                Result = EResult.OK,
                LastError = 0,

                OneTimePastword = callback.OneTimePastword,

                SentryFileHash = sentryHash,
            });

            Console.WriteLine("Done!");
        }

        static void OnAccountInfo(SteamUser.AccountInfoCallback callback)
        {
            // before being able to interact with friends, you must wait for the account info callback
            // this callback is posted shortly after a successful logon

            // at this point, we can go online on friends, so lets do that
            steamFriends.SetPersonaState(EPersonaState.Online);
        }

        static void OnFriendsList(SteamFriends.FriendsListCallback callback)
        {
            // at this point, the client has received it's friends list

            int friendCount = steamFriends.GetFriendCount();

            Console.WriteLine("We have {0} friends", friendCount);

            for (int x = 0; x < friendCount; x++)
            {
                // steamids identify objects that exist on the steam network, such as friends, as an example
                SteamID steamIdFriend = steamFriends.GetFriendByIndex(x);


                AccountController.getAccount(user).AddFriend(new Friend() { steamFrindsID = "" + steamIdFriend.ConvertToUInt64().ToString(), chatLog = new ArrayList(), SteamIDObject = steamIdFriend });

                // we'll just display the STEAM_ rendered version
                Console.WriteLine("Friend: {0}", steamIdFriend.Render());
            }

            // we can also iterate over our friendslist to accept or decline any pending invites
            if (SteamTwoProperties.jsonSetting.autoAddFriendSetting)
            {
                foreach (var friend in callback.FriendList)
                {
                    if (friend.Relationship == EFriendRelationship.RequestRecipient)
                    {
                        // this user has added us, let's add him back
                        steamFriends.AddFriend(friend.SteamID);
                    }
                }
            }
        }

        static void OnFriendAdded(SteamFriends.FriendAddedCallback callback)
        {
            // someone accepted our friend request, or we accepted one
            Console.WriteLine("{0} is now a friend", callback.PersonaName);
        }

        static void OnPersonaState(SteamFriends.PersonaStateCallback callback)
        {
            // this callback is received when the persona state (friend information) of a friend changes

            // for this sample we'll simply display the names of the friends            
            AccountController.getAccount(user).setFriendsName(new Friend() { name = callback.Name, steamFrindsID = callback.FriendID.ConvertToUInt64().ToString() });
            Console.WriteLine("State change: {0}", callback.Name);
        }

        static void OnChatMessage(SteamFriends.FriendMsgCallback callback)
        {
            if (callback.EntryType == EChatEntryType.ChatMsg)
            {             
                if (SteamTwoProperties.jsonSetting.notifyOnMessageSetting && !chatOpen)
                {
                    System.Windows.Forms.MessageBox.Show("New Message!" , "Steam Two" , System.Windows.Forms.MessageBoxButtons.OK,System.Windows.Forms.MessageBoxIcon.Information);
                }
                if (SteamTwoProperties.jsonSetting.forwardCheckSetting)
                {
                    steamFriends.SendChatMessage(new SteamID(SteamTwoProperties.jsonSetting.forwardSetting), EChatEntryType.ChatMsg, "  " + AccountController.getAccount(user).getFriendsName(new Friend() { steamFrindsID = callback.Sender.ConvertToUInt64().ToString() }) + " : " + callback.Message.ToString());}
                AccountController.getAccount(user).updateChatLogs(new Friend() { steamFrindsID =callback.Sender.ConvertToUInt64().ToString() }, callback.Message.ToString(), false);
            }
        }

        public static String getSteamUserID()
        {
            if (steamUser != null)
            {
                return steamUser.SteamID.ConvertToUInt64().ToString();
            }
            return "";
        }

        public static void sendChatMessage(SteamID id, String msg)
        {
            AccountController.getAccount(user).updateChatLogs(new Friend() { steamFrindsID = id.ConvertToUInt64().ToString()},msg,true);
            steamFriends.SendChatMessage(id , EChatEntryType.ChatMsg, msg);
        }

        public static void playGame(int gameID)
        {
            var request = new ClientMsgProtobuf(EMsg.ClientGamesPlayed);

            request.Body.games_played.Add(new CMsgClientGamesPlayed.GamePlayed
            {
                game_id = new GameID(gameID),
            });
            steamClient.Send(request);
        }
    }
}