Пример #1
0
        public static ExecutionInformation GetExecInfo(string matcher)
        {
            var execInfo = new ExecutionInformation();

            execInfo.AddModule(new CallerInfo(false)
            {
                SkipRightsChecks = true, CommandComplexityMax = int.MaxValue
            });
            execInfo.AddModule(new InvokerData((Uid)"InvokerUid"));
            execInfo.AddModule(Filter.GetFilterByName(matcher));
            execInfo.AddModule(cmdMgr);
            return(execInfo);
        }
Пример #2
0
        private ExecutionInformation BuildContext(ApiCall apiCallData)
        {
            var execInfo = new ExecutionInformation(coreInjector);

            execInfo.AddModule(new CallerInfo(true)
            {
                SkipRightsChecks     = false,
                CommandComplexityMax = config.CommandComplexity,
                IsColor = false,
            });
            execInfo.AddModule <InvokerData>(apiCallData);
            execInfo.AddModule(apiCallData);
            execInfo.AddModule(Filter.GetFilterByNameOrDefault(config.Matcher));
            return(execInfo);
        }
Пример #3
0
        public static ExecutionInformation GetExecInfo(string matcher, bool addMainCommands = true)
        {
            var cmdMgr = new CommandManager(null !);

            if (addMainCommands)
            {
                cmdMgr.RegisterCollection(MainCommands.Bag);
            }

            var execInfo = new ExecutionInformation();

            execInfo.AddModule(new CallerInfo(false)
            {
                SkipRightsChecks = true, CommandComplexityMax = int.MaxValue
            });
            execInfo.AddModule(new InvokerData((Uid)"InvokerUid"));
            execInfo.AddModule(Filter.GetFilterByName(matcher) ?? throw new Exception("Test filter not found"));
            execInfo.AddModule(cmdMgr);
            return(execInfo);
        }
Пример #4
0
        public ICommandResult Execute(ExecutionInformation info, IReadOnlyList <ICommand> arguments, IReadOnlyList <CommandResultType> returnTypes)
        {
            info.UseComplexityTokens(1);

            IReadOnlyList <ICommand> backupArguments = null;

            if (!info.TryGet <AliasContext>(out var aliasContext))
            {
                aliasContext = new AliasContext();
                info.AddModule(aliasContext);
            }
            else
            {
                backupArguments = aliasContext.Arguments;
            }

            aliasContext.Arguments = arguments.Select(c => new LazyCommand(c)).ToArray();
            var ret = aliasCommand.Execute(info, Array.Empty <ICommand>(), returnTypes);

            aliasContext.Arguments = backupArguments;
            return(ret);
        }
Пример #5
0
        public async ValueTask <object?> Execute(ExecutionInformation info, IReadOnlyList <ICommand> arguments)
        {
            info.UseComplexityTokens(1);

            IReadOnlyList <ICommand>?backupArguments = null;

            if (!info.TryGet <AliasContext>(out var aliasContext))
            {
                aliasContext = new AliasContext();
                info.AddModule(aliasContext);
            }
            else
            {
                backupArguments = aliasContext.Arguments;
            }

            aliasContext.Arguments = arguments.Select(c => new LazyCommand(c)).ToArray();
            var ret = await aliasCommand.Execute(info, Array.Empty <ICommand>());

            aliasContext.Arguments = backupArguments;
            return(ret);
        }
