public static void Help(TwitchModule module, [Group(1)] bool pdf)
    {
        string manualType = pdf ? "pdf" : "html";

        string manualText = (Repository.GetManual(module.BombComponent.GetModuleID()) ?? module.BombComponent.GetModuleDisplayName()) + TranslatedModuleHelper.GetManualCodeAddOn(module.Solver.LanguageCode);
        string helpText   = string.IsNullOrEmpty(module.Solver.HelpMessage) ? string.Empty : string.Format(module.Solver.HelpMessage, module.Code, module.HeaderText);

        IRCConnection.SendMessage($"{module.HeaderText} : {helpText} : {UrlHelper.ManualFor(manualText, manualType, VanillaRuleModifier.GetModuleRuleSeed(module.Solver.ModInfo.moduleID) != 1)}");
    }
Exemple #2
0
    public static IEnumerator DefaultCommand(TwitchModule module, string user, string cmd)
    {
        if (cmd.RegexMatch(out Match match, @"(?<zoom>zoom *(?<time>\d*\.?\d+)?)? *(?<tilt>tilt *(?<direction>[uptobmdwnlefrigh]+|-?\d+)?)? *(?:send *to *module)? *(?<command>.+)?"))
        {
            var groups  = match.Groups;
            var timed   = groups["time"].Success;
            var zoom    = groups["zoom"].Success;
            var tilt    = groups["tilt"].Success;
            var command = groups["command"].Success;

            // Both a time and a command can't be entered. And either a zoom or tilt needs to take place otherwise, we should let the command run normally.
            if ((!timed || !command) && (zoom || tilt))
            {
                MusicPlayer musicPlayer = null;
                int         delay       = 2;
                if (timed)
                {
                    delay = groups["time"].Value.TryParseInt() ?? 2;
                    delay = Math.Max(2, delay);
                    if (delay >= 15)
                    {
                        musicPlayer = MusicPlayer.StartRandomMusic();
                    }
                }

                object toYield = command ? (object)RunModuleCommand(module, user, groups["command"].Value) : delay;

                IEnumerator routine = null;
                if (tilt)
                {
                    routine = Tilt(module, toYield, groups["direction"].Value);
                }

                if (zoom)
                {
                    routine = Zoom(module, user, routine ?? toYield);
                }

                yield return(routine);

                if (CoroutineCanceller.ShouldCancel)
                {
                    CoroutineCanceller.ResetCancel();
                    IRCConnection.SendMessage($"Sorry @{user}, your request to hold up the bomb for {delay} seconds has been cut short.");
                }

                if (musicPlayer != null)
                {
                    musicPlayer.StopMusic();
                }

                yield break;
            }
        }

        yield return(RunModuleCommand(module, user, cmd));
    }
 public TwitchPlaysProperties()
 {
     AddProperty("TimeMode", new Property(() => OtherModes.TimeModeOn, x => OtherModes.TimeModeOn = (bool)x));
     AddProperty("ZenMode", new Property(() => OtherModes.Unexplodable, x => OtherModes.ZenModeOn = (bool)x));
     AddProperty("TimeModeTimeLimit", new Property(() => TwitchPlaySettings.data.TimeModeStartingTime, SetTimeModeTimeLimit));
     AddProperty("ircConnectionSendMessage", new Property(null, x => IRCConnection.SendMessage((string)x)));
     AddProperty("Reward", new Property(() => TwitchPlaySettings.GetRewardBonus(), x => TwitchPlaySettings.SetRewardBonus((int)x)));
     AddProperty("CauseFakeStrike", new Property(null, CauseFakeStrike));
 }
Exemple #4
0
 public static bool DefaultCommand(string cmd, string user, bool isWhisper)
 {
     if (TwitchPlaySettings.data.BombCustomMessages.ContainsKey(cmd.ToLowerInvariant()))
     {
         IRCConnection.SendMessage(TwitchPlaySettings.data.BombCustomMessages[cmd.ToLowerInvariant()], user, !isWhisper);
         return(true);
     }
     return(false);
 }
