Skip to content

Commit

Permalink
2.4.0: New features, fixes
Browse files Browse the repository at this point in the history
- Added restart prompt to Mods dialog
- Added automatic restart setting
- Mod load order changes are now detected and will also prompt for a restart
- Added "Files" menu to log window: open log file, browse save and mods directories
- Added hotkeys for opening the log file and restarting the game (define to use)
- "already detoured" error will now properly report on the existing destination
- Fixed ModSettingsPack mod name accessibility
  • Loading branch information
UnlimitedHugs committed Jan 31, 2017
1 parent bec28c6 commit 517165d
Show file tree
Hide file tree
Showing 21 changed files with 357 additions and 119 deletions.
3 changes: 3 additions & 0 deletions HugsLib.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@
<Compile Include="Source\Attrib\AttributeDetector.cs" />
<Compile Include="Source\Attrib\DetectableAttributeHandler.cs" />
<Compile Include="Source\Attrib\IDetectableAttribute.cs" />
<Compile Include="Source\Core\KeyBindingHandler.cs" />
<Compile Include="Source\Restarter\Dialog_RestartGame.cs" />
<Compile Include="Source\Restarter\AutoRestarter.cs" />
<Compile Include="Source\Shell\Shell.cs" />
<Compile Include="Source\Shell\ShellOpenDirectory.cs" />
<Compile Include="Source\Shell\ShellOpenLog.cs" />
Expand Down
2 changes: 1 addition & 1 deletion Mods/HugsLib/About/About.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
<targetVersion>0.16.0</targetVersion>
<description>&lt;color=orange&gt;&lt;b&gt;Important: &lt;/b&gt; This mod should be one of the first to be loaded to work properly.&lt;/color&gt;\n
HugsLib is a library that provides shared functionality to other mods.
Version: 2.3.3
Version: 2.4.0
</description>
</ModMetaData>
2 changes: 1 addition & 1 deletion Mods/HugsLib/About/Version.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<VersionData>
<overrideVersion>2.3.3</overrideVersion>
<overrideVersion>2.4.0</overrideVersion>
<gitHubRepository>UnlimitedHugs/RimworldHugsLib</gitHubRepository>
</VersionData>
Binary file modified Mods/HugsLib/Assemblies/HugsLib.dll
Binary file not shown.
16 changes: 14 additions & 2 deletions Mods/HugsLib/Defs/KeyBindingDefs/KeyBindings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,20 @@
<KeyBindingDef>
<category>HugsLibShortcuts</category>
<defName>PublishLogs</defName>
<label>Share log file (hold Ctrl)</label>
<label>Publish log file (hold Ctrl)</label>
<defaultKeyCodeA>F12</defaultKeyCodeA>
</KeyBindingDef>


<KeyBindingDef>
<category>HugsLibShortcuts</category>
<defName>OpenLogFile</defName>
<label>Open log file</label>
</KeyBindingDef>

<KeyBindingDef>
<category>HugsLibShortcuts</category>
<defName>RestartRimworld</defName>
<label>Restart Rimworld</label>
</KeyBindingDef>

</KeyBindingDefs>
15 changes: 14 additions & 1 deletion Mods/HugsLib/Languages/English/Keyed/English.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<HugsLib_logs_copy>Copy</HugsLib_logs_copy>
<HugsLib_logs_shareBtn>Share logs</HugsLib_logs_shareBtn>
<HugsLib_logs_shareConfirmTitle>Confirm</HugsLib_logs_shareConfirmTitle>
<HugsLib_logs_shareConfirmMessage>Upload game logs now?\n\nThis will post your game logs to a public server and give you the link to share with others. This is useful if you need help fixing a problem or would like to report an issue to a mod author.\nNo private information will be shared.</HugsLib_logs_shareConfirmMessage>
<HugsLib_logs_shareConfirmMessage>Upload game logs now?\n\nThis will post your game logs to a public server and give you the link to share with others. This is useful if you need help fixing a problem or would like to report an issue to a mod author.\n\nNo private information will be shared.</HugsLib_logs_shareConfirmMessage>
<HugsLib_logs_publisherTitle>Log publisher</HugsLib_logs_publisherTitle>
<HugsLib_logs_uploading>Uploading{0}</HugsLib_logs_uploading>
<HugsLib_logs_shortening>Getting URL{0}</HugsLib_logs_shortening>
Expand All @@ -36,7 +36,20 @@
<HugsLib_logs_abortBtn>Abort</HugsLib_logs_abortBtn>
<HugsLib_logs_retryBtn>Retry</HugsLib_logs_retryBtn>
<HugsLib_logs_browseBtn>Open in browser</HugsLib_logs_browseBtn>

<HugsLib_logs_filesBtn>Files</HugsLib_logs_filesBtn>
<HugsLib_logs_openLogFile>Open log file</HugsLib_logs_openLogFile>
<HugsLib_logs_openSaveDir>Open save folder</HugsLib_logs_openSaveDir>
<HugsLib_logs_openModsDir>Open mods folder</HugsLib_logs_openModsDir>

<HugsLib_restart_title>Restart game</HugsLib_restart_title>
<HugsLib_restart_text>Changes have been saved.\n\nTo activate the new mod configuration it is recommended to restart the game.</HugsLib_restart_text>
<HugsLib_restart_restartNowBtn>Restart now</HugsLib_restart_restartNowBtn>
<HugsLib_restart_autoToggle>Restart automatically</HugsLib_restart_autoToggle>
<HugsLib_restart_restarting>Restarting</HugsLib_restart_restarting>
<HugsLib_setting_autoRestart_label>Restart after Mods menu changes</HugsLib_setting_autoRestart_label>
<HugsLib_setting_autoRestart_desc>Automatically restarts the game after changes to the Mods menu have been made.</HugsLib_setting_autoRestart_desc>

<test_enumSetting_DefaultValue>Default Value</test_enumSetting_DefaultValue>
<test_enumSetting_ValueOne>Value One</test_enumSetting_ValueOne>
<test_enumSetting_ValueTwo>Value Two</test_enumSetting_ValueTwo>
Expand Down
12 changes: 12 additions & 0 deletions Mods/HugsLib/Languages/Russian/Keyed/Russian.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,16 @@
<HugsLib_logs_retryBtn>Повторить попытку</HugsLib_logs_retryBtn>
<HugsLib_logs_browseBtn>Открыть в браузере</HugsLib_logs_browseBtn>

<HugsLib_logs_filesBtn>Файлы</HugsLib_logs_filesBtn>
<HugsLib_logs_openLogFile>Открыть журнал событий</HugsLib_logs_openLogFile>
<HugsLib_logs_openSaveDir>Открыть папку с сохраненными играми</HugsLib_logs_openSaveDir>
<HugsLib_logs_openModsDir>Открыть папку с модами</HugsLib_logs_openModsDir>

<HugsLib_restart_title>Требуется перезапуск</HugsLib_restart_title>
<HugsLib_restart_text>Изменения сохранены.\n\nЧтобы изменения вступили в силу, необходимо перезапустить игру.</HugsLib_restart_text>
<HugsLib_restart_restartNowBtn>Перезапустить сейчас</HugsLib_restart_restartNowBtn>
<HugsLib_restart_autoToggle>Перезапускать автоматически</HugsLib_restart_autoToggle>
<HugsLib_restart_restarting>Перезапуск</HugsLib_restart_restarting>
<HugsLib_setting_autoRestart_label>Перезапускать при перенастройке модов</HugsLib_setting_autoRestart_label>
<HugsLib_setting_autoRestart_desc>Автоматически перезапускает игру если состав или порядок загрузки модов был изменен.</HugsLib_setting_autoRestart_desc>
</LanguageData>
2 changes: 2 additions & 0 deletions Source/Core/KeyBindingDefOf.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ namespace HugsLib.Core {
// ReSharper disable UnassignedField.Global
public static class HugsLibKeyBingings {
public static KeyBindingDef PublishLogs;
public static KeyBindingDef OpenLogFile;
public static KeyBindingDef RestartRimworld;
}
}
24 changes: 24 additions & 0 deletions Source/Core/KeyBindingHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using HugsLib.Restarter;
using HugsLib.Shell;
using HugsLib.Utils;
using UnityEngine;

