mirror of
https://github.com/Manu098vm/Switch-Gift-Data-Manager.git
synced 2026-03-22 09:54:18 -05:00
Compare commits
No commits in common. "main" and "1.3.1" have entirely different histories.
72
.github/workflows/Linux.yml
vendored
72
.github/workflows/Linux.yml
vendored
|
|
@ -1,3 +1,41 @@
|
|||
# This workflow uses actions that are not certified by GitHub.
|
||||
# They are provided by a third-party and are governed by
|
||||
# separate terms of service, privacy policy, and support
|
||||
# documentation.
|
||||
|
||||
# This workflow will build, test, sign and package a WPF or Windows Forms desktop application
|
||||
# built on .NET Core.
|
||||
# To learn how to migrate your existing application to .NET Core,
|
||||
# refer to https://docs.microsoft.com/en-us/dotnet/desktop-wpf/migration/convert-project-from-net-framework
|
||||
#
|
||||
# To configure this workflow:
|
||||
#
|
||||
# 1. Configure environment variables
|
||||
# GitHub sets default environment variables for every workflow run.
|
||||
# Replace the variables relative to your project in the "env" section below.
|
||||
#
|
||||
# 2. Signing
|
||||
# Generate a signing certificate in the Windows Application
|
||||
# Packaging Project or add an existing signing certificate to the project.
|
||||
# Next, use PowerShell to encode the .pfx file using Base64 encoding
|
||||
# by running the following Powershell script to generate the output string:
|
||||
#
|
||||
# $pfx_cert = Get-Content '.\SigningCertificate.pfx' -Encoding Byte
|
||||
# [System.Convert]::ToBase64String($pfx_cert) | Out-File 'SigningCertificate_Encoded.txt'
|
||||
#
|
||||
# Open the output file, SigningCertificate_Encoded.txt, and copy the
|
||||
# string inside. Then, add the string to the repo as a GitHub secret
|
||||
# and name it "Base64_Encoded_Pfx."
|
||||
# For more information on how to configure your signing certificate for
|
||||
# this workflow, refer to https://github.com/microsoft/github-actions-for-desktop-apps#signing
|
||||
#
|
||||
# Finally, add the signing certificate password to the repo as a secret and name it "Pfx_Key".
|
||||
# See "Build the Windows Application Packaging project" below to see how the secret is used.
|
||||
#
|
||||
# For more information on GitHub Actions, refer to https://github.com/features/actions
|
||||
# For a complete CI/CD sample to get started with GitHub Action workflows for Desktop Applications,
|
||||
# refer to https://github.com/microsoft/github-actions-for-desktop-apps
|
||||
|
||||
name: Linux
|
||||
|
||||
on:
|
||||
|
|
@ -14,33 +52,35 @@ jobs:
|
|||
matrix:
|
||||
configuration: [Release]
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-latest # For a list of available runner types, refer to
|
||||
# https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on
|
||||
|
||||
env:
|
||||
Solution_Name: SwitchGiftDataManager.sln
|
||||
Project_Path: SwitchGiftDataManager.CommandLine/SwitchGiftDataManager.CommandLine.csproj
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
# Install the .NET Core workload
|
||||
- name: Install .NET Core
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: 9.0.x
|
||||
|
||||
- name: Clean previous build artifacts
|
||||
run: dotnet clean ${{ env.Project_Path }} --configuration ${{ matrix.configuration }}
|
||||
|
||||
- name: Install dependencies and build
|
||||
run: |
|
||||
dotnet restore ${{ env.Project_Path }}
|
||||
dotnet build ${{ env.Project_Path }} --configuration ${{ matrix.configuration }} --no-restore
|
||||
dotnet-version: 7.0.x
|
||||
|
||||
# Create the app package by building and packaging
|
||||
- name: Install dependencies
|
||||
run: dotnet restore
|
||||
- name: Build
|
||||
run: dotnet build SwitchGiftDataManager.CommandLine/SwitchGiftDataManager.CommandLine.csproj --configuration Release --no-restore
|
||||
- name: Test
|
||||
run: dotnet test SwitchGiftDataManager.CommandLine/SwitchGiftDataManager.CommandLine.csproj --no-restore --verbosity normal
|
||||
|
||||
# Upload the artifact: https://github.com/marketplace/actions/upload-a-build-artifact
|
||||
- name: Upload Linux CommandLine build artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Linux.CommandLine.App
|
||||
path: SwitchGiftDataManager.CommandLine/bin
|
||||
path: SwitchGiftDataManager.CommandLine/bin
|
||||
|
|
|
|||
75
.github/workflows/Mac.yml
vendored
75
.github/workflows/Mac.yml
vendored
|
|
@ -1,3 +1,41 @@
|
|||
# This workflow uses actions that are not certified by GitHub.
|
||||
# They are provided by a third-party and are governed by
|
||||
# separate terms of service, privacy policy, and support
|
||||
# documentation.
|
||||
|
||||
# This workflow will build, test, sign and package a WPF or Windows Forms desktop application
|
||||
# built on .NET Core.
|
||||
# To learn how to migrate your existing application to .NET Core,
|
||||
# refer to https://docs.microsoft.com/en-us/dotnet/desktop-wpf/migration/convert-project-from-net-framework
|
||||
#
|
||||
# To configure this workflow:
|
||||
#
|
||||
# 1. Configure environment variables
|
||||
# GitHub sets default environment variables for every workflow run.
|
||||
# Replace the variables relative to your project in the "env" section below.
|
||||
#
|
||||
# 2. Signing
|
||||
# Generate a signing certificate in the Windows Application
|
||||
# Packaging Project or add an existing signing certificate to the project.
|
||||
# Next, use PowerShell to encode the .pfx file using Base64 encoding
|
||||
# by running the following Powershell script to generate the output string:
|
||||
#
|
||||
# $pfx_cert = Get-Content '.\SigningCertificate.pfx' -Encoding Byte
|
||||
# [System.Convert]::ToBase64String($pfx_cert) | Out-File 'SigningCertificate_Encoded.txt'
|
||||
#
|
||||
# Open the output file, SigningCertificate_Encoded.txt, and copy the
|
||||
# string inside. Then, add the string to the repo as a GitHub secret
|
||||
# and name it "Base64_Encoded_Pfx."
|
||||
# For more information on how to configure your signing certificate for
|
||||
# this workflow, refer to https://github.com/microsoft/github-actions-for-desktop-apps#signing
|
||||
#
|
||||
# Finally, add the signing certificate password to the repo as a secret and name it "Pfx_Key".
|
||||
# See "Build the Windows Application Packaging project" below to see how the secret is used.
|
||||
#
|
||||
# For more information on GitHub Actions, refer to https://github.com/features/actions
|
||||
# For a complete CI/CD sample to get started with GitHub Action workflows for Desktop Applications,
|
||||
# refer to https://github.com/microsoft/github-actions-for-desktop-apps
|
||||
|
||||
name: MacOS
|
||||
|
||||
on:
|
||||
|
|
@ -14,42 +52,35 @@ jobs:
|
|||
matrix:
|
||||
configuration: [Release]
|
||||
|
||||
runs-on: macos-latest
|
||||
runs-on: macos-latest # For a list of available runner types, refer to
|
||||
# https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on
|
||||
|
||||
env:
|
||||
Solution_Name: SwitchGiftDataManager.sln
|
||||
Project_Path: SwitchGiftDataManager.CommandLine/SwitchGiftDataManager.CommandLine.csproj
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
# Install the .NET Core workload
|
||||
- name: Install .NET Core
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: 9.0.x
|
||||
|
||||
- name: Cache NuGet packages
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-nuget-
|
||||
|
||||
dotnet-version: 7.0.x
|
||||
|
||||
# Create the app package by building and packaging
|
||||
- name: Install dependencies
|
||||
run: dotnet restore ${{ env.Project_Path }}
|
||||
|
||||
run: dotnet restore
|
||||
- name: Build
|
||||
run: dotnet build ${{ env.Project_Path }} --configuration ${{ matrix.configuration }} --no-restore
|
||||
|
||||
run: dotnet build SwitchGiftDataManager.CommandLine/SwitchGiftDataManager.CommandLine.csproj --configuration Release --no-restore
|
||||
- name: Test
|
||||
run: dotnet test ${{ env.Project_Path }} --no-restore --verbosity normal
|
||||
run: dotnet test SwitchGiftDataManager.CommandLine/SwitchGiftDataManager.CommandLine.csproj --no-restore --verbosity normal
|
||||
|
||||
# Upload the artifact: https://github.com/marketplace/actions/upload-a-build-artifact
|
||||
- name: Upload MacOS CommandLine build artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: MacOS.CommandLine.App
|
||||
path: SwitchGiftDataManager.CommandLine/bin
|
||||
path: SwitchGiftDataManager.CommandLine/bin
|
||||
|
|
|
|||
76
.github/workflows/Windows.yml
vendored
76
.github/workflows/Windows.yml
vendored
|
|
@ -1,3 +1,41 @@
|
|||
# This workflow uses actions that are not certified by GitHub.
|
||||
# They are provided by a third-party and are governed by
|
||||
# separate terms of service, privacy policy, and support
|
||||
# documentation.
|
||||
|
||||
# This workflow will build, test, sign and package a WPF or Windows Forms desktop application
|
||||
# built on .NET Core.
|
||||
# To learn how to migrate your existing application to .NET Core,
|
||||
# refer to https://docs.microsoft.com/en-us/dotnet/desktop-wpf/migration/convert-project-from-net-framework
|
||||
#
|
||||
# To configure this workflow:
|
||||
#
|
||||
# 1. Configure environment variables
|
||||
# GitHub sets default environment variables for every workflow run.
|
||||
# Replace the variables relative to your project in the "env" section below.
|
||||
#
|
||||
# 2. Signing
|
||||
# Generate a signing certificate in the Windows Application
|
||||
# Packaging Project or add an existing signing certificate to the project.
|
||||
# Next, use PowerShell to encode the .pfx file using Base64 encoding
|
||||
# by running the following Powershell script to generate the output string:
|
||||
#
|
||||
# $pfx_cert = Get-Content '.\SigningCertificate.pfx' -Encoding Byte
|
||||
# [System.Convert]::ToBase64String($pfx_cert) | Out-File 'SigningCertificate_Encoded.txt'
|
||||
#
|
||||
# Open the output file, SigningCertificate_Encoded.txt, and copy the
|
||||
# string inside. Then, add the string to the repo as a GitHub secret
|
||||
# and name it "Base64_Encoded_Pfx."
|
||||
# For more information on how to configure your signing certificate for
|
||||
# this workflow, refer to https://github.com/microsoft/github-actions-for-desktop-apps#signing
|
||||
#
|
||||
# Finally, add the signing certificate password to the repo as a secret and name it "Pfx_Key".
|
||||
# See "Build the Windows Application Packaging project" below to see how the secret is used.
|
||||
#
|
||||
# For more information on GitHub Actions, refer to https://github.com/features/actions
|
||||
# For a complete CI/CD sample to get started with GitHub Action workflows for Desktop Applications,
|
||||
# refer to https://github.com/microsoft/github-actions-for-desktop-apps
|
||||
|
||||
name: Windows
|
||||
|
||||
on:
|
||||
|
|
@ -14,42 +52,52 @@ jobs:
|
|||
matrix:
|
||||
configuration: [Release]
|
||||
|
||||
runs-on: windows-latest
|
||||
runs-on: windows-latest # For a list of available runner types, refer to
|
||||
# https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on
|
||||
|
||||
env:
|
||||
Solution_Name: SwitchGiftDataManager.sln
|
||||
Configuration: ${{ matrix.configuration }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
# Install the .NET Core workload
|
||||
- name: Install .NET Core
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: 9.0.x
|
||||
dotnet-version: 7.0.x
|
||||
|
||||
# Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
uses: microsoft/setup-msbuild@v1.1
|
||||
|
||||
# Execute all unit tests in the solution
|
||||
- name: Execute unit tests
|
||||
run: dotnet test
|
||||
|
||||
- name: Restore and build the application
|
||||
run: |
|
||||
msbuild $env:Solution_Name /t:Restore /p:Configuration=$env:Configuration
|
||||
msbuild $env:Solution_Name /property:Configuration=$env:Configuration
|
||||
# Restore the application to populate the obj folder with RuntimeIdentifiers
|
||||
- name: Restore the application
|
||||
run: msbuild $env:Solution_Name /t:Restore /p:Configuration=$env:Configuration
|
||||
env:
|
||||
Configuration: ${{ matrix.configuration }}
|
||||
|
||||
# Create the app package by building and packaging the Windows Application Packaging project
|
||||
- name: Create the app package
|
||||
run: msbuild $env:Solution_Name /property:Configuration=Release
|
||||
|
||||
# Upload the artifact: https://github.com/marketplace/actions/upload-a-build-artifact
|
||||
- name: Upload WinForms build artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: WindowsForm.GUI.App
|
||||
path: SwitchGiftDataManager.WinForm/bin
|
||||
|
||||
# Upload the artifact: https://github.com/marketplace/actions/upload-a-build-artifact
|
||||
- name: Upload Windows CommandLine build artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Windows.CommandLine.App
|
||||
path: SwitchGiftDataManager.CommandLine/bin
|
||||
path: SwitchGiftDataManager.CommandLine/bin
|
||||
|
|
|
|||
7
.gitignore
vendored
7
.gitignore
vendored
|
|
@ -2,9 +2,4 @@
|
|||
.vs
|
||||
.vscode
|
||||
**/bin
|
||||
**/obj
|
||||
**/PublishProfiles
|
||||
**.user
|
||||
**.config
|
||||
**.pubxml
|
||||
**.pubxml.user
|
||||
**/obj
|
||||
79
README.md
79
README.md
|
|
@ -1,76 +1,71 @@
|
|||
# Switch Gift Data Manager
|
||||

|
||||

|
||||
|
||||
## About
|
||||
This tool aims to bring back past Mystery Gift event content in all Pokémon games for Nintendo Switch.
|
||||
Since these games don't allow event injection in the save file, this tool creates a forged BCAT package, which can be injected using homebrew tools like [JKSV](https://github.com/J-D-K/JKSV/releases).
|
||||
This allows wondercards to be redeemed through the in-game Mystery Gift menu. The use of this tool does not involve hacking the game ROM or modifying the game save file.
|
||||
This tool aims to make past Mystery Gift event contents back again in all the Pokémon games for Nintendo Switch.
|
||||
Since those games won't allow event injection in the SAV file, this tool creates a forged BCAT package, injectable with homebrews like [JKSV](https://github.com/J-D-K/JKSV/releases).
|
||||
This allows wondercards to be redeemed through the In-Game Mystery Gift Menu. The use of this tool does not involve hacking the game ROM nor hacking the game SAV.
|
||||
|
||||
### Compatible files
|
||||
* Let's Go Pikachu and Let's Go Eevee wondercard full files (.wb7full)
|
||||
* Sword and Shield wondercard files (.wc8)
|
||||
* Brilliant Diamond and Shining Pearl wondercard files (.wb8)
|
||||
* Legends Arceus wondercard files (.wa8)
|
||||
* Scarlet & Violet wondercard files (.wc9)
|
||||
* Legends Z-A wondercard files (.wa9)
|
||||
* BCAT wondercard files, containing either multiple or single wondercards (no file format extension)
|
||||
* Scarlet & Violet wondercard files (.wc9)
|
||||
* BCAT wondercard files, either with mutiple or single wondercards (no file format extension)
|
||||
|
||||
### Compatible games
|
||||
* Pokémon Let's Go Pikachu and Eevee
|
||||
* Pokémon Sword and Shield
|
||||
* Pokémon Brilliant Diamond and Shining Pearl
|
||||
* Pokémon Legends Arceus
|
||||
* Pokémon Scarlet and Violet
|
||||
* Pokémon Legends Z-A
|
||||
* Pokémon Scarlet and Violet
|
||||
|
||||
## Disclosure
|
||||
Neither I nor the Project Pokémon staff take any responsibility for possible adverse outcomes or bans resulting from the use of this tool. Use it at your own discretion.
|
||||
|
||||
**N.B.:** Some BCAT files contain sensitive console-specific information that you should keep secure. Do not share your BCAT with others!
|
||||
Neither I nor the Project Pokémon staff takes any responsibility for possible adverse outcomes or bans due to the use of this tool. Use at your own discretion.
|
||||
**N.B:** Some BCAT files contain sensible console-specific informations, which you should keep safe. Don't share your BCAT to others!
|
||||
|
||||
## Usage
|
||||
This section refers to the Windows Form app. The Command Line app usage is similar and should be fairly intuitive.
|
||||
* Ensure you have the required [.NET 9.0 Desktop Runtime](https://dotnet.microsoft.com/it-it/download/dotnet/9.0) installed correctly.
|
||||
* Dump your game's BCAT with [JKSV](https://github.com/J-D-K/JKSV/releases) and keep some copies in a safe place.
|
||||
* Open the tool and select your game of choice.
|
||||
* Import the wondercard files of your choice (by drag & drop or by clicking the `Open Files` button).
|
||||
* Optionally, edit the wondercard ID (WCID) if you have duplicate WCs, then click `Apply`.
|
||||
* Click the `Save as BCAT Package` button and browse to your dumped BCAT.
|
||||
* A folder called "Forged_BCAT_{Game}" should appear next to your dumped BCAT.
|
||||
* Restore the forged BCAT using JKSV.
|
||||
* To redeem the old event gifts, open your game -> Menu -> Mystery Gift -> Redeem via Internet.
|
||||
* When you're done, restore your original BCAT package with JKSV (not doing so may cause sync issues).
|
||||
This paragraph refers to the Windows Form app. The Command Line app usage is similar and should be fairly intuitive.
|
||||
* Ensure you have the required [.NET 7.0 Desktop Runtime](https://dotnet.microsoft.com/en-us/download/dotnet/7.0) correctly installed
|
||||
* Dump your game's BCAT with [JKSV](https://github.com/J-D-K/JKSV/releases) and keep some copies somewhere safe
|
||||
* Open the tool and select your game of choice
|
||||
* Import wondercard files of your choice (by drag & drop or by clicking the `Open Files` button)
|
||||
* Eventually edit the wondercard id (WCID) if you have duplicated WCs and click `Apply`
|
||||
* Click the `Save as BCAT Package` button and browse to your dumped BCAT
|
||||
* A folder called "Forged_BCAT_{Game}" should appear next to your dumped BCAT
|
||||
* Restore the Forged Bcat with JKSV
|
||||
* To redeem the old fashion events, open your game -> Menu -> Mystery Gift -> redeem via Internet
|
||||
* When you're done, restore your original BCAT package with JKSV (not doing so may cause sync issues)
|
||||
|
||||
**N.B.:** BCAT sync usually occurs between 12:00 AM (UTC) and 01:00 AM (UTC). I recommend avoiding this procedure during that timeframe to prevent desynchronization.
|
||||
**N.B**: BCAT Sync usually occurs between 12:00 AM (UTC) and 01:00 AM (UTC). I suggest to not follow this procedure during that timeframe to avoid a desync.
|
||||
If you experience a desync, follow one of these methods to resync:
|
||||
* Open JKSV, select BCAT, hover over your game, press X to open the menu, then click `Reset Save Data`.
|
||||
* Download the latest BCAT for your game from [citrusbolt](https://github.com/citrusbolt)'s [website](http://citrusbolt.net/bcat/) and add the missing files to your dumped BCAT, then restore it with JKSV.
|
||||
* Open JKSV, select BCAT, hover over your game and press X to open the menu, then click `Reset Save Data`.
|
||||
* Download the latest BCAT for your game from my [bcat_updates](https://github.com/Manu098vm/bcat_updates) repo or from [citrusbolt](https://github.com/citrusbolt)'s [website](http://citrusbolt.net/bcat/) and add the missing files to your dumped BCAT, then restore it with JKSV.
|
||||
|
||||
## Support/Troubleshooting
|
||||
If you find any bugs or need support, please post in the [relevant topic on the Project Pokémon forums](https://projectpokemon.org/home/forums/topic/62491-switch-gift-data-manager-import-wondercards-into-switch-games-by-faking-bcat-packages/).
|
||||
Alternatively, feel free to contact me on my [Discord server](https://discord.gg/yWveAjKbKt).
|
||||
|
||||
[<img src="https://canary.discordapp.com/api/guilds/693083823197519873/widget.png?style=banner2">](https://discord.gg/yWveAjKbKt)
|
||||
If you find any bug or you need support, please write in the [relevant topic in the Project Pokémon forums](https://projectpokemon.org/home/forums/topic/62491-switch-gift-data-manager-import-wondercards-into-switch-games-by-faking-bcat-packages/).
|
||||
Alternatively, feel free to contact me on Discord by DMs (SkyLink98#5946 - **only for bug reports**) or in my [server](https://discord.gg/F9nMfvw9sS).
|
||||
|
||||
## Building
|
||||
* All Switch Gift Data Manager projects require .NET 9.0.
|
||||
* `.WinForm` is a Windows Form application and can only be built on Windows operating systems.
|
||||
* `.Core` and `.CommandLine` can be built on any platform.
|
||||
* Use the Debug build configuration when editing or developing code related to the `.WinForm` project. Build as Release only once the code is finalized.
|
||||
* To build the projects, open the `.sln` file in the root directory with an IDE such as Visual Studio 2022, then click `Build` -> `Build Solution`.
|
||||
* All the Switch Gift Data Manager projects require .NET 7.0.
|
||||
* .WinForm is a Windows Form application and can only be built in Windows Operating Systems.
|
||||
* .Core and .CommandLine can be built in any platform OS.
|
||||
* Use the Debug build configuration when editing or developing code related to the .WinForm project. Build as Release only once the code is finished.
|
||||
* To build the projects, open the .sln file in the root directory with an IDE such as Visual Studio 2022, click `Build` -> `Build Solution`.
|
||||
|
||||
The `.CommandLine` project is currently just a simple script that calls the `.Core` functionalities and can run on any popular OS. Feel free to improve it and/or submit a pull request if you'd like :-)
|
||||
The .CommandLine project is currently just a simple script that calls the .Core functionalities and can run on any popular OS. Feel free to improve it and/or submit a pull request if you'd like :-)
|
||||
|
||||
## Credits
|
||||
* [PNZeml](https://github.com/PNZeml) for the CRC-16/CCITT-FALSE with lookup table [implementation](https://gist.github.com/tijnkooijmans/10981093?permalink_comment_id=3996072#gistcomment-3996072).
|
||||
* [kwsch](https://github.com/kwsch), [sora10pls](https://github.com/sora10pls), and all the [PKHeX](https://github.com/kwsch/PKHeX) and [pkNX](https://github.com/kwsch/pkNX) developers and contributors for various offsets and resources.
|
||||
* [PP-theSLAYER](https://github.com/PP-theSLAYER) and [pasqualenardiello](https://github.com/pasqualenardiello) for their research on the Sword & Shield fashion block and the Scarlet & Violet fashion block, respectively.
|
||||
* All the Project Pokémon staff and the [Event Gallery](https://github.com/projectpokemon/EventsGallery) contributors for their archival efforts that made this project possible.
|
||||
* [PNZeml](https://github.com/PNZeml) for the CRC-16/CCITT-FALSE with lookup table [implementation](https://gist.github.com/tijnkooijmans/10981093?permalink_comment_id=3996072#gistcomment-3996072)
|
||||
* [kwsch](https://github.com/kwsch), [sora10pls](https://github.com/sora10pls) and all the [PKHeX](https://github.com/kwsch/PKHeX) and [pkNX](https://github.com/kwsch/pkNX) devs and contributors
|
||||
for a lot of offsets and resources
|
||||
* [PP-theSLAYER](https://github.com/PP-theSLAYER) for his researches in the Sword and Shield fashion block and for the clothing names resources
|
||||
* All the Project Pokémon Staff and the [Event Gallery](https://github.com/projectpokemon/EventsGallery) contributors for their archival efforts that made this possible
|
||||
|
||||
## License
|
||||

|
||||
|
||||
Copyright © 2025 Manu098vm
|
||||
Copyright © 2023 Manu098vm
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
|
|||
|
|
@ -1,259 +1,236 @@
|
|||
using SwitchGiftDataManager.Core;
|
||||
using Enums;
|
||||
|
||||
namespace SwitchGiftDataManager.CommandLine;
|
||||
|
||||
public static class Program
|
||||
namespace SwitchGiftDataManager.CommandLine
|
||||
{
|
||||
public static void Main()
|
||||
public static class Program
|
||||
{
|
||||
var msg = $"Switch Gift Data Manager v{BCATManager.Version}";
|
||||
Log(msg);
|
||||
|
||||
Task.Run(TryUpdate).Wait();
|
||||
|
||||
msg = $"{Environment.NewLine}Select your game:{Environment.NewLine}{Environment.NewLine}" +
|
||||
$"1 - LGPE{Environment.NewLine}" +
|
||||
$"2 - SWSH{Environment.NewLine}" +
|
||||
$"3 - BDSP{Environment.NewLine}" +
|
||||
$"4 - PLA{Environment.NewLine}" +
|
||||
$"5 - SCVI{Environment.NewLine}" +
|
||||
$"6 - ZA";
|
||||
Log(msg);
|
||||
|
||||
Games game = (Games)int.Parse(Console.ReadLine()!);
|
||||
if (game is Games.None || game > Games.ZA)
|
||||
public static void Main()
|
||||
{
|
||||
Log("Invalid input. Aborted.");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
}
|
||||
|
||||
var bcat = new BCATManager(game);
|
||||
|
||||
msg = $"{Environment.NewLine}Enter a valid input path.{Environment.NewLine}{Environment.NewLine}The path can be either:{Environment.NewLine}" +
|
||||
$"- A direct (full) path to a wondercard file{Environment.NewLine}" +
|
||||
$"- A (full) path to a folder containing wondercard files";
|
||||
Log(msg);
|
||||
|
||||
var path = Console.ReadLine()!;
|
||||
if (File.Exists(path))
|
||||
bcat.TryAddWondercards(File.ReadAllBytes(path));
|
||||
else if (CheckValidPath(path))
|
||||
foreach (var file in Directory.GetFiles(path))
|
||||
if (!bcat.TryAddWondercards(File.ReadAllBytes(file)))
|
||||
Log($"{file} could not be loaded.");
|
||||
|
||||
if (bcat.Count() <= 0)
|
||||
{
|
||||
Log("No valid files have been loaded. Aborted.");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
}
|
||||
|
||||
bcat.Sort();
|
||||
|
||||
var methodSelectionInfo = $"{Environment.NewLine}The Pokémon Scarlet & Violet v2.0.1 Update, released on September 13 - 2023, introduced a new TID / SID handling method for Wondercards.{Environment.NewLine}" +
|
||||
$"This Pokémon Gift could be redeemed both before and after the v2.0.1 release, meaning it can be redeemed with either the old or new TID/SID handling method, depending on the redemption date.{Environment.NewLine}" +
|
||||
$"The redemption date can be changed with the homebrew 'switch-time'. If you're not going to use 'switch-time', please select 'After v2.0.1'.";
|
||||
|
||||
foreach (var (i, title) in bcat.GetListNames().Select((title, i) => (i, title)).Where(x => bcat.GetRequiresMethodSelection(x.i)))
|
||||
{
|
||||
var method = 0;
|
||||
while (method is not (1 or 2))
|
||||
{
|
||||
Log($"{Environment.NewLine}[{title}] This Pokémon Gift could be redeemed both before and after the v2.0.1 release. Please select the redemption method you want to use, depending on the Date/Time you'll redeem the gift." +
|
||||
$"{Environment.NewLine}1 - Before v2.0.1" +
|
||||
$"{Environment.NewLine}2 - After v2.0.1" +
|
||||
$"{Environment.NewLine}3 - Info");
|
||||
|
||||
method = int.Parse(Console.ReadLine()!);
|
||||
|
||||
if (method is (1 or 2))
|
||||
bcat.SetIsBefore201(i, method == 1);
|
||||
else
|
||||
Log(methodSelectionInfo);
|
||||
}
|
||||
}
|
||||
|
||||
Log($"{Environment.NewLine}Enter the source (full) path to your dumped BCAT:");
|
||||
var sourcepath = Console.ReadLine()!;
|
||||
if (!CheckValidBcatPath(sourcepath))
|
||||
{
|
||||
Log("Not a valid BCAT folder path. Aborted.");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
}
|
||||
|
||||
Log($"{Environment.NewLine}Enter a destination (full) path to save the forged BCAT:");
|
||||
var destpath = Console.ReadLine()!;
|
||||
if (!CheckValidPath(destpath))
|
||||
{
|
||||
Log("Not a valid path. Aborted.");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
}
|
||||
|
||||
if (game is not (Games.LGPE or Games.BDSP))
|
||||
{
|
||||
msg = $"{Environment.NewLine}Select a build option:{Environment.NewLine}{Environment.NewLine}" +
|
||||
$"1 - Merge as one file{Environment.NewLine}" +
|
||||
$"2 - Keep separate files";
|
||||
var msg = $"Switch Gift Data Manager v{BCATManager.Version}";
|
||||
Log(msg);
|
||||
}
|
||||
|
||||
var opt = game switch {
|
||||
Games.LGPE => 2,
|
||||
Games.BDSP => 1,
|
||||
_ => int.Parse(Console.ReadLine()!),
|
||||
};
|
||||
Task.Run(TryUpdate).Wait();
|
||||
|
||||
if(opt < 1 || opt > 2)
|
||||
{
|
||||
Log("Invalid input. Aborted.");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
}
|
||||
msg = $"{Environment.NewLine}Select your game:{Environment.NewLine}{Environment.NewLine}" +
|
||||
$"1 - LGPE{Environment.NewLine}" +
|
||||
$"2 - SWSH{Environment.NewLine}" +
|
||||
$"3 - BDSP{Environment.NewLine}" +
|
||||
$"4 - PLA{Environment.NewLine}" +
|
||||
$"5 - SCVI";
|
||||
Log(msg);
|
||||
|
||||
destpath = Path.Combine(destpath, $"Forged_BCAT_{game}");
|
||||
CopyDirectory(sourcepath, destpath);
|
||||
|
||||
if (opt == 1)
|
||||
{
|
||||
try
|
||||
Games game = (Games)int.Parse(Console.ReadLine()!);
|
||||
if (game is Games.None || game > Games.SCVI)
|
||||
{
|
||||
var wcdata = bcat.ConcatenateFiles();
|
||||
var metadata = bcat.ForgeMetaInfo(wcdata.ToArray());
|
||||
Log("Invalid input. Aborted.");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
}
|
||||
|
||||
var bcat = new BCATManager(game);
|
||||
|
||||
msg = $"{Environment.NewLine}Enter a valid input path.{Environment.NewLine}{Environment.NewLine}The path can be either:{Environment.NewLine}" +
|
||||
$"- A direct (full) path to a wondercard file{Environment.NewLine}" +
|
||||
$"- A (full) path to a folder containing wondercard files";
|
||||
Log(msg);
|
||||
|
||||
var path = Console.ReadLine()!;
|
||||
if (File.Exists(path))
|
||||
bcat.TryAddWondercards(File.ReadAllBytes(path));
|
||||
else if (CheckValidPath(path))
|
||||
foreach (var file in Directory.GetFiles(path))
|
||||
if (!bcat.TryAddWondercards(File.ReadAllBytes(file)))
|
||||
Log($"{file} could not be loaded.");
|
||||
|
||||
if (bcat.Count() <= 0)
|
||||
{
|
||||
Log("No valid files have been loaded. Aborted.");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
}
|
||||
|
||||
bcat.Sort();
|
||||
Log($"{Environment.NewLine}Enter the source (full) path to your dumped BCAT:");
|
||||
var sourcepath = Console.ReadLine()!;
|
||||
if (!CheckValidBcatPath(sourcepath))
|
||||
{
|
||||
Log("Not a valid BCAT folder path. Aborted.");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
}
|
||||
|
||||
Log($"{Environment.NewLine}Enter a destination (full) path to save the forged BCAT:");
|
||||
var destpath = Console.ReadLine()!;
|
||||
if (!CheckValidPath(destpath))
|
||||
{
|
||||
Log("Not a valid path. Aborted.");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
}
|
||||
|
||||
if (game is not (Games.LGPE or Games.BDSP))
|
||||
{
|
||||
msg = $"{Environment.NewLine}Select a build option:{Environment.NewLine}{Environment.NewLine}" +
|
||||
$"1 - Merge as one file{Environment.NewLine}" +
|
||||
$"2 - Keep separate files";
|
||||
Log(msg);
|
||||
}
|
||||
|
||||
var opt = game switch {
|
||||
Games.LGPE => 2,
|
||||
Games.BDSP => 1,
|
||||
_ => int.Parse(Console.ReadLine()!),
|
||||
};
|
||||
|
||||
if(opt < 1 || opt > 2)
|
||||
{
|
||||
Log("Invalid input. Aborted.");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
}
|
||||
|
||||
destpath = Path.Combine(destpath, $"Forged_BCAT_{game}");
|
||||
CopyDirectory(sourcepath, destpath);
|
||||
|
||||
if (opt == 1)
|
||||
{
|
||||
try
|
||||
{
|
||||
var wcdata = bcat.ConcatenateFiles();
|
||||
var metadata = bcat.ForgeMetaInfo(wcdata.ToArray());
|
||||
var metadatapath = Path.Combine(destpath, "directories");
|
||||
metadatapath = Path.Combine(metadatapath, bcat.GetDefaultBcatFolderName());
|
||||
var wcpath = Path.Combine(metadatapath, "files");
|
||||
|
||||
if (Directory.Exists(metadatapath))
|
||||
DeleteFilesAndDirectory(metadatapath);
|
||||
|
||||
Directory.CreateDirectory(wcpath);
|
||||
File.WriteAllBytes(Path.Combine(metadatapath, "files.meta"), metadata.ToArray());
|
||||
File.WriteAllBytes(Path.Combine(wcpath, bcat.GetDefaultBcatFileName()), wcdata.ToArray());
|
||||
Log("Done. Press any key to exit...");
|
||||
Console.ReadKey();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Log("Internal Error. Press any key to exit...");
|
||||
Console.ReadKey();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var metadata = bcat.ForgeMetaInfo();
|
||||
var metadatapath = Path.Combine(destpath, "directories");
|
||||
metadatapath = Path.Combine(metadatapath, bcat.GetDefaultBcatFolderName());
|
||||
var wcpath = Path.Combine(metadatapath, "files");
|
||||
var wcspath = Path.Combine(metadatapath, "files");
|
||||
|
||||
if (Directory.Exists(metadatapath))
|
||||
DeleteFilesAndDirectory(metadatapath);
|
||||
|
||||
Directory.CreateDirectory(wcpath);
|
||||
Directory.CreateDirectory(wcspath);
|
||||
File.WriteAllBytes(Path.Combine(metadatapath, "files.meta"), metadata.ToArray());
|
||||
File.WriteAllBytes(Path.Combine(wcpath, bcat.GetDefaultBcatFileName()), wcdata.ToArray());
|
||||
Log($"Saved in {path}{Environment.NewLine}BCAT forge was successful.{Environment.NewLine}Press any key to exit...");
|
||||
Console.ReadKey();
|
||||
if (bcat.TrySaveAllWondercards(wcspath))
|
||||
{
|
||||
Log("Done. Press any key to exit...");
|
||||
Console.ReadKey();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("Internal error. Press any key to exit...");
|
||||
Console.ReadKey();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
private static bool CheckValidPath(string path)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
return false;
|
||||
|
||||
if (!Directory.Exists(path))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool CheckValidBcatPath(string path)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
return false;
|
||||
|
||||
if (!Directory.Exists(Path.Combine(path, "directories")))
|
||||
return false;
|
||||
|
||||
if (!File.Exists(Path.Combine(path, "directories.meta")))
|
||||
return false;
|
||||
|
||||
if (!File.Exists(Path.Combine(path, "etag.bin")))
|
||||
return false;
|
||||
|
||||
if (!File.Exists(Path.Combine(path, "list.msgpack")))
|
||||
return false;
|
||||
|
||||
if (!File.Exists(Path.Combine(path, "na_required")))
|
||||
return false;
|
||||
|
||||
if (!File.Exists(Path.Combine(path, "passphrase.bin")))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void CopyDirectory(string source, string dest)
|
||||
{
|
||||
var dir = new DirectoryInfo(source);
|
||||
DirectoryInfo[] dirs = dir.GetDirectories();
|
||||
Directory.CreateDirectory(dest);
|
||||
|
||||
foreach (FileInfo file in dir.GetFiles())
|
||||
{
|
||||
Log("Internal Error. Press any key to exit...");
|
||||
Console.ReadKey();
|
||||
string targetFilePath = Path.Combine(dest, file.Name);
|
||||
if (!File.Exists(targetFilePath))
|
||||
file.CopyTo(targetFilePath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var metadata = bcat.ForgeMetaInfo();
|
||||
var metadatapath = Path.Combine(destpath, "directories");
|
||||
metadatapath = Path.Combine(metadatapath, bcat.GetDefaultBcatFolderName());
|
||||
var wcspath = Path.Combine(metadatapath, "files");
|
||||
|
||||
if (Directory.Exists(metadatapath))
|
||||
DeleteFilesAndDirectory(metadatapath);
|
||||
|
||||
Directory.CreateDirectory(wcspath);
|
||||
File.WriteAllBytes(Path.Combine(metadatapath, "files.meta"), metadata.ToArray());
|
||||
if (bcat.TrySaveAllWondercards(wcspath))
|
||||
foreach (DirectoryInfo subDir in dirs)
|
||||
{
|
||||
Log($"Saved in {path}{Environment.NewLine}BCAT forge was successful.{Environment.NewLine}Press any key to exit...");
|
||||
Console.ReadKey();
|
||||
string newDestinationDir = Path.Combine(dest, subDir.Name);
|
||||
CopyDirectory(subDir.FullName, newDestinationDir);
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
private static void DeleteFilesAndDirectory(string targetDir)
|
||||
{
|
||||
string[] files = Directory.GetFiles(targetDir);
|
||||
string[] dirs = Directory.GetDirectories(targetDir);
|
||||
|
||||
foreach (string file in files)
|
||||
{
|
||||
Log("Internal error. Press any key to exit...");
|
||||
Console.ReadKey();
|
||||
File.SetAttributes(file, FileAttributes.Normal);
|
||||
File.Delete(file);
|
||||
}
|
||||
|
||||
foreach (string dir in dirs)
|
||||
DeleteFilesAndDirectory(dir);
|
||||
|
||||
Directory.Delete(targetDir, false);
|
||||
}
|
||||
|
||||
private static async Task TryUpdate()
|
||||
{
|
||||
if (await GitHubUtil.IsUpdateAvailable())
|
||||
{
|
||||
Log("A program update is available. Do you want to download the latest release?\n[Y\\n]:");
|
||||
var str = Console.ReadLine();
|
||||
if (!string.IsNullOrWhiteSpace(str) && (str.ToLower().Equals("y") || str.ToLower().Equals("yes")))
|
||||
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo { FileName = @"https://github.com/Manu098vm/Switch-Gift-Data-Manager/releases", UseShellExecute = true });
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
private static void Log(string msg) => Console.WriteLine(msg);
|
||||
}
|
||||
|
||||
private static bool CheckValidPath(string path)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
return false;
|
||||
|
||||
if (!Directory.Exists(path))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool CheckValidBcatPath(string path)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
return false;
|
||||
|
||||
if (!Directory.Exists(Path.Combine(path, "directories")))
|
||||
return false;
|
||||
|
||||
if (!File.Exists(Path.Combine(path, "directories.meta")))
|
||||
return false;
|
||||
|
||||
if (!File.Exists(Path.Combine(path, "etag.bin")))
|
||||
return false;
|
||||
|
||||
if (!File.Exists(Path.Combine(path, "list.msgpack")))
|
||||
return false;
|
||||
|
||||
if (!File.Exists(Path.Combine(path, "na_required")))
|
||||
return false;
|
||||
|
||||
if (!File.Exists(Path.Combine(path, "passphrase.bin")))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void CopyDirectory(string source, string dest)
|
||||
{
|
||||
var dir = new DirectoryInfo(source);
|
||||
DirectoryInfo[] dirs = dir.GetDirectories();
|
||||
Directory.CreateDirectory(dest);
|
||||
|
||||
foreach (FileInfo file in dir.GetFiles())
|
||||
{
|
||||
string targetFilePath = Path.Combine(dest, file.Name);
|
||||
if (!File.Exists(targetFilePath))
|
||||
file.CopyTo(targetFilePath);
|
||||
}
|
||||
|
||||
foreach (DirectoryInfo subDir in dirs)
|
||||
{
|
||||
string newDestinationDir = Path.Combine(dest, subDir.Name);
|
||||
CopyDirectory(subDir.FullName, newDestinationDir);
|
||||
}
|
||||
}
|
||||
|
||||
private static void DeleteFilesAndDirectory(string targetDir)
|
||||
{
|
||||
string[] files = Directory.GetFiles(targetDir);
|
||||
string[] dirs = Directory.GetDirectories(targetDir);
|
||||
|
||||
foreach (string file in files)
|
||||
{
|
||||
File.SetAttributes(file, FileAttributes.Normal);
|
||||
File.Delete(file);
|
||||
}
|
||||
|
||||
foreach (string dir in dirs)
|
||||
DeleteFilesAndDirectory(dir);
|
||||
|
||||
Directory.Delete(targetDir, false);
|
||||
}
|
||||
|
||||
private static async Task TryUpdate()
|
||||
{
|
||||
if (await GitHubUtil.IsUpdateAvailable())
|
||||
{
|
||||
Log("A program update is available. Do you want to download the latest release?\n[Y\\n]:");
|
||||
var str = Console.ReadLine();
|
||||
if (!string.IsNullOrWhiteSpace(str) && (str.ToLower().Equals("y") || str.ToLower().Equals("yes")))
|
||||
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo { FileName = @"https://github.com/Manu098vm/Switch-Gift-Data-Manager/releases", UseShellExecute = true });
|
||||
}
|
||||
}
|
||||
|
||||
private static void Log(string msg) => Console.WriteLine(msg);
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>bin\Release\net7.0\linux-x64\publish\linux-x64\</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<_TargetId>Folder</_TargetId>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
||||
<SelfContained>false</SelfContained>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<History>True|2023-01-28T15:02:21.7075281Z;</History>
|
||||
<LastFailureDetails />
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<History>True|2023-01-28T14:55:36.8109882Z;True|2023-01-28T15:48:22.9284343+01:00;</History>
|
||||
<LastFailureDetails />
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>bin\Release\net7.0\osx-x64\publish\</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<_TargetId>Folder</_TargetId>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<RuntimeIdentifier>osx-x64</RuntimeIdentifier>
|
||||
<SelfContained>false</SelfContained>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<History>True|2023-01-28T15:02:13.7381611Z;</History>
|
||||
<LastFailureDetails />
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<History>True|2023-01-28T14:58:16.5887032Z;True|2023-01-28T15:57:34.0451151+01:00;</History>
|
||||
<LastFailureDetails />
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>bin\Release\net7.0\win-x64\publish\</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<_TargetId>Folder</_TargetId>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<SelfContained>false</SelfContained>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<History>True|2023-01-28T15:02:06.8383516Z;</History>
|
||||
<LastFailureDetails />
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<History>True|2023-01-28T14:45:49.3435089Z;True|2023-01-23T20:03:47.7790063+01:00;</History>
|
||||
<LastFailureDetails />
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Authors>Manu098vm</Authors>
|
||||
<Copyright>Copyright (C) 2024 Manu098vm</Copyright>
|
||||
<Copyright>Copyright (C) 2022 Manu098vm</Copyright>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<PackageTags>pokemon; mystery gift; wondercard; reader; nintendo; bcat; event injection;</PackageTags>
|
||||
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||
|
|
@ -36,10 +36,10 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\README.md">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
<None Include="..\README.md">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
@ -56,4 +56,4 @@
|
|||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DebuggerFlavor>ProjectDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ActiveDebugProfile>SwitchGiftDataManager.CommandLine</ActiveDebugProfile>
|
||||
<_LastSelectedProfileId>D:\Projects\SwitchGiftDataManager\SwitchGiftDataManager.CommandLine\Properties\PublishProfiles\windows_x64.pubxml</_LastSelectedProfileId>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -3,402 +3,358 @@ using System.Globalization;
|
|||
using System.Text;
|
||||
using Enums;
|
||||
|
||||
namespace SwitchGiftDataManager.Core;
|
||||
|
||||
public class BCATManager
|
||||
namespace SwitchGiftDataManager.Core
|
||||
{
|
||||
public const string Version = "1.9.0";
|
||||
|
||||
private const int FileNameOffset = 0x00;
|
||||
private const int UnkOffset = 0x20;
|
||||
private const int FileSizeOffset = 0x28;
|
||||
private const int ChecksumOffset = 0x30;
|
||||
private const int MaxFileNameLength = 0x1F;
|
||||
private const int WCMetaInfoLength = 0x80;
|
||||
private const int MetaHeaderLength = 0x04;
|
||||
|
||||
private Games Game { get; set; }
|
||||
private List<Wondercard>? WCList { get; set; }
|
||||
|
||||
public BCATManager(Games game)
|
||||
public class BCATManager
|
||||
{
|
||||
Game = game;
|
||||
WCList = new();
|
||||
}
|
||||
public const string Version = "1.3.0";
|
||||
|
||||
private Wondercard CreateWondercard(ReadOnlySpan<byte> data)
|
||||
{
|
||||
return Game switch
|
||||
private const int FileNameOffset = 0x00;
|
||||
private const int UnkOffset = 0x20;
|
||||
private const int FileSizeOffset = 0x28;
|
||||
private const int ChecksumOffset = 0x30;
|
||||
private const int MaxFileNameLength = 0x1F;
|
||||
private const int WCMetaInfoLength = 0x80;
|
||||
private const int MetaHeaderLength = 0x04;
|
||||
|
||||
private Games Game { get; set; }
|
||||
private List<Wondercard>? WCList { get; set; }
|
||||
|
||||
public BCATManager(Games game)
|
||||
{
|
||||
Games.LGPE => new WB7(data),
|
||||
Games.SWSH => new WC8(data),
|
||||
Games.BDSP => new WB8(data),
|
||||
Games.PLA => new WA8(data),
|
||||
Games.SCVI => new WC9(data),
|
||||
Games.ZA => new WA9(data),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(Game)),
|
||||
};
|
||||
}
|
||||
Game = game;
|
||||
WCList = new();
|
||||
}
|
||||
|
||||
public bool TryAddWondercards(ReadOnlySpan<byte> data, bool sort = false)
|
||||
{
|
||||
var success = false;
|
||||
if (Game is not Games.None && WCList is not null)
|
||||
if (Game is not Games.LGPE || (Game is Games.LGPE && WCList.Count == 0))
|
||||
private Wondercard CreateWondercard(ReadOnlySpan<byte> data)
|
||||
{
|
||||
return Game switch
|
||||
{
|
||||
var game = GetCompatibleGamesFromWC(data);
|
||||
if (game == Game)
|
||||
Games.LGPE => new WB7(data),
|
||||
Games.SWSH => new WC8(data),
|
||||
Games.BDSP => new WB8(data),
|
||||
Games.PLA => new WA8(data),
|
||||
Games.SCVI => new WC9(data),
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
}
|
||||
|
||||
public bool TryAddWondercards(ReadOnlySpan<byte> data, bool sort = false)
|
||||
{
|
||||
var success = false;
|
||||
if (Game is not Games.None && WCList is not null)
|
||||
if (Game is not Games.LGPE || (Game is Games.LGPE && WCList.Count == 0))
|
||||
{
|
||||
var size = (int)Wondercard.GetSize(game);
|
||||
var qty = data.Length / size;
|
||||
for (int i = 0; i < qty; i++)
|
||||
var game = GetCompatibleGamesFromWC(data);
|
||||
if (game == Game)
|
||||
{
|
||||
var wc = CreateWondercard(data[(i * size)..((i + 1) * size)]);
|
||||
if (wc.IsValid())
|
||||
var size = (int)Wondercard.GetSize(game);
|
||||
var qty = data.Length / size;
|
||||
for (int i = 0; i < qty; i++)
|
||||
{
|
||||
WCList.Add(wc);
|
||||
success = true;
|
||||
var wc = CreateWondercard(data[(i * size)..((i + 1) * size)]);
|
||||
if (wc.IsValid())
|
||||
{
|
||||
WCList.Add(wc);
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sort)
|
||||
Sort();
|
||||
}
|
||||
if (sort)
|
||||
Sort();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
public void Sort() => WCList!.Sort((x, y) => x.WCID.CompareTo(y.WCID));
|
||||
|
||||
public int Count()
|
||||
{
|
||||
if (WCList is not null)
|
||||
return WCList.Count;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void RemoveWC(int index)
|
||||
{
|
||||
if (WCList is not null && WCList.Count > 0 && WCList.Count >= index - 1)
|
||||
WCList.RemoveAt(index);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
if(WCList is not null)
|
||||
WCList.Clear();
|
||||
else
|
||||
WCList = new List<Wondercard>();
|
||||
}
|
||||
|
||||
public void SetWCID(int index, ushort wcid)
|
||||
{
|
||||
if (WCList is not null && WCList.Count > 0 && WCList.Count >= index - 1 && index >= 0)
|
||||
{
|
||||
var wc = WCList.ElementAt(index);
|
||||
wc.SetID(wcid);
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
||||
public ushort GetWCID(int index)
|
||||
{
|
||||
if (WCList is not null && WCList.Count > 0 && WCList.Count >= index - 1 && index >= 0)
|
||||
return WCList.ElementAt(index).WCID;
|
||||
return 0;
|
||||
}
|
||||
public void Sort() => WCList!.Sort((x, y) => x.WCID.CompareTo(y.WCID));
|
||||
|
||||
public void SetIsRepeatable(int index, bool repeatable)
|
||||
{
|
||||
if (WCList is not null && WCList.Count > 0 && WCList.Count >= index - 1 && index >= 0)
|
||||
public int Count()
|
||||
{
|
||||
var wc = WCList.ElementAt(index);
|
||||
wc.SetRepeatable(repeatable);
|
||||
if (WCList is not null)
|
||||
return WCList.Count;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public bool GetIsRepeatable(int index)
|
||||
{
|
||||
if (WCList is not null && WCList.Count > 0 && WCList.Count >= index - 1 && index >= 0)
|
||||
return WCList.ElementAt(index).IsRepeatable;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool GetRequiresMethodSelection(int index)
|
||||
{
|
||||
if (WCList is not null && WCList.Count > 0 && WCList.Count >= index - 1 && index >= 0)
|
||||
if (WCList.ElementAt(index) is WC9 wc9)
|
||||
return wc9.RequiresMethodSelection;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool GetIsBefore201(int index)
|
||||
{
|
||||
if (WCList is not null && WCList.Count > 0 && WCList.Count >= index - 1 && index >= 0)
|
||||
if (WCList.ElementAt(index) is WC9 wc9)
|
||||
return wc9.IsBefore201;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void SetIsBefore201(int index, bool before201)
|
||||
{
|
||||
if (WCList is not null && WCList.Count > 0 && WCList.Count >= index - 1 && index >= 0)
|
||||
if (WCList.ElementAt(index) is WC9 wc9 && wc9.RequiresMethodSelection)
|
||||
if (before201)
|
||||
wc9.UpdateOldToNewTIDSID();
|
||||
else
|
||||
wc9.UpdateNewToOldTIDSID();
|
||||
}
|
||||
|
||||
public int GetIndex(ushort wcid)
|
||||
{
|
||||
if (WCList is not null && WCList.Count > 0)
|
||||
return WCList.FindIndex((x) => x.WCID == wcid);
|
||||
else
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
public List<string> GetListNames()
|
||||
{
|
||||
List<string> list = new();
|
||||
if (WCList is not null && WCList.Count > 0)
|
||||
foreach (var wc in WCList)
|
||||
{
|
||||
var str = wc.Type!.ToString()!.Equals("Pokemon") ? ((PokemonGift)wc.Content!).GetSpeciesName().Replace("\r","") : wc.Type!.ToString()!;
|
||||
list.Add($"{Game} #{wc.WCID}: {str}");
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<string> GetContentToString(int index)
|
||||
{
|
||||
var wcid = "";
|
||||
var el1 = "";
|
||||
var el2 = "";
|
||||
var el3 = "";
|
||||
var el4 = "";
|
||||
var el5 = "";
|
||||
var el6 = "";
|
||||
var el7 = "";
|
||||
|
||||
if (WCList is not null && WCList.Count > 0 && WCList.Count >= index)
|
||||
public void RemoveWC(int index)
|
||||
{
|
||||
var wc = WCList.ElementAt(index);
|
||||
wcid = wc.WCID.ToString();
|
||||
var content = wc.Content;
|
||||
if (content!.GetType() == typeof(PokemonGift))
|
||||
if (WCList is not null && WCList.Count > 0 && WCList.Count >= index - 1)
|
||||
WCList.RemoveAt(index);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
if(WCList is not null)
|
||||
WCList.Clear();
|
||||
else
|
||||
WCList = new List<Wondercard>();
|
||||
}
|
||||
|
||||
public void SetWCID(int index, ushort wcid)
|
||||
{
|
||||
if (WCList is not null && WCList.Count >= index && WCList.Count >= index)
|
||||
{
|
||||
var c = (PokemonGift)content;
|
||||
el1 = GetShinyString(c.ShinyType);
|
||||
el2 = c.GetSpeciesName();
|
||||
el3 = GetPIDString(c.PIDType);
|
||||
var wc = WCList.ElementAt(index);
|
||||
wc.SetID(wcid);
|
||||
wc.UpdateChecksum();
|
||||
}
|
||||
else if (content!.GetType() == typeof(List<OtherGift>))
|
||||
{
|
||||
foreach (var c in (List<OtherGift>)content)
|
||||
}
|
||||
|
||||
public ushort GetWCID(int index)
|
||||
{
|
||||
if (WCList is not null && WCList.Count >= index && WCList.Count >= index)
|
||||
return WCList.ElementAt(index).WCID;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int GetIndex(ushort wcid)
|
||||
{
|
||||
if (WCList is not null && WCList.Count > 0)
|
||||
return WCList.FindIndex((x) => x.WCID == wcid);
|
||||
else
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
public static Games GetCompatibleGamesFromWC(ReadOnlySpan<byte> data)
|
||||
{
|
||||
if (data.Length % (int)Wondercard.GetSize(Games.LGPE) == 0)
|
||||
return Games.LGPE;
|
||||
else if (data.Length % (int)Wondercard.GetSize(Games.SWSH) == 0)
|
||||
return Games.SWSH;
|
||||
else if (data.Length % (int)Wondercard.GetSize(Games.BDSP) == 0)
|
||||
return Games.BDSP;
|
||||
else if (data.Length % (int)Wondercard.GetSize(Games.SCVI) == 0)
|
||||
return data[Wondercard.GenOffset] != 0 ? Games.PLA : Games.SCVI;
|
||||
else
|
||||
return Games.None;
|
||||
}
|
||||
|
||||
public List<string> GetListNames()
|
||||
{
|
||||
List<string> list = new();
|
||||
if (WCList is not null && WCList.Count > 0)
|
||||
foreach (var wc in WCList)
|
||||
{
|
||||
var item = c.GetItemName().Replace("\r","");
|
||||
var qty = c.Quantity;
|
||||
var str = $"{item.Replace("BP", "Battle Points").Replace("LP", "League Points")}";
|
||||
if (qty != 0x0 && qty != ushort.MaxValue)
|
||||
str = $"{str} x{qty}";
|
||||
if (el1.Equals(""))
|
||||
el1 = str;
|
||||
else if (el2.Equals(""))
|
||||
el2 = str;
|
||||
else if (el3.Equals(""))
|
||||
el3 = str;
|
||||
else if (el4.Equals(""))
|
||||
el4 = str;
|
||||
else if (el5.Equals(""))
|
||||
el5 = str;
|
||||
else if (el6.Equals(""))
|
||||
el6 = str;
|
||||
else if (el7.Equals(""))
|
||||
el7 = str;
|
||||
var str = wc.Type!.ToString()!.Equals("Pokemon") ? ((PokemonGift)wc.Content!).GetSpeciesName().Replace("\r","") : wc.Type!.ToString()!;
|
||||
list.Add($"{Game} #{wc.WCID}: {str}");
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<string> GetContentToString(int index)
|
||||
{
|
||||
var wcid = "";
|
||||
var el1 = "";
|
||||
var el2 = "";
|
||||
var el3 = "";
|
||||
var el4 = "";
|
||||
var el5 = "";
|
||||
var el6 = "";
|
||||
var el7 = "";
|
||||
|
||||
if (WCList is not null && WCList.Count > 0 && WCList.Count >= index)
|
||||
{
|
||||
var wc = WCList.ElementAt(index);
|
||||
wcid = wc.WCID.ToString();
|
||||
var content = wc.Content;
|
||||
if (content!.GetType() == typeof(PokemonGift))
|
||||
{
|
||||
var c = (PokemonGift)content;
|
||||
el1 = GetShinyString(c.ShinyType);
|
||||
el2 = c.GetSpeciesName();
|
||||
el3 = GetPIDString(c.PIDType);
|
||||
}
|
||||
else if (content!.GetType() == typeof(List<OtherGift>))
|
||||
{
|
||||
foreach (var c in (List<OtherGift>)content)
|
||||
{
|
||||
var item = c.GetItemName().Replace("\r","");
|
||||
var qty = c.Quantity;
|
||||
var str = $"{item.Replace("BP", "Battle Points").Replace("LP", "League Points")}";
|
||||
if (qty != 0x0 && qty != 0xFFFF)
|
||||
str = $"{str} x{qty}";
|
||||
if (el1.Equals(""))
|
||||
el1 = str;
|
||||
else if (el2.Equals(""))
|
||||
el2 = str;
|
||||
else if (el3.Equals(""))
|
||||
el3 = str;
|
||||
else if (el4.Equals(""))
|
||||
el4 = str;
|
||||
else if (el5.Equals(""))
|
||||
el5 = str;
|
||||
else if (el6.Equals(""))
|
||||
el6 = str;
|
||||
else if (el7.Equals(""))
|
||||
el7 = str;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new List<string> { wcid, el1, el2, el3, el4, el5, el6, el7 };
|
||||
}
|
||||
return new List<string> { wcid, el1, el2, el3, el4, el5, el6, el7 };
|
||||
}
|
||||
|
||||
public List<ushort>? GetDuplicatedWCID()
|
||||
{
|
||||
if (WCList is not null && WCList.Count > 1)
|
||||
public List<ushort>? GetDuplicatedWCID()
|
||||
{
|
||||
var l = WCList.GroupBy(x => x.WCID)
|
||||
.Where(g => g.Count() > 1)
|
||||
.Select(y => y.Key)
|
||||
.ToList();
|
||||
return l;
|
||||
if (WCList is not null && WCList.Count > 1)
|
||||
{
|
||||
var l = WCList.GroupBy(x => x.WCID)
|
||||
.Where(g => g.Count() > 1)
|
||||
.Select(y => y.Key)
|
||||
.ToList();
|
||||
return l;
|
||||
}
|
||||
else
|
||||
return new List<ushort>();
|
||||
}
|
||||
else
|
||||
return new List<ushort>();
|
||||
}
|
||||
|
||||
public string GetDefaultBcatFolderName() => GetDefaultBcatFolderName(this.Game);
|
||||
public string GetDefaultBcatFileName() => GetDefaultBcatFileName(this.Game);
|
||||
public string GetDefaultBcatFolderName() => GetDefaultBcatFolderName(this.Game);
|
||||
public string GetDefaultBcatFileName() => GetDefaultBcatFileName(this.Game);
|
||||
|
||||
public bool TrySaveAllWondercards(string path)
|
||||
{
|
||||
if (WCList is null || WCList.Count == 0)
|
||||
return false;
|
||||
public static string GetDefaultBcatFolderName(Games game)
|
||||
{
|
||||
return game switch
|
||||
{
|
||||
Games.LGPE => "normal",
|
||||
Games.SWSH => "normal",
|
||||
Games.BDSP => "99",
|
||||
Games.PLA => "normal",
|
||||
Games.SCVI => "normal",
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
}
|
||||
|
||||
for (int i = 0; i < WCList.Count; i++)
|
||||
if (!TrySaveWondercard(i, path))
|
||||
|
||||
public static string GetDefaultBcatFileName(Games game)
|
||||
{
|
||||
return game switch
|
||||
{
|
||||
Games.SWSH => "distribution_internet",
|
||||
Games.BDSP => "99",
|
||||
Games.PLA => "distribution_internet",
|
||||
Games.SCVI => "distribution_internet",
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
}
|
||||
|
||||
public bool TrySaveAllWondercards(string path)
|
||||
{
|
||||
if (WCList is null || WCList.Count == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
for (int i = 0; i < WCList.Count; i++)
|
||||
if (!TrySaveWondercard(i, path))
|
||||
return false;
|
||||
|
||||
public bool TrySaveWondercard(int index, string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
var wc = WCList!.ElementAt(index);
|
||||
File.WriteAllBytes(Path.Combine(path, ForgeWcFileName(wc)), wc.Data!);
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public ReadOnlySpan<byte> ConcatenateFiles()
|
||||
{
|
||||
var size = (int)Wondercard.GetSize(Game);
|
||||
var data = new byte[size * WCList!.Count];
|
||||
foreach (var el in WCList!.Select((wc, i) => new { i, wc }))
|
||||
el.wc.Data!.CopyTo(data, el.i * size);
|
||||
return data.AsSpan();
|
||||
}
|
||||
|
||||
public ReadOnlySpan<byte> ForgeMetaInfo(object? data = null)
|
||||
{
|
||||
if (data is not null && data.GetType() == typeof(byte[]))
|
||||
public bool TrySaveWondercard(int index, string path)
|
||||
{
|
||||
var fileName = System.Text.Encoding.UTF8.GetBytes(GetDefaultBcatFileName());
|
||||
var fileSize = (uint)((byte[])data).Length;
|
||||
var checksum = ChecksumCalculator.CalcReverseMD5((byte[])data);
|
||||
var metainfo = new byte[WCMetaInfoLength];
|
||||
fileName.CopyTo(metainfo, FileNameOffset);
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(metainfo.AsSpan(UnkOffset), uint.MaxValue);
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(metainfo.AsSpan(FileSizeOffset), fileSize);
|
||||
checksum.ToArray().CopyTo(metainfo, ChecksumOffset);
|
||||
return ForgeMetaInfoHeader(metainfo);
|
||||
try
|
||||
{
|
||||
var wc = WCList!.ElementAt(index);
|
||||
File.WriteAllBytes(Path.Combine(path, ForgeWcFileName(wc)), wc.Data!);
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
public ReadOnlySpan<byte> ConcatenateFiles()
|
||||
{
|
||||
var metainfo = new byte[WCMetaInfoLength * WCList!.Count];
|
||||
var size = (int)Wondercard.GetSize(Game);
|
||||
var data = new byte[size * WCList!.Count];
|
||||
foreach (var el in WCList!.Select((wc, i) => new { i, wc }))
|
||||
ForgeWcMetaInfo(el.wc).ToArray().CopyTo(metainfo, el.i * WCMetaInfoLength);
|
||||
return ForgeMetaInfoHeader(metainfo);
|
||||
el.wc.Data!.CopyTo(data, el.i * size);
|
||||
return data.AsSpan();
|
||||
}
|
||||
}
|
||||
|
||||
private static ReadOnlySpan<byte> ForgeWcMetaInfo(Wondercard wc)
|
||||
{
|
||||
var fileName = System.Text.Encoding.UTF8.GetBytes(ForgeWcFileName(wc));
|
||||
var fileSize = (uint)Wondercard.GetSize(wc.Game);
|
||||
var checksum = wc.CalcMetaChecksum();
|
||||
var data = new byte[WCMetaInfoLength];
|
||||
fileName.CopyTo(data, FileNameOffset);
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(data.AsSpan(UnkOffset), uint.MaxValue);
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(data.AsSpan(FileSizeOffset), fileSize);
|
||||
checksum.ToArray().CopyTo(data, ChecksumOffset);
|
||||
return data.AsSpan();
|
||||
}
|
||||
|
||||
private static string ForgeWcFileName(Wondercard wc)
|
||||
{
|
||||
var type = wc.Type!.ToString()!;
|
||||
var content = type.Equals("Pokemon") ? $"{((PokemonGift)wc.Content!).GetSpeciesName().Replace("\r", "")}" : type;
|
||||
var str = $"{wc.WCID:0000}_{content}";
|
||||
var sb = new System.Text.StringBuilder();
|
||||
foreach (char c in str)
|
||||
if (c != '\\' && c != '/' && c != ':' && c != '*' && c != '?' && c != '"' && c != '<' && c != '>' && c != '|')
|
||||
sb.Append(c);
|
||||
var _sb = new System.Text.StringBuilder();
|
||||
foreach (char c in sb.ToString().Normalize(NormalizationForm.FormD))
|
||||
if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
|
||||
_sb.Append(c);
|
||||
return _sb.ToString().ToLower();
|
||||
}
|
||||
|
||||
private static ReadOnlySpan<byte> ForgeMetaInfoHeader(ReadOnlySpan<byte> data)
|
||||
{
|
||||
uint header = 0x1;
|
||||
byte[] filesDotMeta = new byte[data.Length + MetaHeaderLength];
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(filesDotMeta.AsSpan(), header);
|
||||
data.ToArray().CopyTo(filesDotMeta, MetaHeaderLength);
|
||||
return filesDotMeta.AsSpan();
|
||||
}
|
||||
|
||||
public static Games GetCompatibleGamesFromWC(ReadOnlySpan<byte> data)
|
||||
{
|
||||
if (data.Length % (int)Wondercard.GetSize(Games.LGPE) == 0)
|
||||
return Games.LGPE;
|
||||
else if (data.Length % (int)Wondercard.GetSize(Games.SWSH) == 0)
|
||||
return Games.SWSH;
|
||||
else if (data.Length % (int)Wondercard.GetSize(Games.BDSP) == 0)
|
||||
return Games.BDSP;
|
||||
else if (data.Length % (int)Wondercard.GetSize(Games.PLA) == 0 && data[0x0F] != 0)
|
||||
return Games.PLA;
|
||||
else if (data.Length % (int)Wondercard.GetSize(Games.SCVI) == 0 && data[0x0F] == 0 && data[0x2C0] == 0)
|
||||
return Games.SCVI;
|
||||
else if (data.Length % (int)Wondercard.GetSize(Games.ZA) == 0 && data[0x2C0] != 0)
|
||||
return Games.ZA;
|
||||
else
|
||||
return Games.None;
|
||||
}
|
||||
|
||||
public static string GetDefaultBcatFolderName(Games game)
|
||||
{
|
||||
return game switch
|
||||
private string ForgeWcFileName(Wondercard wc)
|
||||
{
|
||||
Games.LGPE => "normal",
|
||||
Games.SWSH => "normal",
|
||||
Games.BDSP => "99",
|
||||
Games.PLA => "normal",
|
||||
Games.SCVI => "normal",
|
||||
Games.ZA => "normal",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(game)),
|
||||
};
|
||||
}
|
||||
var type = wc.Type!.ToString()!;
|
||||
var content = type.Equals("Pokemon") ? $"{((PokemonGift)wc.Content!).GetSpeciesName().Replace("\r","")}" : type;
|
||||
var str = $"{wc.WCID:0000}_{content}";
|
||||
var sb = new System.Text.StringBuilder();
|
||||
foreach (char c in str)
|
||||
if (c != '\\' && c != '/' && c != ':' && c != '*' && c != '?' && c != '"' && c != '<' && c != '>' && c != '|')
|
||||
sb.Append(c);
|
||||
var _sb = new System.Text.StringBuilder();
|
||||
foreach (char c in sb.ToString().Normalize(NormalizationForm.FormD))
|
||||
if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
|
||||
_sb.Append(c);
|
||||
return _sb.ToString().ToLower();
|
||||
}
|
||||
|
||||
public static string GetDefaultBcatFileName(Games game)
|
||||
{
|
||||
return game switch
|
||||
public ReadOnlySpan<byte> ForgeMetaInfo(object? data = null)
|
||||
{
|
||||
Games.SWSH => "distribution_internet",
|
||||
Games.BDSP => "99",
|
||||
Games.PLA => "distribution_internet",
|
||||
Games.SCVI => "distribution_internet",
|
||||
Games.ZA => "distribution_internet",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(game)),
|
||||
};
|
||||
}
|
||||
if (data is not null && data.GetType() == typeof(byte[]))
|
||||
{
|
||||
var fileName = System.Text.Encoding.UTF8.GetBytes(GetDefaultBcatFileName());
|
||||
var unknown = 0xFFFFFFFF;
|
||||
var fileSize = (uint)((byte[])data).Length;
|
||||
var checksum = ChecksumCalculator.CalcReverseMD5((byte[])data);
|
||||
var metainfo = new byte[WCMetaInfoLength];
|
||||
fileName.CopyTo(metainfo, FileNameOffset);
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(metainfo.AsSpan(UnkOffset), unknown);
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(metainfo.AsSpan(FileSizeOffset), fileSize);
|
||||
checksum.ToArray().CopyTo(metainfo, ChecksumOffset);
|
||||
return ForgeMetaInfoHeader(metainfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
var metainfo = new byte[WCMetaInfoLength * WCList!.Count];
|
||||
foreach (var el in WCList!.Select((wc, i) => new { i, wc }))
|
||||
ForgeWcMetaInfo(el.wc).ToArray().CopyTo(metainfo, el.i * WCMetaInfoLength);
|
||||
return ForgeMetaInfoHeader(metainfo);
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetShinyString(ShinyType type)
|
||||
{
|
||||
return type switch
|
||||
private ReadOnlySpan<byte> ForgeWcMetaInfo(Wondercard wc)
|
||||
{
|
||||
ShinyType.ShinyLocked => "Shiny Locked",
|
||||
ShinyType.ShinyPossible => "Shiny Standard Odds",
|
||||
ShinyType.ShinyHighOdds => "Shiny High Odds",
|
||||
ShinyType.ShinyForced => "Shiny Forced",
|
||||
ShinyType.ShinyTIDAbuse => "Shiny Possible (TID Abuse)",
|
||||
_ => throw new IndexOutOfRangeException()
|
||||
};
|
||||
}
|
||||
var fileName = System.Text.Encoding.UTF8.GetBytes(ForgeWcFileName(wc));
|
||||
var unknown = 0xFFFFFFFF;
|
||||
var fileSize = (uint)Wondercard.GetSize(Game);
|
||||
var checksum = wc.CalcMetaChecksum();
|
||||
var data = new byte[WCMetaInfoLength];
|
||||
fileName.CopyTo(data, FileNameOffset);
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(data.AsSpan(UnkOffset), unknown);
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(data.AsSpan(FileSizeOffset), fileSize);
|
||||
checksum.ToArray().CopyTo(data, ChecksumOffset);
|
||||
return data.AsSpan();
|
||||
}
|
||||
|
||||
private static string GetPIDString(PIDType type)
|
||||
{
|
||||
return type switch
|
||||
private ReadOnlySpan<byte> ForgeMetaInfoHeader(ReadOnlySpan<byte> data)
|
||||
{
|
||||
PIDType.FixedPID => "Fixed PID",
|
||||
PIDType.RandomPID => "Random PID",
|
||||
_ => throw new IndexOutOfRangeException()
|
||||
};
|
||||
uint header = 0x1;
|
||||
byte[] filesDotMeta = new byte[data.Length + MetaHeaderLength];
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(filesDotMeta.AsSpan(), header);
|
||||
data.ToArray().CopyTo(filesDotMeta, MetaHeaderLength);
|
||||
return filesDotMeta.AsSpan();
|
||||
}
|
||||
|
||||
private string GetShinyString(ShinyType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
ShinyType.ShinyLocked => "Shiny Locked",
|
||||
ShinyType.ShinyPossible => "Shiny Standard Odds",
|
||||
ShinyType.ShinyHighOdds => "Shiny High Odds",
|
||||
ShinyType.ShinyForced => "Shiny Forced",
|
||||
ShinyType.ShinyTIDAbuse => "Shiny Possible (TID Abuse)",
|
||||
_ => throw new IndexOutOfRangeException()
|
||||
};
|
||||
}
|
||||
|
||||
private string GetPIDString(PIDType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
PIDType.FixedPID => "Fixed PID",
|
||||
PIDType.RandomPID => "Random PID",
|
||||
_ => throw new IndexOutOfRangeException()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,76 +1,77 @@
|
|||
using System.Security.Cryptography;
|
||||
|
||||
//Credits for the CalcCcittFalse implementation to PNZEmil: https://gist.github.com/tijnkooijmans/10981093?permalink_comment_id=3996072#gistcomment-3996072
|
||||
namespace SwitchGiftDataManager.Core;
|
||||
|
||||
public static class ChecksumCalculator
|
||||
namespace SwitchGiftDataManager.Core
|
||||
{
|
||||
private const ushort InitialValue = 0xFFFF;
|
||||
|
||||
private static readonly ushort[] ccittFalseCrc16Table = {
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
|
||||
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
|
||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
|
||||
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
|
||||
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
|
||||
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
|
||||
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
|
||||
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
|
||||
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
|
||||
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
|
||||
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
|
||||
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
|
||||
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
|
||||
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
|
||||
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
|
||||
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
|
||||
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
|
||||
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
|
||||
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
|
||||
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
|
||||
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
|
||||
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
|
||||
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
|
||||
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
|
||||
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
|
||||
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
|
||||
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
|
||||
};
|
||||
|
||||
public static ushort CalcCcittFalse(ReadOnlySpan<byte> bytes)
|
||||
public static class ChecksumCalculator
|
||||
{
|
||||
var crc16 = InitialValue;
|
||||
private const ushort InitialValue = 0xFFFF;
|
||||
|
||||
var length = bytes.Length;
|
||||
var byteIndex = 0;
|
||||
while (length-- > 0)
|
||||
private static readonly ushort[] ccittFalseCrc16Table = {
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
|
||||
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
|
||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
|
||||
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
|
||||
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
|
||||
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
|
||||
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
|
||||
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
|
||||
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
|
||||
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
|
||||
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
|
||||
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
|
||||
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
|
||||
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
|
||||
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
|
||||
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
|
||||
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
|
||||
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
|
||||
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
|
||||
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
|
||||
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
|
||||
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
|
||||
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
|
||||
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
|
||||
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
|
||||
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
|
||||
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
|
||||
};
|
||||
|
||||
public static ushort CalcCcittFalse(ReadOnlySpan<byte> bytes)
|
||||
{
|
||||
var tableIndex = crc16 >> 8 ^ bytes[byteIndex++];
|
||||
crc16 = (ushort)(crc16 << 8 ^ ccittFalseCrc16Table[tableIndex]);
|
||||
var crc16 = InitialValue;
|
||||
|
||||
var length = bytes.Length;
|
||||
var byteIndex = 0;
|
||||
while (length-- > 0)
|
||||
{
|
||||
var tableIndex = crc16 >> 8 ^ bytes[byteIndex++];
|
||||
crc16 = (ushort)(crc16 << 8 ^ ccittFalseCrc16Table[tableIndex]);
|
||||
}
|
||||
|
||||
return crc16;
|
||||
}
|
||||
|
||||
return crc16;
|
||||
}
|
||||
public static Span<byte> CalcReverseMD5(byte[] data)
|
||||
{
|
||||
var md5 = MD5.Create().ComputeHash(data);
|
||||
|
||||
public static Span<byte> CalcReverseMD5(byte[] data)
|
||||
{
|
||||
var md5 = MD5.Create().ComputeHash(data);
|
||||
var tmp1 = md5.AsSpan((md5.Length / 2)..);
|
||||
tmp1.Reverse();
|
||||
|
||||
var tmp1 = md5.AsSpan((md5.Length / 2)..);
|
||||
tmp1.Reverse();
|
||||
var tmp2 = md5.AsSpan(0..(md5.Length / 2));
|
||||
tmp2.Reverse();
|
||||
|
||||
var b = new byte[md5.Length];
|
||||
tmp2.ToArray().CopyTo(b, 0);
|
||||
tmp1.ToArray().CopyTo(b, tmp1.Length);
|
||||
|
||||
var tmp2 = md5.AsSpan(0..(md5.Length / 2));
|
||||
tmp2.Reverse();
|
||||
|
||||
var b = new byte[md5.Length];
|
||||
tmp2.ToArray().CopyTo(b, 0);
|
||||
tmp1.ToArray().CopyTo(b, tmp1.Length);
|
||||
|
||||
return b.AsSpan();
|
||||
return b.AsSpan();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,123 +1,111 @@
|
|||
using Enums;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace SwitchGiftDataManager.Core;
|
||||
|
||||
public class OtherGift
|
||||
namespace SwitchGiftDataManager.Core
|
||||
{
|
||||
public object? Type { get; set; }
|
||||
public ushort Item { get; set; }
|
||||
public uint Quantity { get; set; }
|
||||
public uint Opt { get; set; }
|
||||
|
||||
public string GetItemName() => GetItemName(Item, Type!, Opt);
|
||||
|
||||
public static string GetItemName(ushort id, object type, uint opt = 0)
|
||||
public class OtherGift
|
||||
{
|
||||
var str = "";
|
||||
public object? Type { get; set; }
|
||||
public ushort Item { get; set; }
|
||||
public uint Quantity { get; set; }
|
||||
public ushort Opt { get; set; }
|
||||
|
||||
if (type.GetType() == typeof(GiftType7))
|
||||
public string GetItemName() => GetItemName(Item, Type!, Opt);
|
||||
|
||||
public static string GetItemName(ushort id, object type, ushort opt = 0)
|
||||
{
|
||||
if ((GiftType7)type is GiftType7.Item)
|
||||
str = Properties.Resources.Items.Split(new String[] { "\n" }, StringSplitOptions.None)[id];
|
||||
else
|
||||
str = ((GiftType7)type).ToString();
|
||||
}
|
||||
else if (type.GetType() == typeof(GiftType8))
|
||||
{
|
||||
if ((GiftType8)type is GiftType8.Item)
|
||||
str = Properties.Resources.Items.Split(new String[] { "\n" }, StringSplitOptions.None)[id];
|
||||
else if ((GiftType8)type is GiftType8.Clothing)
|
||||
var str = "";
|
||||
|
||||
if (type.GetType() == typeof(GiftType7))
|
||||
{
|
||||
if ((GiftType7)type is GiftType7.Item)
|
||||
str = Properties.Resources.Items.Split(new String[] { "\n" }, StringSplitOptions.None)[id];
|
||||
else
|
||||
str = ((GiftType7)type).ToString();
|
||||
}
|
||||
else if (type.GetType() == typeof(GiftType8))
|
||||
{
|
||||
if ((GiftType8)type is GiftType8.Item)
|
||||
str = Properties.Resources.Items.Split(new String[] { "\n" }, StringSplitOptions.None)[id];
|
||||
else if ((GiftType8)type is GiftType8.Clothing)
|
||||
{
|
||||
var category = (ClothingType8)id;
|
||||
var description = category switch
|
||||
{
|
||||
ClothingType8.Glasses => Properties.Resources.SWSHClothingGlasses.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8.Hats => Properties.Resources.SWSHClothingHats.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8.Jackets => Properties.Resources.SWSHClothingJackets.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8.Tops => Properties.Resources.SWSHClothingTops.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8.Bags => Properties.Resources.SWSHClothingBags.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8.Gloves => Properties.Resources.SWSHClothingGloves.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8.Bottoms => Properties.Resources.SWSHClothingBottoms.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8.Legwear => Properties.Resources.SWSHClothingLegwear.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8.Shoes => Properties.Resources.SWSHClothingShoes.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
str = $"[{category}] {description}";
|
||||
}
|
||||
else
|
||||
str = ((GiftType8)type).ToString();
|
||||
}
|
||||
else if(type.GetType() == typeof(GiftType8B))
|
||||
{
|
||||
if ((GiftType8B)type is GiftType8B.Item)
|
||||
str = Properties.Resources.Items.Split(new String[] { "\n" }, StringSplitOptions.None)[id];
|
||||
else if ((GiftType8B)type is GiftType8B.Clothing)
|
||||
str = Properties.Resources.BDSPClothing.Split(new String[] { "\n" }, StringSplitOptions.None)[id];
|
||||
else if ((GiftType8B)type is GiftType8B.Underground)
|
||||
str = Properties.Resources.UndergroundItems.Split(new String[] { "\n" }, StringSplitOptions.None)[id];
|
||||
else
|
||||
str = ((GiftType8B)type).ToString();
|
||||
}
|
||||
else if (type.GetType() == typeof(GiftType8A))
|
||||
{
|
||||
if ((GiftType8A)type is GiftType8A.Item)
|
||||
str = Properties.Resources.Items.Split(new String[] { "\n" }, StringSplitOptions.None)[id];
|
||||
else if ((GiftType8A)type is GiftType8A.Clothing)
|
||||
{
|
||||
var category = (ClothingType8)id;
|
||||
var category = (ClothingType8A)id;
|
||||
var description = category switch
|
||||
{
|
||||
ClothingType8.Glasses => Properties.Resources.SWSHClothingGlasses.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8.Hats => Properties.Resources.SWSHClothingHats.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8.Jackets => Properties.Resources.SWSHClothingJackets.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8.Tops => Properties.Resources.SWSHClothingTops.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8.Bags => Properties.Resources.SWSHClothingBags.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8.Gloves => Properties.Resources.SWSHClothingGloves.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8.Bottoms => Properties.Resources.SWSHClothingBottoms.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8.Legwear => Properties.Resources.SWSHClothingLegwear.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8.Footwear => Properties.Resources.SWSHClothingShoes.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8A.Heads => Properties.Resources.PLAClothingHeads.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8A.Tops => Properties.Resources.PLAClothingTops.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8A.Bottoms => Properties.Resources.PLAClothingBottoms.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8A.Outfit => "",
|
||||
ClothingType8A.Shoes => "",
|
||||
ClothingType8A.Glasses => "",
|
||||
ClothingType8A.Eyes => "",
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
if(string.IsNullOrWhiteSpace(description))
|
||||
description = $"{opt:X4}";
|
||||
str = $"[{category}] {description}";
|
||||
}
|
||||
else
|
||||
str = ((GiftType8)type).ToString();
|
||||
}
|
||||
else if(type.GetType() == typeof(GiftType8B))
|
||||
{
|
||||
if ((GiftType8B)type is GiftType8B.Item)
|
||||
str = Properties.Resources.Items.Split(new String[] { "\n" }, StringSplitOptions.None)[id];
|
||||
else if ((GiftType8B)type is GiftType8B.Clothing)
|
||||
str = Properties.Resources.BDSPClothing.Split(new String[] { "\n" }, StringSplitOptions.None)[id];
|
||||
else if ((GiftType8B)type is GiftType8B.Underground)
|
||||
str = Properties.Resources.UndergroundItems.Split(new String[] { "\n" }, StringSplitOptions.None)[id];
|
||||
else
|
||||
str = ((GiftType8B)type).ToString();
|
||||
}
|
||||
else if (type.GetType() == typeof(GiftType8A))
|
||||
{
|
||||
if ((GiftType8A)type is GiftType8A.Item)
|
||||
str = Properties.Resources.Items.Split(new String[] { "\n" }, StringSplitOptions.None)[id];
|
||||
else if ((GiftType8A)type is GiftType8A.Clothing)
|
||||
else
|
||||
str = ((GiftType8A)type).ToString();
|
||||
}
|
||||
else if (type.GetType() == typeof(GiftType9))
|
||||
{
|
||||
var category = (ClothingType8A)id;
|
||||
var description = category switch
|
||||
if ((GiftType9)type is GiftType9.Item)
|
||||
str = Properties.Resources.Items.Split(new String[] { "\n" }, StringSplitOptions.None)[id];
|
||||
else if ((GiftType9)type is GiftType9.Clothing)
|
||||
{
|
||||
ClothingType8A.Headwear => Properties.Resources.PLAClothingHeads.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8A.Tops => Properties.Resources.PLAClothingTops.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8A.Bottoms => Properties.Resources.PLAClothingBottoms.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType8A.Outfit => "",
|
||||
ClothingType8A.Footwear => "",
|
||||
ClothingType8A.Glasses => "",
|
||||
ClothingType8A.Eyewear => "",
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
if(string.IsNullOrWhiteSpace(description))
|
||||
description = $"{opt:X4}";
|
||||
str = $"[{category}] {description}";
|
||||
var category = (ClothingType9)id;
|
||||
var description = category switch
|
||||
{
|
||||
ClothingType9.Uniform => Properties.Resources.SCVIClothingBags.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
ClothingType9.Bags => Properties.Resources.SCVIClothingBags.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
|
||||
_ => "",
|
||||
};
|
||||
if (string.IsNullOrWhiteSpace(description))
|
||||
description = $"{opt:X4}";
|
||||
//str = $"[{category}] {description}";
|
||||
str = $"{description}";
|
||||
}
|
||||
else
|
||||
str = ((GiftType9)type).ToString();
|
||||
}
|
||||
else
|
||||
str = ((GiftType8A)type).ToString();
|
||||
}
|
||||
else if (type.GetType() == typeof(GiftType9))
|
||||
{
|
||||
if ((GiftType9)type is GiftType9.Item)
|
||||
str = Properties.Resources.Items.Split(new String[] { "\n" }, StringSplitOptions.None)[id];
|
||||
else if ((GiftType9)type is GiftType9.Clothing)
|
||||
{
|
||||
var category = (ClothingType9)id;
|
||||
var description = Properties.Resources.SCVIClothings.Split(new String[] { "\n" }, StringSplitOptions.None)[opt];
|
||||
if (string.IsNullOrWhiteSpace(description))
|
||||
description = $"{opt:X4}";
|
||||
str = $"[{category.ToString().Replace("Uniform", "Clothing")}] {description}";
|
||||
}
|
||||
else
|
||||
str = ((GiftType9)type).ToString();
|
||||
}
|
||||
else if (type.GetType() == typeof(GiftType9A))
|
||||
{
|
||||
if ((GiftType9A)type is GiftType9A.Item or GiftType9A.Flag)
|
||||
str = Properties.Resources.Items.Split(new String[] { "\n" }, StringSplitOptions.None)[id];
|
||||
else if ((GiftType9A)type is GiftType9A.Clothing)
|
||||
{
|
||||
if (!Clothing9A.TryGetValue(opt, out str))
|
||||
str = "Unknown Clothing Item";
|
||||
}
|
||||
else
|
||||
{
|
||||
str = ((GiftType9A)type).ToString();
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
private static Dictionary<uint, string> Clothing9A = new()
|
||||
{
|
||||
{ 0x2E1937, "Trench Coat and Pants Set (Beige)" },
|
||||
};
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,32 +1,39 @@
|
|||
using Enums;
|
||||
|
||||
namespace SwitchGiftDataManager.Core;
|
||||
|
||||
public class PokemonGift
|
||||
namespace SwitchGiftDataManager.Core
|
||||
{
|
||||
public ushort Species { get; set; }
|
||||
public uint PID { get; set; }
|
||||
public uint TID { get; set; }
|
||||
public uint SID { get; set; }
|
||||
public ShinyType ShinyType { get; set; }
|
||||
public PIDType PIDType { get; set; }
|
||||
|
||||
public string GetSpeciesName() => GetSpeciesName(Species);
|
||||
|
||||
public bool IsShiny() => ShinyType switch
|
||||
public class PokemonGift
|
||||
{
|
||||
ShinyType.ShinyForced => true,
|
||||
ShinyType.ShinyPossible => (PID != 0 && TID != 0 && SID != 0) && IsShiny(PID, TID, SID),
|
||||
_ => false,
|
||||
};
|
||||
public ushort Species { get; set; }
|
||||
public uint PID { get; set; }
|
||||
public uint TID { get; set; }
|
||||
public uint SID { get; set; }
|
||||
public ShinyType ShinyType { get; set; }
|
||||
public PIDType PIDType { get; set; }
|
||||
|
||||
public static string GetSpeciesName(uint species) => Properties.Resources.Species.Split(["\n"], StringSplitOptions.None)[species];
|
||||
public string GetSpeciesName() => GetSpeciesName(Species);
|
||||
|
||||
public static bool IsShiny(uint pid, uint tid, uint sid) => (sid != 0 || tid != 0) && (sid ^ tid ^ (pid >> 16) ^ (pid & 0xFFFF)) < 16;
|
||||
public bool IsShiny()
|
||||
{
|
||||
if (ShinyType is ShinyType.ShinyForced)
|
||||
return true;
|
||||
else if (ShinyType is ShinyType.ShinyPossible && PID != 0 && TID != 0 && SID != 0)
|
||||
return IsShiny(PID, TID, SID);
|
||||
|
||||
public static bool IsTIDAbusePossible(uint tid, uint sid, PIDType type) => type switch
|
||||
{
|
||||
PIDType.FixedPID => tid == 0 && sid == 0,
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static string GetSpeciesName(uint species) => Properties.Resources.Species.Split(new string[] { "\n" }, StringSplitOptions.None)[species].Replace(",", "");
|
||||
|
||||
public static bool IsShiny(uint pid, uint tid, uint sid) => sid != 0 || tid != 0 ? (sid ^ tid ^ (pid >> 16) ^ (pid & 0xFFFF)) < 16 : false;
|
||||
|
||||
public static bool IsTIDAbusePossible(uint tid, uint sid, PIDType type)
|
||||
{
|
||||
if (type is PIDType.FixedPID)
|
||||
if (tid == 0)
|
||||
if (sid == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,139 +1,131 @@
|
|||
using System.Buffers.Binary;
|
||||
using Enums;
|
||||
|
||||
namespace SwitchGiftDataManager.Core;
|
||||
|
||||
public class WA8 : Wondercard
|
||||
namespace SwitchGiftDataManager.Core
|
||||
{
|
||||
private const int WondercardIDOffset = 0x08;
|
||||
private const int FlagOffset = 0x0E;
|
||||
private const int GiftTypeOffset = 0x0F;
|
||||
private const int ItemOffset = 0x18;
|
||||
private const int QuantityOffset = 0x1A;
|
||||
private const int ClothingOffset = 0x1C;
|
||||
private const int TIDOffset = 0x18;
|
||||
private const int SIDOffset = 0x1A;
|
||||
private const int PIDOffset = 0x24;
|
||||
private const int SpeciesOffset = 0x238;
|
||||
private const int ShinyTypeOffset = 0x240;
|
||||
private const int ChecksumOffset = 0x2C4;
|
||||
|
||||
public WA8(ReadOnlySpan<byte> data) : base(data)
|
||||
internal class WA8 : Wondercard
|
||||
{
|
||||
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
|
||||
IsRepeatable = (Data![FlagOffset] & 1) == 0;
|
||||
Type = (GiftType8A)Data![GiftTypeOffset];
|
||||
Content = Type switch
|
||||
{
|
||||
GiftType8A.Pokemon => GetPokemon(),
|
||||
_ => GetItems(),
|
||||
};
|
||||
}
|
||||
private const int WondercardIDOffset = 0x08;
|
||||
private const int GiftTypeOffset = 0x0F;
|
||||
private const int ItemOffset = 0x18;
|
||||
private const int QuantityOffset = 0x1A;
|
||||
private const int ClothingOffset = 0x1C;
|
||||
private const int TIDOffset = 0x18;
|
||||
private const int SIDOffset = 0x1A;
|
||||
private const int PIDOffset = 0x24;
|
||||
private const int SpeciesOffset = 0x238;
|
||||
private const int ShinyTypeOffset = 0x240;
|
||||
private const int ChecksumOffset = 0x2C4;
|
||||
|
||||
private PokemonGift GetPokemon()
|
||||
{
|
||||
var species = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(SpeciesOffset));
|
||||
var pid = BinaryPrimitives.ReadUInt32LittleEndian(Data.AsSpan(PIDOffset));
|
||||
var tid = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(TIDOffset));
|
||||
var sid = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(SIDOffset));
|
||||
var test = (ShinyType8)Data![ShinyTypeOffset];
|
||||
var pidtype = (ShinyType8)Data![ShinyTypeOffset] switch
|
||||
public WA8(ReadOnlySpan<byte> data) : base(data)
|
||||
{
|
||||
ShinyType8.ShinyLocked => PIDType.RandomPID,
|
||||
ShinyType8.ShinyRandom => PIDType.RandomPID,
|
||||
ShinyType8.ShinyStar => PIDType.FixedPID,
|
||||
ShinyType8.ShinySquare => PIDType.FixedPID,
|
||||
ShinyType8.Fixed => PIDType.FixedPID,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
var shinytype = (ShinyType8)Data![ShinyTypeOffset] switch
|
||||
{
|
||||
ShinyType8.ShinyLocked => ShinyType.ShinyLocked,
|
||||
ShinyType8.ShinyRandom => ShinyType.ShinyPossible,
|
||||
ShinyType8.ShinyStar or ShinyType8.ShinySquare => ShinyType.ShinyForced,
|
||||
ShinyType8.Fixed => PokemonGift.IsShiny(pid, tid, sid) ? ShinyType.ShinyForced :
|
||||
PokemonGift.IsTIDAbusePossible(tid, sid, pidtype) ? ShinyType.ShinyTIDAbuse : ShinyType.ShinyLocked,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
return new PokemonGift
|
||||
{
|
||||
Species = species,
|
||||
PID = pid,
|
||||
TID = tid,
|
||||
SID = sid,
|
||||
ShinyType = shinytype,
|
||||
PIDType = pidtype,
|
||||
};
|
||||
}
|
||||
|
||||
private List<OtherGift> GetItems()
|
||||
{
|
||||
List<OtherGift> items = new();
|
||||
for (int i = 0; i < MaxItemCount; i++)
|
||||
{
|
||||
ushort item = 0;
|
||||
ushort quantity = 0;
|
||||
ushort opt = 0;
|
||||
var type = (GiftType8A)Type!;
|
||||
|
||||
if (type is GiftType8A.Clothing)
|
||||
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
|
||||
Type = (GiftType8A)Data![GiftTypeOffset];
|
||||
Content = Type switch
|
||||
{
|
||||
item = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ItemOffset + (0x08 * i)));
|
||||
opt = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ClothingOffset + (0x08 * i)));
|
||||
}
|
||||
else
|
||||
{
|
||||
item = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ItemOffset + (0x04 * i)));
|
||||
quantity = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(QuantityOffset + (0x04 * i)));
|
||||
}
|
||||
GiftType8A.Pokemon => GetPokemon(),
|
||||
_ => GetItems(),
|
||||
};
|
||||
}
|
||||
|
||||
var gift = new OtherGift
|
||||
private PokemonGift GetPokemon()
|
||||
{
|
||||
var species = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(SpeciesOffset));
|
||||
var pid = BinaryPrimitives.ReadUInt32LittleEndian(Data.AsSpan(PIDOffset));
|
||||
var tid = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(TIDOffset));
|
||||
var sid = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(SIDOffset));
|
||||
var test = (ShinyType8)Data![ShinyTypeOffset];
|
||||
var pidtype = (ShinyType8)Data![ShinyTypeOffset] switch
|
||||
{
|
||||
Type = type,
|
||||
Item = item,
|
||||
Quantity = quantity,
|
||||
Opt = opt,
|
||||
ShinyType8.ShinyLocked => PIDType.RandomPID,
|
||||
ShinyType8.ShinyRandom => PIDType.RandomPID,
|
||||
ShinyType8.ShinyStar => PIDType.FixedPID,
|
||||
ShinyType8.ShinySquare => PIDType.FixedPID,
|
||||
ShinyType8.Fixed => PIDType.FixedPID,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
var shinytype = (ShinyType8)Data![ShinyTypeOffset] switch
|
||||
{
|
||||
ShinyType8.ShinyLocked => ShinyType.ShinyLocked,
|
||||
ShinyType8.ShinyRandom => ShinyType.ShinyPossible,
|
||||
ShinyType8.ShinyStar or ShinyType8.ShinySquare => ShinyType.ShinyForced,
|
||||
ShinyType8.Fixed => PokemonGift.IsShiny(pid, tid, sid) ? ShinyType.ShinyForced :
|
||||
PokemonGift.IsTIDAbusePossible(tid, sid, pidtype) ? ShinyType.ShinyTIDAbuse : ShinyType.ShinyLocked,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
if ((type is not GiftType8A.Clothing && gift.Item != ushort.MinValue) || (type is GiftType8A.Clothing && opt != ushort.MaxValue))
|
||||
items.Add(gift);
|
||||
return new PokemonGift
|
||||
{
|
||||
Species = species,
|
||||
PID = pid,
|
||||
TID = tid,
|
||||
SID = sid,
|
||||
ShinyType = shinytype,
|
||||
PIDType = pidtype,
|
||||
};
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
public override bool IsChecksumValid()
|
||||
{
|
||||
if (Data is not null)
|
||||
private List<OtherGift> GetItems()
|
||||
{
|
||||
var oldChecksum = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ChecksumOffset));
|
||||
var span = Data.ToArray().AsSpan();
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(span[ChecksumOffset..], 0x0);
|
||||
var newchecksum = ChecksumCalculator.CalcCcittFalse(span);
|
||||
if (oldChecksum == newchecksum)
|
||||
return true;
|
||||
List<OtherGift> items = new();
|
||||
for (int i = 0; i < MaxItemCount; i++)
|
||||
{
|
||||
ushort item = 0;
|
||||
ushort quantity = 0;
|
||||
ushort opt = 0;
|
||||
var type = (GiftType8A)Type!;
|
||||
|
||||
if (type is GiftType8A.Clothing)
|
||||
{
|
||||
item = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ItemOffset + (0x08 * i)));
|
||||
opt = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ClothingOffset + (0x08 * i)));
|
||||
}
|
||||
else
|
||||
{
|
||||
item = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ItemOffset + (0x04 * i)));
|
||||
quantity = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(QuantityOffset + (0x04 * i)));
|
||||
}
|
||||
|
||||
var gift = new OtherGift
|
||||
{
|
||||
Type = type,
|
||||
Item = item,
|
||||
Quantity = quantity,
|
||||
Opt = opt,
|
||||
};
|
||||
|
||||
if ((type is not GiftType8A.Clothing && gift.Item != 0x00) || (type is GiftType8A.Clothing && opt != 0xFFFF))
|
||||
items.Add(gift);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void UpdateChecksum()
|
||||
{
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(ChecksumOffset), 0x0);
|
||||
var checksum = ChecksumCalculator.CalcCcittFalse(Data.AsSpan());
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(ChecksumOffset), checksum);
|
||||
}
|
||||
public override bool IsChecksumValid()
|
||||
{
|
||||
if (Data is not null)
|
||||
{
|
||||
var oldChecksum = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ChecksumOffset));
|
||||
var span = Data.ToArray().AsSpan();
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(span[ChecksumOffset..], 0x0);
|
||||
var newchecksum = ChecksumCalculator.CalcCcittFalse(span);
|
||||
if (oldChecksum == newchecksum)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void SetID(ushort wcid)
|
||||
{
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(WondercardIDOffset), wcid);
|
||||
WCID = wcid;
|
||||
UpdateChecksum();
|
||||
}
|
||||
public override void UpdateChecksum()
|
||||
{
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(ChecksumOffset), 0x0);
|
||||
var checksum = ChecksumCalculator.CalcCcittFalse(Data.AsSpan());
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(ChecksumOffset), checksum);
|
||||
}
|
||||
|
||||
public override void SetRepeatable(bool repeatable)
|
||||
{
|
||||
Data![FlagOffset] = (byte)((Data![FlagOffset] & ~1) | (repeatable ? 0 : 1));
|
||||
IsRepeatable = repeatable;
|
||||
UpdateChecksum();
|
||||
public override void SetID(ushort wcid)
|
||||
{
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(WondercardIDOffset), wcid);
|
||||
WCID = wcid;
|
||||
UpdateChecksum();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,142 +0,0 @@
|
|||
using System.Buffers.Binary;
|
||||
using Enums;
|
||||
|
||||
namespace SwitchGiftDataManager.Core;
|
||||
|
||||
public class WA9 : Wondercard
|
||||
{
|
||||
private const int WondercardIDOffset = 0x08;
|
||||
private const int FlagOffset = 0x10;
|
||||
private const int GiftTypeOffset = 0x11;
|
||||
private const int ItemOffset = 0x18;
|
||||
private const int QuantityOffset = 0x1A;
|
||||
private const int TIDOffset = 0x18;
|
||||
private const int SIDOffset = 0x1A;
|
||||
private const int PIDOffset = 0x24;
|
||||
private const int FlagStringOffset = 0x28;
|
||||
private const int FlagItemOffset = 0x6C;
|
||||
private const int FlagItemQuantityOffset = 0x6E;
|
||||
private const int SpeciesOffset = 0x270;
|
||||
private const int ShinyTypeOffset = 0x278;
|
||||
private const int ChecksumOffset = 0x2C0;
|
||||
|
||||
public WA9(ReadOnlySpan<byte> data) : base(data)
|
||||
{
|
||||
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
|
||||
IsRepeatable = (Data![FlagOffset] & 1) == 0;
|
||||
Type = (GiftType9A)Data![GiftTypeOffset];
|
||||
Content = Type switch
|
||||
{
|
||||
GiftType9A.Pokemon => GetPokemon(),
|
||||
_ => GetItems(),
|
||||
};
|
||||
}
|
||||
|
||||
private PokemonGift GetPokemon()
|
||||
{
|
||||
var species = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(SpeciesOffset));
|
||||
var pid = BinaryPrimitives.ReadUInt32LittleEndian(Data.AsSpan(PIDOffset));
|
||||
var tid = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(TIDOffset));
|
||||
var sid = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(SIDOffset));
|
||||
var pidtype = (ShinyType9)Data![ShinyTypeOffset] switch
|
||||
{
|
||||
ShinyType9.ShinyLocked => PIDType.RandomPID,
|
||||
ShinyType9.ShinyRandom => PIDType.RandomPID,
|
||||
ShinyType9.ShinyStar => PIDType.FixedPID,
|
||||
ShinyType9.ShinySquare => PIDType.FixedPID,
|
||||
ShinyType9.Fixed => PIDType.FixedPID,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
var shinytype = (ShinyType9)Data![ShinyTypeOffset] switch
|
||||
{
|
||||
ShinyType9.ShinyLocked => ShinyType.ShinyLocked,
|
||||
ShinyType9.ShinyRandom => ShinyType.ShinyPossible,
|
||||
ShinyType9.ShinyStar or ShinyType9.ShinySquare => ShinyType.ShinyForced,
|
||||
ShinyType9.Fixed => PokemonGift.IsShiny(pid, tid, sid) ? ShinyType.ShinyForced :
|
||||
PokemonGift.IsTIDAbusePossible(tid, sid, pidtype) ? ShinyType.ShinyTIDAbuse : ShinyType.ShinyLocked,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
return new PokemonGift
|
||||
{
|
||||
Species = species,
|
||||
PID = pid,
|
||||
TID = tid,
|
||||
SID = sid,
|
||||
ShinyType = shinytype,
|
||||
PIDType = pidtype,
|
||||
};
|
||||
}
|
||||
|
||||
private List<OtherGift> GetItems()
|
||||
{
|
||||
List<OtherGift> items = new();
|
||||
for (int i = 0; i < MaxItemCount; i++)
|
||||
{
|
||||
ushort item = 0;
|
||||
uint quantity = 0;
|
||||
uint opt = 0;
|
||||
var type = (GiftType9A)Type!;
|
||||
|
||||
if (type is GiftType9A.Clothing)
|
||||
{
|
||||
item = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ItemOffset + (0x04 * i)));
|
||||
opt = BinaryPrimitives.ReadUInt32LittleEndian(Data.AsSpan(ItemOffset + (0x04 * i)));
|
||||
}
|
||||
else
|
||||
{
|
||||
item = type is GiftType9A.Flag ? BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(FlagItemOffset + (0x04 * i))) :
|
||||
BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ItemOffset + (0x04 * i)));
|
||||
quantity = type is GiftType9A.Flag ? BinaryPrimitives.ReadUInt32LittleEndian(Data.AsSpan(FlagItemQuantityOffset + (0x04 * i))) :
|
||||
BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(QuantityOffset + (0x04 * i)));
|
||||
}
|
||||
|
||||
var gift = new OtherGift
|
||||
{
|
||||
Type = type,
|
||||
Item = item,
|
||||
Quantity = quantity,
|
||||
Opt = opt,
|
||||
};
|
||||
|
||||
if ((type is not GiftType9A.Clothing && gift.Item != ushort.MinValue) || (type is GiftType9A.Clothing && item != ushort.MaxValue))
|
||||
items.Add(gift);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
public override bool IsChecksumValid()
|
||||
{
|
||||
if (Data is not null)
|
||||
{
|
||||
var oldChecksum = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ChecksumOffset));
|
||||
var span = Data.ToArray().AsSpan();
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(span[ChecksumOffset..], 0x0);
|
||||
var newchecksum = ChecksumCalculator.CalcCcittFalse(span);
|
||||
if (oldChecksum == newchecksum)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void UpdateChecksum()
|
||||
{
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(ChecksumOffset), 0x0);
|
||||
var checksum = ChecksumCalculator.CalcCcittFalse(Data.AsSpan());
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(ChecksumOffset), checksum);
|
||||
}
|
||||
|
||||
public override void SetID(ushort wcid)
|
||||
{
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(WondercardIDOffset), wcid);
|
||||
WCID = wcid;
|
||||
UpdateChecksum();
|
||||
}
|
||||
|
||||
public override void SetRepeatable(bool repeatable)
|
||||
{
|
||||
Data![FlagOffset] = (byte)((Data![FlagOffset] & ~1) | (repeatable ? 0 : 1));
|
||||
IsRepeatable = repeatable;
|
||||
UpdateChecksum();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,123 +1,115 @@
|
|||
using System.Buffers.Binary;
|
||||
using Enums;
|
||||
|
||||
namespace SwitchGiftDataManager.Core;
|
||||
|
||||
public class WB7 : Wondercard
|
||||
namespace SwitchGiftDataManager.Core
|
||||
{
|
||||
private const int WondercardIDOffset = 0x208;
|
||||
private const int GiftTypeOffset = 0x259;
|
||||
private const int FlagOffset = 0x25A;
|
||||
private const int ItemOffset = 0x270;
|
||||
private const int QuantityOffset = 0x272;
|
||||
private const int TIDOffset = 0x270;
|
||||
private const int SIDOffset = 0x272;
|
||||
private const int SpeciesOffset = 0x28A;
|
||||
private const int ShinyTypeOffset = 0x2AB;
|
||||
private const int PIDOffset = 0x2DC;
|
||||
private const int ChecksumOffset = 0x202;
|
||||
|
||||
public WB7(ReadOnlySpan<byte> data) : base(data)
|
||||
internal class WB7 : Wondercard
|
||||
{
|
||||
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
|
||||
IsRepeatable = (Data![FlagOffset] & 1) == 0;
|
||||
Type = (GiftType7)Data![GiftTypeOffset];
|
||||
Content = Type switch
|
||||
{
|
||||
GiftType7.Pokemon => GetPokemon(),
|
||||
_ => GetItems(),
|
||||
};
|
||||
}
|
||||
private const int WondercardIDOffset = 0x208;
|
||||
private const int GiftTypeOffset = 0x259;
|
||||
private const int ItemOffset = 0x270;
|
||||
private const int QuantityOffset = 0x272;
|
||||
private const int TIDOffset = 0x270;
|
||||
private const int SIDOffset = 0x272;
|
||||
private const int SpeciesOffset = 0x28A;
|
||||
private const int ShinyTypeOffset = 0x2AB;
|
||||
private const int PIDOffset = 0xD4;
|
||||
private const int ChecksumOffset = 0x202;
|
||||
|
||||
private PokemonGift GetPokemon()
|
||||
{
|
||||
var species = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(SpeciesOffset));
|
||||
var pid = BinaryPrimitives.ReadUInt32LittleEndian(Data.AsSpan(PIDOffset));
|
||||
var tid = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(TIDOffset));
|
||||
var sid = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(SIDOffset));
|
||||
var pidtype = (ShinyType7)Data![ShinyTypeOffset] switch
|
||||
public WB7(ReadOnlySpan<byte> data) : base(data)
|
||||
{
|
||||
ShinyType7.Fixed => PIDType.FixedPID,
|
||||
ShinyType7.ShinyRandom => PIDType.RandomPID,
|
||||
ShinyType7.Shiny => PIDType.RandomPID,
|
||||
ShinyType7.ShinyLocked => PIDType.RandomPID,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
var shinytype = (ShinyType7)Data![ShinyTypeOffset] switch
|
||||
{
|
||||
ShinyType7.Fixed => PokemonGift.IsShiny(pid, tid, sid) ? ShinyType.ShinyForced :
|
||||
PokemonGift.IsTIDAbusePossible(tid, sid, pidtype) ? ShinyType.ShinyTIDAbuse : ShinyType.ShinyLocked,
|
||||
ShinyType7.ShinyRandom => ShinyType.ShinyPossible,
|
||||
ShinyType7.Shiny => ShinyType.ShinyForced,
|
||||
ShinyType7.ShinyLocked => ShinyType.ShinyLocked,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
return new PokemonGift
|
||||
{
|
||||
Species = species,
|
||||
PID = pid,
|
||||
TID = tid,
|
||||
SID = sid,
|
||||
ShinyType = shinytype,
|
||||
PIDType = pidtype,
|
||||
};
|
||||
}
|
||||
|
||||
private List<OtherGift> GetItems()
|
||||
{
|
||||
List<OtherGift> items = new();
|
||||
for (int i = 0; i < MaxItemCount; i++)
|
||||
{
|
||||
var type = (GiftType7)Type!;
|
||||
var item = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ItemOffset + (0x04 * i)));
|
||||
var quantity = type is GiftType7.BP ? item : BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(QuantityOffset + (0x04 * i)));
|
||||
|
||||
var gift = new OtherGift
|
||||
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
|
||||
Type = (GiftType7)Data![GiftTypeOffset];
|
||||
Content = Type switch
|
||||
{
|
||||
Type = type,
|
||||
Item = item,
|
||||
Quantity = quantity,
|
||||
GiftType7.Pokemon => GetPokemon(),
|
||||
_ => GetItems(),
|
||||
};
|
||||
}
|
||||
|
||||
private PokemonGift GetPokemon()
|
||||
{
|
||||
var species = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(SpeciesOffset));
|
||||
var pid = BinaryPrimitives.ReadUInt32LittleEndian(Data.AsSpan(PIDOffset));
|
||||
var tid = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(TIDOffset));
|
||||
var sid = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(SIDOffset));
|
||||
var pidtype = (ShinyType7)Data![ShinyTypeOffset] switch
|
||||
{
|
||||
ShinyType7.Fixed => PIDType.FixedPID,
|
||||
ShinyType7.ShinyRandom => PIDType.RandomPID,
|
||||
ShinyType7.Shiny => PIDType.RandomPID,
|
||||
ShinyType7.ShinyLocked => PIDType.RandomPID,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
var shinytype = (ShinyType7)Data![ShinyTypeOffset] switch
|
||||
{
|
||||
ShinyType7.Fixed => PokemonGift.IsShiny(pid, tid, sid) ? ShinyType.ShinyForced :
|
||||
PokemonGift.IsTIDAbusePossible(tid, sid, pidtype) ? ShinyType.ShinyTIDAbuse : ShinyType.ShinyLocked,
|
||||
ShinyType7.ShinyRandom => ShinyType.ShinyPossible,
|
||||
ShinyType7.Shiny => ShinyType.ShinyForced,
|
||||
ShinyType7.ShinyLocked => ShinyType.ShinyLocked,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
if (gift.Item != ushort.MinValue)
|
||||
items.Add(gift);
|
||||
return new PokemonGift
|
||||
{
|
||||
Species = species,
|
||||
PID = pid,
|
||||
TID = tid,
|
||||
SID = sid,
|
||||
ShinyType = shinytype,
|
||||
PIDType = pidtype,
|
||||
};
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
public override bool IsChecksumValid()
|
||||
{
|
||||
if (Data is not null)
|
||||
private List<OtherGift> GetItems()
|
||||
{
|
||||
var oldChecksum = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ChecksumOffset));
|
||||
var span = Data.ToArray().AsSpan();
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(span[ChecksumOffset..], 0x0);
|
||||
var newchecksum = ChecksumCalculator.CalcCcittFalse(span);
|
||||
if (oldChecksum == newchecksum)
|
||||
return true;
|
||||
List<OtherGift> items = new();
|
||||
for (int i = 0; i < MaxItemCount; i++)
|
||||
{
|
||||
var type = (GiftType7)Type!;
|
||||
var item = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ItemOffset + (0x04 * i)));
|
||||
var quantity = type is GiftType7.BP ? item : BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(QuantityOffset + (0x04 * i)));
|
||||
|
||||
var gift = new OtherGift
|
||||
{
|
||||
Type = type,
|
||||
Item = item,
|
||||
Quantity = quantity,
|
||||
};
|
||||
|
||||
if (gift.Item != 0)
|
||||
items.Add(gift);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void UpdateChecksum()
|
||||
{
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(ChecksumOffset), 0x0);
|
||||
var checksum = ChecksumCalculator.CalcCcittFalse(Data.AsSpan());
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(ChecksumOffset), checksum);
|
||||
}
|
||||
public override bool IsChecksumValid()
|
||||
{
|
||||
if (Data is not null)
|
||||
{
|
||||
var oldChecksum = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ChecksumOffset));
|
||||
var span = Data.ToArray().AsSpan();
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(span[ChecksumOffset..], 0x0);
|
||||
var newchecksum = ChecksumCalculator.CalcCcittFalse(span);
|
||||
if (oldChecksum == newchecksum)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void SetID(ushort wcid)
|
||||
{
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(WondercardIDOffset), wcid);
|
||||
WCID = wcid;
|
||||
UpdateChecksum();
|
||||
}
|
||||
public override void UpdateChecksum()
|
||||
{
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(ChecksumOffset), 0x0);
|
||||
var checksum = ChecksumCalculator.CalcCcittFalse(Data.AsSpan());
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(ChecksumOffset), checksum);
|
||||
}
|
||||
|
||||
public override void SetRepeatable(bool repeatable)
|
||||
{
|
||||
Data![FlagOffset] = (byte)((Data![FlagOffset] & ~1) | (repeatable ? 0 : 1));
|
||||
IsRepeatable = repeatable;
|
||||
UpdateChecksum();
|
||||
public override void SetID(ushort wcid)
|
||||
{
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(WondercardIDOffset), wcid);
|
||||
WCID = wcid;
|
||||
UpdateChecksum();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,125 +1,117 @@
|
|||
using System.Buffers.Binary;
|
||||
using Enums;
|
||||
|
||||
namespace SwitchGiftDataManager.Core;
|
||||
|
||||
public class WB8 : Wondercard
|
||||
namespace SwitchGiftDataManager.Core
|
||||
{
|
||||
private const int WondercardIDOffset = 0x08;
|
||||
private const int FlagOffset = 0x10;
|
||||
private const int GiftTypeOffset = 0x11;
|
||||
private const int ItemOffset = 0x20;
|
||||
private const int QuantityOffset = 0x22;
|
||||
private const int TIDOffset = 0x20;
|
||||
private const int SIDOffset = 0x22;
|
||||
private const int PIDOffset = 0x2C;
|
||||
private const int SpeciesOffset = 0x288;
|
||||
private const int ShinyTypeOffset = 0x290;
|
||||
private const int ChecksumOffset = 0x2D0;
|
||||
|
||||
public WB8(ReadOnlySpan<byte> data) : base(data)
|
||||
internal class WB8 : Wondercard
|
||||
{
|
||||
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
|
||||
IsRepeatable = (Data![FlagOffset] & 1) == 0;
|
||||
Type = (GiftType8B)Data![GiftTypeOffset];
|
||||
Content = Type switch
|
||||
{
|
||||
GiftType8B.Pokemon => GetPokemon(),
|
||||
_ => GetItems(),
|
||||
};
|
||||
}
|
||||
private const int WondercardIDOffset = 0x08;
|
||||
private const int GiftTypeOffset = 0x11;
|
||||
private const int ItemOffset = 0x20;
|
||||
private const int QuantityOffset = 0x22;
|
||||
private const int TIDOffset = 0x20;
|
||||
private const int SIDOffset = 0x22;
|
||||
private const int PIDOffset = 0x2C;
|
||||
private const int SpeciesOffset = 0x288;
|
||||
private const int ShinyTypeOffset = 0x290;
|
||||
private const int ChecksumOffset = 0x2D0;
|
||||
|
||||
private PokemonGift GetPokemon()
|
||||
{
|
||||
var species = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(SpeciesOffset));
|
||||
var pid = BinaryPrimitives.ReadUInt32LittleEndian(Data.AsSpan(PIDOffset));
|
||||
var tid = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(TIDOffset));
|
||||
var sid = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(SIDOffset));
|
||||
var test = (ShinyType8)Data![ShinyTypeOffset];
|
||||
var pidtype = (ShinyType8)Data![ShinyTypeOffset] switch
|
||||
public WB8(ReadOnlySpan<byte> data) : base(data)
|
||||
{
|
||||
ShinyType8.ShinyLocked => PIDType.RandomPID,
|
||||
ShinyType8.ShinyRandom => PIDType.RandomPID,
|
||||
ShinyType8.ShinyStar => PIDType.FixedPID,
|
||||
ShinyType8.ShinySquare => PIDType.FixedPID,
|
||||
ShinyType8.Fixed => PIDType.FixedPID,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
var shinytype = (ShinyType8)Data![ShinyTypeOffset] switch
|
||||
{
|
||||
ShinyType8.ShinyLocked => ShinyType.ShinyLocked,
|
||||
ShinyType8.ShinyRandom => ShinyType.ShinyPossible,
|
||||
ShinyType8.ShinyStar or ShinyType8.ShinySquare => ShinyType.ShinyForced,
|
||||
ShinyType8.Fixed => PokemonGift.IsShiny(pid, tid, sid) ? ShinyType.ShinyForced :
|
||||
PokemonGift.IsTIDAbusePossible(tid, sid, pidtype) ? ShinyType.ShinyTIDAbuse : ShinyType.ShinyLocked,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
return new PokemonGift
|
||||
{
|
||||
Species = species,
|
||||
PID = pid,
|
||||
TID = tid,
|
||||
SID = sid,
|
||||
ShinyType = shinytype,
|
||||
PIDType = pidtype,
|
||||
};
|
||||
}
|
||||
|
||||
private List<OtherGift> GetItems()
|
||||
{
|
||||
List<OtherGift> items = new();
|
||||
for (int i = 0; i < MaxItemCount; i++)
|
||||
{
|
||||
var type = (GiftType8B)Type!;
|
||||
var item = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ItemOffset + (0x10 * i)));
|
||||
var quantity = type is GiftType8B.BP or GiftType8B.Money ? item : BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(QuantityOffset + (0x10 * i)));
|
||||
|
||||
var gift = new OtherGift
|
||||
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
|
||||
Type = (GiftType8B)Data![GiftTypeOffset];
|
||||
Content = Type switch
|
||||
{
|
||||
Type = Type,
|
||||
Item = item,
|
||||
Quantity = quantity,
|
||||
GiftType8B.Pokemon => GetPokemon(),
|
||||
_ => GetItems(),
|
||||
};
|
||||
}
|
||||
|
||||
private PokemonGift GetPokemon()
|
||||
{
|
||||
var species = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(SpeciesOffset));
|
||||
var pid = BinaryPrimitives.ReadUInt32LittleEndian(Data.AsSpan(PIDOffset));
|
||||
var tid = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(TIDOffset));
|
||||
var sid = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(SIDOffset));
|
||||
var test = (ShinyType8)Data![ShinyTypeOffset];
|
||||
var pidtype = (ShinyType8)Data![ShinyTypeOffset] switch
|
||||
{
|
||||
ShinyType8.ShinyLocked => PIDType.RandomPID,
|
||||
ShinyType8.ShinyRandom => PIDType.RandomPID,
|
||||
ShinyType8.ShinyStar => PIDType.FixedPID,
|
||||
ShinyType8.ShinySquare => PIDType.FixedPID,
|
||||
ShinyType8.Fixed => PIDType.FixedPID,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
var shinytype = (ShinyType8)Data![ShinyTypeOffset] switch
|
||||
{
|
||||
ShinyType8.ShinyLocked => ShinyType.ShinyLocked,
|
||||
ShinyType8.ShinyRandom => ShinyType.ShinyPossible,
|
||||
ShinyType8.ShinyStar or ShinyType8.ShinySquare => ShinyType.ShinyForced,
|
||||
ShinyType8.Fixed => PokemonGift.IsShiny(pid, tid, sid) ? ShinyType.ShinyForced :
|
||||
PokemonGift.IsTIDAbusePossible(tid, sid, pidtype) ? ShinyType.ShinyTIDAbuse : ShinyType.ShinyLocked,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
if (gift.Item != ushort.MinValue)
|
||||
items.Add(gift);
|
||||
return new PokemonGift
|
||||
{
|
||||
Species = species,
|
||||
PID = pid,
|
||||
TID = tid,
|
||||
SID = sid,
|
||||
ShinyType = shinytype,
|
||||
PIDType = pidtype,
|
||||
};
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
public override bool IsChecksumValid()
|
||||
{
|
||||
if (Data is not null)
|
||||
private List<OtherGift> GetItems()
|
||||
{
|
||||
var oldChecksum = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ChecksumOffset));
|
||||
var span = Data.ToArray().AsSpan();
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(span[ChecksumOffset..], 0x0);
|
||||
var newchecksum = ChecksumCalculator.CalcCcittFalse(span);
|
||||
if (oldChecksum == newchecksum)
|
||||
return true;
|
||||
List<OtherGift> items = new();
|
||||
for (int i = 0; i < MaxItemCount; i++)
|
||||
{
|
||||
var type = (GiftType8B)Type!;
|
||||
var item = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ItemOffset + (0x10 * i)));
|
||||
var quantity = type is GiftType8B.BP or GiftType8B.Money ? item : BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(QuantityOffset + (0x10 * i)));
|
||||
|
||||
var gift = new OtherGift
|
||||
{
|
||||
Type = Type,
|
||||
Item = item,
|
||||
Quantity = quantity,
|
||||
};
|
||||
|
||||
if (gift.Item != 0)
|
||||
items.Add(gift);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void UpdateChecksum()
|
||||
{
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(ChecksumOffset), 0x0);
|
||||
var checksum = ChecksumCalculator.CalcCcittFalse(Data.AsSpan());
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(ChecksumOffset), checksum);
|
||||
}
|
||||
public override bool IsChecksumValid()
|
||||
{
|
||||
if (Data is not null)
|
||||
{
|
||||
var oldChecksum = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ChecksumOffset));
|
||||
var span = Data.ToArray().AsSpan();
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(span[ChecksumOffset..], 0x0);
|
||||
var newchecksum = ChecksumCalculator.CalcCcittFalse(span);
|
||||
if (oldChecksum == newchecksum)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void SetID(ushort wcid)
|
||||
{
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(WondercardIDOffset), wcid);
|
||||
WCID = wcid;
|
||||
UpdateChecksum();
|
||||
}
|
||||
public override void UpdateChecksum()
|
||||
{
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(ChecksumOffset), 0x0);
|
||||
var checksum = ChecksumCalculator.CalcCcittFalse(Data.AsSpan());
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(ChecksumOffset), checksum);
|
||||
}
|
||||
|
||||
public override void SetRepeatable(bool repeatable)
|
||||
{
|
||||
Data![FlagOffset] = (byte)((Data![FlagOffset] & ~1) | (repeatable ? 0 : 1));
|
||||
IsRepeatable = repeatable;
|
||||
UpdateChecksum();
|
||||
public override void SetID(ushort wcid)
|
||||
{
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(WondercardIDOffset), wcid);
|
||||
WCID = wcid;
|
||||
UpdateChecksum();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,139 +1,131 @@
|
|||
using System.Buffers.Binary;
|
||||
using Enums;
|
||||
|
||||
namespace SwitchGiftDataManager.Core;
|
||||
|
||||
public class WC8 : Wondercard
|
||||
namespace SwitchGiftDataManager.Core
|
||||
{
|
||||
private const int WondercardIDOffset = 0x08;
|
||||
private const int FlagOffset = 0x10;
|
||||
private const int GiftTypeOffset = 0x11;
|
||||
private const int ItemOffset = 0x20;
|
||||
private const int QuantityOffset = 0x22;
|
||||
private const int ClothingOffset = 0x24;
|
||||
private const int TIDOffset = 0x20;
|
||||
private const int SIDOffset = 0x22;
|
||||
private const int PIDOffset = 0x2C;
|
||||
private const int SpeciesOffset = 0x240;
|
||||
private const int ShinyTypeOffset = 0x248;
|
||||
private const int ChecksumOffset = 0x2CC;
|
||||
|
||||
public WC8(ReadOnlySpan<byte> data) : base(data)
|
||||
internal class WC8 : Wondercard
|
||||
{
|
||||
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
|
||||
IsRepeatable = (Data![FlagOffset] & 1) == 0;
|
||||
Type = (GiftType8)Data![GiftTypeOffset];
|
||||
Content = Type switch
|
||||
{
|
||||
GiftType8.Pokemon => GetPokemon(),
|
||||
_ => GetItems(),
|
||||
};
|
||||
}
|
||||
private const int WondercardIDOffset = 0x08;
|
||||
private const int GiftTypeOffset = 0x11;
|
||||
private const int ItemOffset = 0x20;
|
||||
private const int QuantityOffset = 0x22;
|
||||
private const int ClothingOffset = 0x24;
|
||||
private const int TIDOffset = 0x20;
|
||||
private const int SIDOffset = 0x22;
|
||||
private const int PIDOffset = 0x2C;
|
||||
private const int SpeciesOffset = 0x240;
|
||||
private const int ShinyTypeOffset = 0x248;
|
||||
private const int ChecksumOffset = 0x2CC;
|
||||
|
||||
private PokemonGift GetPokemon()
|
||||
{
|
||||
var species = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(SpeciesOffset));
|
||||
var pid = BinaryPrimitives.ReadUInt32LittleEndian(Data.AsSpan(PIDOffset));
|
||||
var tid = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(TIDOffset));
|
||||
var sid = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(SIDOffset));
|
||||
var test = (ShinyType8)Data![ShinyTypeOffset];
|
||||
var pidtype = (ShinyType8)Data![ShinyTypeOffset] switch
|
||||
public WC8(ReadOnlySpan<byte> data) : base(data)
|
||||
{
|
||||
ShinyType8.ShinyLocked => PIDType.RandomPID,
|
||||
ShinyType8.ShinyRandom => PIDType.RandomPID,
|
||||
ShinyType8.ShinyStar => PIDType.FixedPID,
|
||||
ShinyType8.ShinySquare => PIDType.FixedPID,
|
||||
ShinyType8.Fixed => PIDType.FixedPID,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
var shinytype = (ShinyType8)Data![ShinyTypeOffset] switch
|
||||
{
|
||||
ShinyType8.ShinyLocked => ShinyType.ShinyLocked,
|
||||
ShinyType8.ShinyRandom => ShinyType.ShinyPossible,
|
||||
ShinyType8.ShinyStar or ShinyType8.ShinySquare => ShinyType.ShinyForced,
|
||||
ShinyType8.Fixed => PokemonGift.IsShiny(pid, tid, sid) ? ShinyType.ShinyForced :
|
||||
PokemonGift.IsTIDAbusePossible(tid, sid, pidtype) ? ShinyType.ShinyTIDAbuse : ShinyType.ShinyLocked,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
return new PokemonGift
|
||||
{
|
||||
Species = species,
|
||||
PID = pid,
|
||||
TID = tid,
|
||||
SID = sid,
|
||||
ShinyType = shinytype,
|
||||
PIDType = pidtype,
|
||||
};
|
||||
}
|
||||
|
||||
private List<OtherGift> GetItems()
|
||||
{
|
||||
List<OtherGift> items = new();
|
||||
for (int i = 0; i < MaxItemCount; i++)
|
||||
{
|
||||
ushort item = 0;
|
||||
ushort quantity = 0;
|
||||
ushort opt = 0;
|
||||
var type = (GiftType8)Type!;
|
||||
|
||||
if (type is GiftType8.Clothing)
|
||||
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
|
||||
Type = (GiftType8)Data![GiftTypeOffset];
|
||||
Content = Type switch
|
||||
{
|
||||
item = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ItemOffset + (0x08 * i)));
|
||||
opt = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ClothingOffset + (0x08 * i)));
|
||||
}
|
||||
else
|
||||
{
|
||||
item = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ItemOffset + (0x04 * i)));
|
||||
quantity = type is GiftType8.BP or GiftType8.Money ? item : BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(QuantityOffset + (0x04 * i)));
|
||||
}
|
||||
GiftType8.Pokemon => GetPokemon(),
|
||||
_ => GetItems(),
|
||||
};
|
||||
}
|
||||
|
||||
var gift = new OtherGift
|
||||
private PokemonGift GetPokemon()
|
||||
{
|
||||
var species = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(SpeciesOffset));
|
||||
var pid = BinaryPrimitives.ReadUInt32LittleEndian(Data.AsSpan(PIDOffset));
|
||||
var tid = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(TIDOffset));
|
||||
var sid = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(SIDOffset));
|
||||
var test = (ShinyType8)Data![ShinyTypeOffset];
|
||||
var pidtype = (ShinyType8)Data![ShinyTypeOffset] switch
|
||||
{
|
||||
Type = type,
|
||||
Item = item,
|
||||
Quantity = quantity,
|
||||
Opt = opt,
|
||||
ShinyType8.ShinyLocked => PIDType.RandomPID,
|
||||
ShinyType8.ShinyRandom => PIDType.RandomPID,
|
||||
ShinyType8.ShinyStar => PIDType.FixedPID,
|
||||
ShinyType8.ShinySquare => PIDType.FixedPID,
|
||||
ShinyType8.Fixed => PIDType.FixedPID,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
var shinytype = (ShinyType8)Data![ShinyTypeOffset] switch
|
||||
{
|
||||
ShinyType8.ShinyLocked => ShinyType.ShinyLocked,
|
||||
ShinyType8.ShinyRandom => ShinyType.ShinyPossible,
|
||||
ShinyType8.ShinyStar or ShinyType8.ShinySquare => ShinyType.ShinyForced,
|
||||
ShinyType8.Fixed => PokemonGift.IsShiny(pid, tid, sid) ? ShinyType.ShinyForced :
|
||||
PokemonGift.IsTIDAbusePossible(tid, sid, pidtype) ? ShinyType.ShinyTIDAbuse : ShinyType.ShinyLocked,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
if (gift.Item != ushort.MinValue && opt != ushort.MaxValue)
|
||||
items.Add(gift);
|
||||
return new PokemonGift
|
||||
{
|
||||
Species = species,
|
||||
PID = pid,
|
||||
TID = tid,
|
||||
SID = sid,
|
||||
ShinyType = shinytype,
|
||||
PIDType = pidtype,
|
||||
};
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
public override bool IsChecksumValid()
|
||||
{
|
||||
if (Data is not null)
|
||||
private List<OtherGift> GetItems()
|
||||
{
|
||||
var oldChecksum = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ChecksumOffset));
|
||||
var span = Data.ToArray().AsSpan();
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(span[ChecksumOffset..], 0x0);
|
||||
var newchecksum = ChecksumCalculator.CalcCcittFalse(span);
|
||||
if (oldChecksum == newchecksum)
|
||||
return true;
|
||||
List<OtherGift> items = new();
|
||||
for (int i = 0; i < MaxItemCount; i++)
|
||||
{
|
||||
ushort item = 0;
|
||||
ushort quantity = 0;
|
||||
ushort opt = 0;
|
||||
var type = (GiftType8)Type!;
|
||||
|
||||
if (type is GiftType8.Clothing)
|
||||
{
|
||||
item = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ItemOffset + (0x08 * i)));
|
||||
opt = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ClothingOffset + (0x08 * i)));
|
||||
}
|
||||
else
|
||||
{
|
||||
item = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ItemOffset + (0x04 * i)));
|
||||
quantity = type is GiftType8.BP or GiftType8.Money ? item : BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(QuantityOffset + (0x04 * i)));
|
||||
}
|
||||
|
||||
var gift = new OtherGift
|
||||
{
|
||||
Type = type,
|
||||
Item = item,
|
||||
Quantity = quantity,
|
||||
Opt = opt,
|
||||
};
|
||||
|
||||
if (gift.Item != 0x00 && opt != 0xFFFF)
|
||||
items.Add(gift);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void UpdateChecksum()
|
||||
{
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(ChecksumOffset), 0x0);
|
||||
var checksum = ChecksumCalculator.CalcCcittFalse(Data.AsSpan());
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(ChecksumOffset), checksum);
|
||||
}
|
||||
public override bool IsChecksumValid()
|
||||
{
|
||||
if (Data is not null)
|
||||
{
|
||||
var oldChecksum = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ChecksumOffset));
|
||||
var span = Data.ToArray().AsSpan();
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(span[ChecksumOffset..], 0x0);
|
||||
var newchecksum = ChecksumCalculator.CalcCcittFalse(span);
|
||||
if (oldChecksum == newchecksum)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void SetID(ushort wcid)
|
||||
{
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(WondercardIDOffset), wcid);
|
||||
WCID = wcid;
|
||||
UpdateChecksum();
|
||||
}
|
||||
public override void UpdateChecksum()
|
||||
{
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(ChecksumOffset), 0x0);
|
||||
var checksum = ChecksumCalculator.CalcCcittFalse(Data.AsSpan());
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(ChecksumOffset), checksum);
|
||||
}
|
||||
|
||||
public override void SetRepeatable(bool repeatable)
|
||||
{
|
||||
Data![FlagOffset] = (byte)((Data![FlagOffset] & ~1) | (repeatable ? 0 : 1));
|
||||
IsRepeatable = repeatable;
|
||||
UpdateChecksum();
|
||||
public override void SetID(ushort wcid)
|
||||
{
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(WondercardIDOffset), wcid);
|
||||
WCID = wcid;
|
||||
UpdateChecksum();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,173 +1,131 @@
|
|||
using System.Buffers.Binary;
|
||||
using Enums;
|
||||
|
||||
namespace SwitchGiftDataManager.Core;
|
||||
|
||||
public class WC9 : Wondercard
|
||||
namespace SwitchGiftDataManager.Core
|
||||
{
|
||||
private const int WondercardIDOffset = 0x08;
|
||||
private const int FlagOffset = 0x10;
|
||||
private const int GiftTypeOffset = 0x11;
|
||||
private const int ItemOffset = 0x18;
|
||||
private const int QuantityOffset = 0x1A;
|
||||
private const int ClothingOffset = 0x1C;
|
||||
private const int TIDOffset = 0x18;
|
||||
private const int SIDOffset = 0x1A;
|
||||
private const int PIDOffset = 0x24;
|
||||
private const int SpeciesOffset = 0x238;
|
||||
private const int ShinyTypeOffset = 0x240;
|
||||
private const int ChecksumOffset = 0x2C4;
|
||||
|
||||
// Entities with set TID / SID prior to the v2.0.1 game update would've had their TID / SID modified based on the Wondercard ID.
|
||||
private readonly HashSet<ushort> OldGifts = new() { 0024, 0025, 0028, 0501, 0503, 0504, 0505, 0506, 1002, 1003, 1005 };
|
||||
|
||||
// These Gifts (Birthday Flabébé, Glaseado Cetitan, Home Gifts) could be obtained both before and after the v2.0.1 game update.
|
||||
private readonly HashSet<ushort> MixedGifts = new() { 0001, 1524, 9021, 9022, 9023 };
|
||||
public bool RequiresMethodSelection { get => MixedGifts.Contains(WCID); }
|
||||
|
||||
public bool IsBefore201 { get; set; } = false;
|
||||
|
||||
public WC9(ReadOnlySpan<byte> data) : base(data)
|
||||
internal class WC9 : Wondercard
|
||||
{
|
||||
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
|
||||
IsRepeatable = (Data![FlagOffset] & 1) == 0;
|
||||
Type = (GiftType9)Data![GiftTypeOffset];
|
||||
Content = Type switch
|
||||
{
|
||||
GiftType9.Pokemon => GetPokemon(),
|
||||
_ => GetItems(),
|
||||
};
|
||||
}
|
||||
private const int WondercardIDOffset = 0x08;
|
||||
private const int GiftTypeOffset = 0x11;
|
||||
private const int ItemOffset = 0x18;
|
||||
private const int QuantityOffset = 0x1A;
|
||||
private const int ClothingOffset = 0x1C;
|
||||
private const int TIDOffset = 0x18;
|
||||
private const int PIDOffset = 0x24;
|
||||
private const int SpeciesOffset = 0x238;
|
||||
private const int ShinyTypeOffset = 0x240;
|
||||
private const int ChecksumOffset = 0x2C4;
|
||||
|
||||
private PokemonGift GetPokemon()
|
||||
{
|
||||
if (OldGifts.Contains(WCID) || MixedGifts.Contains(WCID))
|
||||
UpdateOldToNewTIDSID();
|
||||
|
||||
var species = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(SpeciesOffset));
|
||||
var pid = BinaryPrimitives.ReadUInt32LittleEndian(Data.AsSpan(PIDOffset));
|
||||
var tid = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(TIDOffset));
|
||||
var sid = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(SIDOffset));
|
||||
var pidtype = (ShinyType9)Data![ShinyTypeOffset] switch
|
||||
public WC9(ReadOnlySpan<byte> data) : base(data)
|
||||
{
|
||||
ShinyType9.ShinyLocked => PIDType.RandomPID,
|
||||
ShinyType9.ShinyRandom => PIDType.RandomPID,
|
||||
ShinyType9.ShinyStar => PIDType.FixedPID,
|
||||
ShinyType9.ShinySquare => PIDType.FixedPID,
|
||||
ShinyType9.Fixed => PIDType.FixedPID,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
var shinytype = (ShinyType9)Data![ShinyTypeOffset] switch
|
||||
{
|
||||
ShinyType9.ShinyLocked => ShinyType.ShinyLocked,
|
||||
ShinyType9.ShinyRandom => ShinyType.ShinyPossible,
|
||||
ShinyType9.ShinyStar or ShinyType9.ShinySquare => ShinyType.ShinyForced,
|
||||
ShinyType9.Fixed => PokemonGift.IsShiny(pid, tid, sid) ? ShinyType.ShinyForced :
|
||||
PokemonGift.IsTIDAbusePossible(tid, sid, pidtype) ? ShinyType.ShinyTIDAbuse : ShinyType.ShinyLocked,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
return new PokemonGift
|
||||
{
|
||||
Species = species,
|
||||
PID = pid,
|
||||
TID = tid,
|
||||
SID = sid,
|
||||
ShinyType = shinytype,
|
||||
PIDType = pidtype,
|
||||
};
|
||||
}
|
||||
|
||||
private List<OtherGift> GetItems()
|
||||
{
|
||||
List<OtherGift> items = new();
|
||||
for (int i = 0; i < MaxItemCount; i++)
|
||||
{
|
||||
ushort item = 0;
|
||||
uint quantity = 0;
|
||||
ushort opt = 0;
|
||||
var type = (GiftType9)Type!;
|
||||
|
||||
if (type is GiftType9.Clothing)
|
||||
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
|
||||
Type = (GiftType9)Data![GiftTypeOffset];
|
||||
Content = Type switch
|
||||
{
|
||||
item = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ItemOffset + (0x08 * i)));
|
||||
opt = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ClothingOffset + (0x08 * i)));
|
||||
}
|
||||
else
|
||||
{
|
||||
item = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ItemOffset + (0x04 * i)));
|
||||
quantity = type is GiftType9.LP ? BinaryPrimitives.ReadUInt32LittleEndian(Data.AsSpan(ItemOffset + (0x04 * i))) :
|
||||
BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(QuantityOffset + (0x04 * i)));
|
||||
}
|
||||
GiftType9.Pokemon => GetPokemon(),
|
||||
_ => GetItems(),
|
||||
};
|
||||
}
|
||||
|
||||
var gift = new OtherGift
|
||||
private PokemonGift GetPokemon()
|
||||
{
|
||||
var species = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(SpeciesOffset));
|
||||
var pid = BinaryPrimitives.ReadUInt32LittleEndian(Data.AsSpan(PIDOffset));
|
||||
var tid = (ushort)((BinaryPrimitives.ReadUInt32LittleEndian(Data.AsSpan(TIDOffset)) - (0xF4240 * WCID)) & 0xFFFF);
|
||||
var sid = (ushort)((BinaryPrimitives.ReadUInt32LittleEndian(Data.AsSpan(TIDOffset)) - (0xF4240 * WCID)) >> 16 & 0xFFFF);
|
||||
var test = (ShinyType9)Data![ShinyTypeOffset];
|
||||
var pidtype = (ShinyType9)Data![ShinyTypeOffset] switch
|
||||
{
|
||||
Type = type,
|
||||
Item = item,
|
||||
Quantity = quantity,
|
||||
Opt = opt,
|
||||
ShinyType9.ShinyLocked => PIDType.RandomPID,
|
||||
ShinyType9.ShinyRandom => PIDType.RandomPID,
|
||||
ShinyType9.ShinyStar => PIDType.FixedPID,
|
||||
ShinyType9.ShinySquare => PIDType.FixedPID,
|
||||
ShinyType9.Fixed => PIDType.FixedPID,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
var shinytype = (ShinyType9)Data![ShinyTypeOffset] switch
|
||||
{
|
||||
ShinyType9.ShinyLocked => ShinyType.ShinyLocked,
|
||||
ShinyType9.ShinyRandom => ShinyType.ShinyPossible,
|
||||
ShinyType9.ShinyStar or ShinyType9.ShinySquare => ShinyType.ShinyForced,
|
||||
ShinyType9.Fixed => PokemonGift.IsShiny(pid, tid, sid) ? ShinyType.ShinyForced :
|
||||
PokemonGift.IsTIDAbusePossible(tid, sid, pidtype) ? ShinyType.ShinyTIDAbuse : ShinyType.ShinyLocked,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
if ((type is not GiftType9.Clothing && gift.Item != ushort.MinValue) || (type is GiftType9.Clothing && opt != ushort.MaxValue))
|
||||
items.Add(gift);
|
||||
return new PokemonGift
|
||||
{
|
||||
Species = species,
|
||||
PID = pid,
|
||||
TID = tid,
|
||||
SID = sid,
|
||||
ShinyType = shinytype,
|
||||
PIDType = pidtype,
|
||||
};
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
public override bool IsChecksumValid()
|
||||
{
|
||||
if (Data is not null)
|
||||
private List<OtherGift> GetItems()
|
||||
{
|
||||
var oldChecksum = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ChecksumOffset));
|
||||
var span = Data.ToArray().AsSpan();
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(span[ChecksumOffset..], 0x0);
|
||||
var newchecksum = ChecksumCalculator.CalcCcittFalse(span);
|
||||
if (oldChecksum == newchecksum)
|
||||
return true;
|
||||
List<OtherGift> items = new();
|
||||
for (int i = 0; i < MaxItemCount; i++)
|
||||
{
|
||||
ushort item = 0;
|
||||
uint quantity = 0;
|
||||
ushort opt = 0;
|
||||
var type = (GiftType9)Type!;
|
||||
|
||||
if (type is GiftType9.Clothing)
|
||||
{
|
||||
item = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ItemOffset + (0x08 * i)));
|
||||
opt = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ClothingOffset + (0x08 * i)));
|
||||
}
|
||||
else
|
||||
{
|
||||
item = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ItemOffset + (0x04 * i)));
|
||||
quantity = type is GiftType9.LP ? BinaryPrimitives.ReadUInt32LittleEndian(Data.AsSpan(ItemOffset + (0x04 * i))) :
|
||||
BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(QuantityOffset + (0x04 * i)));
|
||||
}
|
||||
|
||||
var gift = new OtherGift
|
||||
{
|
||||
Type = type,
|
||||
Item = item,
|
||||
Quantity = quantity,
|
||||
Opt = opt,
|
||||
};
|
||||
|
||||
if ((type is not GiftType9.Clothing && gift.Item != 0x00) || (type is GiftType9.Clothing && opt != 0xFFFF))
|
||||
items.Add(gift);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
public override bool IsChecksumValid()
|
||||
{
|
||||
if (Data is not null)
|
||||
{
|
||||
var oldChecksum = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(ChecksumOffset));
|
||||
var span = Data.ToArray().AsSpan();
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(span[ChecksumOffset..], 0x0);
|
||||
var newchecksum = ChecksumCalculator.CalcCcittFalse(span);
|
||||
if (oldChecksum == newchecksum)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void UpdateChecksum()
|
||||
{
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(ChecksumOffset), 0x0);
|
||||
var checksum = ChecksumCalculator.CalcCcittFalse(Data.AsSpan());
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(ChecksumOffset), checksum);
|
||||
}
|
||||
|
||||
public override void SetID(ushort wcid)
|
||||
{
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(WondercardIDOffset), wcid);
|
||||
WCID = wcid;
|
||||
UpdateChecksum();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void UpdateOldToNewTIDSID()
|
||||
{
|
||||
if (IsBefore201)
|
||||
return;
|
||||
|
||||
var FTID = BinaryPrimitives.ReadUInt32LittleEndian(Data.AsSpan(TIDOffset)) - (1000000u * WCID);
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(Data.AsSpan(TIDOffset), FTID);
|
||||
UpdateChecksum();
|
||||
IsBefore201 = true;
|
||||
}
|
||||
|
||||
public void UpdateNewToOldTIDSID()
|
||||
{
|
||||
if (!IsBefore201)
|
||||
return;
|
||||
|
||||
var FTID = BinaryPrimitives.ReadUInt32LittleEndian(Data.AsSpan(TIDOffset));
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(Data.AsSpan(TIDOffset), FTID + (1000000u * WCID));
|
||||
UpdateChecksum();
|
||||
IsBefore201 = false;
|
||||
}
|
||||
|
||||
public override void UpdateChecksum()
|
||||
{
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(ChecksumOffset), 0x0);
|
||||
var checksum = ChecksumCalculator.CalcCcittFalse(Data.AsSpan());
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(ChecksumOffset), checksum);
|
||||
}
|
||||
|
||||
public override void SetID(ushort wcid)
|
||||
{
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(Data.AsSpan(WondercardIDOffset), wcid);
|
||||
WCID = wcid;
|
||||
UpdateChecksum();
|
||||
}
|
||||
|
||||
public override void SetRepeatable(bool repeatable)
|
||||
{
|
||||
Data![FlagOffset] = (byte)((Data![FlagOffset] & ~1) | (repeatable ? 0 : 1));
|
||||
IsRepeatable = repeatable;
|
||||
UpdateChecksum();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,74 +1,68 @@
|
|||
using Enums;
|
||||
using System.Buffers.Binary;
|
||||
|
||||
namespace SwitchGiftDataManager.Core;
|
||||
|
||||
public abstract class Wondercard
|
||||
namespace SwitchGiftDataManager.Core
|
||||
{
|
||||
protected const int MaxItemCount = 6;
|
||||
|
||||
public Games Game { get; }
|
||||
public ushort WCID { get; protected set; }
|
||||
public bool IsRepeatable { get; protected set; }
|
||||
public object? Type { get; protected set; }
|
||||
public object? Content { get; protected set; }
|
||||
public byte[]? Data { get; protected set; }
|
||||
|
||||
public Wondercard(ReadOnlySpan<byte> data)
|
||||
internal abstract class Wondercard
|
||||
{
|
||||
Game = (WondercardSize)data.Length switch
|
||||
public static int GenOffset = 0x0F;
|
||||
protected const int MaxItemCount = 6;
|
||||
|
||||
public Games Game { get; }
|
||||
public ushort WCID { get; protected set; }
|
||||
public object? Type { get; protected set; }
|
||||
public object? Content { get; protected set; }
|
||||
public byte[]? Data { get; protected set; }
|
||||
|
||||
public Wondercard(ReadOnlySpan<byte> data)
|
||||
{
|
||||
WondercardSize.WB7 => Games.LGPE,
|
||||
WondercardSize.WC8 => Games.SWSH,
|
||||
WondercardSize.WB8 => Games.BDSP,
|
||||
WondercardSize.WA8 when data[0x0F] != 0 => Games.PLA,
|
||||
WondercardSize.WC9 when data[0x0F] == 0 && data[0x2C0] == 0 => Games.SCVI,
|
||||
WondercardSize.WA9 when data[0x2C0] != 0 => Games.ZA,
|
||||
_ => Games.None,
|
||||
};
|
||||
Data = data.ToArray();
|
||||
}
|
||||
Game = (WondercardSize)data.Length switch
|
||||
{
|
||||
WondercardSize.WB7 => Games.LGPE,
|
||||
WondercardSize.WC8 => Games.SWSH,
|
||||
WondercardSize.WB8 => Games.BDSP,
|
||||
WondercardSize.WC9 => data[GenOffset] != 0 ? Games.PLA : Games.SCVI,
|
||||
_ => Games.None,
|
||||
};
|
||||
Data = data.ToArray();
|
||||
}
|
||||
|
||||
public bool IsValid()
|
||||
{
|
||||
if (WCID <= 0)
|
||||
return false;
|
||||
|
||||
if (Content is null)
|
||||
return false;
|
||||
|
||||
#if DEBUG
|
||||
if (!IsChecksumValid())
|
||||
UpdateChecksum();
|
||||
#endif
|
||||
|
||||
if (!IsChecksumValid())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public ReadOnlySpan<byte> CalcMetaChecksum() => ChecksumCalculator.CalcReverseMD5(Data!);
|
||||
|
||||
public abstract bool IsChecksumValid();
|
||||
|
||||
public abstract void UpdateChecksum();
|
||||
|
||||
public abstract void SetID(ushort wcid);
|
||||
|
||||
public abstract void SetRepeatable(bool repeatable);
|
||||
|
||||
public static WondercardSize GetSize(Games game)
|
||||
{
|
||||
return game switch
|
||||
public bool IsValid()
|
||||
{
|
||||
Games.LGPE => WondercardSize.WB7,
|
||||
Games.SWSH => WondercardSize.WC8,
|
||||
Games.BDSP => WondercardSize.WB8,
|
||||
Games.PLA => WondercardSize.WA8,
|
||||
Games.SCVI => WondercardSize.WC9,
|
||||
Games.ZA => WondercardSize.WA9,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(game)),
|
||||
};
|
||||
if (WCID <= 0)
|
||||
return false;
|
||||
|
||||
if (Content is null)
|
||||
return false;
|
||||
|
||||
if (!IsChecksumValid())
|
||||
return false;
|
||||
|
||||
//if (!IsChecksumValid())
|
||||
//UpdateChecksum();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public ReadOnlySpan<byte> CalcMetaChecksum() => ChecksumCalculator.CalcReverseMD5(Data!);
|
||||
|
||||
public abstract bool IsChecksumValid();
|
||||
|
||||
public abstract void UpdateChecksum();
|
||||
|
||||
public abstract void SetID(ushort wcid);
|
||||
|
||||
public static WondercardSize GetSize(Games game)
|
||||
{
|
||||
return game switch
|
||||
{
|
||||
Games.LGPE => WondercardSize.WB7,
|
||||
Games.SWSH => WondercardSize.WC8,
|
||||
Games.BDSP => WondercardSize.WB8,
|
||||
Games.PLA => WondercardSize.WA8,
|
||||
Games.SCVI => WondercardSize.WC9,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,163 +1,152 @@
|
|||
namespace Enums;
|
||||
namespace Enums {
|
||||
public enum Games : int
|
||||
{
|
||||
None = 0,
|
||||
LGPE = 1,
|
||||
SWSH = 2,
|
||||
BDSP = 3,
|
||||
PLA = 4,
|
||||
SCVI = 5,
|
||||
}
|
||||
|
||||
public enum Games : int
|
||||
{
|
||||
None = 0,
|
||||
LGPE = 1,
|
||||
SWSH = 2,
|
||||
BDSP = 3,
|
||||
PLA = 4,
|
||||
SCVI = 5,
|
||||
ZA = 6,
|
||||
}
|
||||
public enum WCType
|
||||
{
|
||||
Pokemon,
|
||||
Item,
|
||||
}
|
||||
|
||||
public enum WCType
|
||||
{
|
||||
Pokemon,
|
||||
Item,
|
||||
}
|
||||
internal enum WondercardSize : ushort
|
||||
{
|
||||
WB7 = 0x310,
|
||||
WC8 = 0x2D0,
|
||||
WB8 = 0x2DC,
|
||||
WA8 = 0x2C8,
|
||||
WC9 = 0x2C8,
|
||||
}
|
||||
|
||||
public enum WondercardSize : ushort
|
||||
{
|
||||
WB7 = 0x310,
|
||||
WC8 = 0x2D0,
|
||||
WB8 = 0x2DC,
|
||||
WA8 = 0x2C8,
|
||||
WC9 = 0x2C8,
|
||||
WA9 = 0x2C8,
|
||||
}
|
||||
internal enum GiftType7 : byte
|
||||
{
|
||||
Pokemon = 0,
|
||||
Item = 1,
|
||||
Bean = 2,
|
||||
BP = 3,
|
||||
}
|
||||
|
||||
public enum GiftType7 : byte
|
||||
{
|
||||
Pokemon = 0,
|
||||
Item = 1,
|
||||
Bean = 2,
|
||||
BP = 3,
|
||||
}
|
||||
internal enum GiftType8 : byte
|
||||
{
|
||||
None = 0,
|
||||
Pokemon = 1,
|
||||
Item = 2,
|
||||
BP = 3,
|
||||
Clothing = 4,
|
||||
Money = 5,
|
||||
}
|
||||
|
||||
public enum GiftType8 : byte
|
||||
{
|
||||
None = 0,
|
||||
Pokemon = 1,
|
||||
Item = 2,
|
||||
BP = 3,
|
||||
Clothing = 4,
|
||||
Money = 5,
|
||||
}
|
||||
internal enum GiftType8B : byte
|
||||
{
|
||||
None = 0,
|
||||
Pokemon = 1,
|
||||
Item = 2,
|
||||
BP = 3,
|
||||
Clothing = 4,
|
||||
Money = 5,
|
||||
Underground = 6,
|
||||
}
|
||||
|
||||
public enum GiftType8B : byte
|
||||
{
|
||||
None = 0,
|
||||
Pokemon = 1,
|
||||
Item = 2,
|
||||
BP = 3,
|
||||
Clothing = 4,
|
||||
Money = 5,
|
||||
Underground = 6,
|
||||
}
|
||||
internal enum GiftType8A : byte
|
||||
{
|
||||
None = 0,
|
||||
Pokemon = 1,
|
||||
Item = 2,
|
||||
Clothing = 3,
|
||||
}
|
||||
|
||||
public enum GiftType8A : byte
|
||||
{
|
||||
None = 0,
|
||||
Pokemon = 1,
|
||||
Item = 2,
|
||||
Clothing = 3,
|
||||
}
|
||||
internal enum GiftType9 : byte
|
||||
{
|
||||
None = 0,
|
||||
Pokemon = 1,
|
||||
Item = 2,
|
||||
LP = 3,
|
||||
Clothing = 4,
|
||||
}
|
||||
|
||||
public enum GiftType9 : byte
|
||||
{
|
||||
None = 0,
|
||||
Pokemon = 1,
|
||||
Item = 2,
|
||||
LP = 3,
|
||||
Clothing = 4,
|
||||
}
|
||||
public enum PIDType
|
||||
{
|
||||
RandomPID,
|
||||
FixedPID,
|
||||
}
|
||||
|
||||
public enum GiftType9A : byte
|
||||
{
|
||||
None = 0,
|
||||
Pokemon = 1,
|
||||
Item = 2,
|
||||
Flag = 3,
|
||||
Clothing = 4,
|
||||
}
|
||||
public enum ShinyType
|
||||
{
|
||||
ShinyLocked,
|
||||
ShinyPossible,
|
||||
ShinyForced,
|
||||
ShinyTIDAbuse,
|
||||
ShinyHighOdds,
|
||||
}
|
||||
|
||||
public enum PIDType
|
||||
{
|
||||
RandomPID,
|
||||
FixedPID,
|
||||
}
|
||||
internal enum ShinyType7 : byte
|
||||
{
|
||||
Fixed = 0,
|
||||
ShinyRandom = 1,
|
||||
Shiny = 2,
|
||||
ShinyLocked = 3,
|
||||
}
|
||||
|
||||
public enum ShinyType
|
||||
{
|
||||
ShinyLocked,
|
||||
ShinyPossible,
|
||||
ShinyForced,
|
||||
ShinyTIDAbuse,
|
||||
ShinyHighOdds,
|
||||
}
|
||||
internal enum ShinyType8 : byte
|
||||
{
|
||||
ShinyLocked = 0,
|
||||
ShinyRandom = 1,
|
||||
ShinyStar = 2,
|
||||
ShinySquare = 3,
|
||||
Fixed = 4,
|
||||
}
|
||||
|
||||
public enum ShinyType7 : byte
|
||||
{
|
||||
Fixed = 0,
|
||||
ShinyRandom = 1,
|
||||
Shiny = 2,
|
||||
ShinyLocked = 3,
|
||||
}
|
||||
internal enum ShinyType9 : byte
|
||||
{
|
||||
ShinyLocked = 0,
|
||||
ShinyRandom = 1,
|
||||
ShinyStar = 2,
|
||||
ShinySquare = 3,
|
||||
Fixed = 4,
|
||||
}
|
||||
|
||||
public enum ShinyType8 : byte
|
||||
{
|
||||
ShinyLocked = 0,
|
||||
ShinyRandom = 1,
|
||||
ShinyStar = 2,
|
||||
ShinySquare = 3,
|
||||
Fixed = 4,
|
||||
}
|
||||
internal enum ClothingType8: byte
|
||||
{
|
||||
Glasses = 0x06,
|
||||
Hats = 0x07,
|
||||
Jackets = 0x08,
|
||||
Tops = 0x09,
|
||||
Bags = 0x0A,
|
||||
Gloves = 0x0B,
|
||||
Bottoms = 0x0C,
|
||||
Legwear = 0x0D,
|
||||
Shoes = 0x0E,
|
||||
None = 0xFF,
|
||||
}
|
||||
|
||||
public enum ShinyType9 : byte
|
||||
{
|
||||
ShinyLocked = 0,
|
||||
ShinyRandom = 1,
|
||||
ShinyStar = 2,
|
||||
ShinySquare = 3,
|
||||
Fixed = 4,
|
||||
}
|
||||
internal enum ClothingType8A: byte
|
||||
{
|
||||
Heads = 0x00,
|
||||
Tops = 0x01,
|
||||
Bottoms = 0x02,
|
||||
Outfit = 0x03,
|
||||
Shoes = 0x5,
|
||||
Glasses = 0x06,
|
||||
Eyes = 0x08,
|
||||
None = 0xFF,
|
||||
}
|
||||
|
||||
public enum ClothingType8: byte
|
||||
{
|
||||
Glasses = 0x06,
|
||||
Hats = 0x07,
|
||||
Jackets = 0x08,
|
||||
Tops = 0x09,
|
||||
Bags = 0x0A,
|
||||
Gloves = 0x0B,
|
||||
Bottoms = 0x0C,
|
||||
Legwear = 0x0D,
|
||||
Footwear = 0x0E,
|
||||
None = 0xFF,
|
||||
}
|
||||
|
||||
public enum ClothingType8A: byte
|
||||
{
|
||||
Headwear = 0x00,
|
||||
Tops = 0x01,
|
||||
Bottoms = 0x02,
|
||||
Outfit = 0x03,
|
||||
Footwear = 0x5,
|
||||
Glasses = 0x06,
|
||||
Eyewear = 0x08,
|
||||
None = 0xFF,
|
||||
}
|
||||
|
||||
public enum ClothingType9 : byte
|
||||
{
|
||||
Uniform = 0x00,
|
||||
Legwear = 0x01,
|
||||
Footwear = 0x02,
|
||||
Gloves = 0x03,
|
||||
Bags = 0x04,
|
||||
Headwear = 0x5,
|
||||
Eyewear = 0x06,
|
||||
PhoneCase = 0x08,
|
||||
None = 0xFF,
|
||||
internal enum ClothingType9 : byte
|
||||
{
|
||||
Uniform = 0x00,
|
||||
Legs = 0x01,
|
||||
Foots = 0x02,
|
||||
Gloves = 0x03,
|
||||
Bags = 0x04,
|
||||
Heads = 0x5,
|
||||
Eyes = 0x06,
|
||||
Rotom = 0x08,
|
||||
None = 0xFF,
|
||||
}
|
||||
}
|
||||
|
|
@ -836,9 +836,9 @@ namespace SwitchGiftDataManager.Core.Properties {
|
|||
///
|
||||
/// [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string SCVIClothings {
|
||||
internal static string SCVIClothingBags {
|
||||
get {
|
||||
return ResourceManager.GetString("SCVIClothings", resourceCulture);
|
||||
return ResourceManager.GetString("SCVIClothingBags", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -133,8 +133,8 @@
|
|||
<data name="PLAClothingTops" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\PLAClothingTops.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||
</data>
|
||||
<data name="SCVIClothings" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\SCVIClothings.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||
<data name="SCVIClothingBags" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\SCVIClothingBags.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||
</data>
|
||||
<data name="Species" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Species.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||
|
|
|
|||
|
|
@ -2230,64 +2230,64 @@ TM168
|
|||
TM169
|
||||
TM170
|
||||
TM171
|
||||
TM172
|
||||
TM173
|
||||
TM174
|
||||
TM175
|
||||
TM176
|
||||
TM177
|
||||
TM178
|
||||
TM179
|
||||
TM180
|
||||
TM181
|
||||
TM182
|
||||
TM183
|
||||
TM184
|
||||
TM185
|
||||
TM186
|
||||
TM187
|
||||
TM188
|
||||
TM189
|
||||
TM190
|
||||
TM191
|
||||
TM192
|
||||
TM193
|
||||
TM194
|
||||
TM195
|
||||
TM196
|
||||
TM197
|
||||
TM198
|
||||
TM199
|
||||
TM200
|
||||
TM201
|
||||
TM202
|
||||
TM203
|
||||
TM204
|
||||
TM205
|
||||
TM206
|
||||
TM207
|
||||
TM208
|
||||
TM209
|
||||
TM210
|
||||
TM211
|
||||
TM212
|
||||
TM213
|
||||
TM214
|
||||
TM215
|
||||
TM216
|
||||
TM217
|
||||
TM218
|
||||
TM219
|
||||
TM220
|
||||
TM221
|
||||
TM222
|
||||
TM223
|
||||
TM224
|
||||
TM225
|
||||
TM226
|
||||
TM227
|
||||
TM228
|
||||
TM229
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -2398,238 +2398,4 @@ Green Dish
|
|||
Orange Dish
|
||||
Red Dish
|
||||
White Dish
|
||||
Yellow Dish
|
||||
Fairy Feather
|
||||
Syrupy Apple
|
||||
Unremarkable Teacup
|
||||
Masterpiece Teacup
|
||||
Teal Mask
|
||||
Cornerstone Mask
|
||||
Wellspring Mask
|
||||
Hearthflame Mask
|
||||
Teal Style Card
|
||||
Crystal Cluster
|
||||
Health Mochi
|
||||
Muscle Mochi
|
||||
Resist Mochi
|
||||
Genius Mochi
|
||||
Clever Mochi
|
||||
Swift Mochi
|
||||
Simple Chairs
|
||||
Academy Chairs
|
||||
Academy Chairs
|
||||
Whimsical Chairs
|
||||
Leafy Chairs
|
||||
Spooky Chairs
|
||||
Plaid Chairs (Y)
|
||||
Plaid Chairs (B)
|
||||
Plaid Chairs (R)
|
||||
B&W Grass Chairs
|
||||
Battle Chairs
|
||||
Monstrous Chairs
|
||||
Striped Chairs
|
||||
Diamond Chairs
|
||||
Polka-Dot Chairs
|
||||
Lilac Chairs
|
||||
Mint Chairs
|
||||
Peach Chairs
|
||||
Yellow Chairs
|
||||
Blue Chairs
|
||||
Pink Chairs
|
||||
Ekans Fang
|
||||
Sandshrew Claw
|
||||
Cleffa Fur
|
||||
Vulpix Fur
|
||||
Poliwag Slime
|
||||
Bellsprout Vine
|
||||
Geodude Fragment
|
||||
Koffing Gas
|
||||
Munchlax Fang
|
||||
Sentret Fur
|
||||
Hoothoot Feather
|
||||
Spinarak Thread
|
||||
Aipom Hair
|
||||
Yanma Spike
|
||||
Gligar Fang
|
||||
Slugma Lava
|
||||
Swinub Hair
|
||||
Poochyena Fang
|
||||
Lotad Leaf
|
||||
Seedot Stem
|
||||
Nosepass Fragment
|
||||
Volbeat Fluid
|
||||
Illumise Fluid
|
||||
Corphish Shell
|
||||
Feebas Scales
|
||||
Duskull Fragment
|
||||
Chingling Fragment
|
||||
Timburr Sweat
|
||||
Sewaddle Leaf
|
||||
Ducklett Feather
|
||||
Litwick Soot
|
||||
Mienfoo Claw
|
||||
Vullaby Feather
|
||||
Carbink Jewel
|
||||
Phantump Twig
|
||||
Grubbin Thread
|
||||
Cutiefly Powder
|
||||
Jangmo-o Scales
|
||||
Cramorant Down
|
||||
Morpeko Snack
|
||||
Poltchageist Powder
|
||||
Fresh-Start Mochi
|
||||
Roto-Stick
|
||||
Glimmering Charm
|
||||
Metal Alloy
|
||||
Indigo Style Card
|
||||
Oddish Leaf
|
||||
Tentacool Stinger
|
||||
Doduo Down
|
||||
Seel Fur
|
||||
Exeggcute Shell
|
||||
Tyrogue Sweat
|
||||
Rhyhorn Fang
|
||||
Horsea Ink
|
||||
Elekid Fur
|
||||
Magby Hair
|
||||
Lapras Teardrop
|
||||
Porygon Fragment
|
||||
Chinchou Sparks
|
||||
Snubbull Hair
|
||||
Skarmory Feather
|
||||
Smeargle Paint
|
||||
Plusle Fur
|
||||
Minun Fur
|
||||
Trapinch Shell
|
||||
Beldum Claw
|
||||
Cranidos Spike
|
||||
Shieldon Claw
|
||||
Blitzle Mane Hair
|
||||
Drilbur Claw
|
||||
Cottonee Fluff
|
||||
Scraggy Sweat
|
||||
Minccino Fur
|
||||
Solosis Gel
|
||||
Joltik Thread
|
||||
Golett Shard
|
||||
Espurr Fur
|
||||
Inkay Ink
|
||||
Pikipek Feather
|
||||
Dewpider Thread
|
||||
Comfey Flower
|
||||
Minior Shell
|
||||
Milcery Cream
|
||||
Duraludon Tarnish
|
||||
Articuno Treat
|
||||
Zapdos Treat
|
||||
Moltres Treat
|
||||
Raikou Treat
|
||||
Entei Treat
|
||||
Suicune Treat
|
||||
Lugia Treat
|
||||
Ho-Oh Treat
|
||||
Latias Treat
|
||||
Latios Treat
|
||||
Kyogre Treat
|
||||
Groudon Treat
|
||||
Rayquaza Treat
|
||||
Cobalion Treat
|
||||
Terrakion Treat
|
||||
Virizion Treat
|
||||
Reshiram Treat
|
||||
Zekrom Treat
|
||||
Kyurem Treat
|
||||
Solgaleo Treat
|
||||
Lunala Treat
|
||||
Necrozma Treat
|
||||
Kubfu Treat
|
||||
Glastrier Treat
|
||||
Spectrier Treat
|
||||
Indigo Disk
|
||||
Fiery Pick
|
||||
Stellar Tera Shard
|
||||
Mythical Pecha Berry
|
||||
Blueberry Tablecloth
|
||||
Blueberry Chairs
|
||||
Synchro Machine
|
||||
Meteorite
|
||||
Scarlet Book
|
||||
Violet Book
|
||||
Briar’s Book
|
||||
Seed of Mastery
|
||||
Clefablite
|
||||
Victreebelite
|
||||
Starminite
|
||||
Dragoninite
|
||||
Meganiumite
|
||||
Feraligite
|
||||
Skarmorite
|
||||
Froslassite
|
||||
|
||||
|
||||
Emboarite
|
||||
Excadrite
|
||||
Scolipite
|
||||
Scraftinite
|
||||
Eelektrossite
|
||||
Chandelurite
|
||||
Chesnaughtite
|
||||
Delphoxite
|
||||
Greninjite
|
||||
Pyroarite
|
||||
Floettite
|
||||
Malamarite
|
||||
Barbaracite
|
||||
Dragalgite
|
||||
Hawluchanite
|
||||
Zygardite
|
||||
Drampanite
|
||||
|
||||
Falinksite
|
||||
Key to Room 202
|
||||
Super Lumiose Galette
|
||||
Lab Key Card A
|
||||
Lab Key Card B
|
||||
Lab Key Card C
|
||||
|
||||
|
||||
Pebble
|
||||
Cherished Ring
|
||||
Autographed Plush
|
||||
Tasty Trash
|
||||
Revitalizing Twig
|
||||
Lida’s Things
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Mega Shard
|
||||
Colorful Screw
|
||||
Red Canari Plush
|
||||
Red Canari Plush
|
||||
Red Canari Plush
|
||||
Gold Canari Plush
|
||||
Gold Canari Plush
|
||||
Gold Canari Plush
|
||||
Pink Canari Plush
|
||||
Pink Canari Plush
|
||||
Pink Canari Plush
|
||||
Green Canari Plush
|
||||
Green Canari Plush
|
||||
Green Canari Plush
|
||||
Blue Canari Plush
|
||||
Blue Canari Plush
|
||||
Blue Canari Plush
|
||||
Yellow Dish
|
||||
3076
SwitchGiftDataManager.Core/Resources/SCVIClothingBags.txt
Normal file
3076
SwitchGiftDataManager.Core/Resources/SCVIClothingBags.txt
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,66 +1,66 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Authors>Manu098vm</Authors>
|
||||
<Copyright>Copyright (C) 2024 Manu098vm</Copyright>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<PackageTags>pokemon; mystery gift; wondercard; reader; nintendo; bcat; event injection;</PackageTags>
|
||||
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||
<Company>Project Pokémon</Company>
|
||||
<PackageProjectUrl>https://github.com/Manu098vm/Switch-Gift-Data-Manager</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/Manu098vm/Switch-Gift-Data-Manager</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<Configurations>Debug;Release;WSL</Configurations>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Authors>Manu098vm</Authors>
|
||||
<Copyright>Copyright (C) 2022 Manu098vm</Copyright>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<PackageTags>pokemon; mystery gift; wondercard; reader; nintendo; bcat; event injection;</PackageTags>
|
||||
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||
<Company>Project Pokémon</Company>
|
||||
<PackageProjectUrl>https://github.com/Manu098vm/Switch-Gift-Data-Manager</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/Manu098vm/Switch-Gift-Data-Manager</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<Configurations>Debug;Release;WSL</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='WSL|AnyCPU'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='WSL|AnyCPU'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\.editorconfig" Link=".editorconfig" />
|
||||
<None Include="..\README.md">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\.editorconfig" Link=".editorconfig" />
|
||||
<None Include="..\README.md">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\LICENSE">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\LICENSE">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Octokit" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Octokit" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using SwitchGiftDataManager.Core;
|
||||
using System.Diagnostics;
|
||||
using SwitchGiftDataManager.Core;
|
||||
using Octokit;
|
||||
|
||||
namespace SwitchGiftDataManager.Core
|
||||
|
|
|
|||
920
SwitchGiftDataManager.WinForm/MainWindow.Designer.cs
generated
920
SwitchGiftDataManager.WinForm/MainWindow.Designer.cs
generated
|
|
@ -1,518 +1,414 @@
|
|||
namespace SwitchGiftDataManager.WinForm;
|
||||
|
||||
partial class MainWindow
|
||||
namespace SwitchGiftDataManager.WinForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
partial class MainWindow
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
components.Dispose();
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainWindow));
|
||||
this.BtnLGPE = new System.Windows.Forms.Button();
|
||||
this.BtnSWSH = new System.Windows.Forms.Button();
|
||||
this.BtnBDSP = new System.Windows.Forms.Button();
|
||||
this.BtnSCVI = new System.Windows.Forms.Button();
|
||||
this.BtnPLA = new System.Windows.Forms.Button();
|
||||
this.ListBoxWC = new System.Windows.Forms.ListBox();
|
||||
this.BtnOpen = new System.Windows.Forms.Button();
|
||||
this.BtnSave = new System.Windows.Forms.Button();
|
||||
this.GrpBCAT = new System.Windows.Forms.GroupBox();
|
||||
this.BtnApply = new System.Windows.Forms.Button();
|
||||
this.GrpContent = new System.Windows.Forms.GroupBox();
|
||||
this.LblInfo7 = new System.Windows.Forms.Label();
|
||||
this.LblInfo6 = new System.Windows.Forms.Label();
|
||||
this.LblInfo5 = new System.Windows.Forms.Label();
|
||||
this.LblInfo4 = new System.Windows.Forms.Label();
|
||||
this.LblInfo3 = new System.Windows.Forms.Label();
|
||||
this.LblInfo2 = new System.Windows.Forms.Label();
|
||||
this.LblInfo1 = new System.Windows.Forms.Label();
|
||||
this.TxtWCID = new System.Windows.Forms.TextBox();
|
||||
this.LblWCID = new System.Windows.Forms.Label();
|
||||
this.ContextMenuStripWC = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.BtnRemove = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.BtnRemoveAll = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.OpenFileDialogWC = new System.Windows.Forms.OpenFileDialog();
|
||||
this.ToolTipWcid = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.GrpBCAT.SuspendLayout();
|
||||
this.GrpContent.SuspendLayout();
|
||||
this.ContextMenuStripWC.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// BtnLGPE
|
||||
//
|
||||
this.BtnLGPE.AccessibleDescription = "";
|
||||
this.BtnLGPE.AccessibleName = "";
|
||||
this.BtnLGPE.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.BtnLGPE.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.BtnLGPE.Location = new System.Drawing.Point(5, 12);
|
||||
this.BtnLGPE.Name = "BtnLGPE";
|
||||
this.BtnLGPE.Size = new System.Drawing.Size(136, 60);
|
||||
this.BtnLGPE.TabIndex = 0;
|
||||
this.BtnLGPE.TabStop = false;
|
||||
this.BtnLGPE.Text = "LGPE";
|
||||
this.BtnLGPE.UseVisualStyleBackColor = true;
|
||||
this.BtnLGPE.Click += new System.EventHandler(this.BtnLGPE_Click);
|
||||
//
|
||||
// BtnSWSH
|
||||
//
|
||||
this.BtnSWSH.AccessibleDescription = "";
|
||||
this.BtnSWSH.AccessibleName = "";
|
||||
this.BtnSWSH.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.BtnSWSH.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.BtnSWSH.Location = new System.Drawing.Point(147, 12);
|
||||
this.BtnSWSH.Name = "BtnSWSH";
|
||||
this.BtnSWSH.Size = new System.Drawing.Size(136, 60);
|
||||
this.BtnSWSH.TabIndex = 1;
|
||||
this.BtnSWSH.TabStop = false;
|
||||
this.BtnSWSH.Text = "SWSH";
|
||||
this.BtnSWSH.UseVisualStyleBackColor = true;
|
||||
this.BtnSWSH.Click += new System.EventHandler(this.BtnSWSH_Click);
|
||||
//
|
||||
// BtnBDSP
|
||||
//
|
||||
this.BtnBDSP.AccessibleDescription = "";
|
||||
this.BtnBDSP.AccessibleName = "";
|
||||
this.BtnBDSP.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.BtnBDSP.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.BtnBDSP.Location = new System.Drawing.Point(289, 12);
|
||||
this.BtnBDSP.Name = "BtnBDSP";
|
||||
this.BtnBDSP.Size = new System.Drawing.Size(136, 60);
|
||||
this.BtnBDSP.TabIndex = 2;
|
||||
this.BtnBDSP.TabStop = false;
|
||||
this.BtnBDSP.Text = "BDSP";
|
||||
this.BtnBDSP.UseVisualStyleBackColor = true;
|
||||
this.BtnBDSP.Click += new System.EventHandler(this.BtnBDSP_Click);
|
||||
//
|
||||
// BtnSCVI
|
||||
//
|
||||
this.BtnSCVI.AccessibleDescription = "";
|
||||
this.BtnSCVI.AccessibleName = "";
|
||||
this.BtnSCVI.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.BtnSCVI.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.BtnSCVI.Location = new System.Drawing.Point(573, 12);
|
||||
this.BtnSCVI.Name = "BtnSCVI";
|
||||
this.BtnSCVI.Size = new System.Drawing.Size(136, 60);
|
||||
this.BtnSCVI.TabIndex = 3;
|
||||
this.BtnSCVI.TabStop = false;
|
||||
this.BtnSCVI.Text = "SCVI";
|
||||
this.BtnSCVI.UseVisualStyleBackColor = true;
|
||||
this.BtnSCVI.Click += new System.EventHandler(this.BtnSCVI_Click);
|
||||
//
|
||||
// BtnPLA
|
||||
//
|
||||
this.BtnPLA.AccessibleDescription = "";
|
||||
this.BtnPLA.AccessibleName = "";
|
||||
this.BtnPLA.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.BtnPLA.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.BtnPLA.Location = new System.Drawing.Point(431, 12);
|
||||
this.BtnPLA.Name = "BtnPLA";
|
||||
this.BtnPLA.Size = new System.Drawing.Size(136, 60);
|
||||
this.BtnPLA.TabIndex = 4;
|
||||
this.BtnPLA.TabStop = false;
|
||||
this.BtnPLA.Text = "PLA";
|
||||
this.BtnPLA.UseVisualStyleBackColor = true;
|
||||
this.BtnPLA.Click += new System.EventHandler(this.BtnPLA_Click);
|
||||
//
|
||||
// ListBoxWC
|
||||
//
|
||||
this.ListBoxWC.AllowDrop = true;
|
||||
this.ListBoxWC.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
|
||||
this.ListBoxWC.FormattingEnabled = true;
|
||||
this.ListBoxWC.ItemHeight = 20;
|
||||
this.ListBoxWC.Location = new System.Drawing.Point(7, 96);
|
||||
this.ListBoxWC.Name = "ListBoxWC";
|
||||
this.ListBoxWC.Size = new System.Drawing.Size(214, 304);
|
||||
this.ListBoxWC.TabIndex = 5;
|
||||
this.ToolTipWcid.SetToolTip(this.ListBoxWC, " Wondercards with duplicated WC ID will not be seen by the" +
|
||||
" game. ");
|
||||
this.ListBoxWC.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.ListBoxWC_DrawItem);
|
||||
this.ListBoxWC.SelectedIndexChanged += new System.EventHandler(this.ListBoxWC_SelectedIndexChanged);
|
||||
this.ListBoxWC.DragDrop += new System.Windows.Forms.DragEventHandler(this.FileDragDrop);
|
||||
this.ListBoxWC.DragEnter += new System.Windows.Forms.DragEventHandler(this.FileDragEnter);
|
||||
this.ListBoxWC.MouseUp += new System.Windows.Forms.MouseEventHandler(this.ListBoxWC_MouseUp);
|
||||
//
|
||||
// BtnOpen
|
||||
//
|
||||
this.BtnOpen.Location = new System.Drawing.Point(7, 26);
|
||||
this.BtnOpen.Name = "BtnOpen";
|
||||
this.BtnOpen.Size = new System.Drawing.Size(214, 29);
|
||||
this.BtnOpen.TabIndex = 6;
|
||||
this.BtnOpen.Text = "Open Wondercard Files...";
|
||||
this.BtnOpen.UseVisualStyleBackColor = true;
|
||||
this.BtnOpen.Click += new System.EventHandler(this.BtnOpen_Click);
|
||||
//
|
||||
// BtnSave
|
||||
//
|
||||
this.BtnSave.Enabled = false;
|
||||
this.BtnSave.Location = new System.Drawing.Point(6, 61);
|
||||
this.BtnSave.Name = "BtnSave";
|
||||
this.BtnSave.Size = new System.Drawing.Size(214, 29);
|
||||
this.BtnSave.TabIndex = 7;
|
||||
this.BtnSave.Text = "Save as BCAT Package...";
|
||||
this.BtnSave.UseVisualStyleBackColor = true;
|
||||
this.BtnSave.Click += new System.EventHandler(this.BtnSave_Click);
|
||||
//
|
||||
// GrpBCAT
|
||||
//
|
||||
this.GrpBCAT.Controls.Add(this.BtnApply);
|
||||
this.GrpBCAT.Controls.Add(this.GrpContent);
|
||||
this.GrpBCAT.Controls.Add(this.TxtWCID);
|
||||
this.GrpBCAT.Controls.Add(this.LblWCID);
|
||||
this.GrpBCAT.Controls.Add(this.ListBoxWC);
|
||||
this.GrpBCAT.Controls.Add(this.BtnSave);
|
||||
this.GrpBCAT.Controls.Add(this.BtnOpen);
|
||||
this.GrpBCAT.Enabled = false;
|
||||
this.GrpBCAT.Location = new System.Drawing.Point(5, 78);
|
||||
this.GrpBCAT.Name = "GrpBCAT";
|
||||
this.GrpBCAT.Size = new System.Drawing.Size(704, 409);
|
||||
this.GrpBCAT.TabIndex = 8;
|
||||
this.GrpBCAT.TabStop = false;
|
||||
this.GrpBCAT.Text = "BCAT Manager";
|
||||
//
|
||||
// BtnApply
|
||||
//
|
||||
this.BtnApply.Enabled = false;
|
||||
this.BtnApply.Location = new System.Drawing.Point(426, 368);
|
||||
this.BtnApply.Name = "BtnApply";
|
||||
this.BtnApply.Size = new System.Drawing.Size(97, 32);
|
||||
this.BtnApply.TabIndex = 11;
|
||||
this.BtnApply.Text = "Apply";
|
||||
this.BtnApply.UseVisualStyleBackColor = true;
|
||||
this.BtnApply.Click += new System.EventHandler(this.BtnApply_Click);
|
||||
//
|
||||
// GrpContent
|
||||
//
|
||||
this.GrpContent.Controls.Add(this.LblInfo7);
|
||||
this.GrpContent.Controls.Add(this.LblInfo6);
|
||||
this.GrpContent.Controls.Add(this.LblInfo5);
|
||||
this.GrpContent.Controls.Add(this.LblInfo4);
|
||||
this.GrpContent.Controls.Add(this.LblInfo3);
|
||||
this.GrpContent.Controls.Add(this.LblInfo2);
|
||||
this.GrpContent.Controls.Add(this.LblInfo1);
|
||||
this.GrpContent.Enabled = false;
|
||||
this.GrpContent.Location = new System.Drawing.Point(294, 99);
|
||||
this.GrpContent.Name = "GrpContent";
|
||||
this.GrpContent.Size = new System.Drawing.Size(358, 263);
|
||||
this.GrpContent.TabIndex = 10;
|
||||
this.GrpContent.TabStop = false;
|
||||
this.GrpContent.Text = "Gift Content";
|
||||
//
|
||||
// LblInfo7
|
||||
//
|
||||
this.LblInfo7.AutoSize = true;
|
||||
this.LblInfo7.Location = new System.Drawing.Point(158, 230);
|
||||
this.LblInfo7.Name = "LblInfo7";
|
||||
this.LblInfo7.Size = new System.Drawing.Size(49, 20);
|
||||
this.LblInfo7.TabIndex = 6;
|
||||
this.LblInfo7.Text = "Info_7";
|
||||
this.LblInfo7.Visible = false;
|
||||
this.LblInfo7.SizeChanged += new System.EventHandler(this.LblInfo_SizeChanged);
|
||||
//
|
||||
// LblInfo6
|
||||
//
|
||||
this.LblInfo6.AutoSize = true;
|
||||
this.LblInfo6.Location = new System.Drawing.Point(158, 198);
|
||||
this.LblInfo6.Name = "LblInfo6";
|
||||
this.LblInfo6.Size = new System.Drawing.Size(49, 20);
|
||||
this.LblInfo6.TabIndex = 5;
|
||||
this.LblInfo6.Text = "Info_6";
|
||||
this.LblInfo6.Visible = false;
|
||||
this.LblInfo6.SizeChanged += new System.EventHandler(this.LblInfo_SizeChanged);
|
||||
//
|
||||
// LblInfo5
|
||||
//
|
||||
this.LblInfo5.AutoSize = true;
|
||||
this.LblInfo5.Location = new System.Drawing.Point(158, 165);
|
||||
this.LblInfo5.Name = "LblInfo5";
|
||||
this.LblInfo5.Size = new System.Drawing.Size(49, 20);
|
||||
this.LblInfo5.TabIndex = 4;
|
||||
this.LblInfo5.Text = "Info_5";
|
||||
this.LblInfo5.Visible = false;
|
||||
this.LblInfo5.SizeChanged += new System.EventHandler(this.LblInfo_SizeChanged);
|
||||
//
|
||||
// LblInfo4
|
||||
//
|
||||
this.LblInfo4.AutoSize = true;
|
||||
this.LblInfo4.Location = new System.Drawing.Point(158, 132);
|
||||
this.LblInfo4.Name = "LblInfo4";
|
||||
this.LblInfo4.Size = new System.Drawing.Size(49, 20);
|
||||
this.LblInfo4.TabIndex = 3;
|
||||
this.LblInfo4.Text = "Info_4";
|
||||
this.LblInfo4.Visible = false;
|
||||
this.LblInfo4.SizeChanged += new System.EventHandler(this.LblInfo_SizeChanged);
|
||||
//
|
||||
// LblInfo3
|
||||
//
|
||||
this.LblInfo3.AutoSize = true;
|
||||
this.LblInfo3.Location = new System.Drawing.Point(158, 99);
|
||||
this.LblInfo3.Name = "LblInfo3";
|
||||
this.LblInfo3.Size = new System.Drawing.Size(49, 20);
|
||||
this.LblInfo3.TabIndex = 2;
|
||||
this.LblInfo3.Text = "Info_3";
|
||||
this.LblInfo3.Visible = false;
|
||||
this.LblInfo3.SizeChanged += new System.EventHandler(this.LblInfo_SizeChanged);
|
||||
//
|
||||
// LblInfo2
|
||||
//
|
||||
this.LblInfo2.AutoSize = true;
|
||||
this.LblInfo2.Location = new System.Drawing.Point(158, 66);
|
||||
this.LblInfo2.Name = "LblInfo2";
|
||||
this.LblInfo2.Size = new System.Drawing.Size(49, 20);
|
||||
this.LblInfo2.TabIndex = 1;
|
||||
this.LblInfo2.Text = "Info_2";
|
||||
this.LblInfo2.Visible = false;
|
||||
this.LblInfo2.SizeChanged += new System.EventHandler(this.LblInfo_SizeChanged);
|
||||
//
|
||||
// LblInfo1
|
||||
//
|
||||
this.LblInfo1.AutoSize = true;
|
||||
this.LblInfo1.Location = new System.Drawing.Point(158, 33);
|
||||
this.LblInfo1.Name = "LblInfo1";
|
||||
this.LblInfo1.Size = new System.Drawing.Size(49, 20);
|
||||
this.LblInfo1.TabIndex = 0;
|
||||
this.LblInfo1.Text = "Info_1";
|
||||
this.LblInfo1.Visible = false;
|
||||
this.LblInfo1.SizeChanged += new System.EventHandler(this.LblInfo_SizeChanged);
|
||||
//
|
||||
// TxtWCID
|
||||
//
|
||||
this.TxtWCID.Enabled = false;
|
||||
this.TxtWCID.Location = new System.Drawing.Point(435, 63);
|
||||
this.TxtWCID.MaxLength = 4;
|
||||
this.TxtWCID.Name = "TxtWCID";
|
||||
this.TxtWCID.Size = new System.Drawing.Size(115, 27);
|
||||
this.TxtWCID.TabIndex = 9;
|
||||
this.TxtWCID.TextChanged += new System.EventHandler(this.TxtWCID_TextChanged);
|
||||
this.TxtWCID.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.TxtWCID_KeyPress);
|
||||
//
|
||||
// LblWCID
|
||||
//
|
||||
this.LblWCID.AutoSize = true;
|
||||
this.LblWCID.Enabled = false;
|
||||
this.LblWCID.Location = new System.Drawing.Point(375, 66);
|
||||
this.LblWCID.Name = "LblWCID";
|
||||
this.LblWCID.Size = new System.Drawing.Size(54, 20);
|
||||
this.LblWCID.TabIndex = 8;
|
||||
this.LblWCID.Text = "WC ID:";
|
||||
//
|
||||
// ContextMenuStripWC
|
||||
//
|
||||
this.ContextMenuStripWC.ImageScalingSize = new System.Drawing.Size(20, 20);
|
||||
this.ContextMenuStripWC.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.BtnRemove,
|
||||
this.BtnRemoveAll});
|
||||
this.ContextMenuStripWC.Name = "ConextMenuStripWC";
|
||||
this.ContextMenuStripWC.Size = new System.Drawing.Size(155, 52);
|
||||
this.ContextMenuStripWC.Text = "Remove";
|
||||
//
|
||||
// BtnRemove
|
||||
//
|
||||
this.BtnRemove.Name = "BtnRemove";
|
||||
this.BtnRemove.Size = new System.Drawing.Size(154, 24);
|
||||
this.BtnRemove.Text = "Remove";
|
||||
this.BtnRemove.Click += new System.EventHandler(this.BtnRemove_Click);
|
||||
//
|
||||
// BtnRemoveAll
|
||||
//
|
||||
this.BtnRemoveAll.Name = "BtnRemoveAll";
|
||||
this.BtnRemoveAll.Size = new System.Drawing.Size(154, 24);
|
||||
this.BtnRemoveAll.Text = "Remove All";
|
||||
this.BtnRemoveAll.Click += new System.EventHandler(this.BtnRemoveAll_Click);
|
||||
//
|
||||
// OpenFileDialogWC
|
||||
//
|
||||
this.OpenFileDialogWC.Multiselect = true;
|
||||
//
|
||||
// ToolTipWcid
|
||||
//
|
||||
this.ToolTipWcid.AutoPopDelay = 100000;
|
||||
this.ToolTipWcid.InitialDelay = 500;
|
||||
this.ToolTipWcid.OwnerDraw = true;
|
||||
this.ToolTipWcid.ReshowDelay = 100;
|
||||
this.ToolTipWcid.UseAnimation = false;
|
||||
this.ToolTipWcid.UseFading = false;
|
||||
this.ToolTipWcid.Draw += new System.Windows.Forms.DrawToolTipEventHandler(this.ToolTipWcid_Draw);
|
||||
//
|
||||
// MainWindow
|
||||
//
|
||||
this.AllowDrop = true;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(715, 495);
|
||||
this.Controls.Add(this.GrpBCAT);
|
||||
this.Controls.Add(this.BtnPLA);
|
||||
this.Controls.Add(this.BtnSCVI);
|
||||
this.Controls.Add(this.BtnBDSP);
|
||||
this.Controls.Add(this.BtnSWSH);
|
||||
this.Controls.Add(this.BtnLGPE);
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "MainWindow";
|
||||
this.Text = "Switch Gift Data Manager v";
|
||||
this.DragDrop += new System.Windows.Forms.DragEventHandler(this.FileDragDrop);
|
||||
this.DragEnter += new System.Windows.Forms.DragEventHandler(this.FileDragEnter);
|
||||
this.GrpBCAT.ResumeLayout(false);
|
||||
this.GrpBCAT.PerformLayout();
|
||||
this.GrpContent.ResumeLayout(false);
|
||||
this.GrpContent.PerformLayout();
|
||||
this.ContextMenuStripWC.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Button BtnLGPE;
|
||||
private Button BtnSWSH;
|
||||
private Button BtnBDSP;
|
||||
private Button BtnSCVI;
|
||||
private Button BtnPLA;
|
||||
private ListBox ListBoxWC;
|
||||
private Button BtnOpen;
|
||||
private Button BtnSave;
|
||||
private GroupBox GrpBCAT;
|
||||
private Button BtnApply;
|
||||
private GroupBox GrpContent;
|
||||
private TextBox TxtWCID;
|
||||
private Label LblWCID;
|
||||
private ContextMenuStrip ContextMenuStripWC;
|
||||
private ToolStripMenuItem BtnRemove;
|
||||
private Label LblInfo5;
|
||||
private Label LblInfo4;
|
||||
private Label LblInfo3;
|
||||
private Label LblInfo2;
|
||||
private Label LblInfo1;
|
||||
private OpenFileDialog OpenFileDialogWC;
|
||||
private ToolStripMenuItem BtnRemoveAll;
|
||||
private ToolTip ToolTipWcid;
|
||||
private Label LblInfo7;
|
||||
private Label LblInfo6;
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainWindow));
|
||||
BtnLGPE = new Button();
|
||||
BtnSWSH = new Button();
|
||||
BtnBDSP = new Button();
|
||||
BtnSCVI = new Button();
|
||||
BtnPLA = new Button();
|
||||
ListBoxWC = new ListBox();
|
||||
BtnOpen = new Button();
|
||||
BtnSave = new Button();
|
||||
GrpBCAT = new GroupBox();
|
||||
cmbRedemptionMethod = new ComboBox();
|
||||
ChkRepeatable = new CheckBox();
|
||||
lblRedemptionMethod = new Label();
|
||||
BtnApply = new Button();
|
||||
GrpContent = new GroupBox();
|
||||
LblInfo7 = new Label();
|
||||
LblInfo6 = new Label();
|
||||
LblInfo5 = new Label();
|
||||
LblInfo4 = new Label();
|
||||
LblInfo3 = new Label();
|
||||
LblInfo2 = new Label();
|
||||
LblInfo1 = new Label();
|
||||
TxtWCID = new TextBox();
|
||||
LblWCID = new Label();
|
||||
ContextMenuStripWC = new ContextMenuStrip(components);
|
||||
BtnRemove = new ToolStripMenuItem();
|
||||
BtnRemoveAll = new ToolStripMenuItem();
|
||||
OpenFileDialogWC = new OpenFileDialog();
|
||||
ToolTipWcid = new ToolTip(components);
|
||||
MenuStrip = new MenuStrip();
|
||||
ToolsToolStripMenu = new ToolStripMenuItem();
|
||||
MenuItemMGDB = new ToolStripMenuItem();
|
||||
toolTipRedemptionMethod = new ToolTip(components);
|
||||
BtnZA = new Button();
|
||||
GrpBCAT.SuspendLayout();
|
||||
GrpContent.SuspendLayout();
|
||||
ContextMenuStripWC.SuspendLayout();
|
||||
MenuStrip.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// BtnLGPE
|
||||
//
|
||||
BtnLGPE.AccessibleDescription = "";
|
||||
BtnLGPE.AccessibleName = "";
|
||||
BtnLGPE.Cursor = Cursors.Hand;
|
||||
BtnLGPE.FlatStyle = FlatStyle.Flat;
|
||||
BtnLGPE.Location = new Point(5, 37);
|
||||
BtnLGPE.Name = "BtnLGPE";
|
||||
BtnLGPE.Size = new Size(111, 60);
|
||||
BtnLGPE.TabIndex = 0;
|
||||
BtnLGPE.TabStop = false;
|
||||
BtnLGPE.Text = "LGPE";
|
||||
BtnLGPE.UseVisualStyleBackColor = true;
|
||||
BtnLGPE.Click += BtnLGPE_Click;
|
||||
//
|
||||
// BtnSWSH
|
||||
//
|
||||
BtnSWSH.AccessibleDescription = "";
|
||||
BtnSWSH.AccessibleName = "";
|
||||
BtnSWSH.Cursor = Cursors.Hand;
|
||||
BtnSWSH.FlatStyle = FlatStyle.Flat;
|
||||
BtnSWSH.Location = new Point(122, 37);
|
||||
BtnSWSH.Name = "BtnSWSH";
|
||||
BtnSWSH.Size = new Size(111, 60);
|
||||
BtnSWSH.TabIndex = 1;
|
||||
BtnSWSH.TabStop = false;
|
||||
BtnSWSH.Text = "SWSH";
|
||||
BtnSWSH.UseVisualStyleBackColor = true;
|
||||
BtnSWSH.Click += BtnSWSH_Click;
|
||||
//
|
||||
// BtnBDSP
|
||||
//
|
||||
BtnBDSP.AccessibleDescription = "";
|
||||
BtnBDSP.AccessibleName = "";
|
||||
BtnBDSP.Cursor = Cursors.Hand;
|
||||
BtnBDSP.FlatStyle = FlatStyle.Flat;
|
||||
BtnBDSP.Location = new Point(239, 37);
|
||||
BtnBDSP.Name = "BtnBDSP";
|
||||
BtnBDSP.Size = new Size(111, 60);
|
||||
BtnBDSP.TabIndex = 2;
|
||||
BtnBDSP.TabStop = false;
|
||||
BtnBDSP.Text = "BDSP";
|
||||
BtnBDSP.UseVisualStyleBackColor = true;
|
||||
BtnBDSP.Click += BtnBDSP_Click;
|
||||
//
|
||||
// BtnSCVI
|
||||
//
|
||||
BtnSCVI.AccessibleDescription = "";
|
||||
BtnSCVI.AccessibleName = "";
|
||||
BtnSCVI.Cursor = Cursors.Hand;
|
||||
BtnSCVI.FlatStyle = FlatStyle.Flat;
|
||||
BtnSCVI.Location = new Point(473, 37);
|
||||
BtnSCVI.Name = "BtnSCVI";
|
||||
BtnSCVI.Size = new Size(111, 60);
|
||||
BtnSCVI.TabIndex = 3;
|
||||
BtnSCVI.TabStop = false;
|
||||
BtnSCVI.Text = "SCVI";
|
||||
BtnSCVI.UseVisualStyleBackColor = true;
|
||||
BtnSCVI.Click += BtnSCVI_Click;
|
||||
//
|
||||
// BtnPLA
|
||||
//
|
||||
BtnPLA.AccessibleDescription = "";
|
||||
BtnPLA.AccessibleName = "";
|
||||
BtnPLA.Cursor = Cursors.Hand;
|
||||
BtnPLA.FlatStyle = FlatStyle.Flat;
|
||||
BtnPLA.Location = new Point(356, 37);
|
||||
BtnPLA.Name = "BtnPLA";
|
||||
BtnPLA.Size = new Size(111, 60);
|
||||
BtnPLA.TabIndex = 4;
|
||||
BtnPLA.TabStop = false;
|
||||
BtnPLA.Text = "PLA";
|
||||
BtnPLA.UseVisualStyleBackColor = true;
|
||||
BtnPLA.Click += BtnPLA_Click;
|
||||
//
|
||||
// ListBoxWC
|
||||
//
|
||||
ListBoxWC.AllowDrop = true;
|
||||
ListBoxWC.DrawMode = DrawMode.OwnerDrawFixed;
|
||||
ListBoxWC.FormattingEnabled = true;
|
||||
ListBoxWC.Location = new Point(7, 96);
|
||||
ListBoxWC.Name = "ListBoxWC";
|
||||
ListBoxWC.Size = new Size(214, 304);
|
||||
ListBoxWC.TabIndex = 5;
|
||||
ToolTipWcid.SetToolTip(ListBoxWC, " Wondercards with duplicated WC ID will not be seen by the game. ");
|
||||
ListBoxWC.DrawItem += ListBoxWC_DrawItem;
|
||||
ListBoxWC.SelectedIndexChanged += ListBoxWC_SelectedIndexChanged;
|
||||
ListBoxWC.DragDrop += FileDragDrop;
|
||||
ListBoxWC.DragEnter += FileDragEnter;
|
||||
ListBoxWC.MouseUp += ListBoxWC_MouseUp;
|
||||
//
|
||||
// BtnOpen
|
||||
//
|
||||
BtnOpen.Location = new Point(7, 26);
|
||||
BtnOpen.Name = "BtnOpen";
|
||||
BtnOpen.Size = new Size(214, 29);
|
||||
BtnOpen.TabIndex = 6;
|
||||
BtnOpen.Text = "Open Wondercard Files...";
|
||||
BtnOpen.UseVisualStyleBackColor = true;
|
||||
BtnOpen.Click += BtnOpen_Click;
|
||||
//
|
||||
// BtnSave
|
||||
//
|
||||
BtnSave.Enabled = false;
|
||||
BtnSave.Location = new Point(6, 61);
|
||||
BtnSave.Name = "BtnSave";
|
||||
BtnSave.Size = new Size(214, 29);
|
||||
BtnSave.TabIndex = 7;
|
||||
BtnSave.Text = "Save as BCAT Package...";
|
||||
BtnSave.UseVisualStyleBackColor = true;
|
||||
BtnSave.Click += BtnSave_Click;
|
||||
//
|
||||
// GrpBCAT
|
||||
//
|
||||
GrpBCAT.Controls.Add(cmbRedemptionMethod);
|
||||
GrpBCAT.Controls.Add(ChkRepeatable);
|
||||
GrpBCAT.Controls.Add(lblRedemptionMethod);
|
||||
GrpBCAT.Controls.Add(BtnApply);
|
||||
GrpBCAT.Controls.Add(GrpContent);
|
||||
GrpBCAT.Controls.Add(TxtWCID);
|
||||
GrpBCAT.Controls.Add(LblWCID);
|
||||
GrpBCAT.Controls.Add(ListBoxWC);
|
||||
GrpBCAT.Controls.Add(BtnSave);
|
||||
GrpBCAT.Controls.Add(BtnOpen);
|
||||
GrpBCAT.Enabled = false;
|
||||
GrpBCAT.Location = new Point(5, 103);
|
||||
GrpBCAT.Name = "GrpBCAT";
|
||||
GrpBCAT.Size = new Size(696, 409);
|
||||
GrpBCAT.TabIndex = 8;
|
||||
GrpBCAT.TabStop = false;
|
||||
GrpBCAT.Text = "BCAT Manager";
|
||||
//
|
||||
// cmbRedemptionMethod
|
||||
//
|
||||
cmbRedemptionMethod.Enabled = false;
|
||||
cmbRedemptionMethod.FormattingEnabled = true;
|
||||
cmbRedemptionMethod.Items.AddRange(new object[] { "Before v2.0.1", "After v2.0.1" });
|
||||
cmbRedemptionMethod.Location = new Point(501, 32);
|
||||
cmbRedemptionMethod.Name = "cmbRedemptionMethod";
|
||||
cmbRedemptionMethod.Size = new Size(121, 28);
|
||||
cmbRedemptionMethod.TabIndex = 14;
|
||||
cmbRedemptionMethod.Visible = false;
|
||||
cmbRedemptionMethod.SelectedIndexChanged += CmbRedemptionMethod_IndexChanged;
|
||||
//
|
||||
// ChkRepeatable
|
||||
//
|
||||
ChkRepeatable.AutoSize = true;
|
||||
ChkRepeatable.Location = new Point(510, 69);
|
||||
ChkRepeatable.Name = "ChkRepeatable";
|
||||
ChkRepeatable.Size = new Size(121, 24);
|
||||
ChkRepeatable.TabIndex = 12;
|
||||
ChkRepeatable.Text = "Is Repeatable";
|
||||
ChkRepeatable.UseVisualStyleBackColor = true;
|
||||
ChkRepeatable.CheckedChanged += ChkRepeatable_CheckedChanged;
|
||||
//
|
||||
// lblRedemptionMethod
|
||||
//
|
||||
lblRedemptionMethod.AutoSize = true;
|
||||
lblRedemptionMethod.Enabled = false;
|
||||
lblRedemptionMethod.Location = new Point(324, 35);
|
||||
lblRedemptionMethod.Name = "lblRedemptionMethod";
|
||||
lblRedemptionMethod.Size = new Size(171, 20);
|
||||
lblRedemptionMethod.TabIndex = 13;
|
||||
lblRedemptionMethod.Text = "Redemption Method (?):";
|
||||
lblRedemptionMethod.Visible = false;
|
||||
//
|
||||
// BtnApply
|
||||
//
|
||||
BtnApply.Enabled = false;
|
||||
BtnApply.Location = new Point(426, 368);
|
||||
BtnApply.Name = "BtnApply";
|
||||
BtnApply.Size = new Size(97, 32);
|
||||
BtnApply.TabIndex = 11;
|
||||
BtnApply.Text = "Apply";
|
||||
BtnApply.UseVisualStyleBackColor = true;
|
||||
BtnApply.Click += BtnApply_Click;
|
||||
//
|
||||
// GrpContent
|
||||
//
|
||||
GrpContent.Controls.Add(LblInfo7);
|
||||
GrpContent.Controls.Add(LblInfo6);
|
||||
GrpContent.Controls.Add(LblInfo5);
|
||||
GrpContent.Controls.Add(LblInfo4);
|
||||
GrpContent.Controls.Add(LblInfo3);
|
||||
GrpContent.Controls.Add(LblInfo2);
|
||||
GrpContent.Controls.Add(LblInfo1);
|
||||
GrpContent.Enabled = false;
|
||||
GrpContent.Location = new Point(294, 99);
|
||||
GrpContent.Name = "GrpContent";
|
||||
GrpContent.Size = new Size(358, 263);
|
||||
GrpContent.TabIndex = 10;
|
||||
GrpContent.TabStop = false;
|
||||
GrpContent.Text = "Gift Content";
|
||||
//
|
||||
// LblInfo7
|
||||
//
|
||||
LblInfo7.AutoSize = true;
|
||||
LblInfo7.Location = new Point(158, 230);
|
||||
LblInfo7.Name = "LblInfo7";
|
||||
LblInfo7.Size = new Size(49, 20);
|
||||
LblInfo7.TabIndex = 6;
|
||||
LblInfo7.Text = "Info_7";
|
||||
LblInfo7.Visible = false;
|
||||
LblInfo7.SizeChanged += LblInfo_SizeChanged;
|
||||
//
|
||||
// LblInfo6
|
||||
//
|
||||
LblInfo6.AutoSize = true;
|
||||
LblInfo6.Location = new Point(158, 198);
|
||||
LblInfo6.Name = "LblInfo6";
|
||||
LblInfo6.Size = new Size(49, 20);
|
||||
LblInfo6.TabIndex = 5;
|
||||
LblInfo6.Text = "Info_6";
|
||||
LblInfo6.Visible = false;
|
||||
LblInfo6.SizeChanged += LblInfo_SizeChanged;
|
||||
//
|
||||
// LblInfo5
|
||||
//
|
||||
LblInfo5.AutoSize = true;
|
||||
LblInfo5.Location = new Point(158, 165);
|
||||
LblInfo5.Name = "LblInfo5";
|
||||
LblInfo5.Size = new Size(49, 20);
|
||||
LblInfo5.TabIndex = 4;
|
||||
LblInfo5.Text = "Info_5";
|
||||
LblInfo5.Visible = false;
|
||||
LblInfo5.SizeChanged += LblInfo_SizeChanged;
|
||||
//
|
||||
// LblInfo4
|
||||
//
|
||||
LblInfo4.AutoSize = true;
|
||||
LblInfo4.Location = new Point(158, 132);
|
||||
LblInfo4.Name = "LblInfo4";
|
||||
LblInfo4.Size = new Size(49, 20);
|
||||
LblInfo4.TabIndex = 3;
|
||||
LblInfo4.Text = "Info_4";
|
||||
LblInfo4.Visible = false;
|
||||
LblInfo4.SizeChanged += LblInfo_SizeChanged;
|
||||
//
|
||||
// LblInfo3
|
||||
//
|
||||
LblInfo3.AutoSize = true;
|
||||
LblInfo3.Location = new Point(158, 99);
|
||||
LblInfo3.Name = "LblInfo3";
|
||||
LblInfo3.Size = new Size(49, 20);
|
||||
LblInfo3.TabIndex = 2;
|
||||
LblInfo3.Text = "Info_3";
|
||||
LblInfo3.Visible = false;
|
||||
LblInfo3.SizeChanged += LblInfo_SizeChanged;
|
||||
//
|
||||
// LblInfo2
|
||||
//
|
||||
LblInfo2.AutoSize = true;
|
||||
LblInfo2.Location = new Point(158, 66);
|
||||
LblInfo2.Name = "LblInfo2";
|
||||
LblInfo2.Size = new Size(49, 20);
|
||||
LblInfo2.TabIndex = 1;
|
||||
LblInfo2.Text = "Info_2";
|
||||
LblInfo2.Visible = false;
|
||||
LblInfo2.SizeChanged += LblInfo_SizeChanged;
|
||||
//
|
||||
// LblInfo1
|
||||
//
|
||||
LblInfo1.AutoSize = true;
|
||||
LblInfo1.Location = new Point(158, 33);
|
||||
LblInfo1.Name = "LblInfo1";
|
||||
LblInfo1.Size = new Size(49, 20);
|
||||
LblInfo1.TabIndex = 0;
|
||||
LblInfo1.Text = "Info_1";
|
||||
LblInfo1.Visible = false;
|
||||
LblInfo1.SizeChanged += LblInfo_SizeChanged;
|
||||
//
|
||||
// TxtWCID
|
||||
//
|
||||
TxtWCID.Enabled = false;
|
||||
TxtWCID.Location = new Point(379, 66);
|
||||
TxtWCID.MaxLength = 4;
|
||||
TxtWCID.Name = "TxtWCID";
|
||||
TxtWCID.Size = new Size(115, 27);
|
||||
TxtWCID.TabIndex = 9;
|
||||
TxtWCID.TextChanged += TxtWCID_TextChanged;
|
||||
TxtWCID.KeyPress += TxtWCID_KeyPress;
|
||||
//
|
||||
// LblWCID
|
||||
//
|
||||
LblWCID.AutoSize = true;
|
||||
LblWCID.Enabled = false;
|
||||
LblWCID.Location = new Point(319, 69);
|
||||
LblWCID.Name = "LblWCID";
|
||||
LblWCID.Size = new Size(54, 20);
|
||||
LblWCID.TabIndex = 8;
|
||||
LblWCID.Text = "WC ID:";
|
||||
//
|
||||
// ContextMenuStripWC
|
||||
//
|
||||
ContextMenuStripWC.ImageScalingSize = new Size(20, 20);
|
||||
ContextMenuStripWC.Items.AddRange(new ToolStripItem[] { BtnRemove, BtnRemoveAll });
|
||||
ContextMenuStripWC.Name = "ConextMenuStripWC";
|
||||
ContextMenuStripWC.Size = new Size(155, 52);
|
||||
ContextMenuStripWC.Text = "Remove";
|
||||
//
|
||||
// BtnRemove
|
||||
//
|
||||
BtnRemove.Name = "BtnRemove";
|
||||
BtnRemove.Size = new Size(154, 24);
|
||||
BtnRemove.Text = "Remove";
|
||||
BtnRemove.Click += BtnRemove_Click;
|
||||
//
|
||||
// BtnRemoveAll
|
||||
//
|
||||
BtnRemoveAll.Name = "BtnRemoveAll";
|
||||
BtnRemoveAll.Size = new Size(154, 24);
|
||||
BtnRemoveAll.Text = "Remove All";
|
||||
BtnRemoveAll.Click += BtnRemoveAll_Click;
|
||||
//
|
||||
// OpenFileDialogWC
|
||||
//
|
||||
OpenFileDialogWC.Multiselect = true;
|
||||
//
|
||||
// ToolTipWcid
|
||||
//
|
||||
ToolTipWcid.AutoPopDelay = 100000;
|
||||
ToolTipWcid.InitialDelay = 500;
|
||||
ToolTipWcid.OwnerDraw = true;
|
||||
ToolTipWcid.ReshowDelay = 100;
|
||||
ToolTipWcid.UseAnimation = false;
|
||||
ToolTipWcid.UseFading = false;
|
||||
ToolTipWcid.Draw += ToolTipWcid_Draw;
|
||||
//
|
||||
// MenuStrip
|
||||
//
|
||||
MenuStrip.BackColor = SystemColors.ButtonFace;
|
||||
MenuStrip.ImageScalingSize = new Size(20, 20);
|
||||
MenuStrip.Items.AddRange(new ToolStripItem[] { ToolsToolStripMenu });
|
||||
MenuStrip.Location = new Point(0, 0);
|
||||
MenuStrip.Name = "MenuStrip";
|
||||
MenuStrip.Size = new Size(709, 28);
|
||||
MenuStrip.TabIndex = 9;
|
||||
MenuStrip.Text = "menuStrip1";
|
||||
//
|
||||
// ToolsToolStripMenu
|
||||
//
|
||||
ToolsToolStripMenu.DropDownItems.AddRange(new ToolStripItem[] { MenuItemMGDB });
|
||||
ToolsToolStripMenu.Name = "ToolsToolStripMenu";
|
||||
ToolsToolStripMenu.Size = new Size(58, 24);
|
||||
ToolsToolStripMenu.Text = "Tools";
|
||||
//
|
||||
// MenuItemMGDB
|
||||
//
|
||||
MenuItemMGDB.Name = "MenuItemMGDB";
|
||||
MenuItemMGDB.Size = new Size(351, 26);
|
||||
MenuItemMGDB.Text = "Download latest Mystery Gift Database";
|
||||
MenuItemMGDB.Click += MenuItemMGDB_Click;
|
||||
//
|
||||
// toolTipRedemptionMethod
|
||||
//
|
||||
toolTipRedemptionMethod.AutoPopDelay = 50000;
|
||||
toolTipRedemptionMethod.InitialDelay = 500;
|
||||
toolTipRedemptionMethod.IsBalloon = true;
|
||||
toolTipRedemptionMethod.ReshowDelay = 100;
|
||||
toolTipRedemptionMethod.ShowAlways = true;
|
||||
toolTipRedemptionMethod.ToolTipIcon = ToolTipIcon.Info;
|
||||
toolTipRedemptionMethod.ToolTipTitle = "Redemption Date";
|
||||
//
|
||||
// BtnZA
|
||||
//
|
||||
BtnZA.AccessibleDescription = "";
|
||||
BtnZA.AccessibleName = "";
|
||||
BtnZA.Cursor = Cursors.Hand;
|
||||
BtnZA.FlatStyle = FlatStyle.Flat;
|
||||
BtnZA.Location = new Point(590, 37);
|
||||
BtnZA.Name = "BtnZA";
|
||||
BtnZA.Size = new Size(111, 60);
|
||||
BtnZA.TabIndex = 10;
|
||||
BtnZA.TabStop = false;
|
||||
BtnZA.Text = "ZA";
|
||||
BtnZA.UseVisualStyleBackColor = true;
|
||||
BtnZA.Click += BtnZA_Click;
|
||||
//
|
||||
// MainWindow
|
||||
//
|
||||
AllowDrop = true;
|
||||
AutoScaleDimensions = new SizeF(8F, 20F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(709, 518);
|
||||
Controls.Add(BtnZA);
|
||||
Controls.Add(MenuStrip);
|
||||
Controls.Add(GrpBCAT);
|
||||
Controls.Add(BtnPLA);
|
||||
Controls.Add(BtnSCVI);
|
||||
Controls.Add(BtnBDSP);
|
||||
Controls.Add(BtnSWSH);
|
||||
Controls.Add(BtnLGPE);
|
||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||
MainMenuStrip = MenuStrip;
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "MainWindow";
|
||||
Text = "Switch Gift Data Manager v";
|
||||
DragDrop += FileDragDrop;
|
||||
DragEnter += FileDragEnter;
|
||||
GrpBCAT.ResumeLayout(false);
|
||||
GrpBCAT.PerformLayout();
|
||||
GrpContent.ResumeLayout(false);
|
||||
GrpContent.PerformLayout();
|
||||
ContextMenuStripWC.ResumeLayout(false);
|
||||
MenuStrip.ResumeLayout(false);
|
||||
MenuStrip.PerformLayout();
|
||||
ResumeLayout(false);
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Button BtnLGPE;
|
||||
private Button BtnSWSH;
|
||||
private Button BtnBDSP;
|
||||
private Button BtnSCVI;
|
||||
private Button BtnPLA;
|
||||
private ListBox ListBoxWC;
|
||||
private Button BtnOpen;
|
||||
private Button BtnSave;
|
||||
private GroupBox GrpBCAT;
|
||||
private Button BtnApply;
|
||||
private GroupBox GrpContent;
|
||||
private TextBox TxtWCID;
|
||||
private Label LblWCID;
|
||||
private ContextMenuStrip ContextMenuStripWC;
|
||||
private ToolStripMenuItem BtnRemove;
|
||||
private Label LblInfo5;
|
||||
private Label LblInfo4;
|
||||
private Label LblInfo3;
|
||||
private Label LblInfo2;
|
||||
private Label LblInfo1;
|
||||
private OpenFileDialog OpenFileDialogWC;
|
||||
private ToolStripMenuItem BtnRemoveAll;
|
||||
private ToolTip ToolTipWcid;
|
||||
private Label LblInfo7;
|
||||
private Label LblInfo6;
|
||||
private CheckBox ChkRepeatable;
|
||||
private MenuStrip MenuStrip;
|
||||
private ToolStripMenuItem ToolsToolStripMenu;
|
||||
private ToolStripMenuItem MenuItemMGDB;
|
||||
private Label lblRedemptionMethod;
|
||||
private ToolTip toolTipRedemptionMethod;
|
||||
private ComboBox cmbRedemptionMethod;
|
||||
private Button BtnZA;
|
||||
}
|
||||
|
|
@ -1,511 +1,448 @@
|
|||
using System.Text.RegularExpressions;
|
||||
using SwitchGiftDataManager.Core;
|
||||
using Enums;
|
||||
using System.Diagnostics;
|
||||
using System.IO.Compression;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace SwitchGiftDataManager.WinForm;
|
||||
|
||||
public partial class MainWindow : Form
|
||||
{
|
||||
private Games CurrentGame = Games.None;
|
||||
private BCATManager PackageLGPE = new(Games.LGPE);
|
||||
private BCATManager PackageSWSH = new(Games.SWSH);
|
||||
private BCATManager PackageBDSP = new(Games.BDSP);
|
||||
private BCATManager PackagePLA = new(Games.PLA);
|
||||
private BCATManager PackageSCVI = new(Games.SCVI);
|
||||
private BCATManager PackageZA = new(Games.ZA);
|
||||
private List<ushort> Duplicated = new List<ushort>();
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
Task.Run(TryUpdate).Wait();
|
||||
InitializeComponent();
|
||||
Text += BCATManager.Version;
|
||||
cmbRedemptionMethod.SelectedIndex = 0;
|
||||
toolTipRedemptionMethod.SetToolTip(lblRedemptionMethod, $"The Pokémon Scarlet & Violet v2.0.1 Update, released on September 13 - 2023, introduced a new TID / SID handling method for Wondercards.{Environment.NewLine}" +
|
||||
$"This Pokémon Gift could be redeemed both before and after the v2.0.1 release, meaning it can be redeemed with either the old or new TID/SID handling method, depending on the redemption date.{Environment.NewLine}" +
|
||||
$"The redemption date can be changed with the homebrew 'switch-time'. If you're not going to use 'switch-time', please select 'After v2.0.1'.");
|
||||
}
|
||||
|
||||
private static async Task TryUpdate()
|
||||
{
|
||||
if (await GitHubUtil.IsUpdateAvailable())
|
||||
{
|
||||
var result = MessageBox.Show("A program update is available. Do you want to download the latest release?", "Update available", MessageBoxButtons.YesNo);
|
||||
if (result == DialogResult.Yes)
|
||||
Process.Start(new ProcessStartInfo { FileName = @"https://github.com/Manu098vm/Switch-Gift-Data-Manager/releases", UseShellExecute = true });
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangeGame(Games game)
|
||||
{
|
||||
GrpBCAT.Enabled = true;
|
||||
CurrentGame = game;
|
||||
RestoreMenu();
|
||||
EditFileFilter();
|
||||
EditGameButton();
|
||||
UpdateWCList();
|
||||
ListBoxWC.SelectedIndex = -1;
|
||||
DisableContent();
|
||||
}
|
||||
|
||||
private void RestoreMenu()
|
||||
{
|
||||
BtnLGPE.Enabled = true;
|
||||
BtnSWSH.Enabled = true;
|
||||
BtnBDSP.Enabled = true;
|
||||
BtnPLA.Enabled = true;
|
||||
BtnSCVI.Enabled = true;
|
||||
BtnZA.Enabled = true;
|
||||
|
||||
BtnLGPE.Font = new Font(BtnLGPE.Font.Name, BtnLGPE.Font.Size, FontStyle.Regular);
|
||||
BtnSWSH.Font = new Font(BtnSWSH.Font.Name, BtnSWSH.Font.Size, FontStyle.Regular);
|
||||
BtnBDSP.Font = new Font(BtnBDSP.Font.Name, BtnBDSP.Font.Size, FontStyle.Regular);
|
||||
BtnPLA.Font = new Font(BtnPLA.Font.Name, BtnPLA.Font.Size, FontStyle.Regular);
|
||||
BtnSCVI.Font = new Font(BtnSCVI.Font.Name, BtnSCVI.Font.Size, FontStyle.Regular);
|
||||
BtnZA.Font = new Font(BtnZA.Font.Name, BtnZA.Font.Size, FontStyle.Regular);
|
||||
}
|
||||
|
||||
private void EditFileFilter()
|
||||
{
|
||||
OpenFileDialogWC.Filter = CurrentGame switch
|
||||
{
|
||||
Games.LGPE => "wb7full files (*.wb7full)|*.wb7full|All files (*.*)|*.*",
|
||||
Games.SWSH => "wc8 files (*.wc8)|*.wc8|All files (*.*)|*.*",
|
||||
Games.BDSP => "wb8 files (*.wb8)|*.wb8|All files (*.*)|*.*",
|
||||
Games.PLA => "wa8 files (*.wa8)|*.wa8|All files (*.*)|*.*",
|
||||
Games.SCVI => "wc9 files (*.wc9)|*.wc9|All files (*.*)|*.*",
|
||||
Games.ZA => "wa9 files (*.wa9)|*.wa9|All files (*.*)|*.*",
|
||||
_ => "All files (*.*)|*.*",
|
||||
};
|
||||
}
|
||||
|
||||
private void EditGameButton()
|
||||
{
|
||||
Button btn = CurrentGame switch
|
||||
{
|
||||
Games.LGPE => BtnLGPE,
|
||||
Games.SWSH => BtnSWSH,
|
||||
Games.BDSP => BtnBDSP,
|
||||
Games.PLA => BtnPLA,
|
||||
Games.SCVI => BtnSCVI,
|
||||
Games.ZA => BtnZA,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
EditSelectedButton(btn);
|
||||
}
|
||||
|
||||
private void EditSelectedButton(Button btn)
|
||||
{
|
||||
btn.Font = new Font(btn.Font.Name, btn.Font.Size, FontStyle.Bold);
|
||||
btn.Enabled = false;
|
||||
}
|
||||
|
||||
private void UpdateWCList()
|
||||
{
|
||||
if (ListBoxWC.Items.Count > 0)
|
||||
ListBoxWC.Items.Clear();
|
||||
|
||||
var list = CurrentGame switch
|
||||
{
|
||||
Games.LGPE => PackageLGPE.GetListNames(),
|
||||
Games.SWSH => PackageSWSH.GetListNames(),
|
||||
Games.BDSP => PackageBDSP.GetListNames(),
|
||||
Games.PLA => PackagePLA.GetListNames(),
|
||||
Games.SCVI => PackageSCVI.GetListNames(),
|
||||
Games.ZA => PackageZA.GetListNames(),
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
UpdateDuplicatedList();
|
||||
|
||||
foreach (var el in list)
|
||||
ListBoxWC.Items.Add(el);
|
||||
|
||||
if (ListBoxWC.Items.Count > 0)
|
||||
BtnSave.Enabled = true;
|
||||
else
|
||||
BtnSave.Enabled = false;
|
||||
}
|
||||
|
||||
private void UpdateDuplicatedList()
|
||||
{
|
||||
var list = GetCurrentList().GetDuplicatedWCID();
|
||||
if (list != null)
|
||||
Duplicated = list;
|
||||
else
|
||||
Duplicated = new List<ushort> { 0 };
|
||||
}
|
||||
|
||||
private BCATManager GetCurrentList()
|
||||
{
|
||||
return CurrentGame switch
|
||||
{
|
||||
Games.LGPE => PackageLGPE,
|
||||
Games.SWSH => PackageSWSH,
|
||||
Games.BDSP => PackageBDSP,
|
||||
Games.PLA => PackagePLA,
|
||||
Games.SCVI => PackageSCVI,
|
||||
Games.ZA => PackageZA,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
}
|
||||
|
||||
private void LoadLocalFiles(string[] files)
|
||||
{
|
||||
DisableContent();
|
||||
var list = GetCurrentList();
|
||||
var errList = new List<string>();
|
||||
foreach (var path in files)
|
||||
{
|
||||
var data = File.ReadAllBytes(path);
|
||||
var success = list.TryAddWondercards(data.AsSpan());
|
||||
if (!success)
|
||||
{
|
||||
if (errList.Count == 0)
|
||||
if (CurrentGame is Games.LGPE && list.Count() >= 1)
|
||||
errList.Add("LGPE only supports one (1) wondercard at a time. Aborted file(s):\n");
|
||||
else
|
||||
errList.Add($"Attempted to load invalid files. Aborted file(s):\n");
|
||||
errList.Add($"- {Path.GetFileName(path)}");
|
||||
}
|
||||
}
|
||||
|
||||
if (errList.Count > 0)
|
||||
{
|
||||
var msg = "";
|
||||
foreach (var err in errList)
|
||||
msg = $"{msg}\n{err}";
|
||||
MessageBox.Show(msg);
|
||||
}
|
||||
|
||||
list.Sort();
|
||||
UpdateWCList();
|
||||
}
|
||||
|
||||
private void BtnLGPE_Click(object sender, EventArgs e) => ChangeGame(Games.LGPE);
|
||||
|
||||
private void BtnSWSH_Click(object sender, EventArgs e) => ChangeGame(Games.SWSH);
|
||||
|
||||
private void BtnBDSP_Click(object sender, EventArgs e) => ChangeGame(Games.BDSP);
|
||||
|
||||
private void BtnPLA_Click(object sender, EventArgs e) => ChangeGame(Games.PLA);
|
||||
|
||||
private void BtnSCVI_Click(object sender, EventArgs e) => ChangeGame(Games.SCVI);
|
||||
|
||||
private void BtnZA_Click(object sender, EventArgs e) => ChangeGame(Games.ZA);
|
||||
|
||||
private void BtnSave_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.Enabled = false;
|
||||
var saveForm = new SaveWindow(GetCurrentList(), CurrentGame);
|
||||
saveForm.FormClosed += (s, e) => this.Enabled = true;
|
||||
saveForm.Location = this.Location;
|
||||
saveForm.Show();
|
||||
}
|
||||
|
||||
private void BtnApply_Click(object sender, EventArgs e)
|
||||
{
|
||||
var list = GetCurrentList();
|
||||
var wcid = UInt16.Parse(TxtWCID.Text);
|
||||
var repeatable = ChkRepeatable.Checked;
|
||||
var isBefore201 = cmbRedemptionMethod.SelectedIndex == 0;
|
||||
|
||||
if (wcid != list.GetWCID(ListBoxWC.SelectedIndex))
|
||||
{
|
||||
var index = list.GetIndex(wcid);
|
||||
if (index == -1)
|
||||
{
|
||||
list.SetWCID(ListBoxWC.SelectedIndex, wcid);
|
||||
list.Sort();
|
||||
UpdateWCList();
|
||||
ListBoxWC.SelectedIndex = list.GetIndex(wcid);
|
||||
BtnApply.Enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show($"WCID {wcid} already exists.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (repeatable != list.GetIsRepeatable(ListBoxWC.SelectedIndex))
|
||||
{
|
||||
list.SetIsRepeatable(ListBoxWC.SelectedIndex, repeatable);
|
||||
BtnApply.Enabled = false;
|
||||
}
|
||||
|
||||
if (list.GetRequiresMethodSelection(ListBoxWC.SelectedIndex))
|
||||
{
|
||||
list.SetIsBefore201(ListBoxWC.SelectedIndex, isBefore201);
|
||||
BtnApply.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void BtnRemove_Click(object sender, EventArgs e)
|
||||
{
|
||||
var list = GetCurrentList();
|
||||
list.RemoveWC(ListBoxWC.SelectedIndex);
|
||||
ListBoxWC.SelectedIndex = -1;
|
||||
DisableContent();
|
||||
UpdateWCList();
|
||||
}
|
||||
|
||||
private void BtnRemoveAll_Click(object sender, EventArgs e)
|
||||
{
|
||||
var list = GetCurrentList();
|
||||
list.Reset();
|
||||
ListBoxWC.SelectedIndex = -1;
|
||||
DisableContent();
|
||||
UpdateWCList();
|
||||
}
|
||||
|
||||
private void BtnOpen_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (OpenFileDialogWC.ShowDialog() == DialogResult.OK)
|
||||
LoadLocalFiles(OpenFileDialogWC.FileNames);
|
||||
}
|
||||
|
||||
void FileDragEnter(object sender, DragEventArgs e)
|
||||
{
|
||||
if (e.Data is not null && CurrentGame is not Games.None)
|
||||
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||
e.Effect = DragDropEffects.Copy;
|
||||
}
|
||||
|
||||
void FileDragDrop(object sender, DragEventArgs e)
|
||||
{
|
||||
if (e.Data is not null && CurrentGame is not Games.None)
|
||||
{
|
||||
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop)!;
|
||||
LoadLocalFiles(files);
|
||||
}
|
||||
}
|
||||
|
||||
private void TxtWCID_KeyPress(object sender, KeyPressEventArgs e)
|
||||
{
|
||||
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void TxtWCID_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!TxtWCID.Text.Equals(""))
|
||||
{
|
||||
var list = GetCurrentList();
|
||||
var newWcid = UInt16.Parse(TxtWCID.Text);
|
||||
var oldWcid = list.GetWCID(ListBoxWC.SelectedIndex);
|
||||
|
||||
if (oldWcid > 0 && newWcid > 0 && newWcid != oldWcid)
|
||||
BtnApply.Enabled = true;
|
||||
else
|
||||
BtnApply.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void ChkRepeatable_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
var list = GetCurrentList();
|
||||
var newBool = ChkRepeatable.Checked;
|
||||
var oldBool = list.GetIsRepeatable(ListBoxWC.SelectedIndex);
|
||||
|
||||
if (newBool != oldBool)
|
||||
BtnApply.Enabled = true;
|
||||
else
|
||||
BtnApply.Enabled = false;
|
||||
}
|
||||
|
||||
private void CmbRedemptionMethod_IndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (CurrentGame is Games.SCVI)
|
||||
{
|
||||
var list = GetCurrentList();
|
||||
if (list.GetRequiresMethodSelection(ListBoxWC.SelectedIndex))
|
||||
{
|
||||
var newValue = cmbRedemptionMethod.SelectedIndex == 0;
|
||||
var oldValue = list.GetIsBefore201(ListBoxWC.SelectedIndex);
|
||||
|
||||
if (newValue != oldValue)
|
||||
BtnApply.Enabled = true;
|
||||
else
|
||||
BtnApply.Enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ToolTipWcid_Draw(object sender, DrawToolTipEventArgs e)
|
||||
{
|
||||
Point screenPosition = ListBox.MousePosition;
|
||||
Point listBoxClientAreaPosition = ListBoxWC.PointToClient(screenPosition);
|
||||
int hoveredIndex = ListBoxWC.IndexFromPoint(listBoxClientAreaPosition);
|
||||
if (hoveredIndex > -1)
|
||||
{
|
||||
var str = ListBoxWC.Items[hoveredIndex].ToString()!;
|
||||
if (str.Contains('\u26A0'))
|
||||
{
|
||||
var msg = "Wondercards with duplicated identifiers may not be detected correctly by the games.";
|
||||
e.DrawBackground();
|
||||
Graphics g = e.Graphics;
|
||||
g.DrawString(msg, e.Font!, new SolidBrush(Color.Black), new PointF(e.Bounds.X, e.Bounds.Y));
|
||||
}
|
||||
else if (str.Contains('\u2757'))
|
||||
{
|
||||
var msg = "Wondercard count is above the maximum allowed, or the WCID is over the maximum allowed.";
|
||||
e.DrawBackground();
|
||||
Graphics g = e.Graphics;
|
||||
g.DrawString(msg, e.Font!, new SolidBrush(Color.Black), new PointF(e.Bounds.X, e.Bounds.Y));
|
||||
}
|
||||
else
|
||||
{
|
||||
ToolTipWcid.Hide(ListBoxWC);
|
||||
}
|
||||
}
|
||||
else
|
||||
ToolTipWcid.Hide(ListBoxWC);
|
||||
}
|
||||
|
||||
private void ListBoxWC_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
var index = ListBoxWC.IndexFromPoint(e.X, e.Y);
|
||||
if (index >= 0)
|
||||
{
|
||||
ListBoxWC.SelectedIndex = index;
|
||||
ContextMenuStripWC.Show(Cursor.Position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ListBoxWC_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (ListBoxWC.SelectedIndex > -1)
|
||||
{
|
||||
var list = GetCurrentList();
|
||||
var index = ListBoxWC.SelectedIndex;
|
||||
var content = list.GetContentToString(index);
|
||||
var nItem = content.Count();
|
||||
if (nItem >= 1)
|
||||
LblInfo1.Text = content.ElementAt(1);
|
||||
if (nItem >= 2)
|
||||
LblInfo2.Text = content.ElementAt(2);
|
||||
if (nItem >= 3)
|
||||
LblInfo3.Text = content.ElementAt(3);
|
||||
if (nItem >= 4)
|
||||
LblInfo4.Text = content.ElementAt(4);
|
||||
if (nItem >= 5)
|
||||
LblInfo5.Text = content.ElementAt(5);
|
||||
if (nItem >= 6)
|
||||
LblInfo6.Text = content.ElementAt(6);
|
||||
if (nItem >= 7)
|
||||
LblInfo7.Text = content.ElementAt(7);
|
||||
|
||||
TxtWCID.Text = content.ElementAt(0);
|
||||
ChkRepeatable.Checked = list.GetIsRepeatable(index);
|
||||
|
||||
cmbRedemptionMethod.Visible = cmbRedemptionMethod.Enabled = lblRedemptionMethod.Visible
|
||||
= lblRedemptionMethod.Enabled = list.GetRequiresMethodSelection(index);
|
||||
|
||||
if (cmbRedemptionMethod.Enabled)
|
||||
cmbRedemptionMethod.SelectedIndex = list.GetIsBefore201(index) ? 0 : 1;
|
||||
|
||||
EnableContent();
|
||||
}
|
||||
else
|
||||
DisableContent();
|
||||
}
|
||||
|
||||
private void ListBoxWC_DrawItem(object sender, DrawItemEventArgs e)
|
||||
{
|
||||
if (e.Index > -1)
|
||||
{
|
||||
e.DrawBackground();
|
||||
Graphics g = e.Graphics;
|
||||
var curr = ((ListBox)sender).Items[e.Index].ToString()!;
|
||||
var wcid = UInt16.Parse(Regex.Match(curr, @"(?<=\#)(.*?)(?=\:)").Groups[1].Value);
|
||||
var handled = false;
|
||||
if ((CurrentGame is Games.BDSP or Games.LGPE && wcid >= 2048) || (CurrentGame is Games.SWSH && e.Index >= 129))
|
||||
{
|
||||
if (!curr.Contains('\u2757'))
|
||||
((ListBox)sender).Items[e.Index] = $"{curr} \u2757";
|
||||
g.FillRectangle(new SolidBrush(Color.IndianRed), e.Bounds);
|
||||
g.DrawString(((ListBox)sender).Items[e.Index].ToString(), e.Font!, new SolidBrush(e.ForeColor), new PointF(e.Bounds.X, e.Bounds.Y));
|
||||
handled = true;
|
||||
}
|
||||
foreach (var d in Duplicated)
|
||||
{
|
||||
if (d == wcid)
|
||||
{
|
||||
if (!curr.Contains('\u26A0'))
|
||||
((ListBox)sender).Items[e.Index] = $"{curr} \u26A0";
|
||||
g.FillRectangle(new SolidBrush(Color.Orange), e.Bounds);
|
||||
g.DrawString(((ListBox)sender).Items[e.Index].ToString(), e.Font!, new SolidBrush(e.ForeColor), new PointF(e.Bounds.X, e.Bounds.Y));
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
if (!handled)
|
||||
g.DrawString(curr, e.Font!, new SolidBrush(e.ForeColor), new PointF(e.Bounds.X, e.Bounds.Y));
|
||||
}
|
||||
}
|
||||
|
||||
private void LblInfo_SizeChanged(object sender, EventArgs e)
|
||||
{
|
||||
var lbl = (Label)sender;
|
||||
lbl.Left = (GrpContent.Width - lbl.Width) / 2;
|
||||
}
|
||||
|
||||
private void EnableContent()
|
||||
{
|
||||
TxtWCID.Enabled = true;
|
||||
LblWCID.Enabled = true;
|
||||
LblInfo1.Visible = true;
|
||||
LblInfo2.Visible = true;
|
||||
LblInfo3.Visible = true;
|
||||
LblInfo4.Visible = true;
|
||||
LblInfo5.Visible = true;
|
||||
LblInfo6.Visible = true;
|
||||
LblInfo7.Visible = true;
|
||||
GrpContent.Enabled = true;
|
||||
ChkRepeatable.Enabled = true;
|
||||
}
|
||||
|
||||
private void DisableContent()
|
||||
{
|
||||
TxtWCID.Text = "";
|
||||
TxtWCID.Enabled = false;
|
||||
LblWCID.Enabled = false;
|
||||
LblInfo1.Text = "";
|
||||
LblInfo1.Visible = false;
|
||||
LblInfo2.Text = "";
|
||||
LblInfo2.Visible = false;
|
||||
LblInfo3.Text = "";
|
||||
LblInfo3.Visible = false;
|
||||
LblInfo4.Text = "";
|
||||
LblInfo4.Visible = false;
|
||||
LblInfo5.Text = "";
|
||||
LblInfo5.Visible = false;
|
||||
LblInfo6.Text = "";
|
||||
LblInfo6.Visible = false;
|
||||
LblInfo7.Text = "";
|
||||
LblInfo7.Visible = false;
|
||||
BtnApply.Enabled = false;
|
||||
GrpContent.Enabled = false;
|
||||
ChkRepeatable.Checked = false;
|
||||
ChkRepeatable.Enabled = false;
|
||||
lblRedemptionMethod.Visible = false;
|
||||
lblRedemptionMethod.Enabled = false;
|
||||
cmbRedemptionMethod.Visible = false;
|
||||
cmbRedemptionMethod.Enabled = false;
|
||||
}
|
||||
|
||||
private void MenuItemMGDB_Click(object sender, EventArgs e)
|
||||
{
|
||||
var form = new MgdbForm();
|
||||
form.Location = this.Location;
|
||||
form.Show();
|
||||
}
|
||||
using System.Text.RegularExpressions;
|
||||
using SwitchGiftDataManager.Core;
|
||||
using Enums;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace SwitchGiftDataManager.WinForm
|
||||
{
|
||||
public partial class MainWindow : Form
|
||||
{
|
||||
private Games CurrentGame = Games.None;
|
||||
private BCATManager PackageLGPE = new (Games.LGPE);
|
||||
private BCATManager PackageSWSH = new (Games.SWSH);
|
||||
private BCATManager PackageBDSP = new (Games.BDSP);
|
||||
private BCATManager PackagePLA = new (Games.PLA);
|
||||
private BCATManager PackageSCVI = new (Games.SCVI);
|
||||
private List<ushort> Duplicated = new List<ushort>();
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
Task.Run(TryUpdate).Wait();
|
||||
InitializeComponent();
|
||||
Text += BCATManager.Version;
|
||||
}
|
||||
|
||||
private static async Task TryUpdate()
|
||||
{
|
||||
if (await GitHubUtil.IsUpdateAvailable())
|
||||
{
|
||||
var result = MessageBox.Show("A program update is available. Do you want to download the latest release?", "Update available", MessageBoxButtons.YesNo);
|
||||
if (result == DialogResult.Yes)
|
||||
Process.Start(new ProcessStartInfo { FileName = @"https://github.com/Manu098vm/Switch-Gift-Data-Manager/releases", UseShellExecute = true });
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangeGame(Games game)
|
||||
{
|
||||
GrpBCAT.Enabled = true;
|
||||
CurrentGame = game;
|
||||
RestoreMenu();
|
||||
EditFileFilter();
|
||||
EditGameButton();
|
||||
UpdateWCList();
|
||||
ListBoxWC.SelectedIndex = -1;
|
||||
DisableContent();
|
||||
}
|
||||
|
||||
private void RestoreMenu()
|
||||
{
|
||||
BtnLGPE.Enabled = true;
|
||||
BtnSWSH.Enabled = true;
|
||||
BtnBDSP.Enabled = true;
|
||||
BtnPLA.Enabled = true;
|
||||
BtnSCVI.Enabled = true;
|
||||
|
||||
BtnLGPE.Font = new Font(BtnLGPE.Font.Name, BtnLGPE.Font.Size, FontStyle.Regular);
|
||||
BtnSWSH.Font = new Font(BtnSWSH.Font.Name, BtnSWSH.Font.Size, FontStyle.Regular);
|
||||
BtnBDSP.Font = new Font(BtnBDSP.Font.Name, BtnBDSP.Font.Size, FontStyle.Regular);
|
||||
BtnPLA.Font = new Font(BtnPLA.Font.Name, BtnPLA.Font.Size, FontStyle.Regular);
|
||||
BtnSCVI.Font = new Font(BtnSCVI.Font.Name, BtnSCVI.Font.Size, FontStyle.Regular);
|
||||
}
|
||||
|
||||
private void EditFileFilter()
|
||||
{
|
||||
OpenFileDialogWC.Filter = CurrentGame switch
|
||||
{
|
||||
Games.LGPE => "wb7full files (*.wb7full)|*.wb7full|All files (*.*)|*.*",
|
||||
Games.SWSH => "wc8 files (*.wc8)|*.wc8|All files (*.*)|*.*",
|
||||
Games.BDSP => "wb8 files (*.wb8)|*.wb8|All files (*.*)|*.*",
|
||||
Games.PLA => "wa8 files (*.wa8)|*.wa8|All files (*.*)|*.*",
|
||||
Games.SCVI => "wc9 files (*.wc9)|*.wc9|All files (*.*)|*.*",
|
||||
_ => "All files (*.*)|*.*",
|
||||
};
|
||||
}
|
||||
|
||||
private void EditGameButton()
|
||||
{
|
||||
Button btn = CurrentGame switch
|
||||
{
|
||||
Games.LGPE => BtnLGPE,
|
||||
Games.SWSH => BtnSWSH,
|
||||
Games.BDSP => BtnBDSP,
|
||||
Games.PLA => BtnPLA,
|
||||
Games.SCVI => BtnSCVI,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
EditSelectedButton(btn);
|
||||
}
|
||||
|
||||
private void EditSelectedButton(Button btn)
|
||||
{
|
||||
btn.Font = new Font(btn.Font.Name, btn.Font.Size, FontStyle.Bold);
|
||||
btn.Enabled = false;
|
||||
}
|
||||
|
||||
private void UpdateWCList()
|
||||
{
|
||||
if (ListBoxWC.Items.Count > 0)
|
||||
ListBoxWC.Items.Clear();
|
||||
|
||||
var list = CurrentGame switch
|
||||
{
|
||||
Games.LGPE => PackageLGPE.GetListNames(),
|
||||
Games.SWSH => PackageSWSH.GetListNames(),
|
||||
Games.BDSP => PackageBDSP.GetListNames(),
|
||||
Games.PLA => PackagePLA.GetListNames(),
|
||||
Games.SCVI => PackageSCVI.GetListNames(),
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
UpdateDuplicatedList();
|
||||
|
||||
foreach (var el in list)
|
||||
ListBoxWC.Items.Add(el);
|
||||
|
||||
if (ListBoxWC.Items.Count > 0)
|
||||
BtnSave.Enabled = true;
|
||||
else
|
||||
BtnSave.Enabled = false;
|
||||
}
|
||||
|
||||
private void UpdateDuplicatedList()
|
||||
{
|
||||
var list = GetCurrentList().GetDuplicatedWCID();
|
||||
if (list != null)
|
||||
Duplicated = list;
|
||||
else
|
||||
Duplicated = new List<ushort> { 0 };
|
||||
}
|
||||
|
||||
private BCATManager GetCurrentList()
|
||||
{
|
||||
return CurrentGame switch
|
||||
{
|
||||
Games.LGPE => PackageLGPE,
|
||||
Games.SWSH => PackageSWSH,
|
||||
Games.BDSP => PackageBDSP,
|
||||
Games.PLA => PackagePLA,
|
||||
Games.SCVI => PackageSCVI,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
}
|
||||
|
||||
private void LoadLocalFiles(string[] files)
|
||||
{
|
||||
DisableContent();
|
||||
var list = GetCurrentList();
|
||||
var errList = new List<string>();
|
||||
foreach (var path in files)
|
||||
{
|
||||
var data = File.ReadAllBytes(path);
|
||||
var success = list.TryAddWondercards(data.AsSpan());
|
||||
if (!success)
|
||||
{
|
||||
if (errList.Count == 0)
|
||||
if (CurrentGame is Games.LGPE && list.Count() >= 1)
|
||||
errList.Add("LGPE only supports one (1) wondercard at a time. Aborted file(s):\n");
|
||||
else
|
||||
errList.Add($"Attempted to load invalid files. Aborted file(s):\n");
|
||||
errList.Add($"- {Path.GetFileName(path)}");
|
||||
}
|
||||
}
|
||||
|
||||
if (errList.Count > 0)
|
||||
{
|
||||
var msg = "";
|
||||
foreach (var err in errList)
|
||||
msg = $"{msg}\n{err}";
|
||||
MessageBox.Show(msg);
|
||||
}
|
||||
|
||||
list.Sort();
|
||||
UpdateWCList();
|
||||
}
|
||||
|
||||
private void BtnLGPE_Click(object sender, EventArgs e) => ChangeGame(Games.LGPE);
|
||||
|
||||
private void BtnSWSH_Click(object sender, EventArgs e) => ChangeGame(Games.SWSH);
|
||||
|
||||
private void BtnBDSP_Click(object sender, EventArgs e) => ChangeGame(Games.BDSP);
|
||||
|
||||
private void BtnPLA_Click(object sender, EventArgs e) => ChangeGame(Games.PLA);
|
||||
|
||||
private void BtnSCVI_Click(object sender, EventArgs e) => ChangeGame(Games.SCVI);
|
||||
|
||||
private void BtnSave_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.Enabled = false;
|
||||
var saveForm = new SaveWindow(GetCurrentList(), CurrentGame);
|
||||
saveForm.FormClosed += (s, e) => this.Enabled = true;
|
||||
saveForm.Location = this.Location;
|
||||
saveForm.Show();
|
||||
}
|
||||
|
||||
private void BtnApply_Click(object sender, EventArgs e)
|
||||
{
|
||||
var proceed = true;
|
||||
if(CurrentGame is Games.SCVI)
|
||||
{
|
||||
var warning = "WARNING\n\n" +
|
||||
"WCID editings in SV wondercards might impact the entity's TID and SID, resulting in an illegal Pokémon.\n" +
|
||||
"Do not share Pokémon obtained with the use of edited wondercards.\n" +
|
||||
"\nDo you want to coninue?";
|
||||
var disclaimer = MessageBox.Show(warning, "Disclaimer", MessageBoxButtons.YesNo);
|
||||
|
||||
if (disclaimer == DialogResult.No)
|
||||
proceed = false;
|
||||
}
|
||||
|
||||
if (proceed)
|
||||
{
|
||||
try
|
||||
{
|
||||
var list = GetCurrentList();
|
||||
var wcid = UInt16.Parse(TxtWCID.Text);
|
||||
var index = list.GetIndex(wcid);
|
||||
if (index == -1)
|
||||
{
|
||||
list.SetWCID(ListBoxWC.SelectedIndex, wcid);
|
||||
list.Sort();
|
||||
UpdateWCList();
|
||||
ListBoxWC.SelectedIndex = list.GetIndex(wcid);
|
||||
BtnApply.Enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show($"WCID {wcid} already exists.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.ToString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void BtnRemove_Click(object sender, EventArgs e)
|
||||
{
|
||||
var list = GetCurrentList();
|
||||
list.RemoveWC(ListBoxWC.SelectedIndex);
|
||||
ListBoxWC.SelectedIndex = -1;
|
||||
DisableContent();
|
||||
UpdateWCList();
|
||||
}
|
||||
|
||||
private void BtnRemoveAll_Click(object sender, EventArgs e)
|
||||
{
|
||||
var list = GetCurrentList();
|
||||
list.Reset();
|
||||
ListBoxWC.SelectedIndex = -1;
|
||||
DisableContent();
|
||||
UpdateWCList();
|
||||
}
|
||||
|
||||
private void BtnOpen_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (OpenFileDialogWC.ShowDialog() == DialogResult.OK)
|
||||
LoadLocalFiles(OpenFileDialogWC.FileNames);
|
||||
}
|
||||
|
||||
void FileDragEnter(object sender, DragEventArgs e)
|
||||
{
|
||||
if(e.Data is not null && CurrentGame is not Games.None)
|
||||
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||
e.Effect = DragDropEffects.Copy;
|
||||
}
|
||||
|
||||
void FileDragDrop(object sender, DragEventArgs e)
|
||||
{
|
||||
if (e.Data is not null && CurrentGame is not Games.None)
|
||||
{
|
||||
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop)!;
|
||||
LoadLocalFiles(files);
|
||||
}
|
||||
}
|
||||
|
||||
private void TxtWCID_KeyPress(object sender, KeyPressEventArgs e)
|
||||
{
|
||||
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void TxtWCID_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!TxtWCID.Text.Equals(""))
|
||||
{
|
||||
var list = GetCurrentList();
|
||||
var newWcid = UInt16.Parse(TxtWCID.Text);
|
||||
var oldWcid = list.GetWCID(ListBoxWC.SelectedIndex);
|
||||
|
||||
if (oldWcid > 0 && newWcid > 0 && newWcid != oldWcid)
|
||||
BtnApply.Enabled = true;
|
||||
else
|
||||
BtnApply.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void ToolTipWcid_Draw(object sender, DrawToolTipEventArgs e)
|
||||
{
|
||||
Point screenPosition = ListBox.MousePosition;
|
||||
Point listBoxClientAreaPosition = ListBoxWC.PointToClient(screenPosition);
|
||||
int hoveredIndex = ListBoxWC.IndexFromPoint(listBoxClientAreaPosition);
|
||||
if (hoveredIndex > -1)
|
||||
{
|
||||
var str = ListBoxWC.Items[hoveredIndex].ToString()!;
|
||||
if (str.Contains('\u26A0'))
|
||||
{
|
||||
var msg = "Wondercards with duplicated identifiers may cause issues and will not be seen by the game.";
|
||||
e.DrawBackground();
|
||||
Graphics g = e.Graphics;
|
||||
g.DrawString(msg, e.Font!, new SolidBrush(Color.Black), new PointF(e.Bounds.X, e.Bounds.Y));
|
||||
}
|
||||
else if (str.Contains('\u2757'))
|
||||
{
|
||||
var msg = "Wondercard count is above the maximum allowed, or the WCID is over the maximum allowed.";
|
||||
e.DrawBackground();
|
||||
Graphics g = e.Graphics;
|
||||
g.DrawString(msg, e.Font!, new SolidBrush(Color.Black), new PointF(e.Bounds.X, e.Bounds.Y));
|
||||
}
|
||||
else
|
||||
{
|
||||
ToolTipWcid.Hide(ListBoxWC);
|
||||
}
|
||||
}
|
||||
else
|
||||
ToolTipWcid.Hide(ListBoxWC);
|
||||
}
|
||||
|
||||
private void ListBoxWC_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
var index = ListBoxWC.IndexFromPoint(e.X, e.Y);
|
||||
if (index >= 0)
|
||||
{
|
||||
ListBoxWC.SelectedIndex = index;
|
||||
ContextMenuStripWC.Show(Cursor.Position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ListBoxWC_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (ListBoxWC.SelectedIndex > -1)
|
||||
{
|
||||
var list = GetCurrentList();
|
||||
var content = list.GetContentToString(ListBoxWC.SelectedIndex);
|
||||
var nItem = content.Count();
|
||||
if (nItem >= 1)
|
||||
LblInfo1.Text = content.ElementAt(1);
|
||||
if (nItem >= 2)
|
||||
LblInfo2.Text = content.ElementAt(2);
|
||||
if (nItem >= 3)
|
||||
LblInfo3.Text = content.ElementAt(3);
|
||||
if (nItem >= 4)
|
||||
LblInfo4.Text = content.ElementAt(4);
|
||||
if (nItem >= 5)
|
||||
LblInfo5.Text = content.ElementAt(5);
|
||||
if (nItem >= 6)
|
||||
LblInfo6.Text = content.ElementAt(6);
|
||||
if (nItem >= 7)
|
||||
LblInfo7.Text = content.ElementAt(7);
|
||||
|
||||
TxtWCID.Text = content.ElementAt(0);
|
||||
EnableContent();
|
||||
}
|
||||
else
|
||||
DisableContent();
|
||||
}
|
||||
|
||||
private void ListBoxWC_DrawItem(object sender, DrawItemEventArgs e)
|
||||
{
|
||||
if (e.Index > -1)
|
||||
{
|
||||
e.DrawBackground();
|
||||
Graphics g = e.Graphics;
|
||||
var curr = ((ListBox)sender).Items[e.Index].ToString()!;
|
||||
var wcid = UInt16.Parse(Regex.Match(curr, @"(?<=\#)(.*?)(?=\:)").Groups[1].Value);
|
||||
var handled = false;
|
||||
if ((CurrentGame is Games.BDSP && wcid >= 2048) || (CurrentGame is Games.SWSH && e.Index >= 129))
|
||||
{
|
||||
if(!curr.Contains('\u2757'))
|
||||
((ListBox)sender).Items[e.Index] = $"{curr} \u2757";
|
||||
g.FillRectangle(new SolidBrush(Color.IndianRed), e.Bounds);
|
||||
g.DrawString(((ListBox)sender).Items[e.Index].ToString(), e.Font!, new SolidBrush(e.ForeColor), new PointF(e.Bounds.X, e.Bounds.Y));
|
||||
handled = true;
|
||||
}
|
||||
foreach (var d in Duplicated)
|
||||
{
|
||||
if (d == wcid)
|
||||
{
|
||||
if (!curr.Contains('\u26A0'))
|
||||
((ListBox)sender).Items[e.Index] = $"{curr} \u26A0";
|
||||
g.FillRectangle(new SolidBrush(Color.Orange), e.Bounds);
|
||||
g.DrawString(((ListBox)sender).Items[e.Index].ToString(), e.Font!, new SolidBrush(e.ForeColor), new PointF(e.Bounds.X, e.Bounds.Y));
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
if(!handled)
|
||||
g.DrawString(curr, e.Font!, new SolidBrush(e.ForeColor), new PointF(e.Bounds.X, e.Bounds.Y));
|
||||
}
|
||||
}
|
||||
|
||||
private void LblInfo_SizeChanged(object sender, EventArgs e)
|
||||
{
|
||||
var lbl = (Label)sender;
|
||||
lbl.Left = (GrpContent.Width - lbl.Width) / 2;
|
||||
}
|
||||
|
||||
private void EnableContent()
|
||||
{
|
||||
TxtWCID.Enabled = true;
|
||||
LblWCID.Enabled = true;
|
||||
LblInfo1.Visible = true;
|
||||
LblInfo2.Visible = true;
|
||||
LblInfo3.Visible = true;
|
||||
LblInfo4.Visible = true;
|
||||
LblInfo5.Visible = true;
|
||||
LblInfo6.Visible = true;
|
||||
LblInfo7.Visible = true;
|
||||
GrpContent.Enabled = true;
|
||||
}
|
||||
|
||||
private void DisableContent()
|
||||
{
|
||||
TxtWCID.Text = "";
|
||||
TxtWCID.Enabled = false;
|
||||
LblWCID.Enabled = false;
|
||||
LblInfo1.Text = "";
|
||||
LblInfo1.Visible = false;
|
||||
LblInfo2.Text = "";
|
||||
LblInfo2.Visible = false;
|
||||
LblInfo3.Text = "";
|
||||
LblInfo3.Visible = false;
|
||||
LblInfo4.Text = "";
|
||||
LblInfo4.Visible = false;
|
||||
LblInfo5.Text = "";
|
||||
LblInfo5.Visible = false;
|
||||
LblInfo6.Text = "";
|
||||
LblInfo6.Visible = false;
|
||||
LblInfo7.Text = "";
|
||||
LblInfo7.Visible = false;
|
||||
GrpContent.Enabled = false;
|
||||
BtnApply.Enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,64 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
|
|
@ -126,12 +66,6 @@
|
|||
<metadata name="OpenFileDialogWC.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>222, 17</value>
|
||||
</metadata>
|
||||
<metadata name="MenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>549, 17</value>
|
||||
</metadata>
|
||||
<metadata name="toolTipRedemptionMethod.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>677, 17</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
|
|
|
|||
66
SwitchGiftDataManager.WinForm/MgdbForm.Designer.cs
generated
66
SwitchGiftDataManager.WinForm/MgdbForm.Designer.cs
generated
|
|
@ -1,66 +0,0 @@
|
|||
namespace SwitchGiftDataManager.WinForm
|
||||
{
|
||||
partial class MgdbForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MgdbForm));
|
||||
lblMessage = new Label();
|
||||
SuspendLayout();
|
||||
//
|
||||
// lblMessage
|
||||
//
|
||||
lblMessage.AutoSize = true;
|
||||
lblMessage.Location = new Point(94, 9);
|
||||
lblMessage.Name = "lblMessage";
|
||||
lblMessage.Size = new Size(190, 20);
|
||||
lblMessage.TabIndex = 0;
|
||||
lblMessage.Text = "Downloading, please wait...";
|
||||
//
|
||||
// MgdbForm
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(8F, 20F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(392, 37);
|
||||
ControlBox = false;
|
||||
Controls.Add(lblMessage);
|
||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "MgdbForm";
|
||||
ShowInTaskbar = false;
|
||||
StartPosition = FormStartPosition.Manual;
|
||||
Text = "Mystery Gift Database";
|
||||
ResumeLayout(false);
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Label lblMessage;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace SwitchGiftDataManager.WinForm;
|
||||
|
||||
public partial class MgdbForm : Form
|
||||
{
|
||||
public MgdbForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.Shown += (s, e) => Task.Run(async () => await DownloadRepoMGDB()).Wait();
|
||||
}
|
||||
|
||||
private async Task DownloadRepoMGDB()
|
||||
{
|
||||
var url = "https://github.com/projectpokemon/EventsGallery/archive/refs/heads/master.zip";
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
var path = Path.Combine(Environment.CurrentDirectory, "tmp");
|
||||
var mgdbPath = Path.Combine(Environment.CurrentDirectory, "mgdb");
|
||||
|
||||
//Delete old residual files if exist
|
||||
if (Directory.Exists(path))
|
||||
Directory.Delete(path, true);
|
||||
|
||||
if (Directory.Exists(mgdbPath))
|
||||
Directory.Delete(mgdbPath, true);
|
||||
|
||||
Directory.CreateDirectory(path);
|
||||
|
||||
var zipPath = Path.Combine(path, "tmp.zip");
|
||||
using (var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
|
||||
{
|
||||
var totalBytes = response.Content.Headers.ContentLength ?? 0;
|
||||
using (var content = await response.Content.ReadAsStreamAsync())
|
||||
using (var stream = new FileStream(zipPath, FileMode.Create, FileAccess.Write, FileShare.None))
|
||||
{
|
||||
var buffer = new byte[8192];
|
||||
int bytesRead;
|
||||
long totalRead = 0;
|
||||
while ((bytesRead = await content.ReadAsync(buffer, 0, buffer.Length)) > 0)
|
||||
{
|
||||
await stream.WriteAsync(buffer, 0, bytesRead);
|
||||
totalRead += bytesRead;
|
||||
if (totalBytes > 0)
|
||||
{
|
||||
double progressPercentage = (double)totalRead / totalBytes * 100;
|
||||
lblMessage.Text = $"Download progress: {progressPercentage:F2}%";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lblMessage.Text = $"Extracting files...";
|
||||
ZipFile.ExtractToDirectory(zipPath, path);
|
||||
File.Delete(zipPath);
|
||||
|
||||
var tmpMgbdPath = Path.Combine(path, "EventsGallery-master");
|
||||
|
||||
lblMessage.Text = $"Cleaning up residual files...";
|
||||
File.Delete(Path.Combine(tmpMgbdPath, ".gitignore"));
|
||||
Directory.Delete(Path.Combine(tmpMgbdPath, "Extras"), true);
|
||||
Directory.Delete(Path.Combine(tmpMgbdPath, "Unreleased"), true);
|
||||
Directory.Delete(Path.Combine(tmpMgbdPath, "PKHeX Legality"), true);
|
||||
|
||||
var genPath = Path.Combine(tmpMgbdPath, "Released");
|
||||
Directory.Delete(Path.Combine(genPath, "Gen 1"), true);
|
||||
Directory.Delete(Path.Combine(genPath, "Gen 2"), true);
|
||||
Directory.Delete(Path.Combine(genPath, "Gen 3"), true);
|
||||
Directory.Delete(Path.Combine(genPath, "Gen 4"), true);
|
||||
Directory.Delete(Path.Combine(genPath, "Gen 5"), true);
|
||||
Directory.Delete(Path.Combine(genPath, "Gen 6"), true);
|
||||
|
||||
var gen7Path = Path.Combine(genPath, "Gen 7");
|
||||
Directory.Delete(Path.Combine(gen7Path, "3DS"), true);
|
||||
Directory.Delete(Path.Combine(Path.Combine(gen7Path, "Switch"), "Wondercard Records"), true);
|
||||
|
||||
var swshPath = Path.Combine(Path.Combine(genPath, "Gen 8"), "SwSh");
|
||||
Directory.Delete(Path.Combine(swshPath, "Wild Area Events"), true);
|
||||
|
||||
var svPath = Path.Combine(genPath, "Gen 9", "SV");
|
||||
Directory.Delete(Path.Combine(svPath, "Raid Events"), true);
|
||||
Directory.Delete(Path.Combine(svPath, "Outbreak Events"), true);
|
||||
|
||||
Directory.Move(tmpMgbdPath, mgdbPath);
|
||||
Directory.Delete(path, true);
|
||||
|
||||
this.FormClosed += (s, e) => MessageBox.Show($"The Mystery Gift Database has been downloaded in {mgdbPath}", "MGDB",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification);
|
||||
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>bin\Release\net7.0-windows\win-x64\publish\</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<_TargetId>Folder</_TargetId>
|
||||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
<SelfContained>false</SelfContained>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<History>True|2023-01-28T15:01:40.5830936Z;</History>
|
||||
<LastFailureDetails />
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<History>True|2023-01-28T14:44:59.9510590Z;True|2023-01-23T20:01:57.3824432+01:00;False|2023-01-23T20:00:42.5423966+01:00;True|2023-01-23T19:57:25.6949583+01:00;</History>
|
||||
<LastFailureDetails />
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
389
SwitchGiftDataManager.WinForm/SaveWindow.Designer.cs
generated
389
SwitchGiftDataManager.WinForm/SaveWindow.Designer.cs
generated
|
|
@ -1,200 +1,201 @@
|
|||
namespace SwitchGiftDataManager.WinForm;
|
||||
|
||||
partial class SaveWindow
|
||||
namespace SwitchGiftDataManager.WinForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
partial class SaveWindow
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
components.Dispose();
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SaveWindow));
|
||||
this.GrpBuild = new System.Windows.Forms.GroupBox();
|
||||
this.RadioUnique = new System.Windows.Forms.RadioButton();
|
||||
this.RadioMultiple = new System.Windows.Forms.RadioButton();
|
||||
this.TxtDestPath = new System.Windows.Forms.TextBox();
|
||||
this.BtnPath = new System.Windows.Forms.Button();
|
||||
this.GrpDest = new System.Windows.Forms.GroupBox();
|
||||
this.BtnCancel = new System.Windows.Forms.Button();
|
||||
this.BtnSave = new System.Windows.Forms.Button();
|
||||
this.FolderBrowser = new System.Windows.Forms.FolderBrowserDialog();
|
||||
this.groupBox2 = new System.Windows.Forms.GroupBox();
|
||||
this.BtnSrcBrowse = new System.Windows.Forms.Button();
|
||||
this.TxtSourcePath = new System.Windows.Forms.TextBox();
|
||||
this.GrpBuild.SuspendLayout();
|
||||
this.GrpDest.SuspendLayout();
|
||||
this.groupBox2.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// GrpBuild
|
||||
//
|
||||
this.GrpBuild.Controls.Add(this.RadioUnique);
|
||||
this.GrpBuild.Controls.Add(this.RadioMultiple);
|
||||
this.GrpBuild.Location = new System.Drawing.Point(12, 12);
|
||||
this.GrpBuild.Name = "GrpBuild";
|
||||
this.GrpBuild.Size = new System.Drawing.Size(458, 58);
|
||||
this.GrpBuild.TabIndex = 0;
|
||||
this.GrpBuild.TabStop = false;
|
||||
this.GrpBuild.Text = "Build Method";
|
||||
//
|
||||
// RadioUnique
|
||||
//
|
||||
this.RadioUnique.AutoSize = true;
|
||||
this.RadioUnique.Location = new System.Drawing.Point(238, 26);
|
||||
this.RadioUnique.Name = "RadioUnique";
|
||||
this.RadioUnique.Size = new System.Drawing.Size(156, 24);
|
||||
this.RadioUnique.TabIndex = 1;
|
||||
this.RadioUnique.Text = "Keep separate files";
|
||||
this.RadioUnique.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// RadioMultiple
|
||||
//
|
||||
this.RadioMultiple.AutoSize = true;
|
||||
this.RadioMultiple.Checked = true;
|
||||
this.RadioMultiple.Location = new System.Drawing.Point(76, 26);
|
||||
this.RadioMultiple.Name = "RadioMultiple";
|
||||
this.RadioMultiple.Size = new System.Drawing.Size(145, 24);
|
||||
this.RadioMultiple.TabIndex = 0;
|
||||
this.RadioMultiple.TabStop = true;
|
||||
this.RadioMultiple.Text = "Merge as one file";
|
||||
this.RadioMultiple.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// TxtDestPath
|
||||
//
|
||||
this.TxtDestPath.Location = new System.Drawing.Point(6, 26);
|
||||
this.TxtDestPath.Name = "TxtDestPath";
|
||||
this.TxtDestPath.Size = new System.Drawing.Size(358, 27);
|
||||
this.TxtDestPath.TabIndex = 1;
|
||||
//
|
||||
// BtnPath
|
||||
//
|
||||
this.BtnPath.Location = new System.Drawing.Point(370, 26);
|
||||
this.BtnPath.Name = "BtnPath";
|
||||
this.BtnPath.Size = new System.Drawing.Size(82, 29);
|
||||
this.BtnPath.TabIndex = 2;
|
||||
this.BtnPath.Text = "Browse";
|
||||
this.BtnPath.UseVisualStyleBackColor = true;
|
||||
this.BtnPath.Click += new System.EventHandler(this.BtnPath_Click);
|
||||
//
|
||||
// GrpDest
|
||||
//
|
||||
this.GrpDest.Controls.Add(this.TxtDestPath);
|
||||
this.GrpDest.Controls.Add(this.BtnPath);
|
||||
this.GrpDest.Location = new System.Drawing.Point(12, 153);
|
||||
this.GrpDest.Name = "GrpDest";
|
||||
this.GrpDest.Size = new System.Drawing.Size(458, 66);
|
||||
this.GrpDest.TabIndex = 3;
|
||||
this.GrpDest.TabStop = false;
|
||||
this.GrpDest.Text = "Destination BCAT Path";
|
||||
//
|
||||
// BtnCancel
|
||||
//
|
||||
this.BtnCancel.Location = new System.Drawing.Point(99, 225);
|
||||
this.BtnCancel.Name = "BtnCancel";
|
||||
this.BtnCancel.Size = new System.Drawing.Size(125, 29);
|
||||
this.BtnCancel.TabIndex = 4;
|
||||
this.BtnCancel.Text = "Cancel";
|
||||
this.BtnCancel.UseVisualStyleBackColor = true;
|
||||
this.BtnCancel.Click += new System.EventHandler(this.BtnCancel_Click);
|
||||
//
|
||||
// BtnSave
|
||||
//
|
||||
this.BtnSave.Location = new System.Drawing.Point(250, 225);
|
||||
this.BtnSave.Name = "BtnSave";
|
||||
this.BtnSave.Size = new System.Drawing.Size(125, 29);
|
||||
this.BtnSave.TabIndex = 5;
|
||||
this.BtnSave.Text = "Save";
|
||||
this.BtnSave.UseVisualStyleBackColor = true;
|
||||
this.BtnSave.Click += new System.EventHandler(this.BtnSave_Click);
|
||||
//
|
||||
// groupBox2
|
||||
//
|
||||
this.groupBox2.Controls.Add(this.BtnSrcBrowse);
|
||||
this.groupBox2.Controls.Add(this.TxtSourcePath);
|
||||
this.groupBox2.Location = new System.Drawing.Point(12, 76);
|
||||
this.groupBox2.Name = "groupBox2";
|
||||
this.groupBox2.Size = new System.Drawing.Size(458, 66);
|
||||
this.groupBox2.TabIndex = 6;
|
||||
this.groupBox2.TabStop = false;
|
||||
this.groupBox2.Text = "Source BCAT Path";
|
||||
//
|
||||
// BtnSrcBrowse
|
||||
//
|
||||
this.BtnSrcBrowse.Location = new System.Drawing.Point(370, 26);
|
||||
this.BtnSrcBrowse.Name = "BtnSrcBrowse";
|
||||
this.BtnSrcBrowse.Size = new System.Drawing.Size(82, 27);
|
||||
this.BtnSrcBrowse.TabIndex = 1;
|
||||
this.BtnSrcBrowse.Text = "Browse";
|
||||
this.BtnSrcBrowse.UseVisualStyleBackColor = true;
|
||||
this.BtnSrcBrowse.Click += new System.EventHandler(this.BtnSrcBrowse_Click);
|
||||
//
|
||||
// TxtSourcePath
|
||||
//
|
||||
this.TxtSourcePath.Location = new System.Drawing.Point(6, 26);
|
||||
this.TxtSourcePath.Name = "TxtSourcePath";
|
||||
this.TxtSourcePath.Size = new System.Drawing.Size(358, 27);
|
||||
this.TxtSourcePath.TabIndex = 0;
|
||||
//
|
||||
// SaveWindow
|
||||
//
|
||||
this.AcceptButton = this.BtnSave;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.BtnCancel;
|
||||
this.ClientSize = new System.Drawing.Size(483, 261);
|
||||
this.Controls.Add(this.groupBox2);
|
||||
this.Controls.Add(this.BtnSave);
|
||||
this.Controls.Add(this.BtnCancel);
|
||||
this.Controls.Add(this.GrpDest);
|
||||
this.Controls.Add(this.GrpBuild);
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "SaveWindow";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.Text = "Save BCAT Package";
|
||||
this.GrpBuild.ResumeLayout(false);
|
||||
this.GrpBuild.PerformLayout();
|
||||
this.GrpDest.ResumeLayout(false);
|
||||
this.GrpDest.PerformLayout();
|
||||
this.groupBox2.ResumeLayout(false);
|
||||
this.groupBox2.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private GroupBox GrpBuild;
|
||||
private RadioButton RadioUnique;
|
||||
private RadioButton RadioMultiple;
|
||||
private TextBox TxtDestPath;
|
||||
private Button BtnPath;
|
||||
private GroupBox GrpDest;
|
||||
private Button BtnCancel;
|
||||
private Button BtnSave;
|
||||
private FolderBrowserDialog FolderBrowser;
|
||||
private GroupBox groupBox2;
|
||||
private Button BtnSrcBrowse;
|
||||
private TextBox TxtSourcePath;
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SaveWindow));
|
||||
this.GrpBuild = new System.Windows.Forms.GroupBox();
|
||||
this.RadioUnique = new System.Windows.Forms.RadioButton();
|
||||
this.RadioMultiple = new System.Windows.Forms.RadioButton();
|
||||
this.TxtDestPath = new System.Windows.Forms.TextBox();
|
||||
this.BtnPath = new System.Windows.Forms.Button();
|
||||
this.GrpDest = new System.Windows.Forms.GroupBox();
|
||||
this.BtnCancel = new System.Windows.Forms.Button();
|
||||
this.BtnSave = new System.Windows.Forms.Button();
|
||||
this.FolderBrowser = new System.Windows.Forms.FolderBrowserDialog();
|
||||
this.groupBox2 = new System.Windows.Forms.GroupBox();
|
||||
this.BtnSrcBrowse = new System.Windows.Forms.Button();
|
||||
this.TxtSourcePath = new System.Windows.Forms.TextBox();
|
||||
this.GrpBuild.SuspendLayout();
|
||||
this.GrpDest.SuspendLayout();
|
||||
this.groupBox2.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// GrpBuild
|
||||
//
|
||||
this.GrpBuild.Controls.Add(this.RadioUnique);
|
||||
this.GrpBuild.Controls.Add(this.RadioMultiple);
|
||||
this.GrpBuild.Location = new System.Drawing.Point(12, 12);
|
||||
this.GrpBuild.Name = "GrpBuild";
|
||||
this.GrpBuild.Size = new System.Drawing.Size(458, 58);
|
||||
this.GrpBuild.TabIndex = 0;
|
||||
this.GrpBuild.TabStop = false;
|
||||
this.GrpBuild.Text = "Build Method";
|
||||
//
|
||||
// RadioUnique
|
||||
//
|
||||
this.RadioUnique.AutoSize = true;
|
||||
this.RadioUnique.Location = new System.Drawing.Point(238, 26);
|
||||
this.RadioUnique.Name = "RadioUnique";
|
||||
this.RadioUnique.Size = new System.Drawing.Size(156, 24);
|
||||
this.RadioUnique.TabIndex = 1;
|
||||
this.RadioUnique.Text = "Keep separate files";
|
||||
this.RadioUnique.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// RadioMultiple
|
||||
//
|
||||
this.RadioMultiple.AutoSize = true;
|
||||
this.RadioMultiple.Checked = true;
|
||||
this.RadioMultiple.Location = new System.Drawing.Point(76, 26);
|
||||
this.RadioMultiple.Name = "RadioMultiple";
|
||||
this.RadioMultiple.Size = new System.Drawing.Size(145, 24);
|
||||
this.RadioMultiple.TabIndex = 0;
|
||||
this.RadioMultiple.TabStop = true;
|
||||
this.RadioMultiple.Text = "Merge as one file";
|
||||
this.RadioMultiple.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// TxtDestPath
|
||||
//
|
||||
this.TxtDestPath.Location = new System.Drawing.Point(6, 26);
|
||||
this.TxtDestPath.Name = "TxtDestPath";
|
||||
this.TxtDestPath.Size = new System.Drawing.Size(358, 27);
|
||||
this.TxtDestPath.TabIndex = 1;
|
||||
//
|
||||
// BtnPath
|
||||
//
|
||||
this.BtnPath.Location = new System.Drawing.Point(370, 26);
|
||||
this.BtnPath.Name = "BtnPath";
|
||||
this.BtnPath.Size = new System.Drawing.Size(82, 29);
|
||||
this.BtnPath.TabIndex = 2;
|
||||
this.BtnPath.Text = "Browse";
|
||||
this.BtnPath.UseVisualStyleBackColor = true;
|
||||
this.BtnPath.Click += new System.EventHandler(this.BtnPath_Click);
|
||||
//
|
||||
// GrpDest
|
||||
//
|
||||
this.GrpDest.Controls.Add(this.TxtDestPath);
|
||||
this.GrpDest.Controls.Add(this.BtnPath);
|
||||
this.GrpDest.Location = new System.Drawing.Point(12, 153);
|
||||
this.GrpDest.Name = "GrpDest";
|
||||
this.GrpDest.Size = new System.Drawing.Size(458, 66);
|
||||
this.GrpDest.TabIndex = 3;
|
||||
this.GrpDest.TabStop = false;
|
||||
this.GrpDest.Text = "Destination BCAT Path";
|
||||
//
|
||||
// BtnCancel
|
||||
//
|
||||
this.BtnCancel.Location = new System.Drawing.Point(99, 225);
|
||||
this.BtnCancel.Name = "BtnCancel";
|
||||
this.BtnCancel.Size = new System.Drawing.Size(125, 29);
|
||||
this.BtnCancel.TabIndex = 4;
|
||||
this.BtnCancel.Text = "Cancel";
|
||||
this.BtnCancel.UseVisualStyleBackColor = true;
|
||||
this.BtnCancel.Click += new System.EventHandler(this.BtnCancel_Click);
|
||||
//
|
||||
// BtnSave
|
||||
//
|
||||
this.BtnSave.Location = new System.Drawing.Point(250, 225);
|
||||
this.BtnSave.Name = "BtnSave";
|
||||
this.BtnSave.Size = new System.Drawing.Size(125, 29);
|
||||
this.BtnSave.TabIndex = 5;
|
||||
this.BtnSave.Text = "Save";
|
||||
this.BtnSave.UseVisualStyleBackColor = true;
|
||||
this.BtnSave.Click += new System.EventHandler(this.BtnSave_Click);
|
||||
//
|
||||
// groupBox2
|
||||
//
|
||||
this.groupBox2.Controls.Add(this.BtnSrcBrowse);
|
||||
this.groupBox2.Controls.Add(this.TxtSourcePath);
|
||||
this.groupBox2.Location = new System.Drawing.Point(12, 76);
|
||||
this.groupBox2.Name = "groupBox2";
|
||||
this.groupBox2.Size = new System.Drawing.Size(458, 66);
|
||||
this.groupBox2.TabIndex = 6;
|
||||
this.groupBox2.TabStop = false;
|
||||
this.groupBox2.Text = "Source BCAT Path";
|
||||
//
|
||||
// BtnSrcBrowse
|
||||
//
|
||||
this.BtnSrcBrowse.Location = new System.Drawing.Point(370, 26);
|
||||
this.BtnSrcBrowse.Name = "BtnSrcBrowse";
|
||||
this.BtnSrcBrowse.Size = new System.Drawing.Size(82, 27);
|
||||
this.BtnSrcBrowse.TabIndex = 1;
|
||||
this.BtnSrcBrowse.Text = "Browse";
|
||||
this.BtnSrcBrowse.UseVisualStyleBackColor = true;
|
||||
this.BtnSrcBrowse.Click += new System.EventHandler(this.BtnSrcBrowse_Click);
|
||||
//
|
||||
// TxtSourcePath
|
||||
//
|
||||
this.TxtSourcePath.Location = new System.Drawing.Point(6, 26);
|
||||
this.TxtSourcePath.Name = "TxtSourcePath";
|
||||
this.TxtSourcePath.Size = new System.Drawing.Size(358, 27);
|
||||
this.TxtSourcePath.TabIndex = 0;
|
||||
//
|
||||
// SaveWindow
|
||||
//
|
||||
this.AcceptButton = this.BtnSave;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.BtnCancel;
|
||||
this.ClientSize = new System.Drawing.Size(483, 261);
|
||||
this.Controls.Add(this.groupBox2);
|
||||
this.Controls.Add(this.BtnSave);
|
||||
this.Controls.Add(this.BtnCancel);
|
||||
this.Controls.Add(this.GrpDest);
|
||||
this.Controls.Add(this.GrpBuild);
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "SaveWindow";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.Text = "Save BCAT Package";
|
||||
this.GrpBuild.ResumeLayout(false);
|
||||
this.GrpBuild.PerformLayout();
|
||||
this.GrpDest.ResumeLayout(false);
|
||||
this.GrpDest.PerformLayout();
|
||||
this.groupBox2.ResumeLayout(false);
|
||||
this.groupBox2.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private GroupBox GrpBuild;
|
||||
private RadioButton RadioUnique;
|
||||
private RadioButton RadioMultiple;
|
||||
private TextBox TxtDestPath;
|
||||
private Button BtnPath;
|
||||
private GroupBox GrpDest;
|
||||
private Button BtnCancel;
|
||||
private Button BtnSave;
|
||||
private FolderBrowserDialog FolderBrowser;
|
||||
private GroupBox groupBox2;
|
||||
private Button BtnSrcBrowse;
|
||||
private TextBox TxtSourcePath;
|
||||
}
|
||||
|
|
@ -2,188 +2,189 @@
|
|||
using SwitchGiftDataManager.Core;
|
||||
using Enums;
|
||||
|
||||
namespace SwitchGiftDataManager.WinForm;
|
||||
|
||||
public partial class SaveWindow : Form
|
||||
namespace SwitchGiftDataManager.WinForm
|
||||
{
|
||||
private BCATManager Package;
|
||||
private Games Game;
|
||||
|
||||
public SaveWindow(BCATManager bcat, Games game)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Package = bcat;
|
||||
Game = game;
|
||||
|
||||
if (Game is Games.LGPE)
|
||||
{
|
||||
RadioUnique.Checked = true;
|
||||
RadioMultiple.Enabled = false;
|
||||
}
|
||||
else if (Game is Games.BDSP)
|
||||
RadioUnique.Enabled = false;
|
||||
}
|
||||
|
||||
private void BtnCancel_Click(object sender, EventArgs e) => this.Close();
|
||||
|
||||
private void BtnSrcBrowse_Click(object sender, EventArgs e)
|
||||
public partial class SaveWindow : Form
|
||||
{
|
||||
if(FolderBrowser.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
TxtSourcePath.Text = FolderBrowser.SelectedPath;
|
||||
TxtDestPath.Text = Path.GetDirectoryName(FolderBrowser.SelectedPath);
|
||||
}
|
||||
}
|
||||
private BCATManager Package;
|
||||
private Games Game;
|
||||
|
||||
private void BtnPath_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (FolderBrowser.ShowDialog() == DialogResult.OK)
|
||||
TxtDestPath.Text = FolderBrowser.SelectedPath;
|
||||
}
|
||||
public SaveWindow(BCATManager bcat, Games game)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
private void BtnSave_Click(object sender, EventArgs e)
|
||||
{
|
||||
if(!RadioUnique.Checked && !RadioMultiple.Checked)
|
||||
{
|
||||
MessageBox.Show("Select a Build Method.");
|
||||
return;
|
||||
}
|
||||
if (!CheckValidBcatPath(TxtSourcePath.Text))
|
||||
{
|
||||
MessageBox.Show("Invalid BCAT source path");
|
||||
return;
|
||||
}
|
||||
if (!CheckValidPath(TxtDestPath.Text))
|
||||
{
|
||||
MessageBox.Show("Invalid destination path.");
|
||||
return;
|
||||
}
|
||||
Package = bcat;
|
||||
Game = game;
|
||||
|
||||
var path = Path.Combine(TxtDestPath.Text, $"Forged_BCAT_{Game}");
|
||||
CopyDirectory(TxtSourcePath.Text, path);
|
||||
|
||||
if (RadioMultiple.Checked)
|
||||
{
|
||||
try
|
||||
if (Game is Games.LGPE)
|
||||
{
|
||||
var wcdata = Package.ConcatenateFiles();
|
||||
var metadata = Package.ForgeMetaInfo(wcdata.ToArray());
|
||||
RadioUnique.Checked = true;
|
||||
RadioMultiple.Enabled = false;
|
||||
}
|
||||
else if (Game is Games.BDSP)
|
||||
RadioUnique.Enabled = false;
|
||||
}
|
||||
|
||||
private void BtnCancel_Click(object sender, EventArgs e) => this.Close();
|
||||
|
||||
private void BtnSrcBrowse_Click(object sender, EventArgs e)
|
||||
{
|
||||
if(FolderBrowser.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
TxtSourcePath.Text = FolderBrowser.SelectedPath;
|
||||
TxtDestPath.Text = Path.GetDirectoryName(FolderBrowser.SelectedPath);
|
||||
}
|
||||
}
|
||||
|
||||
private void BtnPath_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (FolderBrowser.ShowDialog() == DialogResult.OK)
|
||||
TxtDestPath.Text = FolderBrowser.SelectedPath;
|
||||
}
|
||||
|
||||
private void BtnSave_Click(object sender, EventArgs e)
|
||||
{
|
||||
if(!RadioUnique.Checked && !RadioMultiple.Checked)
|
||||
{
|
||||
MessageBox.Show("Select a Build Method.");
|
||||
return;
|
||||
}
|
||||
if (!CheckValidBcatPath(TxtSourcePath.Text))
|
||||
{
|
||||
MessageBox.Show("Invalid BCAT source path");
|
||||
return;
|
||||
}
|
||||
if (!CheckValidPath(TxtDestPath.Text))
|
||||
{
|
||||
MessageBox.Show("Invalid destination path.");
|
||||
return;
|
||||
}
|
||||
|
||||
var path = Path.Combine(TxtDestPath.Text, $"Forged_BCAT_{Game}");
|
||||
CopyDirectory(TxtSourcePath.Text, path);
|
||||
|
||||
if (RadioMultiple.Checked)
|
||||
{
|
||||
try
|
||||
{
|
||||
var wcdata = Package.ConcatenateFiles();
|
||||
var metadata = Package.ForgeMetaInfo(wcdata.ToArray());
|
||||
var metadatapath = Path.Combine(path, "directories");
|
||||
metadatapath = Path.Combine(metadatapath, Package.GetDefaultBcatFolderName());
|
||||
var wcpath = Path.Combine(metadatapath, "files");
|
||||
|
||||
if (Directory.Exists(metadatapath))
|
||||
DeleteFilesAndDirectory(metadatapath);
|
||||
|
||||
Directory.CreateDirectory(wcpath);
|
||||
File.WriteAllBytes(Path.Combine(metadatapath, "files.meta"), metadata.ToArray());
|
||||
File.WriteAllBytes(Path.Combine(wcpath, Package.GetDefaultBcatFileName()), wcdata.ToArray());
|
||||
MessageBox.Show("Done");
|
||||
this.Close();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
MessageBox.Show("Internal Error");
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var metadata = Package.ForgeMetaInfo();
|
||||
var metadatapath = Path.Combine(path, "directories");
|
||||
metadatapath = Path.Combine(metadatapath, Package.GetDefaultBcatFolderName());
|
||||
var wcpath = Path.Combine(metadatapath, "files");
|
||||
var wcspath = Path.Combine(metadatapath, "files");
|
||||
|
||||
if (Directory.Exists(metadatapath))
|
||||
DeleteFilesAndDirectory(metadatapath);
|
||||
|
||||
Directory.CreateDirectory(wcpath);
|
||||
Directory.CreateDirectory(wcspath);
|
||||
File.WriteAllBytes(Path.Combine(metadatapath, "files.meta"), metadata.ToArray());
|
||||
File.WriteAllBytes(Path.Combine(wcpath, Package.GetDefaultBcatFileName()), wcdata.ToArray());
|
||||
MessageBox.Show($"Saved in {path}{Environment.NewLine}BCAT forge was successful.");
|
||||
this.Close();
|
||||
if (Package.TrySaveAllWondercards(wcspath))
|
||||
{
|
||||
MessageBox.Show("Done.");
|
||||
this.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Internal error.");
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
}
|
||||
|
||||
private static bool CheckValidBcatPath(string path)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
return false;
|
||||
|
||||
if (!Directory.Exists(Path.Combine(path, "directories")))
|
||||
return false;
|
||||
|
||||
if (!File.Exists(Path.Combine(path, "directories.meta")))
|
||||
return false;
|
||||
|
||||
if (!File.Exists(Path.Combine(path, "etag.bin")))
|
||||
return false;
|
||||
|
||||
if (!File.Exists(Path.Combine(path, "list.msgpack")))
|
||||
return false;
|
||||
|
||||
if (!File.Exists(Path.Combine(path, "na_required")))
|
||||
return false;
|
||||
|
||||
if (!File.Exists(Path.Combine(path, "passphrase.bin")))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool CheckValidPath(string path)
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(path))
|
||||
return false;
|
||||
|
||||
if (!Directory.Exists(path))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void CopyDirectory(string source, string dest)
|
||||
{
|
||||
var dir = new DirectoryInfo(source);
|
||||
DirectoryInfo[] dirs = dir.GetDirectories();
|
||||
Directory.CreateDirectory(dest);
|
||||
|
||||
foreach (FileInfo file in dir.GetFiles())
|
||||
{
|
||||
MessageBox.Show("Internal Error");
|
||||
this.Close();
|
||||
string targetFilePath = Path.Combine(dest, file.Name);
|
||||
if(!File.Exists(targetFilePath))
|
||||
file.CopyTo(targetFilePath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var metadata = Package.ForgeMetaInfo();
|
||||
var metadatapath = Path.Combine(path, "directories");
|
||||
metadatapath = Path.Combine(metadatapath, Package.GetDefaultBcatFolderName());
|
||||
var wcspath = Path.Combine(metadatapath, "files");
|
||||
|
||||
if (Directory.Exists(metadatapath))
|
||||
DeleteFilesAndDirectory(metadatapath);
|
||||
|
||||
Directory.CreateDirectory(wcspath);
|
||||
File.WriteAllBytes(Path.Combine(metadatapath, "files.meta"), metadata.ToArray());
|
||||
if (Package.TrySaveAllWondercards(wcspath))
|
||||
foreach (DirectoryInfo subDir in dirs)
|
||||
{
|
||||
MessageBox.Show($"Saved in {path}{Environment.NewLine}BCAT forge was successful.");
|
||||
this.Close();
|
||||
string newDestinationDir = Path.Combine(dest, subDir.Name);
|
||||
CopyDirectory(subDir.FullName, newDestinationDir);
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
private void DeleteFilesAndDirectory(string targetDir)
|
||||
{
|
||||
string[] files = Directory.GetFiles(targetDir);
|
||||
string[] dirs = Directory.GetDirectories(targetDir);
|
||||
|
||||
foreach (string file in files)
|
||||
{
|
||||
MessageBox.Show("Internal error.");
|
||||
this.Close();
|
||||
File.SetAttributes(file, FileAttributes.Normal);
|
||||
File.Delete(file);
|
||||
}
|
||||
|
||||
foreach (string dir in dirs)
|
||||
DeleteFilesAndDirectory(dir);
|
||||
|
||||
Directory.Delete(targetDir, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool CheckValidBcatPath(string path)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
return false;
|
||||
|
||||
if (!Directory.Exists(Path.Combine(path, "directories")))
|
||||
return false;
|
||||
|
||||
if (!File.Exists(Path.Combine(path, "directories.meta")))
|
||||
return false;
|
||||
|
||||
if (!File.Exists(Path.Combine(path, "etag.bin")))
|
||||
return false;
|
||||
|
||||
if (!File.Exists(Path.Combine(path, "list.msgpack")))
|
||||
return false;
|
||||
|
||||
if (!File.Exists(Path.Combine(path, "na_required")))
|
||||
return false;
|
||||
|
||||
if (!File.Exists(Path.Combine(path, "passphrase.bin")))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool CheckValidPath(string path)
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(path))
|
||||
return false;
|
||||
|
||||
if (!Directory.Exists(path))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void CopyDirectory(string source, string dest)
|
||||
{
|
||||
var dir = new DirectoryInfo(source);
|
||||
DirectoryInfo[] dirs = dir.GetDirectories();
|
||||
Directory.CreateDirectory(dest);
|
||||
|
||||
foreach (FileInfo file in dir.GetFiles())
|
||||
{
|
||||
string targetFilePath = Path.Combine(dest, file.Name);
|
||||
if(!File.Exists(targetFilePath))
|
||||
file.CopyTo(targetFilePath);
|
||||
}
|
||||
|
||||
foreach (DirectoryInfo subDir in dirs)
|
||||
{
|
||||
string newDestinationDir = Path.Combine(dest, subDir.Name);
|
||||
CopyDirectory(subDir.FullName, newDestinationDir);
|
||||
}
|
||||
}
|
||||
|
||||
private void DeleteFilesAndDirectory(string targetDir)
|
||||
{
|
||||
string[] files = Directory.GetFiles(targetDir);
|
||||
string[] dirs = Directory.GetDirectories(targetDir);
|
||||
|
||||
foreach (string file in files)
|
||||
{
|
||||
File.SetAttributes(file, FileAttributes.Normal);
|
||||
File.Delete(file);
|
||||
}
|
||||
|
||||
foreach (string dir in dirs)
|
||||
DeleteFilesAndDirectory(dir);
|
||||
|
||||
Directory.Delete(targetDir, false);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +1,34 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net9.0-windows7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<PackageIcon>Resources\icon.png</PackageIcon>
|
||||
<ApplicationIcon>Resources\icon.ico</ApplicationIcon>
|
||||
<Authors>Manu098vm</Authors>
|
||||
<AssemblyName>$(MSBuildProjectName)</AssemblyName>
|
||||
<Copyright>Copyright (C) 2024 Manu098vm</Copyright>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<PackageTags>pokemon; mystery gift; wondercard; reader; nintendo; bcat; event injection;</PackageTags>
|
||||
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||
<Company>Project Pokémon</Company>
|
||||
<PackageProjectUrl>https://github.com/Manu098vm/Switch-Gift-Data-Manager</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/Manu098vm/Switch-Gift-Data-Manager</RepositoryUrl>
|
||||
<Configurations>Debug;Release;WSL</Configurations>
|
||||
<EnableWindowsTargeting>true</EnableWindowsTargeting>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<PackageIcon>Resources\icon.png</PackageIcon>
|
||||
<ApplicationIcon>Resources\icon.ico</ApplicationIcon>
|
||||
<Authors>Manu098vm</Authors>
|
||||
<AssemblyName>$(MSBuildProjectName)</AssemblyName>
|
||||
<Copyright>Copyright (C) 2022 Manu098vm</Copyright>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<PackageTags>pokemon; mystery gift; wondercard; reader; nintendo; bcat; event injection;</PackageTags>
|
||||
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||
<Company>Project Pokémon</Company>
|
||||
<PackageProjectUrl>https://github.com/Manu098vm/Switch-Gift-Data-Manager</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/Manu098vm/Switch-Gift-Data-Manager</RepositoryUrl>
|
||||
<Configurations>Debug;Release;WSL</Configurations>
|
||||
<EnableWindowsTargeting>true</EnableWindowsTargeting>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DebugType>embedded</DebugType>
|
||||
<Optimize>True</Optimize>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DebugType>embedded</DebugType>
|
||||
<Optimize>True</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<DebugType>embedded</DebugType>
|
||||
|
|
@ -40,61 +40,69 @@
|
|||
<SelfContained>false</SelfContained>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\README.md">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\README.md">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\LICENSE">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\LICENSE">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SwitchGiftDataManager.Core\SwitchGiftDataManager.Core.csproj">
|
||||
<Private>True</Private>
|
||||
<CopyLocalSatelliteAssemblies>True</CopyLocalSatelliteAssemblies>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SwitchGiftDataManager.Core\SwitchGiftDataManager.Core.csproj">
|
||||
<Private>True</Private>
|
||||
<CopyLocalSatelliteAssemblies>True</CopyLocalSatelliteAssemblies>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Properties\Settings.Designer.cs">
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Properties\Settings.Designer.cs">
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Update="Resources\icon.png">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Update="Resources\icon.png">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="$(ConfigurationName) == Release and '$(OS)' == 'Windows_NT'">
|
||||
<Move SourceFiles="$(OUTDIR)\SwitchGiftDataManager.WinForm.exe" DestinationFiles="$(OUTDIR)\Switch Gift Data Manager.exe" />
|
||||
</Target>
|
||||
|
||||
<Target Name="PostClean" AfterTargets="Clean" Condition="$(ConfigurationName) == Release">
|
||||
<RemoveDir Directories="$(TargetDir)" />
|
||||
<RemoveDir Directories="$(ProjectDir)$(BaseIntermediateOutputPath)" />
|
||||
<Target Name="PostPublish" AfterTargets="Publish" Condition="$(ConfigurationName) == Release and '$(OS)' == 'Windows_NT'">
|
||||
<Move SourceFiles="$(OUTDIR)\publish\SwitchGiftDataManager.WinForm.exe" DestinationFiles="$(OUTDIR)\publish\Switch Gift Data Manager.exe" />
|
||||
</Target>
|
||||
|
||||
<Target Name="PostClean" AfterTargets="Clean" Condition="$(ConfigurationName) == Release">
|
||||
<RemoveDir Directories="$(TargetDir)" />
|
||||
<RemoveDir Directories="$(ProjectDir)$(BaseIntermediateOutputPath)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<_LastSelectedProfileId>D:\Projects\SwitchGiftDataManager\SwitchGiftDataManager.WinForm\Properties\PublishProfiles\windows.pubxml</_LastSelectedProfileId>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="MainWindow.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Update="SaveWindow.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Loading…
Reference in New Issue
Block a user