示例#1
0
        public PqlCompilerState(
            IExpressionEvaluatorRuntime parentRuntime,
            ParsedRequest parsedRequest,
            DataRequestParams requestParams,
            DataContainerDescriptor containerDescriptor,
            Type contextType,
            Type returnType)
            : base(parentRuntime, contextType, returnType, null)
        {
            if (parsedRequest == null)
            {
                throw new ArgumentNullException("parsedRequest");
            }

            if (containerDescriptor == null)
            {
                throw new ArgumentNullException("containerDescriptor");
            }

            if (requestParams == null)
            {
                throw new ArgumentNullException("requestParams");
            }

            ParsedRequest       = parsedRequest;
            RequestParameters   = requestParams;
            ContainerDescriptor = containerDescriptor;
            FieldRefs           = new Dictionary <int, Tuple <ParameterExpression, Expression> >();
            ParamRefs           = new Dictionary <int, Tuple <ParameterExpression, Expression> >();
        }
示例#2
0
        private static void InitDriverFetchFields(ParsedRequest parsedRequest)
        {
            if (parsedRequest.IsBulk)
            {
                foreach (var field in parsedRequest.BulkInput.BulkInputFields)
                {
                    parsedRequest.BaseDataset.BaseFields.Add(field);
                }

                parsedRequest.BaseDataset.BaseFieldsMainCount = parsedRequest.BaseDataset.BaseFields.Count;
            }
            else
            {
                foreach (var field in parsedRequest.BaseDataset.WhereClauseFields)
                {
                    parsedRequest.BaseDataset.BaseFields.Add(field);
                }

                foreach (var field in parsedRequest.Select.SelectFields)
                {
                    if (!parsedRequest.BaseDataset.BaseFields.Contains(field))
                    {
                        parsedRequest.BaseDataset.BaseFields.Add(field);
                    }
                }

                parsedRequest.BaseDataset.BaseFieldsMainCount = parsedRequest.BaseDataset.WhereClauseFields.Count;
            }
        }
示例#3
0
        private static Expression GetOrAddParameterRefToCompilationContext(ParsedRequest parsedRequest, PqlCompilerState compilerState, int parameterOrdinal)
        {
            Tuple <ParameterExpression, Expression> refTuple;

            if (compilerState.ParamRefs.TryGetValue(parameterOrdinal, out refTuple))
            {
                return(refTuple.Item1);
            }

            ParameterExpression paramRef;
            Expression          paramExtractor;
            var localOrdinal = parsedRequest.Params.OrdinalToLocalOrdinal[parameterOrdinal];
            var dbType       = parsedRequest.Params.DataTypes[parameterOrdinal];

            if (BitVector.Get(compilerState.RequestParameters.IsCollectionFlags, parameterOrdinal))
            {
                var rowData     = Expression.Field(compilerState.Context, "InputParametersCollections");
                var hashsetType = typeof(HashSet <>).MakeGenericType(DriverRowData.DeriveSystemType(dbType));
                paramExtractor = Expression.Convert(Expression.ArrayIndex(rowData, Expression.Constant(localOrdinal, typeof(int))), hashsetType);
                paramRef       = Expression.Variable(paramExtractor.Type);
            }
            else
            {
                var rowData = Expression.Field(compilerState.Context, "InputParametersRow");
                paramExtractor = DriverRowData.CreateReadAccessor(rowData, dbType, localOrdinal);
                paramRef       = Expression.Variable(paramExtractor.Type);
            }

            compilerState.ParamRefs.Add(
                parameterOrdinal, new Tuple <ParameterExpression, Expression>(paramRef, paramExtractor));
            return(paramRef);
        }