Exemple #5
0
 public static void SetNotesClear([Group(1)] int index, string user, bool isWhisper)
 {
     IRCConnection.SendMessage(string.Format(TwitchPlaySettings.data.NoteSlotCleared, index), user, !isWhisper);
     index--;
     if (TwitchGame.Instance.NotesDictionary.ContainsKey(index))
     {
         TwitchGame.Instance.NotesDictionary.Remove(index);
     }
     TwitchGame.ModuleCameras?.SetNotes();
 }
    public MotionSenseComponentSolver(TwitchModule module) :
        base(module)
    {
        _component = module.BombComponent.GetComponent(ComponentType);
        _needy     = (KMNeedyModule)NeedyField.GetValue(_component);
        ModInfo    = ComponentSolverFactory.GetModuleInfo(GetModuleType(), "I am a passive module that awards strikes for motion while I am active. Use !{0} status to find out if I am active, and for how long.");
        _needy.OnNeedyActivation += () => IRCConnection.SendMessage($"Motion Sense just activated: Active for {(int) _needy.GetNeedyTimeRemaining()} seconds.");

        _needy.OnTimerExpired += () => IRCConnection.SendMessage("Motion Sense now Inactive.");
    }
 public static void EndVoteEarly(string user)
 {
     if (!Active)
     {
         IRCConnection.SendMessage($"{user}, there is no vote currently in progress.");
         return;
     }
     IRCConnection.SendMessage("The vote is being ended now.");
     VoteTimeRemaining = 0f;
 }
 public static void CancelVote(string user)
 {
     if (!Active)
     {
         IRCConnection.SendMessage($"{user}, there is no vote currently in progress.");
         return;
     }
     IRCConnection.SendMessage("The vote has been cancelled.");
     DestroyVote();
 }
 public static void EnqueueNamedCommand(string user, bool isWhisper, [Group(1)] string name, [Group(2)] string command)
 {
     if (name.Trim().EqualsIgnoreCase("all"))
     {
         IRCConnection.SendMessage(@"@{0}, you can’t use “all” as a name for queued commands.", user, !isWhisper, user);
         return;
     }
     TwitchGame.Instance.CommandQueue.Add(new CommandQueueItem(command, user, name.Trim()));
     TwitchGame.ModuleCameras?.SetNotes();
 }
Exemple #10
0
    private static void ClaimViewOrPin(TwitchModule module, string user, bool isWhisper, bool view, bool pin)
    {
        if (isWhisper)
        {
            IRCConnection.SendMessage($"@{user}, claiming modules is not allowed in whispers.", user, false);
            return;
        }

        IRCConnection.SendMessage(module.TryClaim(user, view, pin).Message);
    }
Exemple #11
0
    public static void Help(TwitchModule module, [Group(1)] bool pdf)
    {
        string manualType = pdf ? "pdf" : "html";

        string manualText = string.IsNullOrEmpty(module.Solver.ManualCode) ? module.HeaderText : module.Solver.ManualCode;
        string helpText   = string.IsNullOrEmpty(module.Solver.HelpMessage) ? string.Empty : string.Format(module.Solver.HelpMessage, module.Code, module.HeaderText);

        IRCConnection.SendMessage(Regex.IsMatch(manualText, @"^https?://", RegexOptions.IgnoreCase)
                        ? $"{module.HeaderText} : {helpText} : {manualText}"
                        : $"{module.HeaderText} : {helpText} : {UrlHelper.Instance.ManualFor(manualText, manualType, VanillaRuleModifier.GetModuleRuleSeed(module.Solver.ModInfo.moduleID) != 1)}");
    }
    public static IEnumerator Run(string user, [Group(1)] string text)
    {
        if (!UserAccess.HasAccess(user, AccessLevel.Admin, true))
        {
            if (!TwitchPlaySettings.data.EnableDMGForEveryone)
            {
                IRCConnection.SendMessage("Only admins can use the DMG.");
                yield break;
            }
            if (!OtherModes.TrainingModeOn)
            {
                IRCConnection.SendMessage("Only admins can use DMG when not in training mode.");
                yield break;
            }
        }

        var pageNavigation = UnityEngine.Object.FindObjectOfType(pageNavigationType);

        // pageNavigation could be null if this command is run multiple times in the setup room.
        if (pageNavigation == null)
        {
            yield break;
        }

        _backStack = pageNavigation.GetValue <Stack <KMSelectable> >("_backStack");

        while (!CurrentPage.name.EqualsAny("PageOne(Clone)", "Home(Clone)"))
        {
            KTInputManager.Instance.HandleCancel();
            yield return(new WaitForSeconds(0.1f));
        }

        if (CurrentPage.name == "Home(Clone)")
        {
            var entryIndex = ReflectionHelper.FindType("PageManager")
                             .GetValue <IList>("HomePageEntryList")
                             .Cast <object>()
                             .IndexOf(entry => entry.GetValue <string>("DisplayName") == "Dynamic Mission Generator");

            if (entryIndex == -1)
            {
                IRCConnection.SendMessage("DMG is not installed.");
                yield break;
            }

            CurrentPage.Children[entryIndex].OnInteract();
            yield return(new WaitForSeconds(0.1f));
        }

        CurrentPage.gameObject.Traverse <InputField>("Canvas", "InputField").text = text;
        yield return(new WaitForSeconds(0.1f));

        CurrentPage.Children.First(button => button.name.Contains("Run")).OnInteract();
    }
