build workflow and spacing cleanup
This commit is contained in:
44
.github/workflows/build.yml
vendored
Normal file
44
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
name: Build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
compute-version:
|
||||||
|
name: Compute Version
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
version: ${{ steps.version.outputs.version }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@master
|
||||||
|
with:
|
||||||
|
ref: ${{ github.head_ref }}
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- id: version
|
||||||
|
uses: paulhatch/semantic-version@v5.3.0
|
||||||
|
with:
|
||||||
|
tag_prefix: ''
|
||||||
|
major_pattern: 'Add project files'
|
||||||
|
minor_pattern: 'feature:'
|
||||||
|
bump_each_commit: true
|
||||||
|
enable_prerelease_mode: false
|
||||||
|
|
||||||
|
build-nuget:
|
||||||
|
name: Build Nuget package
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [compute-version]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@master
|
||||||
|
|
||||||
|
- uses: actions/setup-dotnet@v4
|
||||||
|
|
||||||
|
- run: dotnet restore ./ --locked-mode
|
||||||
|
name: Restore Project
|
||||||
|
|
||||||
|
- run: dotnet pack -c Release -o ./pub ./ --no-restore -p:Version="${{ needs.compute-version.outputs.version }}"
|
||||||
|
name: Pack Project
|
||||||
|
|
||||||
|
- name: Push Project
|
||||||
|
run: dotnet nuget push -s https://ng.zznty.ru/v3/index.json -k ${{ secrets.NUGET_API_KEY }} ./pub/*.nupkg
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -2,4 +2,5 @@ bin/
|
|||||||
obj/
|
obj/
|
||||||
/packages/
|
/packages/
|
||||||
riderModule.iml
|
riderModule.iml
|
||||||
/_ReSharper.Caches/
|
/_ReSharper.Caches/
|
||||||
|
.vs/
|
@@ -31,7 +31,7 @@ internal static class ModInjector
|
|||||||
{
|
{
|
||||||
var index = __state.FindIndex(b =>
|
var index = __state.FindIndex(b =>
|
||||||
b.PublishedFileId == mod.PublishedFileId && b.PublishedServiceName == mod.PublishedServiceName);
|
b.PublishedFileId == mod.PublishedFileId && b.PublishedServiceName == mod.PublishedServiceName);
|
||||||
|
|
||||||
if (index != -1)
|
if (index != -1)
|
||||||
{
|
{
|
||||||
var stateMod = __state[index];
|
var stateMod = __state[index];
|
||||||
@@ -60,7 +60,7 @@ internal static class ModInjector
|
|||||||
)
|
)
|
||||||
.Instructions();
|
.Instructions();
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPatch(typeof(MyDefinitionManager), nameof(MyDefinitionManager.LoadData))]
|
[HarmonyPatch(typeof(MyDefinitionManager), nameof(MyDefinitionManager.LoadData))]
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
private static void LoadDefinitionsPrefix(ref List<MyObjectBuilder_Checkpoint.ModItem> mods) => AppendToList(ref mods);
|
private static void LoadDefinitionsPrefix(ref List<MyObjectBuilder_Checkpoint.ModItem> mods) => AppendToList(ref mods);
|
||||||
|
@@ -15,14 +15,14 @@ public class ModListComponent : IRenderComponent
|
|||||||
{
|
{
|
||||||
private readonly string _configPath;
|
private readonly string _configPath;
|
||||||
private readonly JsonSerializerOptions _options = new(JsonSerializerDefaults.Web);
|
private readonly JsonSerializerOptions _options = new(JsonSerializerDefaults.Web);
|
||||||
|
|
||||||
private bool _visible;
|
private bool _visible;
|
||||||
private string _searchQuery = string.Empty;
|
private string _searchQuery = string.Empty;
|
||||||
private Task? _searchTask;
|
private Task? _searchTask;
|
||||||
|
|
||||||
private PublishedFileId_t[] _mods = [];
|
private PublishedFileId_t[] _mods = [];
|
||||||
private ImmutableDictionary<ulong, WhitelistItem> _whitelist = ImmutableDictionary<ulong, WhitelistItem>.Empty;
|
private ImmutableDictionary<ulong, WhitelistItem> _whitelist = ImmutableDictionary<ulong, WhitelistItem>.Empty;
|
||||||
|
|
||||||
private List<ModItem> _modList = [];
|
private List<ModItem> _modList = [];
|
||||||
private ModItem? _selected;
|
private ModItem? _selected;
|
||||||
public HashSet<ulong> Installed { get; }
|
public HashSet<ulong> Installed { get; }
|
||||||
@@ -57,18 +57,18 @@ public class ModListComponent : IRenderComponent
|
|||||||
|
|
||||||
var mods = new List<PublishedFileId_t>();
|
var mods = new List<PublishedFileId_t>();
|
||||||
var builder = ImmutableDictionary.CreateBuilder<ulong, WhitelistItem>();
|
var builder = ImmutableDictionary.CreateBuilder<ulong, WhitelistItem>();
|
||||||
|
|
||||||
foreach (var item in response.Mods)
|
foreach (var item in response.Mods)
|
||||||
{
|
{
|
||||||
if (!ulong.TryParse(item.Id, out var id)) continue;
|
if (!ulong.TryParse(item.Id, out var id)) continue;
|
||||||
|
|
||||||
mods.Add(new PublishedFileId_t(id));
|
mods.Add(new PublishedFileId_t(id));
|
||||||
builder.Add(id, item);
|
builder.Add(id, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
_mods = mods.ToArray();
|
_mods = mods.ToArray();
|
||||||
_whitelist = builder.ToImmutable();
|
_whitelist = builder.ToImmutable();
|
||||||
await RefreshAsync();
|
await RefreshAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnFrame()
|
public void OnFrame()
|
||||||
@@ -80,7 +80,7 @@ public class ModListComponent : IRenderComponent
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
InputText("##searchbox", ref _searchQuery, 256);
|
InputText("##searchbox", ref _searchQuery, 256);
|
||||||
|
|
||||||
SameLine();
|
SameLine();
|
||||||
|
|
||||||
if (Button("Search"))
|
if (Button("Search"))
|
||||||
@@ -88,26 +88,27 @@ public class ModListComponent : IRenderComponent
|
|||||||
_searchTask = RefreshAsync();
|
_searchTask = RefreshAsync();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacing();
|
Spacing();
|
||||||
|
|
||||||
switch (_searchTask)
|
switch (_searchTask)
|
||||||
{
|
{
|
||||||
case { IsCompleted: false }:
|
case { IsCompleted: false }:
|
||||||
TextDisabled("Loading...");
|
TextDisabled("Loading...");
|
||||||
return;
|
return;
|
||||||
case { IsCompletedSuccessfully: false }:
|
case { IsCompletedSuccessfully: false }:
|
||||||
{
|
|
||||||
TextDisabled("Failed to load plugins list");
|
|
||||||
if (_searchTask.Exception is null) return;
|
|
||||||
|
|
||||||
foreach (var exception in _searchTask.Exception.InnerExceptions)
|
|
||||||
{
|
{
|
||||||
TextWrapped($"{exception.GetType()}: {exception.Message}");
|
TextDisabled("Failed to load plugins list");
|
||||||
}
|
if (_searchTask.Exception is null)
|
||||||
|
return;
|
||||||
|
|
||||||
return;
|
foreach (var exception in _searchTask.Exception.InnerExceptions)
|
||||||
}
|
{
|
||||||
|
TextWrapped($"{exception.GetType()}: {exception.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_modList.Count == 0)
|
if (_modList.Count == 0)
|
||||||
@@ -115,7 +116,7 @@ public class ModListComponent : IRenderComponent
|
|||||||
TextDisabled("Nothing found");
|
TextDisabled("Nothing found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BeginChild("List", new(400, 0), ImGuiChildFlags.Border | ImGuiChildFlags.ResizeX);
|
BeginChild("List", new(400, 0), ImGuiChildFlags.Border | ImGuiChildFlags.ResizeX);
|
||||||
{
|
{
|
||||||
if (BeginTable("AvailableModsTable", 3,
|
if (BeginTable("AvailableModsTable", 3,
|
||||||
@@ -155,83 +156,83 @@ public class ModListComponent : IRenderComponent
|
|||||||
|
|
||||||
EndChild();
|
EndChild();
|
||||||
}
|
}
|
||||||
|
|
||||||
SameLine();
|
SameLine();
|
||||||
|
|
||||||
BeginGroup();
|
BeginGroup();
|
||||||
|
|
||||||
BeginChild("Mod View", new(0, -GetFrameHeightWithSpacing())); // Leave room for 1 line below us
|
BeginChild("Mod View", new(0, -GetFrameHeightWithSpacing())); // Leave room for 1 line below us
|
||||||
|
|
||||||
if (_selected is not null)
|
if (_selected is not null)
|
||||||
{
|
|
||||||
Text(_selected.Name);
|
|
||||||
Separator();
|
|
||||||
if (BeginTabBar("##ModViewTabs"))
|
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(_selected.Description) && BeginTabItem("Description"))
|
Text(_selected.Name);
|
||||||
|
Separator();
|
||||||
|
if (BeginTabBar("##ModViewTabs"))
|
||||||
{
|
{
|
||||||
TextWrapped(_selected.Description);
|
if (!string.IsNullOrEmpty(_selected.Description) && BeginTabItem("Description"))
|
||||||
EndTabItem();
|
{
|
||||||
|
TextWrapped(_selected.Description);
|
||||||
|
EndTabItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BeginTabItem("Mod Description"))
|
||||||
|
{
|
||||||
|
TextWrapped(string.IsNullOrEmpty(_selected.ModDescription) ? "Nothing." : _selected.ModDescription);
|
||||||
|
EndTabItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BeginTabItem("Details"))
|
||||||
|
{
|
||||||
|
TextLinkOpenURL("Mod URL", _selected.Url);
|
||||||
|
|
||||||
|
Text("Author:");
|
||||||
|
SameLine();
|
||||||
|
TextWrapped(_selected.Author);
|
||||||
|
|
||||||
|
Text("Created:");
|
||||||
|
SameLine();
|
||||||
|
TextWrapped(DateTimeOffset.FromUnixTimeSeconds(_selected.Created).ToString("g"));
|
||||||
|
|
||||||
|
Text("Updated:");
|
||||||
|
SameLine();
|
||||||
|
TextWrapped(DateTimeOffset.FromUnixTimeSeconds(_selected.Updated).ToString("g"));
|
||||||
|
|
||||||
|
EndTabItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
EndTabBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BeginTabItem("Mod Description"))
|
|
||||||
{
|
|
||||||
TextWrapped(string.IsNullOrEmpty(_selected.ModDescription) ? "Nothing." : _selected.ModDescription);
|
|
||||||
EndTabItem();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BeginTabItem("Details"))
|
|
||||||
{
|
|
||||||
TextLinkOpenURL("Mod URL", _selected.Url);
|
|
||||||
|
|
||||||
Text("Author:");
|
|
||||||
SameLine();
|
|
||||||
TextWrapped(_selected.Author);
|
|
||||||
|
|
||||||
Text("Created:");
|
|
||||||
SameLine();
|
|
||||||
TextWrapped(DateTimeOffset.FromUnixTimeSeconds(_selected.Created).ToString("g"));
|
|
||||||
|
|
||||||
Text("Updated:");
|
|
||||||
SameLine();
|
|
||||||
TextWrapped(DateTimeOffset.FromUnixTimeSeconds(_selected.Updated).ToString("g"));
|
|
||||||
|
|
||||||
EndTabItem();
|
|
||||||
}
|
|
||||||
|
|
||||||
EndTabBar();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
EndChild();
|
EndChild();
|
||||||
|
|
||||||
if (_selected is not null)
|
if (_selected is not null)
|
||||||
{
|
|
||||||
var installed = Installed.Contains(_selected.Id);
|
|
||||||
if (Button(installed ? "Uninstall" : "Install"))
|
|
||||||
{
|
{
|
||||||
if (installed)
|
var installed = Installed.Contains(_selected.Id);
|
||||||
Installed.Remove(_selected.Id);
|
if (Button(installed ? "Uninstall" : "Install"))
|
||||||
else
|
{
|
||||||
Installed.Add(_selected.Id);
|
if (installed)
|
||||||
|
Installed.Remove(_selected.Id);
|
||||||
|
else
|
||||||
|
Installed.Add(_selected.Id);
|
||||||
|
|
||||||
Save();
|
Save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
EndGroup();
|
EndGroup();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
End();
|
End();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void Save()
|
private void Save()
|
||||||
{
|
{
|
||||||
using var stream = File.Create(_configPath);
|
using var stream = File.Create(_configPath);
|
||||||
|
|
||||||
JsonSerializer.Serialize(stream, Installed, _options);
|
JsonSerializer.Serialize(stream, Installed, _options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,14 +242,14 @@ public class ModListComponent : IRenderComponent
|
|||||||
|
|
||||||
if (handle.m_UGCQueryHandle == ulong.MaxValue)
|
if (handle.m_UGCQueryHandle == ulong.MaxValue)
|
||||||
throw new Exception("Failed to create UGC request");
|
throw new Exception("Failed to create UGC request");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
SteamUGC.SetSearchText(handle, _searchQuery);
|
SteamUGC.SetSearchText(handle, _searchQuery);
|
||||||
SteamUGC.SetReturnLongDescription(handle, true);
|
SteamUGC.SetReturnLongDescription(handle, true);
|
||||||
// TODO font support for other languages
|
// TODO font support for other languages
|
||||||
// SteamUGC.SetLanguage(handle, MapLanguage(MySandboxGame.Config.Language));
|
// SteamUGC.SetLanguage(handle, MapLanguage(MySandboxGame.Config.Language));
|
||||||
|
|
||||||
var call = SteamUGC.SendQueryUGCRequest(handle);
|
var call = SteamUGC.SendQueryUGCRequest(handle);
|
||||||
|
|
||||||
var result = await CallResultAsync<SteamUGCQueryCompleted_t>.Create(call);
|
var result = await CallResultAsync<SteamUGCQueryCompleted_t>.Create(call);
|
||||||
@@ -261,9 +262,9 @@ public class ModListComponent : IRenderComponent
|
|||||||
break;
|
break;
|
||||||
if (details.m_eResult != EResult.k_EResultOK)
|
if (details.m_eResult != EResult.k_EResultOK)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var title = details.m_rgchTitle;
|
var title = details.m_rgchTitle;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(_searchQuery) && !title.Contains(_searchQuery, StringComparison.OrdinalIgnoreCase))
|
if (!string.IsNullOrEmpty(_searchQuery) && !title.Contains(_searchQuery, StringComparison.OrdinalIgnoreCase))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -278,7 +279,7 @@ public class ModListComponent : IRenderComponent
|
|||||||
description, $"https://steamcommunity.com/sharedfiles/filedetails/?id={details.m_nPublishedFileId.m_PublishedFileId}",
|
description, $"https://steamcommunity.com/sharedfiles/filedetails/?id={details.m_nPublishedFileId.m_PublishedFileId}",
|
||||||
details.m_rtimeCreated, details.m_rtimeUpdated, item.Author));
|
details.m_rtimeCreated, details.m_rtimeUpdated, item.Author));
|
||||||
}
|
}
|
||||||
|
|
||||||
_modList = list;
|
_modList = list;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
@@ -22,7 +22,7 @@ public static class CallResultAsync<T> where T : struct
|
|||||||
|
|
||||||
return await tcs.Task;
|
return await tcs.Task;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 8)]
|
[StructLayout(LayoutKind.Sequential, Pack = 8)]
|
||||||
private struct GenericCallResult
|
private struct GenericCallResult
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user