示例#4
0
        /// <summary>
        /// Parses specified expression text, with a cancellation option.
        /// May incur some waiting in highly concurrent environment, because the number of pooled parsers is limited.
        /// </summary>
        public void Parse(DataRequest request, DataRequestBulk requestBulk, ParsedRequest parsedRequest, CancellationToken cancellation)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            if (parsedRequest == null)
            {
                throw new ArgumentNullException("parsedRequest");
            }

            if (cancellation == null)
            {
                throw new ArgumentNullException("cancellation");
            }

            if (request.HaveRequestBulk && requestBulk == null)
            {
                throw new ArgumentNullException("requestBulk");
            }

            if (request.HaveRequestBulk)
            {
                ParseBulkRequest(requestBulk, parsedRequest);
            }
            else
            {
                ParsePqlStatementRequest(request, parsedRequest, cancellation);
            }

            InitDriverFetchFields(parsedRequest);
        }
        private async Task FragmentHandler(IOwinContext ctx, ParsedRequest req, Channel channel)
        {
            var ct = ctx.Request.CallCancelled;

            using (var subscription = HLSChannelSink.GetSubscription(this, channel, ctx, req.Session)) {
                subscription.Stopped.ThrowIfCancellationRequested();
                using (var cts = CancellationTokenSource.CreateLinkedTokenSource(ct, subscription.Stopped)) {
                    cts.CancelAfter(10000);
                    var segments = await subscription.Segmenter.GetSegmentsAsync(cts.Token).ConfigureAwait(false);

                    var segment = segments.FirstOrDefault(s => s.Index == req.FragmentNumber);
                    if (segment.Index == 0)
                    {
                        ctx.Response.StatusCode = (int)HttpStatusCode.NotFound;
                    }
                    else
                    {
                        ctx.Response.StatusCode = (int)HttpStatusCode.OK;
                        ctx.Response.Headers.Add("Access-Control-Allow-Origin", new string[] { "*" });
                        ctx.Response.ContentType   = "video/MP2T";
                        ctx.Response.ContentLength = segment.Data.LongLength;
                        await ctx.Response.WriteAsync(segment.Data, cts.Token).ConfigureAwait(false);
                    }
                }
            }
        }
示例#6
0
        private static Func <DriverRowData, int> CompileInt32ParamExtractorForPaging(ParsedRequest parsedRequest, ParseTreeNode parseTreeNode, int defaultValue)
        {
            var paramName = parseTreeNode.RequireChild("id_simple", 0).Token.ValueString;

            if (string.IsNullOrEmpty(paramName) || paramName[0] != '@')
            {
                throw new CompilationException("Values for paging clause must be Int32 constants or Int32 parameters", parseTreeNode);
            }

            var names = parsedRequest.Params.Names;

            if (names != null)
            {
                for (var paramOrdinal = 0; paramOrdinal < names.Length; paramOrdinal++)
                {
                    if (StringComparer.OrdinalIgnoreCase.Equals(names[paramOrdinal], paramName))
                    {
                        if (parsedRequest.Params.DataTypes[paramOrdinal] != DbType.Int32)
                        {
                            throw new CompilationException(string.Format(
                                                               "Parameter {0} must be of type Int32 for use in paging options. Actual type: {1}",
                                                               paramName, parsedRequest.Params.DataTypes[paramOrdinal])
                                                           , parseTreeNode);
                        }

                        var localOrdinal = parsedRequest.Params.OrdinalToLocalOrdinal[paramOrdinal];
                        return(data => BitVector.Get(data.NotNulls, localOrdinal) ? data.GetInt32(localOrdinal) : defaultValue);
                    }
                }
            }

            throw new CompilationException("Unknown parameter: " + paramName, parseTreeNode);
        }
示例#7
0
        public void AssertMatches(ParsedRequest requestObject, string regexKey, string expectedMatch, int expectedMatchCount)
        {
            string value = requestObject.ToString();

            expectedMatch = Utilities_String.EscapeSpecialRegexCharacters(expectedMatch);
            List <KeyValuePair <string, object> > matches = requestObject.GetMatches(regexKey);

            Assert.AreEqual(expectedMatchCount, matches.Count, string.Format("Count for value of {0} in {1}", regexKey, value));
            if (matches.Count <= 0)
            {
                return;
            }
            KeyValuePair <string, object> match = matches.First();

            bool isNull = (expectedMatch == null);

            if (isNull)
            {
                Assert.IsNull(match.Value);
            }
            else
            {
                Assert.IsTrue(Regex.IsMatch(match.Value.ToString(), expectedMatch, RegexOptions.IgnoreCase),
                              Utilities_Assertion.ToString(string.Format("Value of {0} in {1}", regexKey, value), expectedMatch, match.Value));
            }

            System.Console.WriteLine(string.Format("HTTP_Request:\n\tType: {0}\tToString: {1}",
                                                   requestObject.GetType(), requestObject.ToString()));
        }
        private async Task HLSHandler(IOwinContext ctx)
        {
            var ct  = ctx.Request.CallCancelled;
            var req = ParsedRequest.Parse(ctx);

            if (!req.IsValid)
            {
                ctx.Response.StatusCode = (int)req.Status;
                return;
            }
            Channel channel;

            try {
                channel = await GetChannelAsync(ctx, req, ct).ConfigureAwait(false);
            }
            catch (TaskCanceledException) {
                ctx.Response.StatusCode = (int)HttpStatusCode.GatewayTimeout;
                return;
            }
            if (channel == null)
            {
                ctx.Response.StatusCode = (int)HttpStatusCode.NotFound;
                return;
            }

            if (req.FragmentNumber.HasValue)
            {
                await FragmentHandler(ctx, req, channel).ConfigureAwait(false);
            }
            else
            {
                await PlayListHandler(ctx, req, channel).ConfigureAwait(false);
            }
        }