Exemple #13
0
 public static void EnqueueNamedCommand(IRCMessage msg, [Group(1)] string name, [Group(2)] string command)
 {
     if (name.Trim().EqualsIgnoreCase("all"))
     {
         IRCConnection.SendMessage(@"@{0}, you can’t use “all” as a name for queued commands.", msg.UserNickName, !msg.IsWhisper, msg.UserNickName);
         return;
     }
     TwitchGame.Instance.CommandQueue.Add(new CommandQueueItem(msg.Duplicate(command), name.Trim()));
     TwitchGame.ModuleCameras?.SetNotes();
     IRCConnection.SendMessage("@{0}, command queued.", msg.UserNickName, !msg.IsWhisper, msg.UserNickName);
 }
Exemple #14
0
    protected override IEnumerator RespondToCommandInternal(string inputCommand)
    {
        if (!inputCommand.Equals("status", StringComparison.InvariantCultureIgnoreCase))
        {
            yield break;
        }

        bool active = (bool)_activeField.GetValue(_component);

        _connection.SendMessage("Motion Sense Status: " + (active ? "Active for " + (int)_needy.GetNeedyTimeRemaining() + " seconds" : "Inactive"));
    }
Exemple #15
0
    public static void FindDuplicate([Group(1)] string queries, string user, bool isWhisper)
    {
        var allMatches = (string.IsNullOrEmpty(queries) ? TwitchGame.Instance.Modules : FindModules(queries.SplitFull(',', ';').Select(q => q.Trim()).Distinct().ToArray()))
                         .GroupBy(module => module.HeaderText)
                         .Where(grouping => grouping.Count() > 1)
                         .Select(grouping => $"{grouping.Key} ({grouping.Select(module => module.Code).Join(", ")})");

        var modules = allMatches.Shuffle().Take(3).ToList();

        IRCConnection.SendMessage(modules.Count > 0 ? $"Duplicates ({allMatches.Count()} total): {modules.Join(", ")}" : "No such duplicate modules.", user, !isWhisper);
    }
Exemple #16
0
    public bool IsAuthorizedDefuser(string userNickName, bool silent = false)
    {
        bool result = (TwitchPlaySettings.data.EnableTwitchPlaysMode || UserAccess.HasAccess(userNickName, AccessLevel.Defuser, true));

        if (!result && !silent)
        {
            _ircConnection.SendMessage(TwitchPlaySettings.data.TwitchPlaysDisabled, userNickName);
        }

        return(result);
    }
Exemple #17
0
 public static void DisableCameraWall(string user)
 {
     if (TwitchPlaySettings.data.EnableAutomaticCameraWall && !UserAccess.HasAccess(user, AccessLevel.Admin, true))
     {
         IRCConnection.SendMessage("The camera wall is being controlled automatically and cannot be disabled.");
     }
     else
     {
         TwitchGame.ModuleCameras.DisableCameraWall();
     }
 }
