diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 08b42ec..ab948a1 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -76,13 +76,13 @@ jobs: ########################### publish-on-nexusmods: if: github.ref == 'refs/heads/master' - needs: ["get-changelog", "build"] + needs: [get-changelog, build] uses: BUTR/workflows/.github/workflows/release-nexusmods.yml@master with: nexusmods_game_id: mountandblade2bannerlord nexusmods_mod_id: 1 mod_filename: 'Bannerlord Software Extender (BLSE)' - mod_version: ${{ needs.build-changelog.outputs.mod_version }} + mod_version: ${{ needs.get-changelog.outputs.mod_version }} mod_description: ${{ needs.build.outputs.mod_description }} artifact_name: bannerlord secrets: @@ -94,11 +94,11 @@ jobs: ########################### publish-on-github: if: github.ref == 'refs/heads/master' - needs: ["get-changelog", "build"] + needs: [get-changelog, build] uses: BUTR/workflows/.github/workflows/release-github.yml@master with: mod_id: Bannerlord.BLSE - mod_version: ${{ needs.build-changelog.outputs.mod_version }} + mod_version: ${{ needs.get-changelog.outputs.mod_version }} mod_description: ${{ needs.build.outputs.mod_description }} artifact_name: bannerlord @@ -107,7 +107,7 @@ jobs: ########################### publish-on-steam: if: github.ref == 'refs/heads/master' - needs: ["get-changelog", "build"] + needs: [get-changelog, build] runs-on: ubuntu-latest steps: - name: Download Module artifact @@ -123,7 +123,7 @@ jobs: ssfnFileName: ${{ secrets.STEAM_SSFN_FILE_NAME }} ssfnFileContents: ${{ secrets.STEAM_SSFN_FILE_CONTENTS }} appId: ${{ secrets.STEAM_APPID }} - buildDescription: ${{ needs.build-changelog.outputs.mod_version }} + buildDescription: ${{ needs.get-changelog.outputs.mod_version }} rootPath: build depot1Path: ./artifact releaseBranch: prerelease diff --git a/build/common.props b/build/common.props index 1df679e..c6e97ff 100644 --- a/build/common.props +++ b/build/common.props @@ -13,11 +13,11 @@ 1.5.0 2.2.2 - 3.0.0.138 + 3.0.0.139 5.0.222 3.2.0.77 1.0.1.50 - 1.0.100 + 1.0.107 full diff --git a/src/Bannerlord.BLSE.Loaders.Launcher/Bannerlord.BLSE.Loaders.Launcher.csproj b/src/Bannerlord.BLSE.Loaders.Launcher/Bannerlord.BLSE.Loaders.Launcher.csproj index 0ca898b..906c6f4 100644 --- a/src/Bannerlord.BLSE.Loaders.Launcher/Bannerlord.BLSE.Loaders.Launcher.csproj +++ b/src/Bannerlord.BLSE.Loaders.Launcher/Bannerlord.BLSE.Loaders.Launcher.csproj @@ -4,7 +4,7 @@ winexe x64 net472 - 11.0 + 12.0 enable ../../resources/BLSE_SMALL.ico true diff --git a/src/Bannerlord.BLSE.Loaders.LauncherEx/Bannerlord.BLSE.Loaders.LauncherEx.csproj b/src/Bannerlord.BLSE.Loaders.LauncherEx/Bannerlord.BLSE.Loaders.LauncherEx.csproj index 73e65b2..bd83798 100644 --- a/src/Bannerlord.BLSE.Loaders.LauncherEx/Bannerlord.BLSE.Loaders.LauncherEx.csproj +++ b/src/Bannerlord.BLSE.Loaders.LauncherEx/Bannerlord.BLSE.Loaders.LauncherEx.csproj @@ -4,7 +4,7 @@ winexe x64 net472 - 11.0 + 12.0 enable ../../resources/BLSE_SMALL.ico true diff --git a/src/Bannerlord.BLSE.Loaders.Standalone/Bannerlord.BLSE.Loaders.Standalone.csproj b/src/Bannerlord.BLSE.Loaders.Standalone/Bannerlord.BLSE.Loaders.Standalone.csproj index 3e43bce..b797fac 100644 --- a/src/Bannerlord.BLSE.Loaders.Standalone/Bannerlord.BLSE.Loaders.Standalone.csproj +++ b/src/Bannerlord.BLSE.Loaders.Standalone/Bannerlord.BLSE.Loaders.Standalone.csproj @@ -4,7 +4,7 @@ winexe x64 net472 - 11.0 + 12.0 enable ../../resources/BLSE_SMALL.ico true diff --git a/src/Bannerlord.BLSE.Shared/Bannerlord.BLSE.Shared.csproj b/src/Bannerlord.BLSE.Shared/Bannerlord.BLSE.Shared.csproj index 1026937..158419f 100644 --- a/src/Bannerlord.BLSE.Shared/Bannerlord.BLSE.Shared.csproj +++ b/src/Bannerlord.BLSE.Shared/Bannerlord.BLSE.Shared.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 11.0 + 12.0 enable x64 library @@ -79,8 +79,8 @@ - - + + diff --git a/src/Bannerlord.BLSE/Bannerlord.BLSE.csproj b/src/Bannerlord.BLSE/Bannerlord.BLSE.csproj index 196a480..6739a13 100644 --- a/src/Bannerlord.BLSE/Bannerlord.BLSE.csproj +++ b/src/Bannerlord.BLSE/Bannerlord.BLSE.csproj @@ -6,7 +6,7 @@ $(Version).$(GITHUB_RUN_NUMBER) netstandard2.0 - 11.0 + 12.0 enable x64 diff --git a/src/Bannerlord.LauncherEx/Adapters/FileSystemProviderImpl.cs b/src/Bannerlord.LauncherEx/Adapters/FileSystemProviderImpl.cs index 43317e0..7c4d5ae 100644 --- a/src/Bannerlord.LauncherEx/Adapters/FileSystemProviderImpl.cs +++ b/src/Bannerlord.LauncherEx/Adapters/FileSystemProviderImpl.cs @@ -56,5 +56,5 @@ public void WriteFileContent(string filePath, byte[]? data) public string[]? ReadDirectoryFileList(string directoryPath) => Directory.Exists(directoryPath) ? Directory.GetFiles(directoryPath) : null; - public string[]? ReadDirectoryList(string directoryPath) => Directory.Exists(directoryPath) ? Directory.GetFiles(directoryPath) : null; + public string[]? ReadDirectoryList(string directoryPath) => Directory.Exists(directoryPath) ? Directory.GetDirectories(directoryPath) : null; } \ No newline at end of file diff --git a/src/Bannerlord.LauncherEx/BUTRLauncherManagerHandler.Utils.cs b/src/Bannerlord.LauncherEx/BUTRLauncherManagerHandler.Utils.cs index 065ec29..f2cd4c4 100644 --- a/src/Bannerlord.LauncherEx/BUTRLauncherManagerHandler.Utils.cs +++ b/src/Bannerlord.LauncherEx/BUTRLauncherManagerHandler.Utils.cs @@ -2,7 +2,6 @@ using Bannerlord.LauncherManager.Models; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; namespace Bannerlord.LauncherEx; @@ -16,8 +15,6 @@ partial class BUTRLauncherManagerHandler public override int GetChangeset() => typeof(TaleWorlds.Library.ApplicationVersion).GetField("DefaultChangeSet")?.GetValue(null) as int? ?? 0; - protected override IEnumerable ReloadModules() => ModuleInfoHelper.GetModules().Select(x => new ModuleInfoExtendedWithPath(x, x.Path)); - // More of a reminder how the callbacks should be handled if needed in C# public Task ShowWarning(string title, string contentPrimary, string contentSecondary) @@ -42,4 +39,6 @@ public Task ShowFileSave(string title, string fileName, IReadOnlyList base.LoadLoadOrder(); + + public new IReadOnlyList GetAllModules() => base.GetAllModules(); } \ No newline at end of file diff --git a/src/Bannerlord.LauncherEx/Bannerlord.LauncherEx.csproj b/src/Bannerlord.LauncherEx/Bannerlord.LauncherEx.csproj index 3d8449e..a4a51e4 100644 --- a/src/Bannerlord.LauncherEx/Bannerlord.LauncherEx.csproj +++ b/src/Bannerlord.LauncherEx/Bannerlord.LauncherEx.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 11.0 + 12.0 enable x64 1.25.0 @@ -24,6 +24,9 @@ 1.2.0 + + + $([System.String]::Copy('$(GameVersion)').Replace('.','')) v$(GameVersionFlat) $(DefineConstants);$(GameVersionConstant) diff --git a/src/Bannerlord.LauncherEx/Helpers/Input/BUTRInputManager.cs b/src/Bannerlord.LauncherEx/Helpers/Input/BUTRInputManager.cs index 34637a1..c244cc1 100644 --- a/src/Bannerlord.LauncherEx/Helpers/Input/BUTRInputManager.cs +++ b/src/Bannerlord.LauncherEx/Helpers/Input/BUTRInputManager.cs @@ -94,23 +94,33 @@ public bool IsKeyDownImmediate(InputKey key) => public void UpdateKeyData(byte[] keyData) => InputManager.UpdateKeyData(keyData); public bool IsControllerConnected() => InputManager.IsControllerConnected(); -#if v100 || v101 || v102 || v103 || v110 || v111 || v112 || v113 || v114 || v115 + +#if v100 || v110 public InputKey GetControllerClickKey() => InputManager.GetControllerClickKey(); #endif -#if v110 || v111 - public void SetRumbleEffect(float[] lowFrequencyLevels, float[] lowFrequencyDurations, int numLowFrequencyElements, float[] highFrequencyLevels, - float[] highFrequencyDurations, int numHighFrequencyElements) => - InputManager.SetRumbleEffect(lowFrequencyLevels, lowFrequencyDurations, numLowFrequencyElements, highFrequencyLevels, highFrequencyDurations, numHighFrequencyElements); - public void SetTriggerFeedback(byte leftTriggerPosition, byte leftTriggerStrength, byte rightTriggerPosition, byte rightTriggerStrength) => - InputManager.SetTriggerFeedback(leftTriggerPosition, leftTriggerStrength, rightTriggerPosition, rightTriggerStrength); - public void SetTriggerWeaponEffect(byte leftStartPosition, byte leftEnd_position, byte leftStrength, byte rightStartPosition, byte rightEndPosition, byte rightStrength) => - InputManager.SetTriggerWeaponEffect(leftStartPosition, leftEnd_position, leftStrength, rightStartPosition, rightEndPosition, rightStrength); - public void SetTriggerVibration(float[] leftTriggerAmplitudes, float[] leftTriggerFrequencies, float[] leftTriggerDurations, int numLeftTriggerElements, - float[] rightTriggerAmplitudes, float[] rightTriggerFrequencies, float[] rightTriggerDurations, int numRightTriggerElements) => - InputManager.SetTriggerVibration(leftTriggerAmplitudes, leftTriggerFrequencies, leftTriggerDurations, numLeftTriggerElements, rightTriggerAmplitudes, - rightTriggerFrequencies, rightTriggerDurations, numRightTriggerElements); - public void SetLightbarColor(float red, float green, float blue) => InputManager.SetLightbarColor(red, green, blue); +#if v110 || v120 + public void SetRumbleEffect(float[] lowFrequencyLevels, float[] lowFrequencyDurations, int numLowFrequencyElements, float[] highFrequencyLevels, float[] highFrequencyDurations, int numHighFrequencyElements) => + InputManager.SetRumbleEffect(lowFrequencyLevels, lowFrequencyDurations, numLowFrequencyElements, highFrequencyLevels, highFrequencyDurations, numHighFrequencyElements); + public void SetTriggerFeedback(byte leftTriggerPosition, byte leftTriggerStrength, byte rightTriggerPosition, byte rightTriggerStrength) => + InputManager.SetTriggerFeedback(leftTriggerPosition, leftTriggerStrength, rightTriggerPosition, rightTriggerStrength); + public void SetTriggerWeaponEffect(byte leftStartPosition, byte leftEnd_position, byte leftStrength, byte rightStartPosition, byte rightEndPosition, byte rightStrength) => + InputManager.SetTriggerWeaponEffect(leftStartPosition, leftEnd_position, leftStrength, rightStartPosition, rightEndPosition, rightStrength); + public void SetTriggerVibration(float[] leftTriggerAmplitudes, float[] leftTriggerFrequencies, float[] leftTriggerDurations, int numLeftTriggerElements, float[] rightTriggerAmplitudes, float[] rightTriggerFrequencies, float[] rightTriggerDurations, int numRightTriggerElements) => + InputManager.SetTriggerVibration(leftTriggerAmplitudes, leftTriggerFrequencies, leftTriggerDurations, numLeftTriggerElements, rightTriggerAmplitudes, rightTriggerFrequencies, rightTriggerDurations, numRightTriggerElements); + public void SetLightbarColor(float red, float green, float blue) => InputManager.SetLightbarColor(red, green, blue); +#endif + +#if v120 + public TaleWorlds.InputSystem.Input.ControllerTypes GetControllerType() => InputManager.GetControllerType(); + + public float GetGyroX() => InputManager.GetGyroX(); + public float GetGyroY() => InputManager.GetGyroY(); + public float GetGyroZ() => InputManager.GetGyroZ(); + + public InputKey[] GetClickKeys() => InputManager.GetClickKeys(); + + public bool IsAnyTouchActive() => InputManager.IsAnyTouchActive(); #endif private static TReturn IsAction(InputKey key, Func action, Func fallback) @@ -138,31 +148,6 @@ private static TReturn IsAction(InputKey key, Func actio return action(rawKey); } -#if v120 - public TaleWorlds.InputSystem.Input.ControllerTypes GetControllerType() => InputManager.GetControllerType(); - - public float GetGyroX() => InputManager.GetGyroX(); - public float GetGyroY() => InputManager.GetGyroY(); - public float GetGyroZ() => InputManager.GetGyroZ(); - - public InputKey[] GetClickKeys() => InputManager.GetClickKeys(); - - public void SetRumbleEffect(float[] lowFrequencyLevels, float[] lowFrequencyDurations, int numLowFrequencyElements, float[] highFrequencyLevels, float[] highFrequencyDurations, int numHighFrequencyElements) => - InputManager.SetRumbleEffect(lowFrequencyLevels, lowFrequencyDurations, numLowFrequencyElements, highFrequencyLevels, highFrequencyDurations, numHighFrequencyElements); - - public void SetTriggerFeedback(byte leftTriggerPosition, byte leftTriggerStrength, byte rightTriggerPosition, byte rightTriggerStrength) => - InputManager.SetTriggerFeedback(leftTriggerPosition, leftTriggerStrength, rightTriggerPosition, rightTriggerStrength); - - public void SetTriggerWeaponEffect(byte leftStartPosition, byte leftEnd_position, byte leftStrength, byte rightStartPosition, byte rightEndPosition, byte rightStrength) => - InputManager.SetTriggerWeaponEffect(leftStartPosition, leftEnd_position, leftStrength, rightStartPosition, rightEndPosition, rightStrength); - - public void SetTriggerVibration(float[] leftTriggerAmplitudes, float[] leftTriggerFrequencies, float[] leftTriggerDurations, int numLeftTriggerElements, float[] rightTriggerAmplitudes, float[] rightTriggerFrequencies, float[] rightTriggerDurations, int numRightTriggerElements) => - InputManager.SetTriggerVibration(leftTriggerAmplitudes, leftTriggerFrequencies, leftTriggerDurations, numLeftTriggerElements, rightTriggerAmplitudes, rightTriggerFrequencies, rightTriggerDurations, numRightTriggerElements); - - public void SetLightbarColor(float red, float green, float blue) => InputManager.SetLightbarColor(red, green, blue); - - public bool IsAnyTouchActive() => InputManager.IsAnyTouchActive(); -#endif public void Dispose() { diff --git a/src/Bannerlord.LauncherEx/Helpers/ModuleChecker.cs b/src/Bannerlord.LauncherEx/Helpers/ModuleChecker.cs index 2fc1c91..98e8dec 100644 --- a/src/Bannerlord.LauncherEx/Helpers/ModuleChecker.cs +++ b/src/Bannerlord.LauncherEx/Helpers/ModuleChecker.cs @@ -1,5 +1,4 @@ using Bannerlord.BUTR.Shared.Helpers; -using Bannerlord.LauncherManager.Extensions; using Bannerlord.LauncherManager.Models; using Bannerlord.ModuleManager; @@ -7,7 +6,6 @@ using Mono.Cecil.Rocks; using System; -using System.Collections.Generic; using System.IO; using System.Linq; @@ -18,13 +16,7 @@ namespace Bannerlord.LauncherEx.Helpers; // TODO: NativeAOT won't cover that? internal static class ModuleChecker { - private static readonly HashSet MainModules = ModuleInfoHelper.GetPhysicalModules().Select(x => x.Id).ToHashSet(); - private static readonly HashSet ExternalModules = ModuleInfoHelper.GetPlatformModules().Select(x => x.Id).ToHashSet(); - - public static bool IsInstalledInMainAndExternalModuleDirectory(ModuleInfoExtendedWithPath moduleInfoExtended) => - MainModules.Contains(moduleInfoExtended.Id) && ExternalModules.Contains(moduleInfoExtended.Id); - - public static bool IsObfuscated(ModuleInfoExtendedWithPath moduleInfoExtended) + public static bool IsObfuscated(ModuleInfoExtendedWithMetadata moduleInfoExtended) { static bool CanBeLoaded(SubModuleInfoExtended x) => ModuleInfoHelper.CheckIfSubModuleCanBeLoaded(x, ApplicationPlatform.CurrentPlatform, ApplicationPlatform.CurrentRuntimeLibrary, TaleWorlds.MountAndBlade.DedicatedServerType.None, false); diff --git a/src/Bannerlord.LauncherEx/Mixins/LauncherModsVMMixin.cs b/src/Bannerlord.LauncherEx/Mixins/LauncherModsVMMixin.cs index 9a083cb..84f13e3 100644 --- a/src/Bannerlord.LauncherEx/Mixins/LauncherModsVMMixin.cs +++ b/src/Bannerlord.LauncherEx/Mixins/LauncherModsVMMixin.cs @@ -33,6 +33,7 @@ internal sealed class LauncherModsVMMixin : ViewModelMixin _modules = new(); private readonly Dictionary _modulesLookup = new(); + private IReadOnlyList _allModuleInfos; [BUTRDataSourceProperty] public bool GlobalCheckboxState { get => _checkboxState; set => SetField(ref _checkboxState, value); } @@ -96,9 +97,10 @@ public LauncherModsVMMixin(LauncherModsVM launcherModsVM) : base(launcherModsVM) _launcherManagerHandler.RegisterModuleViewModelProvider(() => _modules, () => Modules2, SetViewModels); _launcherManagerHandler.RefreshModules(); - foreach (var moduleInfoExtended in _launcherManagerHandler.ExtendedModuleInfoCache.Values.OfType()) + _allModuleInfos = _launcherManagerHandler.GetAllModules(); + foreach (var moduleInfoExtended in _launcherManagerHandler.ExtendedModuleInfoCache.Values.OfType()) { - var moduleVM = new BUTRLauncherModuleVM(moduleInfoExtended, ToggleModuleSelection, ValidateModule); + var moduleVM = new BUTRLauncherModuleVM(moduleInfoExtended, ToggleModuleSelection, ValidateModule, GetPossibleProviders); _modules.Add(moduleVM); _modulesLookup[moduleVM.ModuleInfoExtended.Id] = moduleVM; } @@ -144,9 +146,15 @@ private void SetViewModels(IEnumerable orderedModuleViewModels foreach (var viewModel in orderedModuleViewModels.OfType()) Modules2.Add(viewModel); + _launcherManagerHandler.RefreshModules(); + _allModuleInfos = _launcherManagerHandler.GetAllModules(); + // Validate all VM's after they were selected and ordered foreach (var modules in Modules2) + { modules.Validate(); + modules.Refresh(); + } _launcherManagerHandler.SetGameParametersLoadOrder(Modules2); } @@ -157,6 +165,10 @@ private void ToggleModuleSelection(BUTRLauncherModuleVM moduleVM) SortHelper.ToggleModuleSelection(Modules2, _modulesLookup, moduleVM); _launcherManagerHandler.SetGameParametersLoadOrder(Modules2); } + private ICollection GetPossibleProviders(ModuleInfoExtendedWithMetadata moduleInfo) => _allModuleInfos + .Where(x => x.Id == moduleInfo.Id && x.ModuleProviderType != moduleInfo.ModuleProviderType) + .Select(x => x.ModuleProviderType) + .ToList(); private void ChangeModulePosition(BUTRLauncherModuleVM targetModuleVM, int insertIndex, Action>? onIssues = null) { @@ -201,6 +213,12 @@ static IEnumerable Sort(IEnumerable sour Modules2.Sort(new ByIndexComparer(x => sorted.TryGetValue(x.ModuleInfoExtended.Id, out var idx) ? idx : -1)); //var sorted = Sort(Modules2.Select(x => x.ModuleInfoExtended)).Select(x => x.Id).ToList(); //SortBy(sorted); + + _launcherManagerHandler.RefreshModules(); + _allModuleInfos = _launcherManagerHandler.GetAllModules(); + foreach (var moduleVM in Modules2) + moduleVM.Refresh(); + _launcherManagerHandler.SetGameParametersLoadOrder(Modules2); } diff --git a/src/Bannerlord.LauncherEx/ViewModels/BUTRLauncherModuleVM.cs b/src/Bannerlord.LauncherEx/ViewModels/BUTRLauncherModuleVM.cs index 30a50a3..7f10a54 100644 --- a/src/Bannerlord.LauncherEx/ViewModels/BUTRLauncherModuleVM.cs +++ b/src/Bannerlord.LauncherEx/ViewModels/BUTRLauncherModuleVM.cs @@ -19,8 +19,9 @@ internal sealed class BUTRLauncherModuleVM : BUTRViewModel, IModuleViewModel { private readonly Action _select; private readonly Func> _validate; + private readonly Func> _getPossibleProviders; - public ModuleInfoExtendedWithPath ModuleInfoExtended { get; } + public ModuleInfoExtendedWithMetadata ModuleInfoExtended { get; } public int Index { get; set; } @@ -118,11 +119,13 @@ public string IssuesText public LauncherHintVM? UpdateHint { get => _updateHint; set => SetField(ref _updateHint, value); } private LauncherHintVM? _updateHint; - public BUTRLauncherModuleVM(ModuleInfoExtendedWithPath moduleInfoExtended, Action select, Func> validate) + public BUTRLauncherModuleVM(ModuleInfoExtendedWithMetadata moduleInfoExtended, Action select, Func> validate, + Func> getPossibleProviders) { ModuleInfoExtended = moduleInfoExtended; _select = select; _validate = validate; + _getPossibleProviders = getPossibleProviders; if (ModuleDependencyConstructor.GetDependencyHint(moduleInfoExtended) is { } str) { @@ -130,12 +133,26 @@ public BUTRLauncherModuleVM(ModuleInfoExtendedWithPath moduleInfoExtended, Actio AnyDependencyAvailable = !string.IsNullOrEmpty(str); } + Refresh(); + } + + public void Validate() + { + var validationIssues = _validate(this).ToList(); + + IssuesText = validationIssues.Count > 0 + ? string.Join("\n", validationIssues) + : string.Empty; + } + + public void Refresh() + { var dangerous = string.Empty; - if (ModuleChecker.IsInstalledInMainAndExternalModuleDirectory(moduleInfoExtended)) + if (_getPossibleProviders(ModuleInfoExtended) is { } providers && providers.Any(x => x == ModuleProviderType.Steam)) { dangerous += new BUTRTextObject("{=kfMQEOFS}The Module is installed in the game's /Modules folder and on Steam Workshop!{NL}The /Modules version will be used!").ToString(); } - if (ModuleChecker.IsObfuscated(moduleInfoExtended)) + if (ModuleChecker.IsObfuscated(ModuleInfoExtended)) { if (dangerous.Length != 0) dangerous += "\n"; dangerous += new BUTRTextObject("{=aAYdk1zd}The DLL is obfuscated!{NL}There is no guarantee that the code is safe!{NL}The BUTR Team warns of consequences arising from running obfuscated code!").ToString(); @@ -152,15 +169,6 @@ public BUTRLauncherModuleVM(ModuleInfoExtendedWithPath moduleInfoExtended, Actio } } - public void Validate() - { - var validationIssues = _validate(this).ToList(); - - IssuesText = validationIssues.Count > 0 - ? string.Join("\n", validationIssues) - : string.Empty; - } - [BUTRDataSourceMethod] public void ExecuteSelect() {