namespace HugsLib.Core {
/**
* Handles the key presses for key bindings added by HugsLib
*/
internal static class KeyBindingHandler {
public static void OnGUI() {
if (Event.current.type != EventType.KeyDown) return;
if (HugsLibKeyBingings.PublishLogs.JustPressed && HugsLibUtility.ControlIsHeld) {
HugsLibController.Instance.LogUploader.ShowPublishPrompt();
}
if (HugsLibKeyBingings.OpenLogFile.JustPressed) {
ShellOpenLog.Execute();
}
if (HugsLibKeyBingings.RestartRimworld.JustPressed) {
AutoRestarter.PerformRestart();
}
}
}
}
7 changes: 4 additions & 3 deletions Source/Detour/DetourProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace HugsLib.Source.Detour {
/**
* A tool to detour calls form one method to another. Will use Community Core Library detouring, if available, and its own equivalent otherwise.
* A tool to detour calls form one method to another. Keeps track of already detoured methods so that each method may only be detoured once.
*/
public class DetourProvider {
/**
Expand Down Expand Up @@ -113,8 +113,9 @@ public static MethodInfo TryGetExistingDetourDestination(MethodInfo source) {
}

internal static bool CompatibleDetourWithExceptions(MethodInfo source, MethodInfo destination) {
if (detours.ContainsKey(source)) {
throw new Exception(String.Format("{0} was already detoured to {1}.", source.FullName(), destination.FullName()));
MethodInfo existingDestination;
if (detours.TryGetValue(source, out existingDestination)) {
throw new Exception(String.Format("method was already detoured to {0}.", existingDestination.FullName()));
}
return TryCompatibleDetour(source, destination);
}
Expand Down
7 changes: 6 additions & 1 deletion Source/HugsLibController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using HugsLib.Core;
using HugsLib.Logs;
using HugsLib.News;
using HugsLib.Restarter;
using HugsLib.Settings;
using HugsLib.Source.Attrib;
using HugsLib.Utils;
Expand Down Expand Up @@ -83,6 +84,8 @@ private static VersionFile ReadOwnVersionFile() {
public CallbackScheduler CallbackScheduler { get; private set; }
public DistributedTickScheduler DistributedTicker { get; private set; }
public LogPublisher LogUploader { get; private set; }

internal AutoRestarter AutoRestarter { get; private set; }

private HugsLibController() {
}
Expand All @@ -100,6 +103,7 @@ internal void Initalize() {
DistributedTicker = new DistributedTickScheduler();
LogUploader = new LogPublisher();
reloadWatcher = new DefReloadWatcher(OnDefReloadDetected);
AutoRestarter = new AutoRestarter();
RegisterOwnSettings();
ReadOwnVersionFile();
LoadReloadInitialize();
Expand Down Expand Up @@ -176,7 +180,7 @@ internal void OnFixedUpdate() {

internal void OnGUI() {
try {
LogUploader.OnGUI();
KeyBindingHandler.OnGUI();
for (int i = 0; i < childMods.Count; i++) {
try {
childMods[i].OnGUI();
Expand Down Expand Up @@ -376,6 +380,7 @@ private void RegisterOwnSettings() {
}
return false;
};
AutoRestarter.CreateSettingsHandles(pack);
}
}
}
8 changes: 1 addition & 7 deletions Source/Logs/LogPublisher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Text.RegularExpressions;
using System.Threading;
using HugsLib.Core;
using HugsLib.Shell;
using HugsLib.Utils;
using UnityEngine;
using Verse;
Expand Down Expand Up @@ -41,13 +42,6 @@ public enum PublisherStatus {

private Thread workerThread;

public void OnGUI() {
if (Event.current.type != EventType.KeyDown) return;
if (HugsLibKeyBingings.PublishLogs.JustPressed && HugsLibUtility.ControlIsHeld) {
ShowPublishPrompt();
}
}

public void ShowPublishPrompt() {
if (PublisherIsReady()) {
Find.WindowStack.Add(new Dialog_Confirm("HugsLib_logs_shareConfirmMessage".Translate(), OnPublishConfirmed, false, "HugsLib_logs_shareConfirmTitle".Translate()));
Expand Down
29 changes: 23 additions & 6 deletions Source/Logs/LogWindowInjection.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Reflection;
using System.Collections.Generic;
using System.Reflection;
using HugsLib.GuiInject;
using HugsLib.Shell;
using HugsLib.Utils;
using UnityEngine;
using Verse;
Expand All @@ -23,28 +25,43 @@ public static void PrepareReflection() {
[WindowInjection(typeof(EditWindow_Log))]
private static void DrawLogWindowButtons(Window window, Rect inRect) {
var selectedMessage = selectedMessageField != null ? (LogMessage)selectedMessageField.GetValue(window) : null;
var shareButtonPos = new Vector2(inRect.width, inRect.y);
var prevColor = GUI.color;
var widgetRow = new WidgetRow(inRect.width, inRect.y, UIDirection.LeftThenUp);
// publish logs button
GUI.color = shareButtonColor;
if (DoAutoWidthButton(shareButtonPos, "HugsLib_logs_shareBtn".Translate(), true)) {
if (widgetRow.ButtonText("HugsLib_logs_shareBtn".Translate())) {
HugsLibController.Instance.LogUploader.ShowPublishPrompt();
}
// Files drop-down menu
GUI.color = prevColor;
if (widgetRow.ButtonText("HugsLib_logs_filesBtn".Translate())) {
Find.WindowStack.Add(new FloatMenu(new List<FloatMenuOption> {
new FloatMenuOption("HugsLib_logs_openLogFile".Translate(), () => {
ShellOpenLog.Execute();
}),
new FloatMenuOption("HugsLib_logs_openSaveDir".Translate(), () => {
ShellOpenDirectory.Execute(GenFilePaths.SaveDataFolderPath);
}),
new FloatMenuOption("HugsLib_logs_openModsDir".Translate(), () => {
ShellOpenDirectory.Execute(GenFilePaths.CoreModsFolderPath);
})
}));
}
if (selectedMessage != null) {
var copyButtonPos = new Vector2(inRect.width - MessageDetailsScrollBarWidth, inRect.height);
if (DoAutoWidthButton(copyButtonPos, "HugsLib_logs_copy".Translate(), false)) {
if (DoAutoWidthButton(copyButtonPos, "HugsLib_logs_copy".Translate())) {
CopyMessage(selectedMessage);
}
}
}

private static bool DoAutoWidthButton(Vector2 position, string label, bool topAlign) {
private static bool DoAutoWidthButton(Vector2 position, string label) {
const float ButtonPaddingX = 16f;
const float ButtonPaddingY = 2f;
var buttonSize = Text.CalcSize(label);
buttonSize.x += ButtonPaddingX;
buttonSize.y += ButtonPaddingY;
var buttonRect = new Rect(position.x - buttonSize.x, topAlign ? position.y : position.y - buttonSize.y, buttonSize.x, buttonSize.y);
var buttonRect = new Rect(position.x - buttonSize.x, position.y - buttonSize.y, buttonSize.x, buttonSize.y);
return Widgets.ButtonText(buttonRect, label);
}

Expand Down
80 changes: 80 additions & 0 deletions Source/Restarter/AutoRestarter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using HugsLib.GuiInject;
using HugsLib.Settings;
using HugsLib.Shell;
using RimWorld;
using UnityEngine;
using Verse;

namespace HugsLib.Restarter {
/**
* Makes the the Close button in the Mods dialog prompt the player to restart the game if the mod configuration has changed.
* Will restart the game automatically if the autoRestart setting is active.
* Unlike in vanilla, changes in mod order are also detected and will require a restart.
*/
internal class AutoRestarter {
private static readonly Vector2 CloseButSize = new Vector2(120f, 40f);

private static int lastSeenWindowHash;
private static int lastModListHash;

public SettingHandle<bool> AutoRestartSetting { get; private set; }

public static void PerformRestart() {
LongEventHandler.QueueLongEvent(() => {
ShellRestartRimWorld.Execute();
}, "HugsLib_restart_restarting", true, null);
}

[WindowInjection(typeof (Page_ModsConfig), Mode = WindowInjectionManager.InjectMode.AfterContents)]
private static void DrawLogWindowButtons(Window window, Rect inRect) {
// update mod list hash
if (window.GetHashCode() != lastSeenWindowHash) {
lastSeenWindowHash = window.GetHashCode();
lastModListHash = GetModListHash();
}
// replace close button, handle keys
Text.Font = GameFont.Small;
window.doCloseButton = false;
window.closeOnEscapeKey = false;
var closeBtnRect = new Rect(inRect.width / 2f - CloseButSize.x / 2f, inRect.height - CloseButSize.y, CloseButSize.x, CloseButSize.y);
var keyUsed = Event.current.type == EventType.KeyDown && (Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.Escape);
if (Widgets.ButtonText(closeBtnRect, "CloseButton".Translate()) || keyUsed) {
CloseAction(window);
if(keyUsed) Event.current.Use();
}
}

// TODO: on update, verify that this still does the same thing as Page_ModsConfig.PostClose
private static void CloseAction(Window window) {
ModsConfig.Save();
if (lastModListHash != GetModListHash()) {
if (HugsLibController.Instance.AutoRestarter.AutoRestartSetting) {
PerformRestart();
} else {
Find.WindowStack.Add(new Dialog_RestartGame());
}
} else {
window.Close();
}
}

// an alternative way to detect changes to the mod list that takes mod order into account
private static int GetModListHash() {
int hash = 42;
foreach (var modMetaData in ModsConfig.ActiveModsInLoadOrder) {
if (modMetaData.enabled){
unchecked {
hash <<= 1;
hash += hash + modMetaData.GetHashCode();
}
}
}
return hash;

}

public void CreateSettingsHandles(ModSettingsPack pack) {
AutoRestartSetting = pack.GetHandle("autoRestart", "HugsLib_setting_autoRestart_label".Translate(), "HugsLib_setting_autoRestart_desc".Translate(), false);
}
}
}
Loading

0 comments on commit 517165d

Please sign in to comment.