Exemple #18
0
 public static void ShowClaims(string user, bool isWhisper)
 {
     if (TwitchPlaySettings.data.AnarchyMode)
     {
         IRCConnection.SendMessage($"Sorry {user}, claiming modules is not available in anarchy mode.", user, !isWhisper);
     }
     else
     {
         ShowClaimsOfUser(user, user, isWhisper, TwitchPlaySettings.data.OwnedModuleList, TwitchPlaySettings.data.NoOwnedModules);
     }
 }
Exemple #19
0
    public static bool IsAuthorizedDefuser(string userNickName, bool isWhisper, bool silent = false)
    {
        if (userNickName.EqualsAny("Bomb Factory", TwitchPlaySettings.data.TwitchPlaysDebugUsername) || TwitchGame.Instance.Bombs.Any(x => x.BombName == userNickName))
        {
            return(true);
        }
        BanData ban = UserAccess.IsBanned(userNickName);

        if (ban != null)
        {
            if (silent)
            {
                return(false);
            }

            if (double.IsPositiveInfinity(ban.BanExpiry))
            {
                IRCConnection.SendMessage($"Sorry @{userNickName}, You were banned permanently from Twitch Plays by {ban.BannedBy}{(string.IsNullOrEmpty(ban.BannedReason) ? "." : $", for the following reason: {ban.BannedReason}")}", userNickName, !isWhisper);
            }
            else
            {
                int secondsRemaining = (int)(ban.BanExpiry - DateTime.Now.TotalSeconds());

                int    daysRemaining    = secondsRemaining / 86400; secondsRemaining %= 86400;
                int    hoursRemaining   = secondsRemaining / 3600; secondsRemaining %= 3600;
                int    minutesRemaining = secondsRemaining / 60; secondsRemaining %= 60;
                string timeRemaining    = $"{secondsRemaining} seconds.";
                if (daysRemaining > 0)
                {
                    timeRemaining = $"{daysRemaining} days, {hoursRemaining} hours, {minutesRemaining} minutes, {secondsRemaining} seconds.";
                }
                else if (hoursRemaining > 0)
                {
                    timeRemaining = $"{hoursRemaining} hours, {minutesRemaining} minutes, {secondsRemaining} seconds.";
                }
                else if (minutesRemaining > 0)
                {
                    timeRemaining = $"{minutesRemaining} minutes, {secondsRemaining} seconds.";
                }

                IRCConnection.SendMessage($"Sorry @{userNickName}, You were timed out from Twitch Plays by {ban.BannedBy}{(string.IsNullOrEmpty(ban.BannedReason) ? "." : $", For the following reason: {ban.BannedReason}")} You can participate again in {timeRemaining}", userNickName, !isWhisper);
            }
            return(false);
        }

        bool result = (TwitchPlaySettings.data.EnableTwitchPlaysMode || UserAccess.HasAccess(userNickName, AccessLevel.Defuser, true));

        if (!result && !silent)
        {
            IRCConnection.SendMessage(string.Format(TwitchPlaySettings.data.TwitchPlaysDisabled, userNickName), userNickName, !isWhisper);
        }

        return(result);
    }
Exemple #20
0
 public static IEnumerator Edgework(TwitchBomb bomb, [Group(1)] string edge, string user, bool isWhisper)
 {
     if (TwitchPlaySettings.data.EnableEdgeworkCommand || TwitchPlaySettings.data.AnarchyMode)
     {
         return(bomb.ShowEdgework(edge));
     }
     else
     {
         IRCConnection.SendMessage(string.Format(TwitchPlaySettings.data.BombEdgework, bomb.EdgeworkText.text), user, !isWhisper);
         return(null);
     }
 }
Exemple #21
0
    protected void HandleModuleException(Exception e)
    {
        Debug.Log("[TwitchPlays] While solving a module an exception has occurred! Here's the error:");
        Debug.LogException(e);

        IRCConnection.SendMessage("Looks like a module ran into a problem while running a command, automatically solving module. Some other modules may also be solved to prevent problems.");

        _currentUserNickName        = null;
        _delegatedSolveUserNickName = null;
        BombCommander.RemoveSolveBasedModules();
        CommonReflectedTypeInfo.HandlePassMethod.Invoke(BombComponent, null);
    }
