From ccf0062ef22c033eb27607a1ea083cac8a8935a5 Mon Sep 17 00:00:00 2001 From: Evin Jaff Date: Sat, 8 Jun 2024 01:01:42 -0500 Subject: [PATCH 1/8] Docker can build and make HTTP stub --- pkhex/docker_command.ps1 | 3 +++ pkhex/dockerfile | 27 +++++++++++++++++++ .../pkhex-egglocke/HTTPServer.cs | 12 +++++++++ 3 files changed, 42 insertions(+) create mode 100644 pkhex/docker_command.ps1 create mode 100644 pkhex/dockerfile create mode 100644 pkhex/pkhex-egglocke/pkhex-egglocke/HTTPServer.cs diff --git a/pkhex/docker_command.ps1 b/pkhex/docker_command.ps1 new file mode 100644 index 0000000..9200bfa --- /dev/null +++ b/pkhex/docker_command.ps1 @@ -0,0 +1,3 @@ +docker build -t pkhex . + +docker run -d -it -p 8000:8000 pkhex diff --git a/pkhex/dockerfile b/pkhex/dockerfile new file mode 100644 index 0000000..57d059a --- /dev/null +++ b/pkhex/dockerfile @@ -0,0 +1,27 @@ +FROM ubuntu:22.04 AS builder + +# install the .NET 8 SDK +RUN apt-get update && apt-get install -y dotnet-sdk-8.0 ca-certificates + +# add your application code +WORKDIR /source + +# copy pkhex-egglocke folder to the container +COPY pkhex-egglocke . + + +# Install pkhex dependency +RUN dotnet restore pkhex-egglocke + +# Compile the app to test +RUN dotnet build --no-restore pkhex-egglocke + +# Publish +RUN dotnet publish -c release -r linux-x64 --self-contained + + + +ENV PORT 8080 +EXPOSE 8080 + +# ENTRYPOINT ["dotnet", "/app/dotnetcoresample.dll"] \ No newline at end of file diff --git a/pkhex/pkhex-egglocke/pkhex-egglocke/HTTPServer.cs b/pkhex/pkhex-egglocke/pkhex-egglocke/HTTPServer.cs new file mode 100644 index 0000000..173bad7 --- /dev/null +++ b/pkhex/pkhex-egglocke/pkhex-egglocke/HTTPServer.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace pkhex_egglocke +{ + internal class HTTPServer + { + } +} From 90def8b221e24de3e843c223d355d9dc8ebb5518 Mon Sep 17 00:00:00 2001 From: Evin Jaff Date: Sat, 8 Jun 2024 01:54:46 -0500 Subject: [PATCH 2/8] Add Grapevine dependency for REST API --- .../pkhexEgglockeTests.csproj | 1 + .../pkhex-egglocke/pkhex-egglocke/Program.cs | 13 +++++++++++++ .../pkhex-egglocke/SaveWriter.cs | 3 +++ .../pkhex-egglocke/TestRoute.cs | 19 +++++++++++++++++++ .../pkhex-egglocke/pkhexEgglocke.csproj | 3 ++- 5 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 pkhex/pkhex-egglocke/pkhex-egglocke/TestRoute.cs diff --git a/pkhex/pkhex-egglocke-tests/pkhex-egglocke-tests/pkhexEgglockeTests.csproj b/pkhex/pkhex-egglocke-tests/pkhex-egglocke-tests/pkhexEgglockeTests.csproj index 4390fff..71b3f02 100644 --- a/pkhex/pkhex-egglocke-tests/pkhex-egglocke-tests/pkhexEgglockeTests.csproj +++ b/pkhex/pkhex-egglocke-tests/pkhex-egglocke-tests/pkhexEgglockeTests.csproj @@ -12,6 +12,7 @@ + diff --git a/pkhex/pkhex-egglocke/pkhex-egglocke/Program.cs b/pkhex/pkhex-egglocke/pkhex-egglocke/Program.cs index 7d4f7f2..44cfaa4 100644 --- a/pkhex/pkhex-egglocke/pkhex-egglocke/Program.cs +++ b/pkhex/pkhex-egglocke/pkhex-egglocke/Program.cs @@ -1,14 +1,27 @@ // See https://aka.ms/new-console-template for more information +using PKHeX.Core; using pkhexEgglocke; using System.Reflection; +using Grapevine; +using System; + + class Program { public static void Main(string[] args) { + using (var server = RestServerBuilder.UseDefaults().Build()) + { + server.Start(); + + Console.WriteLine("Press enter to stop the server"); + Console.ReadLine(); + } + var BLANK_SOULSILVER_SAVE = @"C:\Users\Evin Jaff\Downloads\johtocomplete.sav"; SaveWriter sw = new SaveWriter(BLANK_SOULSILVER_SAVE); diff --git a/pkhex/pkhex-egglocke/pkhex-egglocke/SaveWriter.cs b/pkhex/pkhex-egglocke/pkhex-egglocke/SaveWriter.cs index 1a313fb..4664707 100644 --- a/pkhex/pkhex-egglocke/pkhex-egglocke/SaveWriter.cs +++ b/pkhex/pkhex-egglocke/pkhex-egglocke/SaveWriter.cs @@ -93,6 +93,9 @@ public void addEgg( EggCreator pokemon, int boxIndex) { mew.OriginalTrainerName = pokemon.OT; mew.OriginalTrainerGender = pokemon.OTGender; + mew.HeldItem = + + mew.Ability = pokemon.Ability; mew.Nature = pokemon.Nature; diff --git a/pkhex/pkhex-egglocke/pkhex-egglocke/TestRoute.cs b/pkhex/pkhex-egglocke/pkhex-egglocke/TestRoute.cs new file mode 100644 index 0000000..5fee417 --- /dev/null +++ b/pkhex/pkhex-egglocke/pkhex-egglocke/TestRoute.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Grapevine; + +namespace pkhex_egglocke +{ + [RestResource] + public class MyResource + { + [RestRoute("Get", "/api/test")] + public async Task Test(IHttpContext context) + { + await context.Response.SendResponseAsync("Successfully hit the test route!"); + } + } +} diff --git a/pkhex/pkhex-egglocke/pkhex-egglocke/pkhexEgglocke.csproj b/pkhex/pkhex-egglocke/pkhex-egglocke/pkhexEgglocke.csproj index d76cacf..dbb7f34 100644 --- a/pkhex/pkhex-egglocke/pkhex-egglocke/pkhexEgglocke.csproj +++ b/pkhex/pkhex-egglocke/pkhex-egglocke/pkhexEgglocke.csproj @@ -9,8 +9,9 @@ + - + From bbab9ebcca1e337b4ab6959dc785f1821fa5bfde Mon Sep 17 00:00:00 2001 From: Evin Jaff Date: Sat, 8 Jun 2024 02:06:42 -0500 Subject: [PATCH 3/8] Add file download endpoint (just pokemon theme for now) --- .../pkhex-egglocke/TestRoute.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/pkhex/pkhex-egglocke/pkhex-egglocke/TestRoute.cs b/pkhex/pkhex-egglocke/pkhex-egglocke/TestRoute.cs index 5fee417..147e87b 100644 --- a/pkhex/pkhex-egglocke/pkhex-egglocke/TestRoute.cs +++ b/pkhex/pkhex-egglocke/pkhex-egglocke/TestRoute.cs @@ -4,6 +4,7 @@ using System.Text; using System.Threading.Tasks; using Grapevine; +using PKHeX.Core; namespace pkhex_egglocke { @@ -15,5 +16,25 @@ public async Task Test(IHttpContext context) { await context.Response.SendResponseAsync("Successfully hit the test route!"); } + + [RestRoute("Get", "/api/startfile")] + public async Task StartFile(IHttpContext context) + { + await context.Response.SendResponseAsync("Successfully hit the startfile route!"); + } + + [RestRoute("Get", "/api/file1")] + public async Task DownloadFile(IHttpContext context) + { + string filePath = "C:\\Users\\Evin Jaff\\Downloads\\Pokemon.mp3"; + + context.Response.ContentType = "audio/mpeg"; + context.Response.AddHeader("Content-Disposition", "attachment; filename=blank.mp3"); + context.Response.ContentLength64 = new FileInfo(filePath).Length; + + await context.Response.SendResponseAsync(File.ReadAllBytes(filePath)); + + } + } } From b36f7d51c3b7990e7691733d8220ef8ef49ebaa1 Mon Sep 17 00:00:00 2001 From: Evin Jaff Date: Sun, 9 Jun 2024 00:18:36 -0500 Subject: [PATCH 4/8] commit github actions example --- .github/workflows/docker-pkhex.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/docker-pkhex.yml diff --git a/.github/workflows/docker-pkhex.yml b/.github/workflows/docker-pkhex.yml new file mode 100644 index 0000000..a84855a --- /dev/null +++ b/.github/workflows/docker-pkhex.yml @@ -0,0 +1,18 @@ +name: Test pkhex Docker Building + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Build the Docker image + run: docker build test --file pkhex/dockerfile --tag my-image-name:$(date +%s) \ No newline at end of file From c7bd8d497d0697c1a88e61bb114d0e86c0797776 Mon Sep 17 00:00:00 2001 From: Evin Jaff Date: Sun, 9 Jun 2024 00:19:59 -0500 Subject: [PATCH 5/8] path fix --- .github/workflows/docker-pkhex.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-pkhex.yml b/.github/workflows/docker-pkhex.yml index a84855a..029d7eb 100644 --- a/.github/workflows/docker-pkhex.yml +++ b/.github/workflows/docker-pkhex.yml @@ -15,4 +15,4 @@ jobs: steps: - uses: actions/checkout@v4 - name: Build the Docker image - run: docker build test --file pkhex/dockerfile --tag my-image-name:$(date +%s) \ No newline at end of file + run: docker build pkhex/ --file dockerfile --tag my-image-name:$(date +%s) \ No newline at end of file From 66d008b94cdefb3350cea1700548efeebba1035a Mon Sep 17 00:00:00 2001 From: Evin Jaff Date: Sun, 9 Jun 2024 00:27:27 -0500 Subject: [PATCH 6/8] set workdir --- .github/workflows/docker-pkhex.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker-pkhex.yml b/.github/workflows/docker-pkhex.yml index 029d7eb..baeb336 100644 --- a/.github/workflows/docker-pkhex.yml +++ b/.github/workflows/docker-pkhex.yml @@ -15,4 +15,5 @@ jobs: steps: - uses: actions/checkout@v4 - name: Build the Docker image - run: docker build pkhex/ --file dockerfile --tag my-image-name:$(date +%s) \ No newline at end of file + run: docker build . --file dockerfile --tag my-image-name:$(date +%s) + working-directory: ./app \ No newline at end of file From 48a950be3eb12efa751a079872ff8c56fc774873 Mon Sep 17 00:00:00 2001 From: Evin Jaff Date: Sun, 9 Jun 2024 00:28:52 -0500 Subject: [PATCH 7/8] add new path --- .github/workflows/docker-pkhex.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-pkhex.yml b/.github/workflows/docker-pkhex.yml index baeb336..ca2783a 100644 --- a/.github/workflows/docker-pkhex.yml +++ b/.github/workflows/docker-pkhex.yml @@ -16,4 +16,4 @@ jobs: - uses: actions/checkout@v4 - name: Build the Docker image run: docker build . --file dockerfile --tag my-image-name:$(date +%s) - working-directory: ./app \ No newline at end of file + working-directory: ./pkhex \ No newline at end of file From 7c546cf63d41120170b48833fd3a4c9d345f2538 Mon Sep 17 00:00:00 2001 From: Evin Jaff Date: Sun, 9 Jun 2024 02:16:34 -0500 Subject: [PATCH 8/8] Download endpoint works!! --- pkhex/dockerfile | 8 +-- .../pkhex-egglocke/EggCreator.cs | 5 ++ .../pkhex-egglocke/HTTPModels.cs | 15 ++++ .../pkhex-egglocke/HTTPRoutes.cs | 69 +++++++++++++++++++ .../pkhex-egglocke/JSONDecoder.cs | 15 ---- .../pkhex-egglocke/JSONDeserializer.cs | 30 ++++++++ .../pkhex-egglocke/pkhex-egglocke/Program.cs | 19 +++-- .../pkhex-egglocke/SaveWriter.cs | 4 ++ .../pkhex-egglocke/TestRoute.cs | 40 ----------- 9 files changed, 141 insertions(+), 64 deletions(-) create mode 100644 pkhex/pkhex-egglocke/pkhex-egglocke/HTTPModels.cs create mode 100644 pkhex/pkhex-egglocke/pkhex-egglocke/HTTPRoutes.cs delete mode 100644 pkhex/pkhex-egglocke/pkhex-egglocke/JSONDecoder.cs create mode 100644 pkhex/pkhex-egglocke/pkhex-egglocke/JSONDeserializer.cs delete mode 100644 pkhex/pkhex-egglocke/pkhex-egglocke/TestRoute.cs diff --git a/pkhex/dockerfile b/pkhex/dockerfile index 57d059a..13bc053 100644 --- a/pkhex/dockerfile +++ b/pkhex/dockerfile @@ -20,8 +20,8 @@ RUN dotnet build --no-restore pkhex-egglocke RUN dotnet publish -c release -r linux-x64 --self-contained +ENV PORT 1234 +EXPOSE 1234 -ENV PORT 8080 -EXPOSE 8080 - -# ENTRYPOINT ["dotnet", "/app/dotnetcoresample.dll"] \ No newline at end of file +WORKDIR /source/pkhex-egglocke +ENTRYPOINT ["dotnet", "run"] \ No newline at end of file diff --git a/pkhex/pkhex-egglocke/pkhex-egglocke/EggCreator.cs b/pkhex/pkhex-egglocke/pkhex-egglocke/EggCreator.cs index 2f4b2eb..862b450 100644 --- a/pkhex/pkhex-egglocke/pkhex-egglocke/EggCreator.cs +++ b/pkhex/pkhex-egglocke/pkhex-egglocke/EggCreator.cs @@ -80,6 +80,11 @@ public EggCreator(byte ball, ushort dexNumber, int language, int ability, Nature public static EggCreator decodeJSON(string filepath, bool is_filepath) { + /// + /// decodeJSON: Decodes a JSON object into a PokemonCreator object + /// + /// + string json; if (is_filepath) { diff --git a/pkhex/pkhex-egglocke/pkhex-egglocke/HTTPModels.cs b/pkhex/pkhex-egglocke/pkhex-egglocke/HTTPModels.cs new file mode 100644 index 0000000..7ae0686 --- /dev/null +++ b/pkhex/pkhex-egglocke/pkhex-egglocke/HTTPModels.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace pkhex_egglocke +{ + public class SaveFileGeneratorModel + { + public int generation { get; set; } = 4; + public string jsonRaw { get; set; } = ""; + public dynamic[] eggs { get; set; } =Array.Empty(); + } +} diff --git a/pkhex/pkhex-egglocke/pkhex-egglocke/HTTPRoutes.cs b/pkhex/pkhex-egglocke/pkhex-egglocke/HTTPRoutes.cs new file mode 100644 index 0000000..da278ec --- /dev/null +++ b/pkhex/pkhex-egglocke/pkhex-egglocke/HTTPRoutes.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Grapevine; +using Newtonsoft.Json; +using PKHeX.Core; +using pkhexEgglocke; + +namespace pkhex_egglocke +{ + [RestResource] + public class MyResource: Resource + { + [RestRoute("Get", "/api/test")] + public async Task Test(IHttpContext context) + { + await context.Response.SendResponseAsync("Successfully hit the test route!"); + } + + [RestRoute("Get", "/api/startfile")] + public async Task StartFile(IHttpContext context) + { + await context.Response.SendResponseAsync("Successfully hit the startfile route!"); + } + + [RestRoute("Get", "/api/file1")] + public async Task DownloadFile(IHttpContext context) + { + string filePath = "C:\\Users\\Evin Jaff\\Downloads\\Pokemon.mp3"; + + context.Response.ContentType = "audio/mpeg"; + context.Response.AddHeader("Content-Disposition", "attachment; filename=blank.mp3"); + context.Response.ContentLength64 = new FileInfo(filePath).Length; + + await context.Response.SendResponseAsync(File.ReadAllBytes(filePath)); + + } + + [RestRoute("Post", "/api/buildSaveFile")] + public async Task BuildSaveFile(IHttpContext context) + { + // Decode the input stream + var model = await DeserializeAsync(context.Request.InputStream, context.CancellationToken); + + // yields array of dynamic objects + SaveWriter sw = new SaveWriter("C:\\Users\\Evin Jaff\\Downloads\\Blank_SoulSilver.sav"); + + EggCreator[] eggArray = new EggCreator[model.eggs.Length]; + for (int i = 0; i < model.eggs.Length; i++) { + EggCreator constructed_egg_creator = EggCreator.decodeJSON(model.eggs[i].ToString(), false); + sw.addEgg(constructed_egg_creator, i+1); + } + + byte[] saveFile = sw.exportRawBytes(); + + // Prepare the response as a downloadable file + context.Response.ContentType = "application/octet-stream"; + context.Response.AddHeader("Content-Disposition", "attachment; filename=blank.sav"); + context.Response.ContentLength64 = saveFile.Length; + + await context.Response.SendResponseAsync(saveFile); + + } + + + } +} diff --git a/pkhex/pkhex-egglocke/pkhex-egglocke/JSONDecoder.cs b/pkhex/pkhex-egglocke/pkhex-egglocke/JSONDecoder.cs deleted file mode 100644 index 0e8230e..0000000 --- a/pkhex/pkhex-egglocke/pkhex-egglocke/JSONDecoder.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace pkhex_egglocke -{ - internal class JSONDecoder - { - - // Very annoying code that decodes strings to class-defined integers - - } -} diff --git a/pkhex/pkhex-egglocke/pkhex-egglocke/JSONDeserializer.cs b/pkhex/pkhex-egglocke/pkhex-egglocke/JSONDeserializer.cs new file mode 100644 index 0000000..66eebbf --- /dev/null +++ b/pkhex/pkhex-egglocke/pkhex-egglocke/JSONDeserializer.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; + + +namespace pkhex_egglocke +{ + public abstract class Resource + { + public static JsonSerializerOptions SerializerOptions = new JsonSerializerOptions() + { + PropertyNameCaseInsensitive = true + }; + + public async Task DeserializeAsync(Stream stream) + { + return await DeserializeAsync(stream, CancellationToken.None); + } + + public async Task DeserializeAsync(Stream stream, CancellationToken token) + { + return await JsonSerializer.DeserializeAsync(stream, SerializerOptions, token); + } + + } + +} diff --git a/pkhex/pkhex-egglocke/pkhex-egglocke/Program.cs b/pkhex/pkhex-egglocke/pkhex-egglocke/Program.cs index 44cfaa4..70d2115 100644 --- a/pkhex/pkhex-egglocke/pkhex-egglocke/Program.cs +++ b/pkhex/pkhex-egglocke/pkhex-egglocke/Program.cs @@ -14,17 +14,26 @@ class Program { public static void Main(string[] args) { + RestServerBuilder restServerBuilder = RestServerBuilder.UseDefaults(); + + + + // Spin up the REST server using (var server = RestServerBuilder.UseDefaults().Build()) { server.Start(); Console.WriteLine("Press enter to stop the server"); Console.ReadLine(); + + // block the main thread forever + while (true) { } + } var BLANK_SOULSILVER_SAVE = @"C:\Users\Evin Jaff\Downloads\johtocomplete.sav"; - SaveWriter sw = new SaveWriter(BLANK_SOULSILVER_SAVE); + // SaveWriter sw = new SaveWriter(BLANK_SOULSILVER_SAVE); //EggCreator pc = new EggCreator(); @@ -37,13 +46,13 @@ public static void Main(string[] args) var BLANK_GEN4_MAREEP_VALID = Path.Combine("C:\\Users\\Evin Jaff\\Documents\\egglocke-maker\\pkhex\\pkhex-egglocke-tests\\pkhex-egglocke-tests\\testSources", "Mareep.json"); var BLANK_GEN4_LEGENDARY_TRIO = Path.Combine("C:\\Users\\Evin Jaff\\Documents\\egglocke-maker\\pkhex\\pkhex-egglocke-tests\\pkhex-egglocke-tests\\testSources", "LegendaryTrio.json"); - EggCreator ec = EggCreator.decodeJSON(BLANK_GEN4_MAREEP_VALID, true); + // EggCreator ec = EggCreator.decodeJSON(BLANK_GEN4_MAREEP_VALID, true); - sw.massAddEggs(BLANK_GEN4_LEGENDARY_TRIO); + // sw.massAddEggs(BLANK_GEN4_LEGENDARY_TRIO); - sw.export("testPROG.sav"); + // sw.export("testPROG.sav"); - Console.WriteLine("Dumped testPROG"); + // Console.WriteLine("Dumped testPROG"); } diff --git a/pkhex/pkhex-egglocke/pkhex-egglocke/SaveWriter.cs b/pkhex/pkhex-egglocke/pkhex-egglocke/SaveWriter.cs index 4664707..41bfc5e 100644 --- a/pkhex/pkhex-egglocke/pkhex-egglocke/SaveWriter.cs +++ b/pkhex/pkhex-egglocke/pkhex-egglocke/SaveWriter.cs @@ -146,6 +146,10 @@ public void export(string location) { } + public byte[] exportRawBytes() { + return this.currentSave.Write(); + } + // Getters and Setters diff --git a/pkhex/pkhex-egglocke/pkhex-egglocke/TestRoute.cs b/pkhex/pkhex-egglocke/pkhex-egglocke/TestRoute.cs deleted file mode 100644 index 147e87b..0000000 --- a/pkhex/pkhex-egglocke/pkhex-egglocke/TestRoute.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Grapevine; -using PKHeX.Core; - -namespace pkhex_egglocke -{ - [RestResource] - public class MyResource - { - [RestRoute("Get", "/api/test")] - public async Task Test(IHttpContext context) - { - await context.Response.SendResponseAsync("Successfully hit the test route!"); - } - - [RestRoute("Get", "/api/startfile")] - public async Task StartFile(IHttpContext context) - { - await context.Response.SendResponseAsync("Successfully hit the startfile route!"); - } - - [RestRoute("Get", "/api/file1")] - public async Task DownloadFile(IHttpContext context) - { - string filePath = "C:\\Users\\Evin Jaff\\Downloads\\Pokemon.mp3"; - - context.Response.ContentType = "audio/mpeg"; - context.Response.AddHeader("Content-Disposition", "attachment; filename=blank.mp3"); - context.Response.ContentLength64 = new FileInfo(filePath).Length; - - await context.Response.SendResponseAsync(File.ReadAllBytes(filePath)); - - } - - } -}