public GameCoordinator(uint appID, SteamClient steamClient, CallbackManager callbackManager) { // Map gc messages to our callback functions GCMessageMap = new Dictionary<uint, Action<IPacketGCMsg>> { { (uint)EGCBaseClientMsg.k_EMsgGCClientWelcome, OnClientWelcome }, { (uint)EGCItemMsg.k_EMsgGCUpdateItemSchema, OnItemSchemaUpdate }, { (uint)EGCBaseMsg.k_EMsgGCSystemMessage, OnSystemMessage }, { (uint)EGCBaseClientMsg.k_EMsgGCClientConnectionStatus, OnClientConnectionStatus }, { (uint)4008 /* TF2's k_EMsgGCClientGoodbye */, OnClientConnectionStatus } }; this.AppID = appID; this.SteamClient = steamClient; this.SteamGameCoordinator = SteamClient.GetHandler<SteamGameCoordinator>(); this.Name = string.Format("GC {0}", appID); // Make sure Steam knows we're playing the game Timer = new System.Timers.Timer(); Timer.Elapsed += OnTimerPlayGame; Timer.Interval = TimeSpan.FromMinutes(5).TotalMilliseconds; Timer.Start(); Timer = new System.Timers.Timer(); Timer.Elapsed += OnTimer; callbackManager.Register(new Callback<SteamGameCoordinator.MessageCallback>(OnGameCoordinatorMessage)); }
public GameCoordinator(SteamClient steamClient, CallbackManager manager) { SessionMap = new Dictionary<uint, SessionInfo>(); // Map gc messages to our callback functions MessageMap = new Dictionary<uint, Action<uint, IPacketGCMsg>> { { (uint)EGCBaseClientMsg.k_EMsgGCClientConnectionStatus, OnConnectionStatus }, { (uint)EGCBaseClientMsg.k_EMsgGCClientWelcome, OnWelcome }, { (uint)EGCItemMsg.k_EMsgGCUpdateItemSchema, OnItemSchemaUpdate }, { (uint)EGCItemMsg.k_EMsgGCClientVersionUpdated, OnVersionUpdate }, { (uint)EGCBaseMsg.k_EMsgGCSystemMessage, OnSystemMessage }, // TF2 specific messages { k_EMsgGCClientGoodbye, OnConnectionStatus }, { (uint)EGCItemMsg.k_EMsgGCGoldenWrenchBroadcast, OnWrenchBroadcast }, { k_EMsgGCTFSpecificItemBroadcast, OnItemBroadcast }, }; SteamGameCoordinator = steamClient.GetHandler<SteamGameCoordinator>(); SessionTimer = new Timer(); SessionTimer.Interval = TimeSpan.FromSeconds(30).TotalMilliseconds; SessionTimer.Elapsed += OnSessionTick; SessionTimer.Start(); manager.Subscribe<SteamGameCoordinator.MessageCallback>(OnGameCoordinatorMessage); manager.Subscribe<SteamUser.LoggedOffCallback>(OnLoggedOff); manager.Subscribe<SteamClient.DisconnectedCallback>(OnDisconnected); }
protected override void OnGCMessage( SteamGameCoordinator.MessageCallback callback ) { base.OnGCMessage( callback ); var dispatchMap = new Dictionary<uint, Action<IPacketGCMsg>> { { EGCMsg.ClientWelcome, OnClientWelcome }, { EGCMsg.SourceTVGamesResponse, OnSourceTVGames }, { EGCMsg.WatchGameResponse, OnWatchGame }, }; Action<IPacketGCMsg> func; if ( !dispatchMap.TryGetValue( callback.EMsg, out func ) ) return; func( callback.Message ); }
public DotaClient( string userName, string password, uint matchId ) { this.userName = userName; this.password = password; this.matchId = matchId; client = new SteamClient(); // get our handlers user = client.GetHandler<SteamUser>(); gameCoordinator = client.GetHandler<SteamGameCoordinator>(); // setup callbacks callbackMgr = new CallbackManager( client ); new Callback<SteamClient.ConnectedCallback>( OnConnected, callbackMgr ); new Callback<SteamUser.LoggedOnCallback>( OnLoggedOn, callbackMgr ); new Callback<SteamGameCoordinator.MessageCallback>( OnGCMessage, callbackMgr ); }
private void OnGameCoordinatorMessage(SteamGameCoordinator.MessageCallback callback) { Action<IPacketGCMsg> callbackFunction; if (GCMessageMap.TryGetValue(callback.EMsg, out callbackFunction)) { callbackFunction(callback.Message); } else { Log.WriteDebug(Name, "Unhandled GC message - EMsg: {0} ({1})", callback.EMsg, GetEMsgDisplayString((int)callback.EMsg)); } // If we hear from GC, but it's not hello, keep bugging it if (!Timer.Enabled && LastStatus == GCConnectionStatus.GCConnectionStatus_NO_SESSION) { Timer.Interval = TimeSpan.FromSeconds(60).TotalMilliseconds; Timer.Start(); } }
public GameCoordinator(uint appID, SteamClient steamClient, CallbackManager callbackManager) { // Map gc messages to our callback functions GCMessageMap = new Dictionary<uint, Action<IPacketGCMsg>> { { (uint)4008 /* TF2's k_EMsgGCClientGoodbye */, OnConnectionStatus }, { (uint)EGCBaseClientMsg.k_EMsgGCServerConnectionStatus, OnConnectionStatus }, { (uint)EGCBaseClientMsg.k_EMsgGCServerWelcome, OnWelcome }, { (uint)EGCItemMsg.k_EMsgGCUpdateItemSchema, OnItemSchemaUpdate }, { (uint)EGCItemMsg.k_EMsgGCServerVersionUpdated, OnVersionUpdate }, { (uint)EGCBaseMsg.k_EMsgGCSystemMessage, OnSystemMessage } }; this.AppID = appID; this.SteamClient = steamClient; this.SteamGameCoordinator = SteamClient.GetHandler<SteamGameCoordinator>(); this.Name = string.Format("GC {0}", appID); Timer = new System.Timers.Timer(); Timer.Elapsed += OnTimer; callbackManager.Register(new Callback<SteamGameCoordinator.MessageCallback>(OnGameCoordinatorMessage)); }
// called when a gamecoordinator (GC) message arrives // these kinds of messages are designed to be game-specific // in this case, we'll be handling dota's GC messages void OnGCMessage( SteamGameCoordinator.MessageCallback callback ) { // setup our dispatch table for messages // this makes the code cleaner and easier to maintain var messageMap = new Dictionary<uint, Action<IPacketGCMsg>> { { ( uint )EGCBaseMsg.k_EMsgGCClientWelcome, OnClientWelcome }, { ( uint )EDOTAGCMsg.k_EMsgGCMatchDetailsResponse, OnMatchDetails }, }; Action<IPacketGCMsg> func; if ( !messageMap.TryGetValue( callback.EMsg, out func ) ) { // this will happen when we recieve some GC messages that we're not handling // this is okay because we're handling every essential message, and the rest can be ignored return; } func( callback.Message ); }
public Bot(Configuration.BotInfo config, string apiKey, UserHandlerCreator handlerCreator, bool debug = false, bool process = false) { userHandlers = new Dictionary<SteamID, UserHandler>(); logOnDetails = new SteamUser.LogOnDetails { Username = config.Username, Password = config.Password }; DisplayName = config.DisplayName; ChatResponse = config.ChatResponse; MaximumTradeTime = config.MaximumTradeTime; MaximumActionGap = config.MaximumActionGap; DisplayNamePrefix = config.DisplayNamePrefix; tradePollingInterval = config.TradePollingInterval <= 100 ? 800 : config.TradePollingInterval; schemaLang = config.SchemaLang != null && config.SchemaLang.Length == 2 ? config.SchemaLang.ToLower() : "en"; Admins = config.Admins; ApiKey = !String.IsNullOrEmpty(config.ApiKey) ? config.ApiKey : apiKey; isProccess = process; try { if( config.LogLevel != null ) { consoleLogLevel = (Log.LogLevel)Enum.Parse(typeof(Log.LogLevel), config.LogLevel, true); Console.WriteLine(@"(Console) LogLevel configuration parameter used in bot {0} is depreciated and may be removed in future versions. Please use ConsoleLogLevel instead.", DisplayName); } else consoleLogLevel = (Log.LogLevel)Enum.Parse(typeof(Log.LogLevel), config.ConsoleLogLevel, true); } catch (ArgumentException) { Console.WriteLine(@"(Console) ConsoleLogLevel invalid or unspecified for bot {0}. Defaulting to ""Info""", DisplayName); consoleLogLevel = Log.LogLevel.Info; } try { fileLogLevel = (Log.LogLevel)Enum.Parse(typeof(Log.LogLevel), config.FileLogLevel, true); } catch (ArgumentException) { Console.WriteLine(@"(Console) FileLogLevel invalid or unspecified for bot {0}. Defaulting to ""Info""", DisplayName); fileLogLevel = Log.LogLevel.Info; } logFile = config.LogFile; Log = new Log(logFile, DisplayName, consoleLogLevel, fileLogLevel); createHandler = handlerCreator; BotControlClass = config.BotControlClass; SteamWeb = new SteamWeb(); // Hacking around https ServicePointManager.ServerCertificateValidationCallback += SteamWeb.ValidateRemoteCertificate; Log.Debug ("Initializing Steam Bot..."); SteamClient = new SteamClient(); SteamClient.AddHandler(new SteamNotifications()); SteamTrade = SteamClient.GetHandler<SteamTrading>(); SteamUser = SteamClient.GetHandler<SteamUser>(); SteamFriends = SteamClient.GetHandler<SteamFriends>(); SteamGameCoordinator = SteamClient.GetHandler<SteamGameCoordinator>(); SteamNotifications = SteamClient.GetHandler<SteamNotifications>(); botThread = new BackgroundWorker { WorkerSupportsCancellation = true }; botThread.DoWork += BackgroundWorkerOnDoWork; botThread.RunWorkerCompleted += BackgroundWorkerOnRunWorkerCompleted; botThread.RunWorkerAsync(); }
public Bot(Configuration.BotInfo config, string apiKey, UserHandlerCreator handlerCreator, bool debug = false, bool process = false) { logOnDetails = new SteamUser.LogOnDetails { Username = config.Username, Password = config.Password }; DisplayName = config.DisplayName; ChatResponse = config.ChatResponse; MaximumTradeTime = config.MaximumTradeTime; MaximiumActionGap = config.MaximumActionGap; DisplayNamePrefix = config.DisplayNamePrefix; TradePollingInterval = config.TradePollingInterval <= 100 ? 800 : config.TradePollingInterval; Admins = config.Admins; this.apiKey = apiKey; this.isprocess = process; try { LogLevel = (Log.LogLevel)Enum.Parse(typeof(Log.LogLevel), config.LogLevel, true); } catch (ArgumentException) { Console.WriteLine("Invalid LogLevel provided in configuration. Defaulting to 'INFO'"); LogLevel = Log.LogLevel.Info; } log = new Log (config.LogFile, this.DisplayName, LogLevel); CreateHandler = handlerCreator; BotControlClass = config.BotControlClass; // Hacking around https ServicePointManager.ServerCertificateValidationCallback += SteamWeb.ValidateRemoteCertificate; log.Debug ("Initializing Steam Bot..."); SteamClient = new SteamClient(); SteamTrade = SteamClient.GetHandler<SteamTrading>(); SteamUser = SteamClient.GetHandler<SteamUser>(); SteamFriends = SteamClient.GetHandler<SteamFriends>(); SteamGameCoordinator = SteamClient.GetHandler<SteamGameCoordinator>(); backgroundWorker = new BackgroundWorker { WorkerSupportsCancellation = true }; backgroundWorker.DoWork += BackgroundWorkerOnDoWork; backgroundWorker.RunWorkerCompleted += BackgroundWorkerOnRunWorkerCompleted; backgroundWorker.RunWorkerAsync(); }
private void OnGameCoordinatorMessage(SteamGameCoordinator.MessageCallback callback) { Action<uint, IPacketGCMsg> callbackFunction; if (MessageMap.TryGetValue(callback.EMsg, out callbackFunction)) { callbackFunction(callback.AppID, callback.Message); } }
void OnGCMessage( SteamGameCoordinator.MessageCallback callback ) { Log.WriteDebug( "GCManager", "Got GC message {0}", GetEMsgName( callback.EMsg ) ); var matchingCallbacks = callbacks .Where( call => call.EMsg == callback.EMsg ); foreach ( var call in matchingCallbacks ) { call.Run( callback.Message ); } }
public void OnMessage(SteamGameCoordinator.MessageCallback callback) { if ((uint) EGCBaseClientMsg.k_EMsgGCClientWelcome == callback.EMsg) { var pb = new ClientGCMsgProtobuf<CMsgClientWelcome>(callback.Message); if (ClientVersion != pb.Body.version) { log.WarnFormat( "Version mismatch, Clara ver {0} but GC ver {1}", ClientVersion, pb.Body.version); ClientVersion = pb.Body.version; } log.DebugFormat("Welcomed to version {0}", pb.Body.version); foreach (var cache in pb.Body.outofdate_subscribed_caches) { foreach (var obj in cache.objects) { // TODO: Multiple objects??? Set(cache.owner_soid.id, obj.type_id, obj.object_data[0]); } } using (var stream = new MemoryStream(pb.Body.game_data)) { Account = Serializer.Deserialize<CSODOTAGameAccountClient>(stream); } } else if (callback.EMsg == (uint) EDOTAGCMsg.k_EMsgGCJoinChatChannelResponse) { var pb = new ClientGCMsgProtobuf<CMsgDOTAJoinChatChannelResponse>(callback.Message); Channels[pb.Body.channel_name] = pb.Body.channel_id; } else if ((uint) EDOTAGCMsg.k_EMsgGCWatchGameResponse == callback.EMsg) { var pb = new ClientGCMsgProtobuf<CMsgWatchGameResponse>(callback.Message); WatchResponse = pb.Body; } else if ((uint) ESOMsg.k_ESOMsg_Create == callback.EMsg) { var pb = new ClientGCMsgProtobuf<CMsgSOSingleObject>(callback.Message); Set(pb.Body.owner_soid.id, pb.Body.type_id, pb.Body.object_data); } else if ((uint) ESOMsg.k_ESOMsg_Update == callback.EMsg) { var pb = new ClientGCMsgProtobuf<CMsgSOSingleObject>(callback.Message); Set(pb.Body.owner_soid.id, pb.Body.type_id, pb.Body.object_data); } else if ((uint) ESOMsg.k_ESOMsg_UpdateMultiple == callback.EMsg) { var pb = new ClientGCMsgProtobuf<CMsgSOMultipleObjects>(callback.Message); foreach (var obj in pb.Body.objects_modified) { Set(pb.Body.owner_soid.id, obj.type_id, obj.object_data); } } else if ((uint) ESOMsg.k_ESOMsg_CacheUnsubscribed == callback.EMsg) { var pb = new ClientGCMsgProtobuf<CMsgSOCacheUnsubscribed>(callback.Message); Objects.Remove(pb.Body.owner_soid.id); Active = Active.Where(pair => pair.Value != pb.Body.owner_soid.id) .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); } }
protected virtual void OnGCMessage( SteamGameCoordinator.MessageCallback callback ) { DebugLog.WriteLine( "GCClient", "OnGCMessage: {0}", GetEMsgDisplayString( callback.EMsg ) ); }
public Bot(Configuration.BotInfo config, Log log, string apiKey, UserHandlerCreator handlerCreator, Login _login, bool debug = false) { this.main = _login; logOnDetails = new SteamUser.LogOnDetails { Username = _login.Username, Password = _login.Password }; ChatResponse = ""; TradePollingInterval = 500; Admins = new ulong[1]; Admins[0] = 0; this.apiKey = apiKey; try { LogLevel = (Log.LogLevel)Enum.Parse(typeof(Log.LogLevel), "Debug", true); } catch (ArgumentException) { Console.WriteLine("Invalid LogLevel provided in configuration. Defaulting to 'INFO'"); LogLevel = Log.LogLevel.Info; } this.log = log; CreateHandler = handlerCreator; BotControlClass = "SteamBot.SimpleUserHandler"; // Hacking around https ServicePointManager.ServerCertificateValidationCallback += SteamWeb.ValidateRemoteCertificate; log.Debug ("Initializing Steam account..."); main.Invoke((Action)(() => { main.label_status.Text = "Initializing Steam account..."; })); SteamClient = new SteamClient(); SteamClient.AddHandler(new ClientPlayerNicknameListHandler()); SteamTrade = SteamClient.GetHandler<SteamTrading>(); SteamUser = SteamClient.GetHandler<SteamUser>(); SteamFriends = SteamClient.GetHandler<SteamFriends>(); SteamGameCoordinator = SteamClient.GetHandler<SteamGameCoordinator>(); SteamNicknames = SteamClient.GetHandler<ClientPlayerNicknameListHandler>(); log.Info ("Connecting..."); main.Invoke((Action)(() => { main.label_status.Text = "Connecting to Steam..."; })); SteamClient.Connect(); Thread CallbackThread = new Thread(() => // Callback Handling { while (true) { CallbackMsg msg = SteamClient.WaitForCallback(true); new Thread(() => HandleSteamMessage(msg)).Start(); } }); CallbackThread.Start(); CallbackThread.Join(); log.Success("Done loading account!"); main.Invoke((Action)(() => { main.label_status.Text = "Done loading account!"; })); }
/// <summary> /// Starts the callback thread and connects to Steam via SteamKit2. /// </summary> /// <remarks> /// THIS NEVER RETURNS. /// </remarks> /// <returns><c>true</c>. See remarks</returns> public bool RestartBot() { if (IsRunning) return false; log = new Log(LogFile, this.DisplayName, LogLevel); // Hacking around https ServicePointManager.ServerCertificateValidationCallback += SteamWeb.ValidateRemoteCertificate; log.Debug("Initializing Steam Bot..."); SteamClient = new SteamClient(); SteamTrade = SteamClient.GetHandler<SteamTrading>(); SteamUser = SteamClient.GetHandler<SteamUser>(); SteamFriends = SteamClient.GetHandler<SteamFriends>(); SteamGameCoordinator = SteamClient.GetHandler<SteamGameCoordinator>(); backgroundWorker = new BackgroundWorker { WorkerSupportsCancellation = true }; backgroundWorker.DoWork += BackgroundWorkerOnDoWork; backgroundWorker.RunWorkerCompleted += BackgroundWorkerOnRunWorkerCompleted; backgroundWorker.RunWorkerAsync(); log.Info("Connecting..."); SteamClient.Connect(); IsRunning = true; log.Info("Done Loading Bot!"); return true; // never get here }