Exemple #22
0
    public static void ListUnclaimed(string user, bool isWhisper)
    {
        IEnumerable <string> unclaimed = TwitchGame.Instance.Modules
                                         .Where(handle => !handle.Claimed && !handle.Solved)
                                         .Shuffle().Take(3)
                                         .Select(handle => string.Format($"{handle.HeaderText} ({handle.Code})"))
                                         .ToList();

        IRCConnection.SendMessage(unclaimed.Any()
                        ? $"Unclaimed Modules: {unclaimed.Join(", ")}"
                        : string.Format(TwitchPlaySettings.data.NoUnclaimed, user), user, !isWhisper);
    }
Exemple #23
0
    public static void ClaimSpecific(string user, bool isWhisper, [Group(1)] bool view1, [Group(2)] bool view2, [Group(3)] string claimWhat)
    {
        var strings = claimWhat.Split(new[] { ' ', ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
        var modules = strings.Length == 0 ? null : TwitchGame.Instance.Modules.Where(md => strings.Any(str => str.EqualsIgnoreCase(md.Code))).ToArray();

        if (modules == null || modules.Length == 0)
        {
            IRCConnection.SendMessage($"{user}: no such module.", user, !isWhisper);
            return;
        }
        Claim(user, isWhisper, view1 || view2, modules);
    }
    private static IEnumerator VotingCoroutine()
    {
        int oldTime;

        while (VoteTimeRemaining >= 0f)
        {
            oldTime            = TimeLeft;
            VoteTimeRemaining -= Time.deltaTime;
            if (TwitchGame.BombActive && TimeLeft != oldTime)             // Once a second, update notes.
            {
                TwitchGame.ModuleCameras.SetNotes();
            }
            yield return(null);
        }

        if (TwitchGame.BombActive && CurrentVoteType == VoteTypes.Detonation)
        {
            // Add claimed users who didn't vote as "no"
            int           numAddedNoVotes = 0;
            List <string> usersWithClaims = TwitchGame.Instance.Modules
                                            .Where(m => !m.Solved && m.PlayerName != null).Select(m => m.PlayerName).Distinct().ToList();
            foreach (string user in usersWithClaims)
            {
                if (!Voters.ContainsKey(user))
                {
                    ++numAddedNoVotes;
                    Voters.Add(user, false);
                }
            }

            if (numAddedNoVotes == 1)
            {
                IRCConnection.SendMessage("1 no vote was added on the behalf of users with claims that did not vote.");
            }
            else if (numAddedNoVotes > 1)
            {
                IRCConnection.SendMessage($"{numAddedNoVotes} no votes were added on the behalf of users with claims that did not vote.");
            }
        }

        int  yesVotes   = Voters.Count(pair => pair.Value);
        bool votePassed = (yesVotes >= Voters.Count * (TwitchPlaySettings.data.MinimumYesVotes[CurrentVoteType] / 100f));

        IRCConnection.SendMessage($"Voting has ended with {yesVotes}/{Voters.Count} yes votes. The vote has {(votePassed ? "passed" : "failed")}.");

        if (votePassed)
        {
            PossibleVotes[CurrentVoteType].onSuccess();
        }

        DestroyVote();
    }
Exemple #25
0
    protected void SolveModule(string reason = "A module is being automatically solved.", bool removeSolveBasedModules = true)
    {
        IRCConnection.SendMessage("{0}{1}", reason, removeSolveBasedModules ? " Some other modules may also be solved to prevent problems." : "");

        _currentUserNickName        = null;
        _delegatedSolveUserNickName = null;

        if (removeSolveBasedModules)
        {
            TwitchComponentHandle.RemoveSolveBasedModules();
        }
        CommonReflectedTypeInfo.HandlePassMethod.Invoke(BombComponent, null);
    }
 public static IEnumerator Retry(string user, bool isWhisper)
 {
     if (!TwitchPlaySettings.data.EnableRetryButton)
     {
         IRCConnection.SendMessage(TwitchPlaySettings.data.RetryInactive, user, isWhisper);
         return(doButton(Object.FindObjectOfType <ResultPage>().ContinueButton));
     }
     else
     {
         TwitchPlaySettings.SetRetryReward();
         return(doButton(Object.FindObjectOfType <ResultPage>().RetryButton));
     }
 }
    public static void LogException(Exception ex, string message = "An exception has occurred:")
    {
        Log(message);
        Debug.LogException(ex);

        // Avoid spamming this message in chat by only posting it at most once every 5 minutes.
        if (Time.time - lastException >= 5 * 60)
        {
            IRCConnection.SendMessage("Something has caused an exception to occur. Please report this to the TP developers and include the logfile for more information.");
        }

        lastException = Time.time;
    }
    public static void ChangeTimer(TwitchBomb bomb, string user, bool isWhisper, [Group(1)] bool negative, [Group(2)] bool direct, [Group(3)] string amount)
    {
        float time         = 0;
        float originalTime = bomb.Bomb.GetTimer().TimeRemaining;
        var   timeLengths  = new Dictionary <string, float>()
        {
            { "ms", 0.001f },
            { "s", 1 },
            { "m", 60 },
            { "h", 3600 },
            { "d", 86400 },
            { "w", 604800 },
            { "y", 31536000 },
        };

        foreach (string part in amount.Split(new[] { ' ', ',', ';' }, StringSplitOptions.RemoveEmptyEntries))
        {
            bool valid = false;
            foreach (string unit in timeLengths.Keys)
            {
                if (!part.EndsWith(unit, StringComparison.InvariantCultureIgnoreCase) || !float.TryParse(part.Substring(0, part.Length - unit.Length), out float length))
                {
                    continue;
                }
                time += length * timeLengths[unit];
                valid = true;
                break;
            }

            if (!valid)
            {
                IRCConnection.SendMessage(@"I don’t understand “{0}”.", user, !isWhisper, part);
                return;
            }
        }

        time = (float)Math.Round((decimal)time, 2, MidpointRounding.AwayFromZero);
        if (!direct && Math.Abs(time) < 0.01f)
        {
            return;
        }

        bomb.CurrentTimer = direct ? time : negative ? bomb.CurrentTimer - time : bomb.CurrentTimer + time;

        // If the time requested was negative, we need to flip the message.
        bool negativeTime = time < 0 ? !negative : negative;

        IRCConnection.SendMessage(direct
                        ? $"Set the bomb's timer to {Math.Abs(time < 0 ? 0 : time).FormatTime()}."
                        : $"{(negativeTime ? "Subtracted" : "Added")} {Math.Abs(time).FormatTime()} {(negativeTime ? "from" : "to")} the timer.", user, !isWhisper);
    }
Exemple #29
0
 public static void SetNotesAppend([Group(1)] int index, [Group(2)] string notes, string user, bool isWhisper)
 {
     IRCConnection.SendMessage(string.Format(TwitchPlaySettings.data.NotesAppended, index, notes), user, !isWhisper);
     index--;
     if (TwitchGame.Instance.NotesDictionary.ContainsKey(index))
     {
         TwitchGame.Instance.NotesDictionary[index] += " " + notes;
     }
     else
     {
         TwitchGame.Instance.NotesDictionary[index] = notes;
     }
     TwitchGame.ModuleCameras?.AppendNotes(index, notes);
 }
Exemple #30
0
 public static void ShowClaimsOfAnotherPlayer([Group(1)] string targetUser, string user, bool isWhisper)
 {
     if (TwitchPlaySettings.data.AnarchyMode)
     {
         IRCConnection.SendMessage($"Sorry {user}, claiming modules is not available in anarchy mode.", user, !isWhisper);
     }
     else if (isWhisper && TwitchPlaySettings.data.EnableWhispers)
     {
         IRCConnection.SendMessage("Checking other people's claims in whispers is not supported.", user, false);
     }
     else
     {
         ShowClaimsOfUser(targetUser, user, isWhisper, TwitchPlaySettings.data.OwnedModuleListOther, TwitchPlaySettings.data.NoOwnedModulesOther);
     }
 }