commit 68ae9540ad2cd6ca7102c3c6e45d8ca633b39685 Author: Timerix Date: Thu Mar 20 11:54:08 2025 +0500 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c25fee1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +# Build results +[Bb]in/ +.bin/ +[Dd]ebug/ +[Rr]elease/ +[Rr]eleases/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ +[Pp]ublish/ + +# IDE files +.vs/ +.vscode/ +.vshistory/ +.idea/ +с/ +.editorconfig +*.user + +#backups +.old*/ \ No newline at end of file diff --git a/ParadoxSaveParser.Lib/ParadoxSaveParser.Lib.csproj b/ParadoxSaveParser.Lib/ParadoxSaveParser.Lib.csproj new file mode 100644 index 0000000..9c490a9 --- /dev/null +++ b/ParadoxSaveParser.Lib/ParadoxSaveParser.Lib.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + + diff --git a/ParadoxSaveParser.Lib/Parser.cs b/ParadoxSaveParser.Lib/Parser.cs new file mode 100644 index 0000000..e3f223e --- /dev/null +++ b/ParadoxSaveParser.Lib/Parser.cs @@ -0,0 +1,27 @@ +namespace ParadoxSaveParser.Lib; + +public abstract class Parser +{ + protected Stream _saveFile; + + protected Parser(Stream savefile) + { + _saveFile = savefile; + } + + protected enum TokenType + { + Invalid, String, Equals, BracketOpen, BracketClose, + } + + protected struct Token + { + public TokenType type; + public string? value; + } + + protected void BuildAST() + { + + } +} \ No newline at end of file diff --git a/ParadoxSaveParser.Lib/ParserEU4.cs b/ParadoxSaveParser.Lib/ParserEU4.cs new file mode 100644 index 0000000..3542f96 --- /dev/null +++ b/ParadoxSaveParser.Lib/ParserEU4.cs @@ -0,0 +1,8 @@ +namespace ParadoxSaveParser.Lib; + +public class ParserEU4 : Parser +{ + public ParserEU4(Stream savefile) : base(savefile) + { + } +} \ No newline at end of file diff --git a/ParadoxSaveParser.WebAPI/ParadoxSaveParser.WebAPI.csproj b/ParadoxSaveParser.WebAPI/ParadoxSaveParser.WebAPI.csproj new file mode 100644 index 0000000..3249510 --- /dev/null +++ b/ParadoxSaveParser.WebAPI/ParadoxSaveParser.WebAPI.csproj @@ -0,0 +1,14 @@ + + + + net8.0 + enable + disable + true + + + + + + + diff --git a/ParadoxSaveParser.WebAPI/ParadoxSaveParser.WebAPI.http b/ParadoxSaveParser.WebAPI/ParadoxSaveParser.WebAPI.http new file mode 100644 index 0000000..41a6bb5 --- /dev/null +++ b/ParadoxSaveParser.WebAPI/ParadoxSaveParser.WebAPI.http @@ -0,0 +1,6 @@ +@ParadoxSaveParser.WebAPI_HostAddress = http://localhost:5226 + +GET {{ParadoxSaveParser.WebAPI_HostAddress}}/weatherforecast/ +Accept: application/json + +### diff --git a/ParadoxSaveParser.WebAPI/Program.cs b/ParadoxSaveParser.WebAPI/Program.cs new file mode 100644 index 0000000..950426c --- /dev/null +++ b/ParadoxSaveParser.WebAPI/Program.cs @@ -0,0 +1,76 @@ +global using System; +using System.Collections.Concurrent; +using System.IO; +using System.Linq; +using System.Net; +using System.Text.Json; +using System.Text.Json.Serialization; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using ParadoxSaveParser.Lib; + +namespace ParadoxSaveParser.WebAPI; + +public enum SaveFileProcessingStatus +{ + NotFound, Uploading, Parsing, SavingResults, Done, Error +} + +public class SaveFileMetadata +{ + public required string guid; + public required SaveFileProcessingStatus status { get; set; } +} + +public class Program +{ + private const string DATA_DIR = "data"; + private static string SAVES_DIR = Path.Join(DATA_DIR, "saves"); + private static ConcurrentDictionary _saveMetadataStorage = new(); + + public static void Main(string[] args) + { + var builder = WebApplication.CreateBuilder(args); + var app = builder.Build(); + + foreach (var metaFilePath in Directory.GetFiles(SAVES_DIR, "*.meta.json", SearchOption.TopDirectoryOnly)) + { + using var metaFile = File.Open(metaFilePath, FileMode.Open, FileAccess.Read); + var meta = JsonSerializer.Deserialize(metaFile) ?? throw new NullReferenceException(metaFilePath); + if (meta.status != SaveFileProcessingStatus.Done) + { + app.Logger.Log(LogLevel.Warning, $"metadata file '{metaFilePath}' status has invalid status {meta.status}")); + } + + if(!_saveMetadataStorage.TryAdd(meta.guid, meta)) + throw new Exception("Guid collision!"); + } + + app.UseHttpsRedirection(); + app.MapPost("/parse/eu4", async httpContext => + { + var remoteFile = httpContext.Request.Form.Files.FirstOrDefault(); + if(remoteFile is null) + return; + string save_id = Guid.NewGuid().ToString(); + string meta_file_path = Path.Join(SAVES_DIR, save_id + ".meta.json"); + // string save_file_path = Path.Join(SAVES_DIR, save_id + ".eu4"); + // await using var metaFile = File.Open(meta_file_path, FileMode.CreateNew, FileAccess.Write); + if (File.Exists(meta_file_path)) + { + httpContext.Response.StatusCode = StatusCodes.Status500InternalServerError; + throw new Exception($"Guid collision! file {meta_file_path} already exists.") + } + + await using var saveFile = + await remoteFile.OpenReadStream().CopyToAsync(); + var parser = new ParserEU4(stream); + + + }); + + app.Run(); + } +} \ No newline at end of file diff --git a/ParadoxSaveParser.WebAPI/Properties/launchSettings.json b/ParadoxSaveParser.WebAPI/Properties/launchSettings.json new file mode 100644 index 0000000..44a68c4 --- /dev/null +++ b/ParadoxSaveParser.WebAPI/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:38396", + "sslPort": 44312 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "/", + "applicationUrl": "http://localhost:5226", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "/", + "applicationUrl": "https://localhost:7032;http://localhost:5226", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "/", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/ParadoxSaveParser.WebAPI/appsettings.Development.json b/ParadoxSaveParser.WebAPI/appsettings.Development.json new file mode 100644 index 0000000..ff66ba6 --- /dev/null +++ b/ParadoxSaveParser.WebAPI/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/ParadoxSaveParser.WebAPI/appsettings.json b/ParadoxSaveParser.WebAPI/appsettings.json new file mode 100644 index 0000000..4d56694 --- /dev/null +++ b/ParadoxSaveParser.WebAPI/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/ParadoxSaveParser.sln b/ParadoxSaveParser.sln new file mode 100644 index 0000000..8f93e34 --- /dev/null +++ b/ParadoxSaveParser.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParadoxSaveParser.WebAPI", "ParadoxSaveParser.WebAPI\ParadoxSaveParser.WebAPI.csproj", "{7D377558-CE40-4D7E-B0B1-FB33C475AE6A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParadoxSaveParser.Lib", "ParadoxSaveParser.Lib\ParadoxSaveParser.Lib.csproj", "{53ED0135-9513-4DE2-9187-CF2899F179B3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7D377558-CE40-4D7E-B0B1-FB33C475AE6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7D377558-CE40-4D7E-B0B1-FB33C475AE6A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7D377558-CE40-4D7E-B0B1-FB33C475AE6A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7D377558-CE40-4D7E-B0B1-FB33C475AE6A}.Release|Any CPU.Build.0 = Release|Any CPU + {53ED0135-9513-4DE2-9187-CF2899F179B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {53ED0135-9513-4DE2-9187-CF2899F179B3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {53ED0135-9513-4DE2-9187-CF2899F179B3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {53ED0135-9513-4DE2-9187-CF2899F179B3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal