diff --git a/Assemblies/RimGPT.dll b/Assemblies/RimGPT.dll index e8e45c8..969fabe 100644 Binary files a/Assemblies/RimGPT.dll and b/Assemblies/RimGPT.dll differ diff --git a/Source/AI.cs b/Source/AI.cs index 48147a1..021c10d 100644 --- a/Source/AI.cs +++ b/Source/AI.cs @@ -109,6 +109,7 @@ public async Task Evaluate(Persona persona, IEnumerable observat if (lastIndex >= 0) response = response.Substring(firstIdx, lastIndex - firstIdx + 1); } + response = response.Replace("ResponseText:", ""); if (Tools.DEBUG) Logger.Warning($"OUTPUT: {response}"); diff --git a/Source/Main.cs b/Source/Main.cs index f8a18bf..2ad74a4 100644 --- a/Source/Main.cs +++ b/Source/Main.cs @@ -1,12 +1,12 @@ using Brrainz; using HarmonyLib; -using System.Collections.Concurrent; using System; +using System.Collections; +using System.Collections.Concurrent; using System.Threading; using System.Threading.Tasks; using UnityEngine; using Verse; -using System.Collections; namespace RimGPT { diff --git a/Source/OpenAI/Configuration.cs b/Source/OpenAI/Configuration.cs index af9afce..dff1d6c 100644 --- a/Source/OpenAI/Configuration.cs +++ b/Source/OpenAI/Configuration.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using RimGPT; using System; diff --git a/Source/OpenAI/CustomNamingStrategy.cs b/Source/OpenAI/CustomNamingStrategy.cs index 5096714..47bb97c 100644 --- a/Source/OpenAI/CustomNamingStrategy.cs +++ b/Source/OpenAI/CustomNamingStrategy.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json.Serialization; +using Newtonsoft.Json.Serialization; using System.Text.RegularExpressions; namespace OpenAI diff --git a/Source/OpenAI/DataTypes.cs b/Source/OpenAI/DataTypes.cs index 7c7b654..ec3b275 100644 --- a/Source/OpenAI/DataTypes.cs +++ b/Source/OpenAI/DataTypes.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using Newtonsoft.Json; using System.Collections.Generic; namespace OpenAI diff --git a/Source/OpenAI/ExtensionMethods.cs b/Source/OpenAI/ExtensionMethods.cs index 0ffc20f..cc68a51 100644 --- a/Source/OpenAI/ExtensionMethods.cs +++ b/Source/OpenAI/ExtensionMethods.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using UnityEngine.Networking; diff --git a/Source/OpenAI/IResponse.cs b/Source/OpenAI/IResponse.cs index 5a928c4..5381c19 100644 --- a/Source/OpenAI/IResponse.cs +++ b/Source/OpenAI/IResponse.cs @@ -1,4 +1,4 @@ -namespace OpenAI +namespace OpenAI { public interface IResponse { diff --git a/Source/OpenAI/OpenAIApi.cs b/Source/OpenAI/OpenAIApi.cs index 8a603e4..e4210cc 100644 --- a/Source/OpenAI/OpenAIApi.cs +++ b/Source/OpenAI/OpenAIApi.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using RimGPT; using System; @@ -68,6 +68,13 @@ private async Task ProcessRequest(UnityWebRequest request, Action } var response = request.downloadHandler.text; + if (response != null) + { + if (response.StartsWith("{") == false) + response = "{" + response; + if (response.Contains("}") == false) + response += "}"; + } var code = request.responseCode; if (code >= 300) { diff --git a/Source/Persona.cs b/Source/Persona.cs index be2665b..46f2ba0 100644 --- a/Source/Persona.cs +++ b/Source/Persona.cs @@ -1,8 +1,8 @@ -using Verse; +using HarmonyLib; using System; using System.Linq; -using HarmonyLib; using System.Xml.Linq; +using Verse; namespace RimGPT { diff --git a/Source/Personas.cs b/Source/Personas.cs index e55bdb8..3972da6 100644 --- a/Source/Personas.cs +++ b/Source/Personas.cs @@ -90,7 +90,7 @@ public static void UpdateVoiceInformation() TTS.voices = new Voice[0]; if (RimGPTMod.Settings.azureSpeechKey == "" || RimGPTMod.Settings.azureSpeechRegion == "") return; - + Tools.SafeAsync(async () => { TTS.voices = await TTS.DispatchFormPost($"{TTS.APIURL}/voices/list", null, true, null); diff --git a/Source/SSML/FluentSayTime.cs b/Source/SSML/FluentSayTime.cs index 29d3f6b..0381bfe 100644 --- a/Source/SSML/FluentSayTime.cs +++ b/Source/SSML/FluentSayTime.cs @@ -48,17 +48,12 @@ private static string GetValue(TimeSpan value, TimeFormat format) private static string GetFormat(TimeFormat format) { - switch (format) + return format switch { - case TimeFormat.TwelveHour: - return "hms12"; - - case TimeFormat.TwentyFourHour: - return "hms24"; - - default: - throw new ArgumentOutOfRangeException(); - } + TimeFormat.TwelveHour => "hms12", + TimeFormat.TwentyFourHour => "hms24", + _ => throw new ArgumentOutOfRangeException(), + }; } } } \ No newline at end of file diff --git a/Source/SSML/Ssml.cs b/Source/SSML/Ssml.cs index eb27e9e..5ff6685 100644 --- a/Source/SSML/Ssml.cs +++ b/Source/SSML/Ssml.cs @@ -111,13 +111,11 @@ public async Task ToStringAsync() Async = true }; - using (var xmlWriter = XmlWriter.Create(stringBuilder, xmlWriterSettings)) - { - await Write(xmlWriter); - await xmlWriter.FlushAsync(); + using var xmlWriter = XmlWriter.Create(stringBuilder, xmlWriterSettings); + await Write(xmlWriter); + await xmlWriter.FlushAsync(); - return stringBuilder.ToString(); - } + return stringBuilder.ToString(); } public IBreak Break() diff --git a/Source/Settings.cs b/Source/Settings.cs index a4b7d09..2318b90 100644 --- a/Source/Settings.cs +++ b/Source/Settings.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using UnityEngine; @@ -202,7 +203,7 @@ public void DoWindowContents(Rect inRect) list.Gap(16f); - list.Label("FFFF00", "Personas"); + list.Label("FFFF00", "Active personas", "", "All these personas are active and talk about the game and to each other."); var height = inRect.height - UX.ButtonHeight - 24f - list.CurHeight; var outerRect = list.GetRect(height); @@ -324,22 +325,27 @@ public void DoWindowContents(Rect inRect) list.Gap(16f); - _ = list.Label("Sending game information"); - list.Slider(ref selected.phrasesLimit, 1, 100, n => $"Max phrase count: {n}"); + _ = list.Label("Sending game information", -1, "RimGPT limits when and what it sends to ChatGPT. It collects phrases from the game and other personas until after some time it sends some of the phrases batched together to create a comment."); + list.Slider(ref selected.phrasesLimit, 1, 100, n => $"Max phrase count: {n}", 1, "How many unsend phrases should RimGPT keep at a maximum?"); selected.phraseBatchSize = Mathf.Min(selected.phraseBatchSize, selected.phrasesLimit); - list.Slider(ref selected.phraseBatchSize, 1, selected.phrasesLimit, n => $"Batch size: {n} phrases"); + list.Slider(ref selected.phraseBatchSize, 1, selected.phrasesLimit, n => $"Batch size: {n} phrases", 1, "How many phrases should RimGPT send batched together in its data to ChatGPT?"); list.Gap(16f); - _ = list.Label("Delay between comments"); - list.Slider(ref selected.phraseDelayMin, 5f, 1200f, f => $"Min: {Mathf.FloorToInt(f + 0.01f)} sec", 1f, 2); - if (selected.phraseDelayMin > selected.phraseDelayMax) selected.phraseDelayMin = selected.phraseDelayMax; - list.Slider(ref selected.phraseDelayMax, 5f, 1200f, f => $"Max: {Mathf.FloorToInt(f + 0.01f)} sec", 1f, 2); - if (selected.phraseDelayMax < selected.phraseDelayMin) selected.phraseDelayMax = selected.phraseDelayMin; + _ = list.Label("Delay between comments", -1, "To optimize, RimGPT collects text and phrases and only sends it in intervals to ChatGPT to create comments."); + list.Slider(ref selected.phraseDelayMin, 5f, 1200f, f => $"Min: {Mathf.FloorToInt(f + 0.01f)} sec", 1f, 2, "RimGPT creates comments in intervals. What is the shortest time between comments?"); + if (selected.phraseDelayMin > selected.phraseDelayMax) + selected.phraseDelayMin = selected.phraseDelayMax; + var oldMax = selected.phraseDelayMax; + list.Slider(ref selected.phraseDelayMax, 5f, 1200f, f => $"Max: {Mathf.FloorToInt(f + 0.01f)} sec", 1f, 2, "RimGPT creates comments in intervals. What is the longest time between comments?"); + if (selected.phraseDelayMax < selected.phraseDelayMin) + selected.phraseDelayMax = selected.phraseDelayMin; + if (oldMax > selected.phraseDelayMax) + selected.nextPhraseTime = DateTime.Now.AddSeconds(selected.phraseDelayMin); list.Gap(16f); _ = list.Label("Comments"); - list.Slider(ref selected.phraseMaxWordCount, 1, 160, n => $"Max words: {n}"); + list.Slider(ref selected.phraseMaxWordCount, 1, 160, n => $"Max words: {n}", 1, "RimGPT instructs ChatGPT to generate comments that are no longer than this amount of words."); list.Gap(16f); _ = list.Label("History"); - list.Slider(ref selected.historyMaxWordCount, 200, 1200, n => $"Max words: {n}"); + list.Slider(ref selected.historyMaxWordCount, 200, 1200, n => $"Max words: {n}", 1, "RimGPT lets ChatGPT create a history summary that is then send together with new requests to form some kind of memory for ChatGPT. What is the maximum size of the history?"); list.Gap(16f); width = (list.ColumnWidth - 2 * 20) / 3; diff --git a/Source/Tools.cs b/Source/Tools.cs index 827b5d6..60be19e 100644 --- a/Source/Tools.cs +++ b/Source/Tools.cs @@ -32,9 +32,11 @@ public readonly struct Strings public static string PlayerName() { - if (SteamManager.Initialized == false) return null; + if (SteamManager.Initialized == false) + return null; var name = SteamFriends.GetPersonaName(); - if (name == "Brrainz") name = "Andreas"; // for testing + if (name == "Brrainz") + name = "Andreas"; // for testing return name; } @@ -45,10 +47,10 @@ public static async void ReloadGPTModels() var error = response.Error; if (error != null) return; - + var result = response.Data - .Select(m => m.Id) - .Where(id => id.StartsWith("gpt")) + .Select(m => m?.Id) + .Where(id => id?.StartsWith("gpt") ?? false) .OrderBy(id => id) .ToArray(); if (result.Length == 0) diff --git a/Source/Tools/Debouncer.cs b/Source/Tools/Debouncer.cs index 38908c6..2163446 100644 --- a/Source/Tools/Debouncer.cs +++ b/Source/Tools/Debouncer.cs @@ -18,11 +18,7 @@ public void Debounce(Action action) { lock (_lockObject) { - if (_debounceTimer != null) - { - _debounceTimer.Dispose(); - } - + _debounceTimer?.Dispose(); _debounceTimer = new Timer( _ => action(), null, diff --git a/Source/UX.cs b/Source/UX.cs index 58f56cb..83277a6 100644 --- a/Source/UX.cs +++ b/Source/UX.cs @@ -3,7 +3,6 @@ using System.Linq; using UnityEngine; using Verse; -using static RimGPT.AI; namespace RimGPT { @@ -11,7 +10,7 @@ public static class UX { public const float ButtonHeight = 24f; - public static void SmallLabel(this Listing_Standard list, string text) + /*public static void SmallLabel(this Listing_Standard list, string text, string tooltip = null) { var rect = list.GetRect(20f); var anchor = Text.Anchor; @@ -21,12 +20,16 @@ public static void SmallLabel(this Listing_Standard list, string text) Widgets.Label(rect, text); Text.Anchor = anchor; Text.Font = font; - } + if (tooltip != null) + TooltipHandler.TipRegion(rect, tooltip); + }*/ - public static void Label(this Listing_Standard list, string hexColor, string textLeft, string textRight = "") + public static void Label(this Listing_Standard list, string hexColor, string textLeft, string textRight = "", string tooltip = null) { var size = Text.CalcSize(textLeft); var rect = list.GetRect(size.y); + if (tooltip != null) + TooltipHandler.TipRegion(rect, tooltip); var anchor = Text.Anchor; Text.Anchor = TextAnchor.MiddleLeft; Widgets.Label(rect.LeftPartPixels(size.x), new TaggedString($"{textLeft}")); @@ -62,29 +65,29 @@ public static void TextField(this Listing_Standard list, ref string text, string text = list.TextEntry(text); } - public static void Slider(this Listing_Standard list, ref int value, int min, int max, Func label, int logarithmic = 1) + public static void Slider(this Listing_Standard list, ref int value, int min, int max, Func label, int logarithmic = 1, string tooltip = null) { var input = logarithmic != 1 ? Mathf.Log(value, logarithmic) : value; var min2 = logarithmic != 1 ? Mathf.Log(min, logarithmic) : min; var max2 = logarithmic != 1 ? Mathf.Log(max, logarithmic) : max; - HorizontalSlider(list.GetRect(22f), ref input, min2, max2, label == null ? null : label(Mathf.FloorToInt((logarithmic != 1 ? Mathf.Pow(logarithmic, input) : input) + 0.001f)), 1f); + HorizontalSlider(list.GetRect(22f), ref input, min2, max2, label == null ? null : label(Mathf.FloorToInt((logarithmic != 1 ? Mathf.Pow(logarithmic, input) : input) + 0.001f)), 1f, tooltip); value = Mathf.FloorToInt((logarithmic != 1 ? Mathf.Pow(logarithmic, input) : input) + 0.001f); list.Gap(2f); } - public static void Slider(this Listing_Standard list, ref float value, float min, float max, Func label, float roundTo = -1f, int logarithmic = 1) + public static void Slider(this Listing_Standard list, ref float value, float min, float max, Func label, float roundTo = -1f, int logarithmic = 1, string tooltip = null) { var input = logarithmic != 1 ? Mathf.Log(value, logarithmic) : value; var min2 = logarithmic != 1 ? Mathf.Log(min, logarithmic) : min; var max2 = logarithmic != 1 ? Mathf.Log(max, logarithmic) : max; - HorizontalSlider(list.GetRect(22f), ref input, min2, max2, label == null ? null : label(logarithmic != 1 ? Mathf.Pow(logarithmic, input) : input)); + HorizontalSlider(list.GetRect(22f), ref input, min2, max2, label == null ? null : label(logarithmic != 1 ? Mathf.Pow(logarithmic, input) : input), -1f, tooltip); value = Mathf.Max(min, Mathf.Min(max, logarithmic != 1 ? Mathf.Pow(logarithmic, input) : input)); if (roundTo > 0f) value = Mathf.RoundToInt(value / roundTo) * roundTo; list.Gap(2f); } - public static void HorizontalSlider(Rect rect, ref float value, float leftValue, float rightValue, string label, float roundTo = -1f) + public static void HorizontalSlider(Rect rect, ref float value, float leftValue, float rightValue, string label, float roundTo = -1f, string tooltip = null) { var first = rect.width / 2.5f; var second = rect.width - first; @@ -102,6 +105,9 @@ public static void HorizontalSlider(Rect rect, ref float value, float leftValue, value = GUI.HorizontalSlider(rect.RightPartPixels(second), value, leftValue, rightValue); if (roundTo > 0f) value = Mathf.RoundToInt(value / roundTo) * roundTo; + + if (tooltip != null) + TooltipHandler.TipRegion(rect, tooltip); } public static string TextAreaScrollable(Rect rect, string text, ref Vector2 scrollbarPosition)