示例#9
0
        public static string GetUsernameIn(this ParsedRequest request, BotBitsClient client, int index)
        {
            var query = request.Args[index];
            PlayerSearchFilter filter;

            query = MatchHelper.TrimFilterPrefix(query, out filter);

            try
            {
                var list = request
                           .GetPlayersIn(client, index)
                           .Select(p => p.Username)
                           .Distinct()
                           .ToArray();

                if (!filter.HasFlag(PlayerSearchFilter.FirstResult) && list.Length >= 2)
                {
                    throw new CommandException("More than one username was found.");
                }

                return(list.First());
            }
            catch (UnknownPlayerCommandException)
            {
                return(query);
            }
        }
            public static ParsedRequest Parse(IOwinContext ctx)
            {
                var req        = new ParsedRequest();
                var components = (ctx.Request.Path.HasValue ? ctx.Request.Path.Value : "/").Split('/');

                if (components.Length > 2)
                {
                    req.Status = HttpStatusCode.NotFound;
                    return(req);
                }
                if (String.IsNullOrEmpty(components[1]))
                {
                    req.Status = HttpStatusCode.Forbidden;
                    return(req);
                }
                var md = ChannelIdPattern.Match(components[1]);

                if (!md.Success)
                {
                    req.Status = HttpStatusCode.NotFound;
                    return(req);
                }
                var channelId = Guid.Parse(md.Groups[1].Value);
                var ext       = md.Groups[2].Success ? md.Groups[2].Value : null;

                req.Status    = HttpStatusCode.OK;
                req.ChannelId = channelId;
                req.Extension = ext;
                return(req);
            }
 public CommandExceptionEvent(IInvokeSource source, ParsedRequest request, CommandException exception)
 {
     this.Exception = exception;
     this.Source    = source;
     this.Request   = request;
     this.Handled   = exception.Ignored;
 }
示例#12
0
        public void TestEmpty()
        {
            ParsedRequest parsedRequest;
            string        error;
            var           isOk = ParsedRequest.Parse("", 1, out parsedRequest, out error);

            Assert.False(isOk);
        }
示例#13
0
        public void Test_ParsedRequest_Delete(string value, string regexKey, string expectedMatch, int expectedMatchCount)
        {
            ParsedRequest requestObject = ParsedRequest.GetParsedRequest(value);

            requestObject.Delete(regexKey);

            AssertMatches(requestObject, regexKey, expectedMatch, 0);
        }
示例#14
0
        public void Test_ParsedRequest_Parsing_Building_Match(string value, string regexKey, string expectedMatch, int expectedMatchCount)
        {
            ParsedRequest requestObject = ParsedRequest.GetParsedRequest(value);

            Assert.AreEqual(value.ToLower(), requestObject.ToString().ToLower());

            AssertMatches(requestObject, regexKey, expectedMatch, expectedMatchCount);
        }
示例#15
0
        public static Player[] GetPlayersIn(this ParsedRequest request, BotBitsClient client, int index)
        {
            var query = request.Args[index];
            PlayerSearchFilter filter;

            query = MatchHelper.TrimFilterPrefix(query, out filter);
            return(MatchPlayers(client, query, filter));
        }
示例#16
0
        private static TreeIteratorContext GetTreeIteratorContext(ParsedRequest parsedRequest, DataContainerDescriptor containerDescriptor)
        {
            var result = new TreeIteratorContext();

            result.ContainerDescriptor = containerDescriptor;
            result.ParsedRequest       = parsedRequest;
            return(result);
        }
