diff --git a/Languages/English/Keyed/Help.xml b/Languages/English/Keyed/Help.xml index 52dd7fd..93e84eb 100644 --- a/Languages/English/Keyed/Help.xml +++ b/Languages/English/Keyed/Help.xml @@ -9,5 +9,26 @@ Normally if a viewer is using Puppeteer, all Twitch Toolkit responses go to their browser. This option makes the response also go to Twitch chat. Areas for restrictions. Each area is either global if it has no cells or specific to the cells marked (use +/- buttons to edit). You then turn areas on/off for each colonist in the previous list. Displaying areas can be turned on/off with a button in the bottom right of the screen. The list of restrictions is global and you can select (green checkmark) which are active for this area. + + + + Allows the Viewer to Drop their Gear/Items/Food etc. through Puppeteer + Allows the Viewer to Command their Pawn Through the Map. (Haul, Harvest, Jail, etc.) + Allows the Viewer to Draft/Undraft their Pawn + Allows the Viewer to change the reaction the Pawn has to being Shot (default is flee) + Allow the Viewer to change their Work Prios (Very Buggy, only works if streamer has the workinterface open) + Allow the Viewer to change their Sleepschedule (Very Buggy, only works if streamer has the Scheduleinterface open) + Allow Custom Map Interactions (Mod Items). This is a very dangerous one as far as I can tell. + Allow Viewers to change their Area Restrictions + Allows the Viewer to Move their Pawn when drafted. + I honestly haven't quite figured out yet how far this permission stretches + Nom Nom + This will stop your Client from sending the Puppeteer map to the Server. This should in theory massively increase Performance. + + This permissions allows viewers to: Choose a target to attack, Change their Weapon, Select Outfit policy, select Drug policy, and a few other minor things. + + NUCLEAR OPTION: No TTK Botmessage will appear in your chat anymore. Forces Viewer to use Puppeteer website if they want to see the response. + + Will try to automagically assign Viewers to their TTK Pawns diff --git a/Languages/English/Keyed/Text.xml b/Languages/English/Keyed/Text.xml index 43c204a..2c2a45f 100644 --- a/Languages/English/Keyed/Text.xml +++ b/Languages/English/Keyed/Text.xml @@ -11,5 +11,23 @@ Control cooldown preventing respawn (game hours) Send Toolkit chat responses to Twitch - + + Enable Dropping Gear/Items + Enable General Map Interaction + Enable Drafting + Enable Changing Combat Response + Enable Changing Priority + Enable Changing Schedule + Allow Custom Map Interactions (Mod Items) + Allow Changing allowed Zones + Enable Moving Drafted Pawns + Allow Selecting of Areas + Enable Force Consuming Items/Food + Enable Puppeteer Map (reduces Performance) + + Enable Multiple Features + + Remove every single TTK Chatresponse + + Automatically Assign Pawns diff --git a/Source/Core/Jobs.cs b/Source/Core/Jobs.cs index 4bd7b4e..86e1aa0 100644 --- a/Source/Core/Jobs.cs +++ b/Source/Core/Jobs.cs @@ -46,6 +46,7 @@ void RunOnQueue(Func action, string actionName = null) case "attack-target": if (settings.enabled == false) return; + if (!PuppeteerMod.Settings.SendGlobalJob) return; RunOnQueue(AttackTarget, job.method); break; @@ -55,6 +56,7 @@ void RunOnQueue(Func action, string actionName = null) case "select-weapon": if (settings.enabled == false) return; + if (!PuppeteerMod.Settings.SendGlobalJob) return; RunOnQueue(SelectWeapon, job.method); break; @@ -64,6 +66,7 @@ void RunOnQueue(Func action, string actionName = null) case "select-outfit": if (settings.enabled == false) return; + if (!PuppeteerMod.Settings.SendGlobalJob) return; RunOnQueue(SelectOutfit, job.method); break; @@ -73,6 +76,7 @@ void RunOnQueue(Func action, string actionName = null) case "select-drug": if (settings.enabled == false) return; + if (!PuppeteerMod.Settings.SendGlobalJob) return; RunOnQueue(SelectDrug, job.method); break; @@ -82,6 +86,7 @@ void RunOnQueue(Func action, string actionName = null) case "do-rest": if (settings.enabled == false) return; + if (!PuppeteerMod.Settings.SendGlobalJob) return; RunOnQueue(DoRest, job.method); break; @@ -91,6 +96,7 @@ void RunOnQueue(Func action, string actionName = null) case "do-tend": if (settings.enabled == false) return; + if (!PuppeteerMod.Settings.SendGlobalJob) return; RunOnQueue(DoTend, job.method); break; diff --git a/Source/Core/StateCommand.cs b/Source/Core/StateCommand.cs index 182e82d..73fe76c 100644 --- a/Source/Core/StateCommand.cs +++ b/Source/Core/StateCommand.cs @@ -32,12 +32,14 @@ public static void Set(Connection connection, IncomingState state) { case "hostile-response": if (settings.enabled == false) return; + if (!PuppeteerMod.Settings.SendHostileresponse) return; var responseMode = (HostilityResponseMode)Enum.Parse(typeof(HostilityResponseMode), state.val.ToString()); pawn.playerSettings.hostilityResponse = responseMode; pawn.RemoteLog($"Response Mode to {responseMode}"); break; case "drafted": if (settings.enabled == false) return; + if (!PuppeteerMod.Settings.SendDrafted) return; var drafted = Convert.ToBoolean(state.val); if (Tools.CannotMoveOrDo(pawn) == false) pawn.FakeDraft(drafted); @@ -45,6 +47,7 @@ public static void Set(Connection connection, IncomingState state) break; case "zone": if (settings.enabled == false) return; + if (!PuppeteerMod.Settings.SendZone) return; var area = pawn.Map.areaManager.AllAreas.Where(a => a.AssignableAsAllowed()).FirstOrDefault(a => a.Label == state.val.ToString()); pawn.playerSettings.AreaRestriction = area; pawn.RemoteLog(area == null ? "Area unrestricted" : $"Area restricted to {area.Label}"); @@ -52,6 +55,7 @@ public static void Set(Connection connection, IncomingState state) case "priority": { if (settings.enabled == false) return; + if (!PuppeteerMod.Settings.SendPriority) return; var val = Convert.ToInt32(state.val); var idx = val / 100; var prio = val % 100; @@ -66,6 +70,7 @@ public static void Set(Connection connection, IncomingState state) case "schedule": { if (settings.enabled == false) return; + if (!PuppeteerMod.Settings.SendSchedule) return; var pair = Convert.ToString(state.val).Split(':'); if (pair.Length == 2) { @@ -86,6 +91,7 @@ public static void Set(Connection connection, IncomingState state) } case "grid": { + if (!PuppeteerMod.Settings.SendGrid) return; var grid = Tools.SafeParse(state.val, 4); Renderer.RenderMap(puppeteer, grid); break; @@ -93,6 +99,7 @@ public static void Set(Connection connection, IncomingState state) case "goto": { if (settings.enabled == false) return; + if (!PuppeteerMod.Settings.SendGoto) return; var val = Convert.ToString(state.val); var coordinates = val.Split(',').Select(v => { if (int.TryParse(v, out var n)) return n; else return -1000; }).ToArray(); if (coordinates.Length == 2) @@ -154,6 +161,7 @@ public static void Set(Connection connection, IncomingState state) case "action": { if (settings.enabled == false) return; + if (!PuppeteerMod.Settings.SendAction) return; var id = Convert.ToString(state.val); _ = Actions.RunAction(pawn, id); break; @@ -161,6 +169,7 @@ public static void Set(Connection connection, IncomingState state) case "select": { var val = Convert.ToString(state.val); + if (!PuppeteerMod.Settings.SendSelect) return; var coordinates = val.Split(',').Select(v => { if (int.TryParse(v, out var n)) return n; else return -1000; }).ToArray(); if (coordinates.Length == 2) { @@ -256,6 +265,7 @@ void renderOp() case "gizmo": { if (settings.enabled == false) return; + if (!PuppeteerMod.Settings.SendGizmo) return; var id = Convert.ToString(state.val); _ = GizmosHandler.RunAction(pawn, id); break; @@ -263,6 +273,7 @@ void renderOp() case "consume": { if (settings.enabled == false) return; + if (!PuppeteerMod.Settings.SendConsume) return; var id = Convert.ToString(state.val); var thing = pawn.inventory.GetDirectlyHeldThings().FirstOrDefault(t => t.ThingID == id); if (thing != null) @@ -277,6 +288,7 @@ void renderOp() case "drop": { if (settings.enabled == false) return; + if (!PuppeteerMod.Settings.SendDrop) return; var id = Convert.ToString(state.val); var thing = pawn.inventory.GetDirectlyHeldThings().FirstOrDefault(t => t.ThingID == id); if (thing != null) diff --git a/Source/Mod/Controller.cs b/Source/Mod/Controller.cs index 31ad281..0f2dcc7 100644 --- a/Source/Mod/Controller.cs +++ b/Source/Mod/Controller.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Reflection; using System.Timers; +using TwitchToolkit.PawnQueue; using UnityEngine; using Verse; using static HarmonyLib.AccessTools; @@ -147,6 +148,20 @@ public void SetEvent(PuppeteerEvent evt) } } + public static Pawn trygetpawnfromviewer(ViewerID thebase) + { + + if (!((GameComponentPawns)Current.Game.GetComponent()).HasUserBeenNamed(thebase.name)) + { + //Log.Warning("User " + thebase.name + " joined and tried to claim a unassigned TTK Pawn."); + return null; + } + + return Find.Maps + .SelectMany(map => PlayerPawns.FreeColonists(map, false)) + .FirstOrDefault(pawn => ((NameTriple)pawn.Name).Nick == thebase.name); + } + public void Message(byte[] msg) { if (connection == null) return; @@ -164,7 +179,25 @@ public void Message(byte[] msg) break; } case "join": - GeneralCommands.Join(connection, Join.Create(msg).viewer); + var joiner = Join.Create(msg).viewer; + + GeneralCommands.Join(connection, joiner); + + //Automagically assigning Pawns to Viewers with the same name (Sudo TTK automation) + + if (!PuppeteerMod.Settings.TryMagic) break; + + var Pup = State.Instance.PuppeteerForViewer(joiner); + + if (Pup.puppet == null) + { + Pawn viewerpawn = trygetpawnfromviewer(joiner); + if (viewerpawn != null) + { + AssignViewerToPawn(joiner, viewerpawn); + Log.Warning("Automagically assigned " + joiner.name + " to his assigned TTK pawn."); + } + } break; case "leave": GeneralCommands.Leave(Leave.Create(msg).viewer); diff --git a/Source/Mod/Settings.cs b/Source/Mod/Settings.cs index cf866b6..9dfbe62 100644 --- a/Source/Mod/Settings.cs +++ b/Source/Mod/Settings.cs @@ -16,6 +16,22 @@ public class Settings public int playerActionCooldownTicks = GenDate.TicksPerHour; public bool sendChatResponsesToTwitch = false; + public bool SendAction = false; + public bool SendDrop = false; + public bool SendDrafted = false; + public bool SendHostileresponse = false; + public bool SendSchedule = true; + public bool SendGizmo = false; + public bool SendZone = false; + public bool SendGoto = true; + public bool SendSelect = false; + public bool SendConsume = true; + public bool SendGrid = true; + public bool SendGlobalJob = true; + public bool SendPriority = true; + public bool ForcePuppeteerChat = false; + public bool TryMagic = true; + public HashSet menuCommands = new HashSet(); } @@ -63,6 +79,51 @@ public static void DoWindowContents(ref Settings settings, Rect inRect) list.Gap(10f); list.Dialog_Checkbox("SendChatResponsesToTwitch", ref settings.sendChatResponsesToTwitch); + + list.Gap(10f); + list.Dialog_Checkbox("ForcePuppeteerChat", ref settings.ForcePuppeteerChat); + + list.Gap(10f); + list.Dialog_Checkbox("TryMagic", ref settings.TryMagic); + + list.Gap(10f); + list.Dialog_Checkbox("SendGrid", ref settings.SendGrid); + + list.Gap(10f); + list.Dialog_Checkbox("SendAction", ref settings.SendAction); + + list.Gap(10f); + list.Dialog_Checkbox("SendGizmo", ref settings.SendGizmo); + + list.Gap(10f); + list.Dialog_Checkbox("SendSchedule", ref settings.SendSchedule); + + list.Gap(10f); + list.Dialog_Checkbox("SendPriority", ref settings.SendSchedule); + + list.Gap(10f); + list.Dialog_Checkbox("SendDrafted", ref settings.SendDrafted); + + list.Gap(10f); + list.Dialog_Checkbox("SendDrop", ref settings.SendDrop); + + list.Gap(10f); + list.Dialog_Checkbox("SendGoto", ref settings.SendGoto); + + list.Gap(10f); + list.Dialog_Checkbox("SendHostileresponse", ref settings.SendHostileresponse); + + list.Gap(10f); + list.Dialog_Checkbox("SendZone", ref settings.SendZone); + + list.Gap(10f); + list.Dialog_Checkbox("SendSelect", ref settings.SendSelect); + + list.Gap(10f); + list.Dialog_Checkbox("SendConsume", ref settings.SendConsume); + + list.Gap(10f); + list.Dialog_Checkbox("SendJob", ref settings.SendGlobalJob); } list.End(); diff --git a/Source/Services/TwitchToolkit.cs b/Source/Services/TwitchToolkit.cs index ad8f37d..6dc310c 100644 --- a/Source/Services/TwitchToolkit.cs +++ b/Source/Services/TwitchToolkit.cs @@ -115,9 +115,9 @@ public static MethodBase TargetMethod() public static bool Prefix(string message) { if (!message.Contains('→') && !message.StartsWith("@")) - { + { return true; - } + } /*var match = parser.Match(message); if (!match.Success) @@ -130,28 +130,35 @@ public static bool Prefix(string message) var puppeteer = State.Instance.PuppeteerForViewerName(username); if (username == "" || newmessage == "") - { + { string[] test = message.Split(' '); puppeteer = State.Instance.PuppeteerForViewerName(test[0]); - if(puppeteer == null) - { + if (puppeteer == null && !PuppeteerMod.Settings.ForcePuppeteerChat) + { return true; } newmessage = message.Substring(test[0].Length + 1); } - if (puppeteer == null || puppeteer.connected == false) return true; + if (puppeteer == null || puppeteer.connected == false) + { + if (!PuppeteerMod.Settings.ForcePuppeteerChat) + { + return true; + } + return false; + } Controller.instance.SendChatMessage(puppeteer.vID, newmessage); - if (!PuppeteerMod.Settings.sendChatResponsesToTwitch) - { + if (!PuppeteerMod.Settings.sendChatResponsesToTwitch || PuppeteerMod.Settings.ForcePuppeteerChat) + { return false; - } + } return true; } private static string getname(string message) - { + { string sendback = ""; if (message.Contains("→")) @@ -161,17 +168,17 @@ private static string getname(string message) if (userName.StartsWith("@")) userName = userName.Substring(1); sendback = userName; } - else if(message.StartsWith("@")) + else if (message.StartsWith("@")) { string[] name = message.Split(' '); sendback = name[0].Substring(1); } return sendback; - } + } private static string getmessage(string message) - { + { string sendback = ""; if (message.Contains("→")) @@ -188,7 +195,7 @@ private static string getmessage(string message) } return sendback; - } + } } }