/// <summary> /// Create a new game bot /// </summary> /// <param name="details">Auth info</param> /// <param name="reconnectDelay"> /// Delay between reconnection attempts to steam, set to a negative value to disable /// reconnecting /// </param> /// <param name="contrs">Game controllers</param> public DotaBot(SteamUser.LogOnDetails details, double reconnectDelay = 2000) { log = LogManager.GetLogger("Bot " + details.Username); log.Debug("Initializing a new LobbyBot w/username " + details.Username); _logonDetails = details; if (reconnectDelay < 0) { reconnectDelay = 10; _shouldReconnect = false; } _reconnectTimer = new Timer(reconnectDelay); _reconnectTimer.Elapsed += (sender, args) => _state.Fire(Trigger.ConnectRequested); _state = new StateMachine <State, Trigger>(State.SignedOff); _state.OnTransitioned((transition => { log.DebugFormat("{0} => {1}", transition.Source.ToString("G"), transition.Destination.ToString("G")); StateTransitioned?.Invoke(this, transition); })); _state.Configure(State.Conceived) .Permit(Trigger.ShutdownRequested, State.SignedOff); _state.Configure(State.SignedOff) .SubstateOf(State.Conceived) .Ignore(Trigger.SteamDisconnected) .OnEntryFrom(Trigger.SteamInvalidCreds, () => InvalidCreds?.Invoke(this, EventArgs.Empty)) .PermitIf(Trigger.ConnectRequested, State.Steam, () => _isRunning); _state.Configure(State.RetryConnection) .SubstateOf(State.SignedOff) .OnExit(() => _reconnectTimer.Stop()) .OnEntry(() => _reconnectTimer.Start()) .Permit(Trigger.ConnectRequested, State.Steam); _state.Configure(State.Steam) .SubstateOf(State.Conceived) .Permit(Trigger.SteamConnected, State.Dota) .PermitDynamic(Trigger.SteamDisconnected, () => _shouldReconnect ? State.RetryConnection : State.SignedOff) .Permit(Trigger.SteamInvalidCreds, State.SignedOff) .OnEntry(StartSteamConnection) .OnExit(ReleaseSteamConnection); _state.Configure(State.Dota) .SubstateOf(State.Steam) .Permit(Trigger.DotaConnected, State.DotaMenu) .PermitReentry(Trigger.DotaDisconnected) .Permit(Trigger.DotaEnteredLobbyUI, State.DotaLobby) .Permit(Trigger.DotaEnteredLobbyPlay, State.DotaPlay) .OnEntryFrom(Trigger.SteamConnected, StartDotaGCConnection); _state.Configure(State.DotaMenu) .SubstateOf(State.Dota) .Permit(Trigger.DotaEnteredLobbyUI, State.DotaLobby) .Permit(Trigger.DotaEnteredLobbyPlay, State.DotaPlay); _state.Configure(State.DotaLobby) .SubstateOf(State.Dota) .Ignore(Trigger.DotaEnteredLobbyUI) .Permit(Trigger.DotaEnteredLobbyPlay, State.DotaPlay) .Permit(Trigger.DotaNoLobby, State.DotaMenu) .OnEntry(JoinLobbySlot) .OnEntry(JoinLobbyChat) .OnExit(LeaveLobbyChat); _state.Configure(State.DotaPlay) .SubstateOf(State.Dota) .Ignore(Trigger.DotaEnteredLobbyPlay) .Permit(Trigger.DotaEnteredLobbyUI, State.DotaLobby) .Permit(Trigger.DotaNoLobby, State.DotaMenu); }
/// <summary> /// Create a Twitch chatbot. /// </summary> public ChatBot(AuthInfo info, bool whisper, int reconnectTime = 3000) { WhisperClient = whisper; _joinedChannels = new HashSet <string>(); _authInfo = info; _shouldReconnect = reconnectTime > 0; if (_shouldReconnect) { _reconnectTimer = new Timer(reconnectTime); _reconnectTimer.Elapsed += (sender, args) => { _reconnectTimer.Stop(); _stateMachine.Fire(Trigger.ConnectRequested); }; } var _state = _stateMachine = new StateMachine <State, Trigger>(State.SignedOff); _state.OnTransitioned((transition => { _log.DebugFormat("{0} => {1}", transition.Source.ToString("G"), transition.Destination.ToString("G")); })); _state.Configure(State.Conceived) .Permit(Trigger.DisconnectRequested, State.SignedOff); _state.Configure(State.SignedOff) .SubstateOf(State.Conceived) .Ignore(Trigger.Disconnected) .OnEntryFrom(Trigger.AuthInvalid, () => InvalidCreds?.Invoke(this, EventArgs.Empty)) .PermitIf(Trigger.ConnectRequested, whisper ? State.TwitchGroupApi : State.Authenticating, () => _running); _state.Configure(State.RetryConnection) .SubstateOf(State.SignedOff) .OnExit(() => _reconnectTimer.Stop()) .OnEntry(() => _reconnectTimer.Start()) .PermitDynamic(Trigger.ConnectRequested, () => whisper ? State.TwitchGroupApi : State.Twitch); _state.Configure(State.TwitchGroupApi) .SubstateOf(State.Conceived) .OnEntry(CheckGroupApi) .Permit(Trigger.ApiCheckFailed, State.RetryConnection) .Permit(Trigger.GroupInfoReceived, State.Authenticating); _state.Configure(State.Twitch) .SubstateOf(State.Conceived) .Permit(Trigger.Connected, State.Authenticating) .PermitDynamic(Trigger.Disconnected, () => _shouldReconnect ? State.RetryConnection : State.SignedOff) .Permit(Trigger.AuthInvalid, State.SignedOff) .OnEntry(InitializeTwitchConnection) .OnExit(ReleaseTwitchConnection); _state.Configure(State.Authenticating) .SubstateOf(State.Twitch) .Permit(Trigger.SignedIn, State.Ready) .PermitReentry(Trigger.AuthRetry) .Permit(Trigger.AuthInvalid, State.SignedOff); _state.Configure(State.Ready) .SubstateOf(State.Twitch) .OnEntry(() => Ready?.Invoke(this, EventArgs.Empty)) .OnExit(() => Unready?.Invoke(this, EventArgs.Empty)); }