示例#17
0
        private void ParsePqlStatementRequest(DataRequest request, ParsedRequest parsedRequest, CancellationToken cancellation)
        {
            ParseTree parseTree;

            using (var poolAccessor = m_parsers.Take(cancellation))
            {
                try
                {
                    parseTree = poolAccessor.Item.Parse(request.CommandText);
                }
                finally
                {
                    // get rid of temp utility objects right now, to help them be reclaimed with Gen0
                    poolAccessor.Item.Reset();
                }
            }

            if (parseTree.Status != ParseTreeStatus.Parsed)
            {
                throw new CompilationException(BuildParserErrorMessage(parseTree));
            }

            // root is a batch of Pql statements
            var root = parseTree.Root;

            if (root.ChildNodes == null || root.ChildNodes.Count != 1)
            {
                throw new CompilationException("Pql batch must contain exactly one statement", root);
            }

            var statementRoot = root.ChildNodes[0];

            // run first round of syntactical analysis on the tree
            if ("selectStmt".Equals(statementRoot.Term.Name))
            {
                parsedRequest.StatementType = StatementType.Select;
                ParseSelectStatement(parsedRequest, statementRoot);
            }
            else if ("updateStmt".Equals(statementRoot.Term.Name))
            {
                parsedRequest.StatementType = StatementType.Update;
                ParseUpdateStatement(parsedRequest, statementRoot);
            }
            else if ("insertStmt".Equals(statementRoot.Term.Name))
            {
                parsedRequest.StatementType = StatementType.Insert;
                ParseInsertStatement(parsedRequest, statementRoot);
            }
            else if ("deleteStmt".Equals(statementRoot.Term.Name))
            {
                parsedRequest.StatementType = StatementType.Delete;
                ParseDeleteStatement(parsedRequest, statementRoot);
            }
            else
            {
                throw new CompilationException("Invalid statement: " + statementRoot.Term.Name, statementRoot);
            }
        }
示例#18
0
        private void ParseInsertStatement(ParsedRequest parsedRequest, ParseTreeNode insertStmt)
        {
            // get FROM entity name
            var insertEntityClause = insertStmt.RequireChild("Id", 2);

            parsedRequest.TargetEntity = GetTargetEntity(insertEntityClause);

            // preprocess identifiers
            m_preprocessor.ProcessIdentifierAliases(insertStmt, parsedRequest.TargetEntity);

            var insertFieldsListClause = insertStmt.RequireChild("idList", 3, 0);
            var valueListClause        = insertStmt.RequireChild("insertTuplesList", 4, 1);

            if (valueListClause.ChildNodes.Count != 1)
            {
                throw new CompilationException("Multi-tuple explicit list of values for INSERT is not yet supported");
            }

            valueListClause = valueListClause.ChildNodes[0];

            if (insertFieldsListClause.ChildNodes.Count != valueListClause.ChildNodes.Count)
            {
                throw new CompilationException("Number of fields in INSERT clause must match number of expressions in VALUES clause", insertStmt);
            }

            parsedRequest.TargetEntityPkField = m_containerDescriptor.RequireField(parsedRequest.TargetEntity.DocumentType, parsedRequest.TargetEntity.PrimaryKeyFieldName);
            for (var ordinal = 0; ordinal < insertFieldsListClause.ChildNodes.Count; ordinal++)
            {
                var insertFieldNode = insertFieldsListClause.ChildNodes[ordinal];
                var field           = TryGetFieldByIdentifierNode(insertFieldNode, m_containerDescriptor, parsedRequest.TargetEntity.DocumentType);
                if (field == null)
                {
                    throw new CompilationException("Attempting to INSERT into an unknown field", insertFieldNode);
                }

                if (ReferenceEquals(field, parsedRequest.TargetEntityPkField))
                {
                    parsedRequest.OrdinalOfPrimaryKey = ordinal;
                }

                if (parsedRequest.Modify.ModifiedFields.Contains(field))
                {
                    throw new CompilationException("A field can be assigned by INSERT only once: " + field.Name, insertFieldNode);
                }

                var expressionClause = valueListClause.ChildNodes[ordinal];

                // update clauses list will hold value expressions
                parsedRequest.Modify.ModifiedFields.Add(field);
                parsedRequest.Modify.InsertUpdateSetClauses.Add(expressionClause);
            }

            if (parsedRequest.OrdinalOfPrimaryKey < 0)
            {
                throw new CompilationException("Value for primary key field must be specified: " + parsedRequest.TargetEntityPkField.Name);
            }
        }
