Sync with upstream
* Update bug-reports.yml * Fix modifyChatMessage hook * Add LuaCsSetup.Lua back for compatibility * Fix Game.AssignOnExecute having command arguments be passed as varargs instead of a table * Actually use the PackageId const everywhere we need to refer to our content package * Load languages files even if the package is disabled * Fix Hook.Remove not being implemented properly * - Changed event aliases to be case insensitive. * - Fixed assembly logging style. - Fixed double logging during execution. * Fix garbage network data being read by the game when reading LuaCs network messages * PackageId -> PackageName * Added caching toggle to PluginManagementService * Fix LuaCs initializing too late for singleplayer campaigns and rework the C# prompt to only show when enabling mods/joining server * Oops, fix NRE crash * Fix hide username in logs config not doing anything * Fix Cs prompt showing up more than one between rounds * Fix server host being prompted twice with the C# popup * Ignore our workshop packages from the game's dependency thing since it doesn't really make sense * Load console commands after executing and possible fix for the not console command permitted * Added fallback friendly name resolution for ModConfig assembly contents. * Register Voronoi2 stuff * Added configinfo null check to SettingBase.cs * Add safety check so this stops crashing when we look at it the wrong way * Fixed "Folder" attribute files not being found. * Keep the LuaCsConfig class laying around for compatibility, not sure anywhere in our code base (and shouldn't be) * Added fallback compilation for UseInternalsAwareAssembly if the publicized script compilation fails. * Added legacy overload of AddCommand for mod compat. * Added LoggerService to Lua env. Made ILoggerService compliant with LuaCsLogger API. * Changed csharp script compilation algorithm to be best effort. * Added "RunUnrestricted" mode for lua scripts that need to run outside of sandbox. * - Fixed networking sync vars failing to sync initially. - Fixed lua failing to differentiate overloads ISettingBase. * Add alias for human.CPRSuccess and human.CPRFailed * - Fixed up the settings menu. - Made SettingEntry throw an error if "Value" attribute is not found in XML. - Fixed saved values for settings sometimes not reloading after disabling and re-enabling a package. * Fix LuaCs net messages received during connection initialization to be read incorrectly, happened because we would reset the BitPosition in our harmony patch which would cause the message to be read incorrectly later * Allow reloadlua to force the state to running * New icon for settings and make the top left text more user friendly * Fix client.packages hook sending normal packages * Fixed OnUpdate() not passing in deltaTime instead of totalTime. * Missing diffs frombb21a09244* Added networking tests for configs. * Added missing diffs forf61f852a25. * Some tweaks to the text * Remove missing Value error, it should just use the default value if it's not specified * Fix UseInternalAccessName * Always purge cashes for plugin content on unloading. * Fix texture not multiple of 4 * v1.12.7.0 (Spring Update 2026 Hotfix 1) --------- Co-authored-by: Joonas Rikkonen <poe.regalis@gmail.com> Co-authored-by: Evil Factory <36804725+evilfactory@users.noreply.github.com> Co-authored-by: MapleWheels <njainanan@hotmail.com>
This commit is contained in:
@@ -24,7 +24,7 @@ public sealed class SettingControl : SettingBase, ISettingControl
|
||||
public SettingControl(IConfigInfo configInfo, Func<OneOf<string, XElement, object>, bool> valueChangePredicate) : base(configInfo)
|
||||
{
|
||||
_valueChangePredicate = valueChangePredicate;
|
||||
TrySetValue(configInfo.Element);
|
||||
TrySetSerializedValue(configInfo.Element);
|
||||
}
|
||||
|
||||
protected override void OnDispose()
|
||||
@@ -37,7 +37,7 @@ public sealed class SettingControl : SettingBase, ISettingControl
|
||||
public override string GetStringValue() => Value.ToString();
|
||||
public override string GetDefaultStringValue() => new KeyOrMouse(Keys.NumLock).ToString();
|
||||
|
||||
public override bool TrySetValue(OneOf<string, XElement> value)
|
||||
public override bool TrySetSerializedValue(OneOf<string, XElement> value)
|
||||
{
|
||||
var newVal = value.Match<KeyOrMouse>(
|
||||
(string v) => GetKeyOrMouse(v),
|
||||
|
||||
@@ -1,106 +1,47 @@
|
||||
using System;
|
||||
using Barotrauma.CharacterEditor;
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.LuaCs;
|
||||
using Barotrauma.LuaCs.Data;
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Barotrauma.CharacterEditor;
|
||||
using Barotrauma.LuaCs;
|
||||
using Barotrauma.LuaCs.Data;
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using static System.Collections.Specialized.BitVector32;
|
||||
|
||||
// ReSharper disable ObjectCreationAsStatement
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class LuaCsSetup
|
||||
{
|
||||
private bool _isClientPromptActive;
|
||||
private bool _isCsEnabledForSession = false;
|
||||
|
||||
public void CheckRunConditionalHostingCsEnabled(Action onReadyToRun)
|
||||
{
|
||||
public void PromptCSharpMods(Action<bool> onSelection, bool joiningServer)
|
||||
{
|
||||
var res = ReadyToRunNoPrompt();
|
||||
if (res.ShouldRun)
|
||||
{
|
||||
onReadyToRun?.Invoke();
|
||||
return;
|
||||
}
|
||||
|
||||
DisplayCsModsPromptClient(res.Item2, (selectedYes) =>
|
||||
{
|
||||
if (selectedYes)
|
||||
{
|
||||
onReadyToRun?.Invoke();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private (bool ShouldRun, ImmutableArray<ContentPackage> PromptPackages) ReadyToRunNoPrompt()
|
||||
{
|
||||
if (this.IsCsEnabled)
|
||||
{
|
||||
return (true, ImmutableArray<ContentPackage>.Empty);
|
||||
}
|
||||
|
||||
if (!ShouldPromptForCs)
|
||||
{
|
||||
return (true, ImmutableArray<ContentPackage>.Empty);
|
||||
}
|
||||
|
||||
ImmutableArray<ContentPackage> contentPackages = PackageManagementService.GetLoadedAssemblyPackages()
|
||||
.Where(p => p.Name != PackageId)
|
||||
ImmutableArray<ContentPackage> contentPackages = PackageManagementService.GetLoadedUnrestrictedPackages()
|
||||
.Where(p => p.Name != PackageName)
|
||||
.ToImmutableArray();
|
||||
|
||||
return (contentPackages.IsEmpty, contentPackages);
|
||||
}
|
||||
|
||||
partial void CheckReadyToRun(Action onReadyToRun)
|
||||
{
|
||||
var res = ReadyToRunNoPrompt();
|
||||
if (res.ShouldRun)
|
||||
if (_csRunPolicy?.Value is "Enabled")
|
||||
{
|
||||
onReadyToRun?.Invoke();
|
||||
IsCsEnabledForSession = true;
|
||||
onSelection(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (GameMain.Client?.ClientPeer is P2POwnerPeer)
|
||||
else if (_csRunPolicy?.Value is "Disabled")
|
||||
{
|
||||
SetCsPolicyAndContinue(true);
|
||||
IsCsEnabledForSession = false;
|
||||
onSelection(false);
|
||||
return;
|
||||
}
|
||||
|
||||
DisplayCsModsPromptClient(res.PromptPackages, (selectedYes) =>
|
||||
if (contentPackages.None())
|
||||
{
|
||||
SetCsPolicyAndContinue(selectedYes);
|
||||
onSelection(true);
|
||||
return;
|
||||
});
|
||||
|
||||
void SetCsPolicyAndContinue(bool csSessionExecutionPolicy)
|
||||
{
|
||||
var prevRunState = this.CurrentRunState;
|
||||
if (CurrentRunState >= RunState.Running)
|
||||
{
|
||||
SetRunState(RunState.LoadedNoExec);
|
||||
}
|
||||
this._isCsEnabledForSession = csSessionExecutionPolicy;
|
||||
CoroutineManager.Invoke(() =>
|
||||
{
|
||||
if (CurrentRunState != prevRunState)
|
||||
{
|
||||
SetRunState(prevRunState);
|
||||
}
|
||||
onReadyToRun?.Invoke();
|
||||
}, 0f);
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayCsModsPromptClient(ImmutableArray<ContentPackage> contentPackages, Action<bool> onSelection)
|
||||
{
|
||||
if (_isClientPromptActive) { return; }
|
||||
|
||||
_isClientPromptActive = true;
|
||||
|
||||
GUIMessageBox messageBox = new GUIMessageBox(
|
||||
TextManager.Get("warning"),
|
||||
@@ -115,7 +56,7 @@ namespace Barotrauma
|
||||
Stretch = true
|
||||
};
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), msgBoxLayout.RectTransform), "The following mods contain CSharp code",
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), msgBoxLayout.RectTransform), "The following mods contain CSharp code OR Unsandboxed Lua Code",
|
||||
font: GUIStyle.SubHeadingFont, wrap: true, textAlignment: Alignment.Center);
|
||||
|
||||
GUIListBox packageListBox = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.4f), msgBoxLayout.RectTransform))
|
||||
@@ -126,22 +67,39 @@ namespace Barotrauma
|
||||
foreach (ContentPackage package in contentPackages)
|
||||
{
|
||||
GUIFrame packageFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.15f), packageListBox.Content.RectTransform), style: "ListBoxElement");
|
||||
new GUITextBlock(new RectTransform(new Vector2(1f, 1f), packageFrame.RectTransform), package.Name);
|
||||
GUILayoutGroup packageLayout = new GUILayoutGroup(new RectTransform(Vector2.One, packageFrame.RectTransform), true, Anchor.CenterLeft);
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.7f, 1f), packageLayout.RectTransform), package.Name);
|
||||
new GUIButton(new RectTransform(new Vector2(0.3f, 1f), packageLayout.RectTransform, Anchor.CenterRight), "Open Folder", style: "GUIButtonSmall")
|
||||
{
|
||||
OnClicked = (GUIButton button, object obj) =>
|
||||
{
|
||||
string directory = package.Dir;
|
||||
if (string.IsNullOrEmpty(directory)) { return false; }
|
||||
|
||||
ToolBox.OpenFileWithShell(directory);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0f), msgBoxLayout.RectTransform), "C# mods are not sandboxed, meaning that they have unrestrictive access to your computer, please make sure you trust these mods before you continue. If you are not hosting a server, selecting cancel will only run Lua mods.", wrap: true)
|
||||
string bodyText =
|
||||
joiningServer ?
|
||||
"You are joining a server that includes mods with C# code OR unrestricted Lua code. These mods are not sandboxed and may access your computer without restrictions. If you trust these mods, select 'Enable C# for this session'. Otherwise, select 'Cancel' to run only Lua mods."
|
||||
: "You have enabled mods that include C# code. These mods are not sandboxed and may access your computer without restrictions. If you trust these mods, select 'Enable C# for this session'. Otherwise, select 'Cancel' to run only Sandboxed Lua mods.";
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0f), msgBoxLayout.RectTransform), bodyText, wrap: true)
|
||||
{
|
||||
Wrap = true
|
||||
};
|
||||
|
||||
GUILayoutGroup buttonLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.25f), messageBox.Content.RectTransform, Anchor.BottomCenter), isHorizontal: false, childAnchor: Anchor.TopCenter);
|
||||
|
||||
new GUIButton(new RectTransform(new Vector2(0.8f, 0.0f), buttonLayout.RectTransform), "Continue")
|
||||
new GUIButton(new RectTransform(new Vector2(0.8f, 0.0f), buttonLayout.RectTransform), "Enable C# for this session")
|
||||
{
|
||||
TextBlock = { AutoScaleHorizontal = true },
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
_isClientPromptActive = false;
|
||||
IsCsEnabledForSession = true;
|
||||
onSelection(true);
|
||||
messageBox.Close();
|
||||
return true;
|
||||
@@ -152,7 +110,7 @@ namespace Barotrauma
|
||||
{
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
_isClientPromptActive = false;
|
||||
IsCsEnabledForSession = false;
|
||||
onSelection(false);
|
||||
messageBox.Close();
|
||||
return true;
|
||||
@@ -201,10 +159,18 @@ namespace Barotrauma
|
||||
case SpriteEditorScreen:
|
||||
case SubEditorScreen:
|
||||
case TestScreen: // notes: TestScreen is a Linux edge case editor screen and is deprecated.
|
||||
CheckReadyToRun(() =>
|
||||
|
||||
if (screen is NetLobbyScreen && CurrentRunState != RunState.Running && GameMain.Client?.ClientPeer is not P2POwnerPeer)
|
||||
{
|
||||
PromptCSharpMods(selection =>
|
||||
{
|
||||
SetRunState(RunState.Running);
|
||||
}, joiningServer: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetRunState(RunState.Running);
|
||||
});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Logger.LogError(
|
||||
|
||||
@@ -32,11 +32,11 @@ partial class NetworkingService : INetworkingService, IEventServerConnected, IEv
|
||||
}
|
||||
}
|
||||
|
||||
public void OnReceivedServerNetMessage(IReadMessage netMessage, ServerPacketHeader serverPacketHeader)
|
||||
public bool? OnReceivedServerNetMessage(IReadMessage netMessage, ServerPacketHeader serverPacketHeader)
|
||||
{
|
||||
if (serverPacketHeader != ServerHeader)
|
||||
{
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
ServerToClient luaCsHeader = (ServerToClient)netMessage.ReadByte();
|
||||
@@ -55,6 +55,8 @@ partial class NetworkingService : INetworkingService, IEventServerConnected, IEv
|
||||
ReadIds(netMessage);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void SendSyncMessage()
|
||||
|
||||
+180
-34
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Linq;
|
||||
@@ -20,23 +21,87 @@ internal sealed class ModsGameplaySettingsMenu : ModsSettingsMenuBase
|
||||
private string _selectedSearchQuery = string.Empty;
|
||||
private ContentPackage _selectedContentPackage;
|
||||
private string _selectedCategory = string.Empty;
|
||||
private ImmutableArray<ISettingBase> _currentlyDisplayedSettings;
|
||||
private ILoggerService _loggerService;
|
||||
|
||||
private bool _promptOpen = false;
|
||||
|
||||
|
||||
// Note: "static" instead of "const" for Hot Reload and to allow changing at runtime.
|
||||
// ReSharper disable FieldCanBeMadeReadOnly.Local
|
||||
|
||||
// --- UI controls ---
|
||||
private static float MenuTitleHeight = 0.06f; // (ContentDisplayAreaHeightContainer + MenuTitleHeight) < 1f
|
||||
private static float ContentDisplayAreaHeightContainer = 0.93f;
|
||||
private static float ContentDisplayAreaHeightInnerCategories = 0.99f;
|
||||
private static float ContentDisplayAreaHeightInnerSettings = 0.97f;
|
||||
private static float ContentLeftRightSplitPosition = 0.3f;
|
||||
|
||||
// Search Bar
|
||||
private static float SearchBarLayoutHeight = 0.06f;
|
||||
private static float SearchBarLabelWidth = 0.1f;
|
||||
private static float SearchBarLabelBoxSpacing = 0.05f;
|
||||
|
||||
private static float SearchBarTextBoxWidth = 1f - SearchBarLabelWidth - SearchBarLabelBoxSpacing;
|
||||
|
||||
// Categories, Packages Display Area
|
||||
private static float CategoriesDisplayListHeight = 0.945f;
|
||||
private static float CategoryButtonHeightRelative = 0.122f;
|
||||
private static float PackageSelectionButtonHeight = 0.07f;
|
||||
|
||||
private static Color CategoryButtonHoverSelectColor = new Color(50, 50, 50, 255);
|
||||
private static Color CategoryButtonTextColor = Color.PeachPuff;
|
||||
private static Color CategoryButtonTextColorSelected = Color.White;
|
||||
private static Color CategoryButtonColorPressed = Color.TransparentBlack;
|
||||
|
||||
// Settings Display Area
|
||||
private static float SettingLabelWidth = 0.6f;
|
||||
private static float SettingControlWidth = 0.4f;
|
||||
private static float SettingHeight = 0.05625f/ContentDisplayAreaHeightContainer/ContentDisplayAreaHeightInnerSettings;
|
||||
private static Color SettingEntryLabelTextColor = Color.PeachPuff;
|
||||
private static string SettingGUIFrameStyle = "";
|
||||
private static Color? SettingGUIFrameColor = null;
|
||||
|
||||
// settings reset
|
||||
private static Vector2 SettingsResetButtonTopSpacer = new Vector2(0f, 0.02f);
|
||||
private static Vector2 SettingsResetButtonDimensions = new Vector2(0.3f, 0.05f);
|
||||
private static string SettingsResetButtonStyle = "GUIButtonSmall";
|
||||
private static Color SettingsResetButtonColor = Color.DarkOliveGreen;
|
||||
private static Color SettingsResetButtonHoverColor = Color.Olive;
|
||||
private static Color SettingsResetButtonTextColor = Color.PeachPuff;
|
||||
private static Color SettingsResetButtonTextColorSelected = Color.White;
|
||||
|
||||
private static Vector2 ResetConfirmationPromptDimensions = new Vector2(0.15f, 0.2f);
|
||||
|
||||
|
||||
// ReSharper restore FieldCanBeMadeReadOnly.Local
|
||||
private const string SettingsResetButtonText = "LuaCsForBarotrauma.SettingsMenu.ResetVisibleSettings";
|
||||
private const string SettingsResetPromptTitle = "LuaCsForBarotrauma.SettingsMenu.ResetPrompt.Title";
|
||||
private const string SettingsResetPromptContents = "LuaCsForBarotrauma.SettingsMenu.ResetPrompt.Message";
|
||||
private const string SettingsResetPromptYesText = "LuaCsForBarotrauma.SettingsMenu.ResetPrompt.Yes";
|
||||
private const string SettingsResetPromptNoText = "LuaCsForBarotrauma.SettingsMenu.ResetPrompt.No";
|
||||
|
||||
|
||||
private event Action OnApplyInstalledModsChanges;
|
||||
|
||||
public ModsGameplaySettingsMenu(GUIFrame contentFrame,
|
||||
IPackageManagementService packageManagementService,
|
||||
IConfigService configService,
|
||||
ILoggerService loggerService,
|
||||
SettingsMenu settingsMenuInstance) : base(contentFrame, packageManagementService, configService, settingsMenuInstance)
|
||||
{
|
||||
_settingsInstancesGameplay = configService.GetDisplayableConfigs()
|
||||
.ToImmutableArray();
|
||||
|
||||
|
||||
_loggerService = loggerService;
|
||||
|
||||
var mainLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(1f, 1f), contentFrame.RectTransform, Anchor.Center), false, Anchor.TopLeft);
|
||||
// page title
|
||||
var menuTitleLayoutGroup = new GUILayoutGroup(
|
||||
new RectTransform(new Vector2(1f, 0.06f), mainLayoutGroup.RectTransform, Anchor.TopLeft), true, Anchor.TopLeft);
|
||||
GUIUtil.Label(menuTitleLayoutGroup, "Mods Gameplay Settings", GUIStyle.LargeFont, new Vector2(1f, 1f));
|
||||
new RectTransform(new Vector2(1f, MenuTitleHeight), mainLayoutGroup.RectTransform, Anchor.TopLeft), true, Anchor.TopLeft);
|
||||
GUIUtil.Label(menuTitleLayoutGroup,
|
||||
GetLocalizedString("LuaCsForBarotrauma.SettingsMenu.ModGameplayButton", "Mod Gameplay Settings"),
|
||||
GUIStyle.LargeFont, new Vector2(1f, 1f));
|
||||
|
||||
// page contents
|
||||
var contentAreaLayoutGroup = new GUILayoutGroup(
|
||||
@@ -44,10 +109,10 @@ internal sealed class ModsGameplaySettingsMenu : ModsSettingsMenuBase
|
||||
Anchor.TopLeft);
|
||||
|
||||
var searchBarLayoutGroup = new GUILayoutGroup(
|
||||
new RectTransform(new Vector2(1f, 0.06f), contentAreaLayoutGroup.RectTransform, Anchor.TopCenter), true, Anchor.CenterLeft);
|
||||
GUIUtil.Label(searchBarLayoutGroup, "Search: ", GUIStyle.SubHeadingFont, new Vector2(0.1f, 1f));
|
||||
new RectTransform(new Vector2(1f, SearchBarLayoutHeight), contentAreaLayoutGroup.RectTransform, Anchor.TopCenter), true, Anchor.CenterLeft);
|
||||
GUIUtil.Label(searchBarLayoutGroup, "Search: ", GUIStyle.SubHeadingFont, new Vector2(SearchBarLabelWidth, 1f));
|
||||
var searchBar = new GUITextBox(
|
||||
new RectTransform(new Vector2(0.85f, 0.1f), searchBarLayoutGroup.RectTransform, Anchor.TopLeft),
|
||||
new RectTransform(new Vector2(SearchBarTextBoxWidth, 0.1f), searchBarLayoutGroup.RectTransform, Anchor.TopLeft),
|
||||
createClearButton: true)
|
||||
{
|
||||
OnTextChangedDelegate = (btn, txt) =>
|
||||
@@ -56,12 +121,13 @@ internal sealed class ModsGameplaySettingsMenu : ModsSettingsMenuBase
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// main display area
|
||||
var settingsContentAreaGroup = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.90f), contentAreaLayoutGroup.RectTransform, Anchor.BottomCenter));
|
||||
var settingsContentAreaGroup = new GUILayoutGroup(new RectTransform(new Vector2(1f, ContentDisplayAreaHeightContainer), contentAreaLayoutGroup.RectTransform, Anchor.BottomCenter));
|
||||
GUIUtil.Spacer(settingsContentAreaGroup, Vector2.One);
|
||||
(_modCategoryDisplayGroup, _settingsDisplayGroup) = GUIUtil.CreateSidebars(settingsContentAreaGroup, true);
|
||||
_modCategoryDisplayGroup.RectTransform.RelativeSize = new Vector2(0.3f, 1f);
|
||||
_settingsDisplayGroup.RectTransform.RelativeSize = new Vector2(0.7f, 1f);
|
||||
_modCategoryDisplayGroup.RectTransform.RelativeSize = new Vector2(ContentLeftRightSplitPosition, ContentDisplayAreaHeightInnerCategories);
|
||||
_settingsDisplayGroup.RectTransform.RelativeSize = new Vector2(1f-ContentLeftRightSplitPosition, ContentDisplayAreaHeightInnerSettings);
|
||||
|
||||
// default category
|
||||
_selectedCategory = "All";
|
||||
@@ -202,10 +268,11 @@ internal sealed class ModsGameplaySettingsMenu : ModsSettingsMenuBase
|
||||
_selectedCategory = string.Empty;
|
||||
GenerateCategoryListDisplay(_modCategoryDisplayGroup, GetTargetPackagesList(), GetDisplayCategoriesList());
|
||||
GenerateSettingsListDisplay(_settingsDisplayGroup, GetDisplaySettingsList());
|
||||
}, new Vector2(1f, 0.07f));
|
||||
var containerBox = new GUIListBox(new RectTransform(new Vector2(1f, 0.945f), layoutGroup.RectTransform));
|
||||
const float entryHeight = 0.122f;
|
||||
float sizeY = MathF.Max(categories.Length * entryHeight, 1f);
|
||||
}, new Vector2(1f, PackageSelectionButtonHeight));
|
||||
var containerBox = new GUIListBox(new RectTransform(new Vector2(1f, CategoriesDisplayListHeight), layoutGroup.RectTransform));
|
||||
|
||||
|
||||
float sizeY = MathF.Max(categories.Length * CategoryButtonHeightRelative, 1f);
|
||||
var displayedCategoriesFrame = new GUIFrame(new RectTransform(new Vector2(1f, sizeY), containerBox.Content.RectTransform), style: null, color: Color.Black)
|
||||
{
|
||||
CanBeFocused = false
|
||||
@@ -214,17 +281,18 @@ internal sealed class ModsGameplaySettingsMenu : ModsSettingsMenuBase
|
||||
|
||||
foreach (var category in categories)
|
||||
{
|
||||
var btn = new GUIButton(new RectTransform(new Vector2(1f, entryHeight), displayCategoriesLayout.RectTransform),
|
||||
var btn = new GUIButton(new RectTransform(new Vector2(1f, CategoryButtonHeightRelative), displayCategoriesLayout.RectTransform),
|
||||
text: category, color: Color.TransparentBlack)
|
||||
{
|
||||
CanBeFocused = true,
|
||||
CanBeSelected = true,
|
||||
TextColor = Color.PeachPuff,
|
||||
HoverColor = new Color(50, 50, 50, 255),
|
||||
HoverTextColor = Color.White,
|
||||
SelectedColor = new Color(50, 50, 50, 255),
|
||||
SelectedTextColor = Color.White,
|
||||
OnPressed = () =>
|
||||
TextColor = CategoryButtonTextColor,
|
||||
HoverColor = CategoryButtonHoverSelectColor,
|
||||
HoverTextColor = CategoryButtonTextColorSelected,
|
||||
PressedColor = CategoryButtonColorPressed,
|
||||
SelectedColor = CategoryButtonHoverSelectColor,
|
||||
SelectedTextColor = CategoryButtonHoverSelectColor,
|
||||
OnClicked = (btn, obj) =>
|
||||
{
|
||||
_selectedCategory = category;
|
||||
GenerateSettingsListDisplay(_settingsDisplayGroup, GetDisplaySettingsList());
|
||||
@@ -237,26 +305,47 @@ internal sealed class ModsGameplaySettingsMenu : ModsSettingsMenuBase
|
||||
void GenerateSettingsListDisplay(GUILayoutGroup layoutGroup, ImmutableArray<ISettingBase> settings)
|
||||
{
|
||||
layoutGroup.ClearChildren();
|
||||
const float settingHeight = 0.0625f;
|
||||
_currentlyDisplayedSettings = settings;
|
||||
|
||||
var containerBox = new GUIListBox(new RectTransform(new Vector2(1f, 1f), layoutGroup.RectTransform));
|
||||
var containerBox = new GUIListBox(new RectTransform(new Vector2(1f, 1f-SettingsResetButtonDimensions.Y), layoutGroup.RectTransform));
|
||||
foreach (var setting in settings)
|
||||
{
|
||||
var entry = AddSettingToDisplay(
|
||||
setting,
|
||||
containerBox.Content.RectTransform,
|
||||
settingHeight: settingHeight,
|
||||
labelSize: new Vector2(0.6f, 1f),
|
||||
controlSize: new Vector2(0.4f, 1f));
|
||||
|
||||
|
||||
settingHeight: SettingHeight,
|
||||
labelSize: new Vector2(SettingLabelWidth, 1f),
|
||||
controlSize: new Vector2(SettingControlWidth, 1f));
|
||||
}
|
||||
}
|
||||
|
||||
(GUIFrame entryFrame, GUILayoutGroup entryLayoutGroup) AddSettingToDisplay(ISettingBase setting,
|
||||
RectTransform parent, float settingHeight, Vector2 labelSize, Vector2 controlSize)
|
||||
var spacer = new GUIFrame(new RectTransform(SettingsResetButtonTopSpacer, layoutGroup.RectTransform),
|
||||
style: null, color: Color.TransparentBlack);
|
||||
|
||||
var resetSettingsButton = new GUIButton(
|
||||
new RectTransform(SettingsResetButtonDimensions, layoutGroup.RectTransform),
|
||||
GetLocalizedString(SettingsResetButtonText, "Reset Visible Settings"),
|
||||
style: SettingsResetButtonStyle)
|
||||
{
|
||||
CanBeSelected = true,
|
||||
CanBeFocused = true,
|
||||
Color = SettingsResetButtonColor,
|
||||
HoverColor = SettingsResetButtonHoverColor,
|
||||
SelectedColor = SettingsResetButtonHoverColor,
|
||||
SelectedTextColor = SettingsResetButtonTextColorSelected,
|
||||
TextColor = SettingsResetButtonTextColor,
|
||||
OnClicked = (btn, obj) =>
|
||||
{
|
||||
DisplayResetConfirmationPrompt(settings);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
(GUIFrame entryFrame, GUILayoutGroup entryLayoutGroup)
|
||||
AddSettingToDisplay(ISettingBase setting, RectTransform parent, float settingHeight, Vector2 labelSize, Vector2 controlSize)
|
||||
{
|
||||
GUIFrame entryFrame = new GUIFrame(new RectTransform(new Vector2(1f, settingHeight), parent))
|
||||
GUIFrame entryFrame = new GUIFrame(new RectTransform(new Vector2(1f, settingHeight), parent),
|
||||
style: SettingGUIFrameStyle, color: SettingGUIFrameColor)
|
||||
{
|
||||
Color = Color.DarkGray
|
||||
};
|
||||
@@ -266,9 +355,10 @@ internal sealed class ModsGameplaySettingsMenu : ModsSettingsMenuBase
|
||||
new GUIFrame(new RectTransform(new Vector2(0.02f, 1f), entryLayoutGroup.RectTransform),
|
||||
color: Color.TransparentBlack);
|
||||
|
||||
// setting label
|
||||
new GUITextBlock(new RectTransform(labelSize - new Vector2(0.05f, 0f), entryLayoutGroup.RectTransform),
|
||||
GetLocalizedString(setting.GetDisplayInfo().DisplayName, setting.GetDisplayInfo().DisplayName),
|
||||
textColor: Color.PeachPuff,
|
||||
textColor: SettingEntryLabelTextColor,
|
||||
font: GUIStyle.SmallFont,
|
||||
textAlignment: Alignment.Left)
|
||||
{
|
||||
@@ -281,6 +371,58 @@ internal sealed class ModsGameplaySettingsMenu : ModsSettingsMenuBase
|
||||
});
|
||||
return (entryFrame, entryLayoutGroup);
|
||||
}
|
||||
|
||||
void DisplayResetConfirmationPrompt(ImmutableArray<ISettingBase> settings)
|
||||
{
|
||||
if (_promptOpen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_promptOpen = true;
|
||||
|
||||
var msgBox = new GUIMessageBox(GetLocalizedString(SettingsResetPromptTitle, "Reset Visible Settings"),
|
||||
GetLocalizedString(SettingsResetPromptContents,
|
||||
"Are you sure you want to reset the values for currently displayed settings?"),
|
||||
new LocalizedString[]
|
||||
{
|
||||
GetLocalizedString(SettingsResetPromptYesText, "Yes"),
|
||||
GetLocalizedString(SettingsResetPromptNoText, "No")
|
||||
}, ResetConfirmationPromptDimensions);
|
||||
msgBox.Buttons[0].OnClicked = (btn, obj) =>
|
||||
{
|
||||
ResetValuesForDisplayedSettings(settings);
|
||||
btn.Visible = false;
|
||||
_promptOpen = false;
|
||||
msgBox.Close();
|
||||
return true;
|
||||
};
|
||||
msgBox.Buttons[1].OnClicked = (btn, obj) =>
|
||||
{
|
||||
btn.Visible = false;
|
||||
_promptOpen = false;
|
||||
msgBox.Close();
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
void ResetValuesForDisplayedSettings(ImmutableArray<ISettingBase> settings)
|
||||
{
|
||||
if (settings.IsDefaultOrEmpty)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NewValuesCache.Clear();
|
||||
foreach (var setting in settings)
|
||||
{
|
||||
var str = setting.GetDefaultStringValue();
|
||||
NewValuesCache[setting] = str;
|
||||
loggerService.LogDebug($"Resetting value for {setting.InternalName} to '{str}'");
|
||||
}
|
||||
|
||||
ApplyInstalledModChanges();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -303,8 +445,12 @@ internal sealed class ModsGameplaySettingsMenu : ModsSettingsMenuBase
|
||||
continue;
|
||||
}
|
||||
|
||||
kvp.Key.TrySetValue(kvp.Value);
|
||||
ConfigService.SaveConfigValue(kvp.Key);
|
||||
var success = kvp.Key.TrySetSerializedValue(kvp.Value);
|
||||
if (success)
|
||||
{
|
||||
ConfigService.SaveConfigValue(kvp.Key);
|
||||
_loggerService.LogDebug($"Applied save value for {kvp.Key.InternalName} of {kvp.Value.ToString()}");
|
||||
}
|
||||
}
|
||||
NewValuesCache.Clear();
|
||||
OnApplyInstalledModsChanges?.Invoke();
|
||||
|
||||
+3
-1
@@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.LuaCs.Data;
|
||||
using Microsoft.Xna.Framework;
|
||||
using OneOf;
|
||||
|
||||
namespace Barotrauma.LuaCs;
|
||||
|
||||
@@ -12,7 +14,7 @@ internal abstract class ModsSettingsMenuBase : IDisposable
|
||||
protected IPackageManagementService PackageManagementService { get; private set; }
|
||||
protected IConfigService ConfigService { get; private set; }
|
||||
protected SettingsMenu SettingsMenuInstance { get; private set; }
|
||||
protected readonly ConcurrentDictionary<ISettingBase, string> NewValuesCache = new();
|
||||
protected readonly ConcurrentDictionary<ISettingBase, OneOf<string, XElement>> NewValuesCache = new();
|
||||
|
||||
protected ModsSettingsMenuBase(GUIFrame contentFrame,
|
||||
IPackageManagementService packageManagementService,
|
||||
|
||||
+7
-4
@@ -18,12 +18,14 @@ public class SettingsMenuSystem : ISettingsMenuSystem
|
||||
private readonly Harmony _harmony;
|
||||
private readonly IPackageManagementService _packageManagementService;
|
||||
private readonly IConfigService _configService;
|
||||
private readonly ILoggerService _loggerService;
|
||||
private static SettingsMenuSystem SystemInstance;
|
||||
|
||||
public SettingsMenuSystem(IPackageManagementService packageManagementService, IConfigService configService)
|
||||
public SettingsMenuSystem(IPackageManagementService packageManagementService, IConfigService configService, ILoggerService loggerService)
|
||||
{
|
||||
_packageManagementService = packageManagementService;
|
||||
_configService = configService;
|
||||
_loggerService = loggerService;
|
||||
SystemInstance = this;
|
||||
_harmony = Harmony.CreateAndPatchAll(typeof(SettingsMenuSystem));
|
||||
}
|
||||
@@ -43,13 +45,14 @@ public class SettingsMenuSystem : ISettingsMenuSystem
|
||||
var tabGameplayIndex = (SettingsMenu.Tab)tabCount;
|
||||
var tabControlsIndex = (SettingsMenu.Tab)tabCount+1;
|
||||
|
||||
_gameplayContentFrame = CreateNewContentTab(tabGameplayIndex, __instance,
|
||||
"SettingsMenuTab.Mods", "LuaCsForBarotrauma.SettingsMenu.ModGameplayButton");
|
||||
_gameplayContentFrame = CreateNewContentTab(tabGameplayIndex, __instance,
|
||||
GUIStyle.ComponentStyles.ContainsKey("SettingsMenuTab.LuaCsSettings") ? "SettingsMenuTab.LuaCsSettings" : "SettingsMenuTab.Mods",
|
||||
"LuaCsForBarotrauma.SettingsMenu.ModGameplayButton");
|
||||
/*_controlsContentFrame = CreateNewContentTab(tabControlsIndex, __instance,
|
||||
"SettingsMenuTab.Controls", "LuaCsForBarotrauma.SettingsMenu.ModControlsButton");
|
||||
*/
|
||||
|
||||
_gameplayMenuInstance = new ModsGameplaySettingsMenu(_gameplayContentFrame, _packageManagementService, _configService, __instance);
|
||||
_gameplayMenuInstance = new ModsGameplaySettingsMenu(_gameplayContentFrame, _packageManagementService, _configService, _loggerService, __instance);
|
||||
//_controlsMenuInstance = new ModsControlsSettingsMenu(_controlsContentFrame, _packageManagementService, _configService, __instance);
|
||||
}
|
||||
|
||||
|
||||
@@ -1015,25 +1015,20 @@ namespace Barotrauma
|
||||
|
||||
private void TryStartServer()
|
||||
{
|
||||
LuaCsSetup.Instance.CheckRunConditionalHostingCsEnabled(() =>
|
||||
if (SubmarineInfo.SavedSubmarines.Any(s => s.CalculatingHash))
|
||||
{
|
||||
if (SubmarineInfo.SavedSubmarines.Any(s => s.CalculatingHash))
|
||||
var waitBox = new GUIMessageBox(TextManager.Get("pleasewait"), TextManager.Get("waitforsubmarinehashcalculations"), new LocalizedString[] { TextManager.Get("cancel") });
|
||||
var waitCoroutine = CoroutineManager.StartCoroutine(WaitForSubmarineHashCalculations(waitBox), "WaitForSubmarineHashCalculations");
|
||||
waitBox.Buttons[0].OnClicked += (btn, userdata) =>
|
||||
{
|
||||
var waitBox = new GUIMessageBox(TextManager.Get("pleasewait"), TextManager.Get("waitforsubmarinehashcalculations"), new LocalizedString[] { TextManager.Get("cancel") });
|
||||
var waitCoroutine = CoroutineManager.StartCoroutine(WaitForSubmarineHashCalculations(waitBox), "WaitForSubmarineHashCalculations");
|
||||
waitBox.Buttons[0].OnClicked += (btn, userdata) =>
|
||||
{
|
||||
CoroutineManager.StopCoroutines(waitCoroutine);
|
||||
return true;
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
StartServer();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
CoroutineManager.StopCoroutines(waitCoroutine);
|
||||
return true;
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
StartServer();
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<CoroutineStatus> WaitForSubmarineHashCalculations(GUIMessageBox messageBox)
|
||||
|
||||
@@ -174,9 +174,9 @@ namespace Barotrauma
|
||||
public static RectTransform NewItemRectT(GUILayoutGroup parent)
|
||||
=> new RectTransform((1.0f, 0.06f), parent.RectTransform, Anchor.CenterLeft);
|
||||
|
||||
public static void Spacer(GUILayoutGroup parent)
|
||||
public static void Spacer(GUILayoutGroup parent, float height = 0.03f)
|
||||
{
|
||||
new GUIFrame(new RectTransform((1.0f, 0.03f), parent.RectTransform, Anchor.CenterLeft), style: null);
|
||||
new GUIFrame(new RectTransform((1.0f, height), parent.RectTransform, Anchor.CenterLeft), style: null);
|
||||
}
|
||||
|
||||
public static GUITextBlock Label(GUILayoutGroup parent, LocalizedString str, GUIFont font)
|
||||
@@ -507,6 +507,47 @@ namespace Barotrauma
|
||||
return true;
|
||||
}
|
||||
};
|
||||
#if OSX
|
||||
Spacer(voiceChat, 0.003f);
|
||||
|
||||
// On macOS, microphone permission can apparently sometimes end up in a broken state when the app binary changes (eg. after a Steam update).
|
||||
// The device seems to be there, but won't receive anything, even if the mic permission is fine.
|
||||
// This button lets the user reset it and reboot the game, so the mic permission check will be retriggered on next run.
|
||||
new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), voiceChat.RectTransform),
|
||||
text: TextManager.Get("MacResetMicPermissions"),
|
||||
style: "GUIButtonSmall")
|
||||
{
|
||||
ToolTip = TextManager.Get("MacResetMicPermissionsToolTip"),
|
||||
OnClicked = (btn, obj) =>
|
||||
{
|
||||
var confirmBox = new GUIMessageBox(
|
||||
TextManager.Get("MacResetMicPermissions"),
|
||||
TextManager.Get("MacResetMicPermissionsConfirm"),
|
||||
[TextManager.Get("OK"), TextManager.Get("Cancel")]);
|
||||
confirmBox.Buttons[0].OnClicked = (_, _) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
|
||||
{
|
||||
FileName = "tccutil",
|
||||
Arguments = "reset Microphone com.FakeFish.Barotrauma",
|
||||
UseShellExecute = false
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.NewMessage($"Failed to reset microphone permission: {e.Message}", Color.Orange);
|
||||
}
|
||||
GameMain.Instance.Exit();
|
||||
confirmBox.Close();
|
||||
return true;
|
||||
};
|
||||
confirmBox.Buttons[1].OnClicked = confirmBox.Close;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
Spacer(voiceChat);
|
||||
|
||||
Label(voiceChat, TextManager.Get("VCInputMode"), GUIStyle.SubHeadingFont);
|
||||
|
||||
@@ -18,6 +18,10 @@ namespace Barotrauma.Steam
|
||||
{
|
||||
public const int MaxThumbnailSize = 1024 * 1024;
|
||||
|
||||
/// <summary>
|
||||
/// Tags the players can choose for their workshop items. These must match the ones defined in the Steamworks backend. They're case insensitive, but must otherwise match exactly for the tag filtering to work correctly.
|
||||
/// The localized names for these are fetched from the loca files with the identifier "workshop.contenttag.{tag.RemoveWhitespace()}".
|
||||
/// </summary>
|
||||
public static readonly ImmutableArray<Identifier> Tags = new []
|
||||
{
|
||||
"submarine",
|
||||
@@ -25,7 +29,7 @@ namespace Barotrauma.Steam
|
||||
"monster",
|
||||
"mission",
|
||||
"outpost",
|
||||
"beaconstation",
|
||||
"beacon station",
|
||||
"wreck",
|
||||
"ruin",
|
||||
"weapons",
|
||||
@@ -34,14 +38,14 @@ namespace Barotrauma.Steam
|
||||
"art",
|
||||
"event set",
|
||||
"total conversion",
|
||||
"gamemode",
|
||||
"gameplaymechanics",
|
||||
"game mode",
|
||||
"gameplay mechanics",
|
||||
"environment",
|
||||
"item assembly",
|
||||
"language",
|
||||
"qol",
|
||||
"clientside",
|
||||
"serverside",
|
||||
"client-side",
|
||||
"server-side",
|
||||
"outdated",
|
||||
"library"
|
||||
}.ToIdentifiers().ToImmutableArray();
|
||||
|
||||
Reference in New Issue
Block a user