Пример #6
0
        private ExecuteContext GetRightsContext(ExecutionInformation info)
        {
            var localRootRule = TryGetRootSafe();

            if (info.TryGet <ExecuteContext>(out var execCtx))
            {
                return(execCtx);
            }

            execCtx = new ExecuteContext();

            if (info.TryGet <ClientCall>(out var clientCall))
            {
                execCtx.ServerGroups = clientCall.ServerGroups;
                execCtx.ClientUid    = clientCall.ClientUid;
                execCtx.Visibiliy    = clientCall.Visibiliy;
                execCtx.IsApi        = false;

                // Get Required Matcher Data:
                // In this region we will iteratively go through different possibilities to obtain
                // as much data as we can about our invoker.
                // For this step we will prefer query calls which can give us more than one information
                // at once and lazily fall back to other calls as long as needed.

                if (info.TryGet <Ts3Client>(out var ts) && info.TryGet <TsBaseFunctions>(out var tsClient))
                {
                    ServerGroupId[] serverGroups = clientCall.ServerGroups;
                    ChannelId?      channelId    = clientCall.ChannelId;
                    ClientDbId?     databaseId   = clientCall.DatabaseId;
                    ChannelGroupId? channelGroup = clientCall.ChannelGroup;

                    if (clientCall.ClientId != null &&
                        ((needsAvailableGroups && serverGroups is null) ||
                         (needsAvailableChanGroups && channelGroup is null) ||
                         (needsPermOverview.Length > 0 && (databaseId == null || channelId == null))
                        )
                        )
                    {
                        var result = ts.GetClientInfoById(clientCall.ClientId.Value);
                        if (result.Ok)
                        {
                            serverGroups = result.Value.ServerGroups;
                            channelGroup = result.Value.ChannelGroup;
                            databaseId   = result.Value.DatabaseId;
                            channelId    = result.Value.ChannelId;
                        }
                    }

                    if (needsAvailableGroups && serverGroups is null)
                    {
                        if (databaseId == null)
                        {
                            var resultDbId = ts.GetClientDbIdByUid(clientCall.ClientUid);
                            if (resultDbId.Ok)
                            {
                                databaseId = resultDbId.Value;
                            }
                        }

                        if (databaseId != null)
                        {
                            var result = ts.GetClientServerGroups(databaseId.Value);
                            if (result.Ok)
                            {
                                serverGroups = result.Value;
                            }
                        }
                    }

                    execCtx.ChannelGroupId = channelGroup;
                    execCtx.ServerGroups   = serverGroups ?? Array.Empty <ServerGroupId>();

                    if (needsPermOverview.Length > 0 && databaseId != null && channelId != null)
                    {
                        // TODO check if there is any better way to only get the permissions needed.
                        var result = tsClient.PermOverview(databaseId.Value, channelId.Value, 0);
                        if (result.Ok)
                        {
                            execCtx.Permissions = new PermOverview[Enum.GetValues(typeof(TsPermission)).Length];
                            foreach (var perm in result.Value)
                            {
                                if (perm.PermissionId < 0 || (int)perm.PermissionId >= execCtx.Permissions.Length)
                                {
                                    continue;
                                }
                                var cur = execCtx.Permissions[(int)perm.PermissionId];
                                execCtx.Permissions[(int)perm.PermissionId] = cur == null ? perm : cur.Combine(perm);
                            }
                        }
                    }
                }
            }
            else if (info.TryGet <ApiCall>(out var apiCallData))
            {
                execCtx.ClientUid   = apiCallData.ClientUid;
                execCtx.ApiToken    = apiCallData.Token;
                execCtx.ApiCallerIp = apiCallData.IpAddress;
                execCtx.IsApi       = true;
            }

            if (info.TryGet <Bot>(out var bot))
            {
                var botInfo = bot.GetInfo();
                execCtx.Bot  = botInfo.Name;
                execCtx.Host = botInfo.Server;
            }

            if (localRootRule != null)
            {
                ProcessNode(localRootRule, execCtx);
            }

            if (execCtx.MatchingRules.Count == 0)
            {
                return(execCtx);
            }

            foreach (var rule in execCtx.MatchingRules)
            {
                execCtx.DeclAdd.UnionWith(rule.DeclAdd);
            }

            info.AddModule(execCtx);

            return(execCtx);
        }
Пример #7
0
        public Result CommandVote(ExecutionInformation info, Uid invoker, string command, string args = null)
        {
            command = command.ToLower();
            if (string.IsNullOrWhiteSpace(command))
            {
                throw new CommandException("No command to vote for given.", CommandExceptionReason.CommandError);
            }

            if (!VotableCommands.Commands.TryGetValue(command, out var votableCommand))
            {
                throw new CommandException($"The given command \"{command}\" can't be put up to vote.",
                                           CommandExceptionReason.CommandError);
            }

            OnBotChannelChanged();

            bool voteAdded;
            bool votesChanged;
            bool voteCompleted;

            if (CurrentVotes.TryGetValue(command, out var currentVote))
            {
                if (!string.IsNullOrWhiteSpace(args))
                {
                    throw new CommandException(
                              "There is already a vote going on for this command. You can't start another vote for the same command with other parameters right now.",
                              CommandExceptionReason.CommandError);
                }

                if (currentVote.Voters.Remove(invoker))
                {
                    int count = currentVote.Voters.Count;
                    voteAdded = false;
                    if (count == 0)
                    {
                        Remove(currentVote);
                        votesChanged = true;

                        client.SendChannelMessage($"Removed vote of {ClientUtility.GetClientNameFromUid(ts3FullClient, invoker)} and stopped vote for \"{command}\".");
                    }
                    else
                    {
                        votesChanged = false;
                        client.SendChannelMessage($"Removed vote of {ClientUtility.GetClientNameFromUid(ts3FullClient, invoker)} for \"{command}\" ({currentVote.Voters.Count} votes of {Needed})");
                    }

                    voteCompleted = false;
                }
                else
                {
                    currentVote.Voters.Add(invoker);
                    voteAdded = true;
                    client.SendChannelMessage($"Added vote of {ClientUtility.GetClientNameFromUid(ts3FullClient, invoker)} for \"{command}\" ({currentVote.Voters.Count} votes of {Needed})");
                    votesChanged  = false;
                    voteCompleted = CheckAndFire(currentVote);
                }
            }
            else
            {
                info.AddModule(CreateCallerInfo());
                var(executor, removeOnResourceEnd) = votableCommand.Create(info, command, args);

                currentVote = new CurrentVoteData(command, executor, removeOnResourceEnd);
                Add(currentVote);
                voteAdded = true;
                currentVote.Voters.Add(invoker);
                votesChanged = true;
                client.SendChannelMessage($"{ClientUtility.GetClientNameFromUid(ts3FullClient, invoker)} started vote for \"{command}\" ({currentVote.Voters.Count} votes of {Needed})");
                voteCompleted = CheckAndFire(currentVote);
            }

            var result = new Result {
                VoteAdded    = voteAdded,
                VoteComplete = voteCompleted,
                VotesChanged = votesChanged,
                VoteCount    = currentVote.Voters.Count,
                VotesNeeded  = Needed
            };

            if (currentVote.Command == "skip" && (voteAdded || votesChanged || voteCompleted))
            {
                OnSkipVoteChanged?.Invoke(this, new SkipVoteEventArgs(result));
            }

            return(result);
        }