示例#19
0
        public void TestAge40()
        {
            ParsedRequest parsedRequest;
            string        error;
            var           isOk = ParsedRequest.Parse("40", 1, out parsedRequest, out error);

            Assert.True(isOk);
            Assert.Null(parsedRequest.phone);
            Assert.Equal(parsedRequest.age, 40);
        }
示例#20
0
        public void TestAllComponents()
        {
            ParsedRequest parsedRequest;
            string        error;
            var           isOk = ParsedRequest.Parse("20 Johan 1234-567890", 1, out parsedRequest, out error);

            Assert.True(isOk);
            Assert.Equal(parsedRequest.name, "Johan");
            Assert.Equal(parsedRequest.phone, "1234-567890");
            Assert.Equal(parsedRequest.age, 20);
        }
示例#21
0
        public void TestNameWithSpaceAndAge()
        {
            ParsedRequest parsedRequest;
            string        error;
            var           isOk = ParsedRequest.Parse("ders Karl 24", 1, out parsedRequest, out error);

            Assert.True(isOk);
            Assert.Equal(parsedRequest.name, "ders Karl");
            Assert.Null(parsedRequest.phone);
            Assert.Equal(parsedRequest.age, 24);
        }
示例#22
0
        public void TestMix()
        {
            ParsedRequest parsedRequest;
            string        error;
            var           isOk = ParsedRequest.Parse("A1B2C3", 1, out parsedRequest, out error);

            Assert.True(isOk);
            Assert.Equal(parsedRequest.name, "A1B2C3");
            Assert.Null(parsedRequest.phone);
            Assert.Null(parsedRequest.age);
        }
示例#23
0
        public void TestPhone160()
        {
            ParsedRequest parsedRequest;
            string        error;
            var           isOk = ParsedRequest.Parse("160", 1, out parsedRequest, out error);

            Assert.True(isOk);
            Assert.Null(parsedRequest.name);
            Assert.Equal(parsedRequest.phone, "160");
            Assert.Null(parsedRequest.age);
        }
示例#24
0
        private Uri GetPeopleSearchUri(ParsedRequest parsedRequest)
        {
            var relativePath = string.Format("/people/search?{0}{1}{2}{3}",
                                             GetParameterString("name", parsedRequest.name),
                                             GetParameterString("age", parsedRequest.age.HasValue ? (object)parsedRequest.age.Value : null),
                                             GetParameterString("phone", parsedRequest.phone),
                                             GetParameterString("page", parsedRequest.page)
                                             );
            var uri = new Uri(BASE_URL, relativePath);

            return(uri);
        }
示例#25
0
        private void ParseBulkRequest(DataRequestBulk requestBulk, ParsedRequest parsedRequest)
        {
            switch (requestBulk.DbStatementType)
            {
            case StatementType.Insert:
            case StatementType.Update:
                parsedRequest.StatementType = requestBulk.DbStatementType;
                break;

            default:
                throw new ArgumentOutOfRangeException("requestBulk", requestBulk.DbStatementType, "Invalid bulk statement type");
            }

            parsedRequest.TargetEntity = m_containerDescriptor.RequireDocumentType(
                m_containerDescriptor.RequireDocumentTypeName(requestBulk.EntityName));

            if (string.IsNullOrEmpty(parsedRequest.TargetEntity.PrimaryKeyFieldName))
            {
                throw new Exception("Target entity does not have a primary key, cannot perform bulk operations on it");
            }

            parsedRequest.TargetEntityPkField = m_containerDescriptor.RequireField(
                parsedRequest.TargetEntity.DocumentType, parsedRequest.TargetEntity.PrimaryKeyFieldName);

            // we always expect value of primary key into driver row data for bulk requests at first position
            parsedRequest.OrdinalOfPrimaryKey = 0;

            if (0 != StringComparer.OrdinalIgnoreCase.Compare(requestBulk.FieldNames[0], parsedRequest.TargetEntityPkField.Name))
            {
                throw new Exception("First field in bulk request input schema on this entity must be the primary key field");
            }

            for (var ordinal = 0; ordinal < requestBulk.FieldNames.Length; ordinal++)
            {
                var fieldName = requestBulk.FieldNames[ordinal];
                var field     = m_containerDescriptor.RequireField(parsedRequest.TargetEntity.DocumentType, fieldName);

                if (ordinal != 0 && ReferenceEquals(parsedRequest.TargetEntityPkField, field))
                {
                    throw new Exception("Primary key field may only be used in first position");
                }

                if (parsedRequest.Modify.ModifiedFields.Contains(field))
                {
                    throw new CompilationException("A field can be assigned only once: " + field.Name, null);
                }

                parsedRequest.BulkInput.BulkInputFields.Add(field);
                parsedRequest.Modify.ModifiedFields.Add(field);
                parsedRequest.Modify.InsertUpdateSetClauses.Add(null);
            }
        }
