protected CommandInteraction StartOrResetCommandInteraction(TSPlayer forPlayer, int timeoutMs = 0)
        {
            Contract.Requires <ObjectDisposedException>(!this.IsDisposed);
            Contract.Requires <ArgumentNullException>(forPlayer != null);

            CommandInteraction newInteraction = new CommandInteraction(forPlayer);

            lock (this.activeCommandInteractionsLock) {
                this.StopInteraction(forPlayer);
                this.activeCommandInteractions.Add(forPlayer, newInteraction);

                newInteraction.IsActive = true;
            }

            if (timeoutMs > -1)
            {
                if (timeoutMs == 0)
                {
                    timeoutMs = UserInteractionHandlerBase.CommandInteractionDefaultTimeoutMs;
                }

                newInteraction.TimeoutMs    = timeoutMs;
                newInteraction.TimeoutTimer = new System.Threading.Timer(
                    this.InteractionTimeOutTimer_Callback, newInteraction, timeoutMs, Timeout.Infinite
                    );
            }

            return(newInteraction);
        }
        private void InteractionTimeOutTimer_Callback(object state)
        {
            CommandInteraction interaction = (state as CommandInteraction);

            if (interaction == null)
            {
                return;
            }

            lock (this.activeCommandInteractionsLock) {
                if (this.IsDisposed)
                {
                    return;
                }

                if (!this.activeCommandInteractions.ContainsValue(interaction))
                {
                    return;
                }

                if (interaction.ForPlayer.ConnectionAlive && interaction.IsActive)
                {
                    if (interaction.TimeExpiredCallback != null)
                    {
                        try {
                            interaction.TimeExpiredCallback(interaction.ForPlayer);
                        } catch (Exception ex) {
                            this.PluginTrace.WriteLineError("A command interaction's time expired callback has thrown an exception:\n" + ex);
                        }
                    }
                    if (interaction.AbortedCallback != null)
                    {
                        try {
                            interaction.AbortedCallback(interaction.ForPlayer);
                        } catch (Exception ex) {
                            this.PluginTrace.WriteLineError("A command interaction's aborted callback has thrown an exception:\n" + ex);
                        }
                    }
                    interaction.IsActive = false;
                }

                this.activeCommandInteractions.Remove(interaction.ForPlayer);
            }
        }
        protected CommandInteraction StartOrResetCommandInteraction(TSPlayer forPlayer, int timeoutMs = 0)
        {
            Contract.Requires<ObjectDisposedException>(!this.IsDisposed);
              Contract.Requires<ArgumentNullException>(forPlayer != null);

              CommandInteraction newInteraction = new CommandInteraction(forPlayer);

              lock (this.activeCommandInteractionsLock) {
            this.StopInteraction(forPlayer);
            this.activeCommandInteractions.Add(forPlayer, newInteraction);

            newInteraction.IsActive = true;
              }

              if (timeoutMs > -1) {
            if (timeoutMs == 0)
              timeoutMs = UserInteractionHandlerBase.CommandInteractionDefaultTimeoutMs;

            newInteraction.TimeoutMs = timeoutMs;
            newInteraction.TimeoutTimer = new System.Threading.Timer(
              this.InteractionTimeOutTimer_Callback, newInteraction, timeoutMs, Timeout.Infinite
            );
              }

              return newInteraction;
        }