forked from Reloaded-Project/Reloaded-II
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WIP: Separate Reloaded.Utils.Server Mod for Services
- Loading branch information
Showing
71 changed files
with
2,492 additions
and
819 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
147 changes: 147 additions & 0 deletions
147
source/Mods/Reloaded.Utils.Server/.github/workflows/reloaded.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
# Script to build and publish a Reloaded Mod. | ||
# by Sewer56 | ||
|
||
# Produces: | ||
# - Build to Upload to GameBanana | ||
# - Build to Upload to GitHub | ||
# - Build to Upload to NuGet | ||
# - Changelog | ||
|
||
# When pushing a tag | ||
# - Upload to GitHub Releases | ||
# - Upload to Reloaded NuGet Repository (if GitHub Secret RELOADED_NUGET_KEY is specified) | ||
|
||
name: Build and Publish Reloaded Mod | ||
|
||
on: | ||
push: | ||
branches: [ main ] | ||
tags: | ||
- '*' | ||
pull_request: | ||
branches: [ main ] | ||
workflow_dispatch: | ||
|
||
env: | ||
PUBLISH_COMMON_PATH: ./Publish/ToUpload/ | ||
|
||
PUBLISH_GAMEBANANA_PATH: ./Publish/ToUpload/GameBanana | ||
PUBLISH_GITHUB_PATH: ./Publish/ToUpload/Generic | ||
PUBLISH_NUGET_PATH: ./Publish/ToUpload/NuGet | ||
|
||
PUBLISH_CHANGELOG_PATH: ./Publish/Changelog.md | ||
PUBLISH_PATH: ./Publish | ||
|
||
# Default value is official Reloaded package server. | ||
NUGET_URL: http://packages.sewer56.moe:5000/v3/index.json | ||
|
||
IS_RELEASE: ${{ startsWith(github.ref, 'refs/tags/') }} | ||
RELEASE_TAG: ${{ github.ref_name }} | ||
|
||
jobs: | ||
build: | ||
runs-on: windows-latest | ||
defaults: | ||
run: | ||
shell: pwsh | ||
|
||
steps: | ||
- uses: actions/checkout@v2 | ||
with: | ||
fetch-depth: 0 | ||
submodules: 'recursive' | ||
|
||
- name: Setup .NET Core SDK (5.0) | ||
uses: actions/setup-dotnet@v1.8.2 | ||
with: | ||
dotnet-version: 5.0.x | ||
|
||
- name: Setup .NET Core SDK (6.0) | ||
uses: actions/setup-dotnet@v1.8.2 | ||
with: | ||
dotnet-version: 6.0.x | ||
|
||
- name: Setup Node.js | ||
uses: actions/setup-node@v2 | ||
with: | ||
node-version: '14' | ||
|
||
- name: Setup AutoChangelog | ||
run: npm install -g auto-changelog | ||
|
||
- name: Create Changelog | ||
run: | | ||
[System.IO.Directory]::CreateDirectory("$env:PUBLISH_PATH") | ||
if ($env:IS_RELEASE -eq 'true') { | ||
auto-changelog --sort-commits date --hide-credit --template keepachangelog --commit-limit false --starting-version "$env:RELEASE_TAG" --output "$env:PUBLISH_CHANGELOG_PATH" | ||
} | ||
else { | ||
auto-changelog --sort-commits date --hide-credit --template keepachangelog --commit-limit false --unreleased --output "$env:PUBLISH_CHANGELOG_PATH" | ||
} | ||
- name: Build | ||
run: ./Publish.ps1 -ChangelogPath "$env:PUBLISH_CHANGELOG_PATH" | ||
|
||
- name: Upload GitHub Release Artifact | ||
uses: actions/upload-artifact@v2.2.4 | ||
with: | ||
# Artifact name | ||
name: GitHub Release | ||
# A file, directory or wildcard pattern that describes what to upload | ||
path: | | ||
${{ env.PUBLISH_GITHUB_PATH }}/* | ||
- name: Upload GameBanana Release Artifact | ||
uses: actions/upload-artifact@v2.2.4 | ||
with: | ||
# Artifact name | ||
name: GameBanana Release | ||
# A file, directory or wildcard pattern that describes what to upload | ||
path: | | ||
${{ env.PUBLISH_GAMEBANANA_PATH }}/* | ||
- name: Upload NuGet Release Artifact | ||
uses: actions/upload-artifact@v2.2.4 | ||
with: | ||
# Artifact name | ||
name: NuGet Release | ||
# A file, directory or wildcard pattern that describes what to upload | ||
path: | | ||
${{ env.PUBLISH_NUGET_PATH }}/* | ||
- name: Upload Changelog Artifact | ||
uses: actions/upload-artifact@v2.2.4 | ||
with: | ||
# Artifact name | ||
name: Changelog | ||
# A file, directory or wildcard pattern that describes what to upload | ||
path: ${{ env.PUBLISH_CHANGELOG_PATH }} | ||
retention-days: 0 | ||
|
||
- name: Upload to GitHub Releases (on Tag) | ||
uses: softprops/action-gh-release@v0.1.14 | ||
if: env.IS_RELEASE == 'true' | ||
with: | ||
# Path to load note-worthy description of changes in release from | ||
body_path: ${{ env.PUBLISH_CHANGELOG_PATH }} | ||
# Newline-delimited list of path globs for asset files to upload | ||
files: | | ||
${{ env.PUBLISH_GITHUB_PATH }}/* | ||
- name: Push to NuGet (on Tag) | ||
env: | ||
NUGET_KEY: ${{ secrets.RELOADED_NUGET_KEY }} | ||
if: env.IS_RELEASE == 'true' | ||
run: | | ||
if ([string]::IsNullOrEmpty("$env:NUGET_KEY")) | ||
{ | ||
Write-Host "NuGet Repository Key (GitHub Secrets -> RELOADED_NUGET_KEY) Not Specified. Skipping." | ||
return | ||
} | ||
$items = Get-ChildItem -Path "$env:PUBLISH_NUGET_PATH/*.nupkg" | ||
Foreach ($item in $items) | ||
{ | ||
Write-Host "Pushing $item" | ||
dotnet nuget push "$item" -k "$env:NUGET_KEY" -s "$env:NUGET_URL" --skip-duplicate | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Set Working Directory | ||
Split-Path $MyInvocation.MyCommand.Path | Push-Location | ||
[Environment]::CurrentDirectory = $PWD | ||
|
||
Remove-Item "$env:RELOADEDIIMODS/Reloaded.Utils.Server/*" -Force -Recurse | ||
dotnet publish "./Reloaded.Utils.Server.csproj" -c Release -o "$env:RELOADEDIIMODS/Reloaded.Utils.Server" /p:OutputPath="./bin/Release" /p:RobustILLink="true" | ||
|
||
# Restore Working Directory | ||
Pop-Location |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
using System.ComponentModel; | ||
using Reloaded.Utils.Server.Configuration.Implementation; | ||
|
||
namespace Reloaded.Utils.Server.Configuration; | ||
|
||
public class Config : Configurable<Config> | ||
{ | ||
/* | ||
User Properties: | ||
- Please put all of your configurable properties here. | ||
By default, configuration saves as "Config.json" in mod user config folder. | ||
Need more config files/classes? See Configuration.cs | ||
Available Attributes: | ||
- Category | ||
- DisplayName | ||
- Description | ||
- DefaultValue | ||
// Technically Supported but not Useful | ||
- Browsable | ||
- Localizable | ||
The `DefaultValue` attribute is used as part of the `Reset` button in Reloaded-Launcher. | ||
*/ | ||
|
||
|
||
const string CategoryCommon = "Common Server Settings"; | ||
|
||
[DefaultValue(false)] | ||
[Category(CategoryCommon)] | ||
[DisplayName("Log Actions")] | ||
[Description("If enabled, actions performed on the server are logged for debugging purposes.\n" + | ||
"Otherwise, only errors are logged.")] | ||
public bool Log { get; set; } = false; | ||
|
||
public LiteNetLibConfig LiteNetLibConfig { get; set; } = new LiteNetLibConfig(); | ||
} |
145 changes: 145 additions & 0 deletions
145
source/Mods/Reloaded.Utils.Server/Configuration/Implementation/Configurable.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
using Reloaded.Mod.Interfaces; | ||
using System; | ||
using System.ComponentModel; | ||
using System.IO; | ||
using System.Text.Json; | ||
using System.Text.Json.Serialization; | ||
|
||
namespace Reloaded.Utils.Server.Configuration.Implementation; | ||
|
||
public class Configurable<TParentType> : IUpdatableConfigurable where TParentType : Configurable<TParentType>, new() | ||
{ | ||
// Default Serialization Options | ||
public static JsonSerializerOptions SerializerOptions { get; } = new JsonSerializerOptions() | ||
{ | ||
Converters = { new JsonStringEnumConverter() }, | ||
WriteIndented = true | ||
}; | ||
|
||
/* Events */ | ||
|
||
/// <summary> | ||
/// Automatically executed when the external configuration file is updated. | ||
/// Passes a new instance of the configuration as parameter. | ||
/// Inside your event handler, replace the variable storing the configuration with the new one. | ||
/// </summary> | ||
[Browsable(false)] | ||
public event Action<IUpdatableConfigurable>? ConfigurationUpdated; | ||
|
||
/* Class Properties */ | ||
|
||
/// <summary> | ||
/// Full path to the configuration file. | ||
/// </summary> | ||
[JsonIgnore] | ||
[Browsable(false)] | ||
public string? FilePath { get; private set; } | ||
|
||
/// <summary> | ||
/// The name of the configuration file. | ||
/// </summary> | ||
[JsonIgnore] | ||
[Browsable(false)] | ||
public string? ConfigName { get; private set; } | ||
|
||
/// <summary> | ||
/// Receives events on whenever the file is actively changed or updated. | ||
/// </summary> | ||
[JsonIgnore] | ||
[Browsable(false)] | ||
private FileSystemWatcher? ConfigWatcher { get; set; } | ||
|
||
/* Construction */ | ||
public Configurable() { } | ||
|
||
private void Initialize(string filePath, string configName) | ||
{ | ||
// Initializes an instance after construction by e.g. a serializer. | ||
FilePath = filePath; | ||
ConfigName = configName; | ||
|
||
MakeConfigWatcher(); | ||
Save = OnSave; | ||
} | ||
|
||
/* Cleanup */ | ||
public void DisposeEvents() | ||
{ | ||
// Halts the FilesystemWatcher and all events associated with this instance. | ||
ConfigWatcher?.Dispose(); | ||
ConfigurationUpdated = null; | ||
} | ||
|
||
/* Load/Save support. */ | ||
|
||
/// <summary> | ||
/// Saves the configuration to the hard disk. | ||
/// </summary> | ||
[JsonIgnore] | ||
[Browsable(false)] | ||
public Action? Save { get; private set; } | ||
|
||
/// <summary> | ||
/// Safety lock for when changed event gets raised twice on file save. | ||
/// </summary> | ||
[Browsable(false)] | ||
private static object _readLock = new object(); | ||
|
||
/// <summary> | ||
/// Loads a specified configuration from the hard disk, or creates a default if it does not exist. | ||
/// </summary> | ||
/// <param name="filePath">The full file path of the config.</param> | ||
/// <param name="configName">The name of the configuration.</param> | ||
public static TParentType FromFile(string filePath, string configName) => ReadFrom(filePath, configName); | ||
|
||
/* Event */ | ||
|
||
/// <summary> | ||
/// Creates a <see cref="FileSystemWatcher"/> that will automatically raise an | ||
/// <see cref="OnConfigurationUpdated"/> event when the config file is changed. | ||
/// </summary> | ||
/// <returns></returns> | ||
private void MakeConfigWatcher() | ||
{ | ||
ConfigWatcher = new FileSystemWatcher(Path.GetDirectoryName(FilePath)!, Path.GetFileName(FilePath)!); | ||
ConfigWatcher.Changed += (sender, e) => OnConfigurationUpdated(); | ||
ConfigWatcher.EnableRaisingEvents = true; | ||
} | ||
|
||
/// <summary> | ||
/// Reloads the configuration from the hard disk and raises the updated event. | ||
/// </summary> | ||
private void OnConfigurationUpdated() | ||
{ | ||
lock (_readLock) | ||
{ | ||
// Load and copy events. | ||
// Note: External program might still be writing to file while this is being executed, so we need to keep retrying. | ||
var newConfig = Utilities.TryGetValue(() => ReadFrom(this.FilePath!, this.ConfigName!), 250, 2); | ||
newConfig.ConfigurationUpdated = ConfigurationUpdated; | ||
|
||
// Disable events for this instance. | ||
DisposeEvents(); | ||
|
||
// Call subscribers through the new config. | ||
newConfig.ConfigurationUpdated?.Invoke(newConfig); | ||
} | ||
} | ||
|
||
private void OnSave() | ||
{ | ||
var parent = (TParentType)this; | ||
File.WriteAllText(FilePath!, JsonSerializer.Serialize(parent, SerializerOptions)); | ||
} | ||
|
||
/* Utility */ | ||
private static TParentType ReadFrom(string filePath, string configName) | ||
{ | ||
var result = (File.Exists(filePath) | ||
? JsonSerializer.Deserialize<TParentType>(File.ReadAllBytes(filePath), SerializerOptions) | ||
: new TParentType()) ?? new TParentType(); | ||
|
||
result.Initialize(filePath, configName); | ||
return result; | ||
} | ||
} |
Oops, something went wrong.