示例#26
0
        private void ParseRequest(DataRequest request, DataRequestBulk requestBulk, ParsedRequest parsedRequest, CancellationToken cancellation)
        {
            if (parsedRequest.SpecialCommand.IsSpecialCommand)
            {
                if (parsedRequest.SpecialCommand.CommandType != ParsedRequest.SpecialCommandData.SpecialCommandType.Defragment)
                {
                    throw new CompilationException(
                              "Invalid special command type: " + parsedRequest.SpecialCommand.CommandType + ". Command text was: " + request.CommandText);
                }

                return;
            }

            // by now, we have all information about the request at hand, including parameter values data.
            // parser will write results into cacheInfo object
            m_parser.Parse(request, requestBulk, parsedRequest, cancellation);

            if (parsedRequest.StatementType == StatementType.Delete || parsedRequest.StatementType == StatementType.Insert)
            {
                // for insert and delete, we need all columns' data ready for modification before we start
                m_storageDriver.PrepareAllColumnsAndWait(parsedRequest.TargetEntity.DocumentType);
            }
            else
            {
                // for other statement types, we only need fields that we order by, filter on, fetch or update,
                // and we need them in that particular order.

                // schedule loading of sort order fields
                foreach (var field in parsedRequest.BaseDataset.OrderClauseFields)
                {
                    m_storageDriver.BeginPrepareColumnData(field.Item1);
                }

                // schedule loading of where clause fields
                foreach (var field in parsedRequest.BaseDataset.WhereClauseFields)
                {
                    m_storageDriver.BeginPrepareColumnData(field.FieldId);
                }

                // schedule loading of fetched fields
                foreach (var field in parsedRequest.Select.SelectFields)
                {
                    m_storageDriver.BeginPrepareColumnData(field.FieldId);
                }

                // schedule loading of inserted/updated fields
                foreach (var field in parsedRequest.Modify.ModifiedFields)
                {
                    m_storageDriver.BeginPrepareColumnData(field.FieldId);
                }
            }
        }
示例#27
0
 private static async Task<Channel> GetChannelAsync(OwinEnvironment ctx, ParsedRequest req, CancellationToken ct)
 {
   var tip = ctx.Request.Query.Get("tip");
   var channel = ctx.GetPeerCast().RequestChannel(req.ChannelId, OutputStreamBase.CreateTrackerUri(req.ChannelId, tip), true);
   if (channel==null) {
     return null;
   }
   using (var cts=CancellationTokenSource.CreateLinkedTokenSource(ct)) {
     cts.CancelAfter(10000);
     await channel.WaitForReadyContentTypeAsync(cts.Token).ConfigureAwait(false);
   }
   return channel;
 }
示例#28
0
        private static int GetFieldOrdinalInDriverFetchFields(ParsedRequest parsedRequest, FieldMetadata field)
        {
            // get ordinal of this field in the dataset returned by storage driver
            var ordinal = parsedRequest.BaseDataset.BaseFields.IndexOf(field);

            if (ordinal < 0)
            {
                throw new Exception(
                          string.Format(
                              "Internal error: driver fetch fields does have have field {0}, id {1} of entity {2}"
                              , field.Name, field.FieldId, parsedRequest.TargetEntity.Name));
            }
            return(ordinal);
        }
示例#29
0
        private void StopCommand(IInvokeSource source, ParsedRequest request)
        {
            RequireModerator(source);

            if (!roundsManager.Enabled)
            {
                source.Reply("Bot is not enabled!");
            }
            else
            {
                source.Reply("Stopping round...");
                roundsManager.ForceStop();
            }
        }
示例#30
0
        private void OffCommand(IInvokeSource source, ParsedRequest request)
        {
            RequireModerator(source);

            if (!roundsManager.Enabled)
            {
                source.Reply("Bot is already disabled.");
            }
            else
            {
                source.Reply("Disabling bot...");
                roundsManager.Enabled = false;
            }
        }
示例#31
0
 static void HiCommand(IInvokeSource source, ParsedRequest request)
 {
     var player = source.ToPlayerInvokeSource().Player;
     source.Reply("Hello world {0}!", player.Username);
 }