mirror of
https://github.com/Manu098vm/Switch-Gift-Data-Manager.git
synced 2026-03-22 01:44:24 -05:00
Compare commits
66 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef1c90dbea | ||
|
|
f8fb4485c0 | ||
|
|
84ac05f77f | ||
|
|
81cf6514f8 | ||
|
|
e872275c99 | ||
|
|
91b3c89c63 | ||
|
|
900bd9c794 | ||
|
|
1f23818043 | ||
|
|
570e76aae8 | ||
|
|
b2cccb5176 | ||
|
|
fe1f9549a8 | ||
|
|
b683b27d06 | ||
|
|
65e690eda1 | ||
|
|
b70c300df0 | ||
|
|
eb0746a26d | ||
|
|
c9f5783ce4 | ||
|
|
58874682c9 | ||
|
|
dddb3270f7 | ||
|
|
3e925e0c6b | ||
|
|
d0568155a9 | ||
|
|
c7f52d85ee | ||
|
|
37d1bcbc24 | ||
|
|
de3cdacba6 | ||
|
|
1f97759958 | ||
|
|
cf6b480f90 | ||
|
|
ea2547caf9 | ||
|
|
095ff61113 | ||
|
|
bad20714dd | ||
|
|
04babae966 | ||
|
|
0692b19ac3 | ||
|
|
cfd46b8077 | ||
|
|
bf85d40baf | ||
|
|
fb7d53c1f1 | ||
|
|
9e895d34af | ||
|
|
8991a47be3 | ||
|
|
da897918f8 | ||
|
|
084dce0e5b | ||
|
|
fee2b66c98 | ||
|
|
7e05c2fa8a | ||
|
|
c106bf6697 | ||
|
|
88dafe1df4 | ||
|
|
8806614c0b | ||
|
|
72d9555755 | ||
|
|
6faff59266 | ||
|
|
3945beb9b3 | ||
|
|
1e7e532470 | ||
|
|
011eae8ff3 | ||
|
|
35ba2411fa | ||
|
|
86170222b5 | ||
|
|
630d186b6a | ||
|
|
eab6cb1f71 | ||
|
|
32480c8c9b | ||
|
|
0b0e10b07e | ||
|
|
9fcc4681cc | ||
|
|
e794095307 | ||
|
|
8cbe8aef6d | ||
|
|
9c0a6323b9 | ||
|
|
7ded7f7cb0 | ||
|
|
72583a82e7 | ||
|
|
b69db55d60 | ||
|
|
2f3373db92 | ||
|
|
4c234e6831 | ||
|
|
963e8e8455 | ||
|
|
03de3fc875 | ||
|
|
65b9defb9a | ||
|
|
7d063bb85a |
72
.github/workflows/Linux.yml
vendored
72
.github/workflows/Linux.yml
vendored
|
|
@ -1,41 +1,3 @@
|
|||
# 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:
|
||||
|
|
@ -52,35 +14,33 @@ jobs:
|
|||
matrix:
|
||||
configuration: [Release]
|
||||
|
||||
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
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
env:
|
||||
Solution_Name: SwitchGiftDataManager.sln
|
||||
Project_Path: SwitchGiftDataManager.CommandLine/SwitchGiftDataManager.CommandLine.csproj
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# Install the .NET Core workload
|
||||
- name: Install .NET Core
|
||||
uses: actions/setup-dotnet@v3
|
||||
- name: Install .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
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
|
||||
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
|
||||
|
||||
# Upload the artifact: https://github.com/marketplace/actions/upload-a-build-artifact
|
||||
- name: Upload Linux CommandLine build artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Linux.CommandLine.App
|
||||
path: SwitchGiftDataManager.CommandLine/bin
|
||||
path: SwitchGiftDataManager.CommandLine/bin
|
||||
81
.github/workflows/Mac.yml
vendored
81
.github/workflows/Mac.yml
vendored
|
|
@ -1,41 +1,3 @@
|
|||
# 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:
|
||||
|
|
@ -52,35 +14,42 @@ jobs:
|
|||
matrix:
|
||||
configuration: [Release]
|
||||
|
||||
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
|
||||
runs-on: macos-latest
|
||||
|
||||
env:
|
||||
Solution_Name: SwitchGiftDataManager.sln
|
||||
Project_Path: SwitchGiftDataManager.CommandLine/SwitchGiftDataManager.CommandLine.csproj
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# Install the .NET Core workload
|
||||
- name: Install .NET Core
|
||||
uses: actions/setup-dotnet@v3
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
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
|
||||
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-
|
||||
|
||||
- name: Install dependencies
|
||||
run: dotnet restore ${{ env.Project_Path }}
|
||||
|
||||
- name: Build
|
||||
run: dotnet build ${{ env.Project_Path }} --configuration ${{ matrix.configuration }} --no-restore
|
||||
|
||||
- name: Test
|
||||
run: dotnet test ${{ env.Project_Path }} --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@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
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,41 +1,3 @@
|
|||
# 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:
|
||||
|
|
@ -52,52 +14,42 @@ jobs:
|
|||
matrix:
|
||||
configuration: [Release]
|
||||
|
||||
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
|
||||
runs-on: windows-latest
|
||||
|
||||
env:
|
||||
Solution_Name: SwitchGiftDataManager.sln
|
||||
Configuration: ${{ matrix.configuration }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# Install the .NET Core workload
|
||||
- name: Install .NET Core
|
||||
uses: actions/setup-dotnet@v3
|
||||
- name: Install .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 7.0.x
|
||||
dotnet-version: 9.0.x
|
||||
|
||||
# Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v1.1
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
# Execute all unit tests in the solution
|
||||
- name: Execute unit tests
|
||||
run: dotnet test
|
||||
|
||||
# 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
|
||||
- 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
|
||||
|
||||
# Upload the artifact: https://github.com/marketplace/actions/upload-a-build-artifact
|
||||
- name: Upload WinForms build artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
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@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Windows.CommandLine.App
|
||||
path: SwitchGiftDataManager.CommandLine/bin
|
||||
path: SwitchGiftDataManager.CommandLine/bin
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
|
|
@ -2,4 +2,9 @@
|
|||
.vs
|
||||
.vscode
|
||||
**/bin
|
||||
**/obj
|
||||
**/obj
|
||||
**/PublishProfiles
|
||||
**.user
|
||||
**.config
|
||||
**.pubxml
|
||||
**.pubxml.user
|
||||
79
README.md
79
README.md
|
|
@ -1,71 +1,76 @@
|
|||
# Switch Gift Data Manager
|
||||

|
||||

|
||||
|
||||
## About
|
||||
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.
|
||||
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.
|
||||
|
||||
### 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)
|
||||
* BCAT wondercard files, either with mutiple or single wondercards (no file format extension)
|
||||
* Scarlet & Violet wondercard files (.wc9)
|
||||
* Legends Z-A wondercard files (.wa9)
|
||||
* BCAT wondercard files, containing either multiple 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 Scarlet and Violet
|
||||
* Pokémon Legends Z-A
|
||||
|
||||
## Disclosure
|
||||
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!
|
||||
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!
|
||||
|
||||
## Usage
|
||||
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)
|
||||
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).
|
||||
|
||||
**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.
|
||||
**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.
|
||||
If you experience a desync, follow one of these methods to resync:
|
||||
* 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.
|
||||
* 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.
|
||||
|
||||
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).
|
||||
## 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)
|
||||
|
||||
## Building
|
||||
* 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`.
|
||||
* 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`.
|
||||
|
||||
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) 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
|
||||
* [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.
|
||||
|
||||
## License
|
||||

|
||||
|
||||
Copyright © 2023 Manu098vm
|
||||
Copyright © 2025 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,236 +1,259 @@
|
|||
using SwitchGiftDataManager.Core;
|
||||
using Enums;
|
||||
|
||||
namespace SwitchGiftDataManager.CommandLine;
|
||||
|
||||
namespace SwitchGiftDataManager.CommandLine
|
||||
public static class Program
|
||||
{
|
||||
public static class Program
|
||||
public static void Main()
|
||||
{
|
||||
public static void Main()
|
||||
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)
|
||||
{
|
||||
var msg = $"Switch Gift Data Manager v{BCATManager.Version}";
|
||||
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";
|
||||
Log(msg);
|
||||
}
|
||||
|
||||
Task.Run(TryUpdate).Wait();
|
||||
var opt = game switch {
|
||||
Games.LGPE => 2,
|
||||
Games.BDSP => 1,
|
||||
_ => int.Parse(Console.ReadLine()!),
|
||||
};
|
||||
|
||||
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);
|
||||
if(opt < 1 || opt > 2)
|
||||
{
|
||||
Log("Invalid input. Aborted.");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
}
|
||||
|
||||
Games game = (Games)int.Parse(Console.ReadLine()!);
|
||||
if (game is Games.None || game > Games.SCVI)
|
||||
destpath = Path.Combine(destpath, $"Forged_BCAT_{game}");
|
||||
CopyDirectory(sourcepath, destpath);
|
||||
|
||||
if (opt == 1)
|
||||
{
|
||||
try
|
||||
{
|
||||
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 wcdata = bcat.ConcatenateFiles();
|
||||
var metadata = bcat.ForgeMetaInfo(wcdata.ToArray());
|
||||
var metadatapath = Path.Combine(destpath, "directories");
|
||||
metadatapath = Path.Combine(metadatapath, bcat.GetDefaultBcatFolderName());
|
||||
var wcspath = Path.Combine(metadatapath, "files");
|
||||
var wcpath = Path.Combine(metadatapath, "files");
|
||||
|
||||
if (Directory.Exists(metadatapath))
|
||||
DeleteFilesAndDirectory(metadatapath);
|
||||
|
||||
Directory.CreateDirectory(wcspath);
|
||||
Directory.CreateDirectory(wcpath);
|
||||
File.WriteAllBytes(Path.Combine(metadatapath, "files.meta"), metadata.ToArray());
|
||||
if (bcat.TrySaveAllWondercards(wcspath))
|
||||
{
|
||||
Log("Done. Press any key to exit...");
|
||||
Console.ReadKey();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("Internal error. Press any key to exit...");
|
||||
Console.ReadKey();
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
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())
|
||||
catch (Exception)
|
||||
{
|
||||
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);
|
||||
Log("Internal Error. Press any key to exit...");
|
||||
Console.ReadKey();
|
||||
}
|
||||
}
|
||||
|
||||
private static void DeleteFilesAndDirectory(string targetDir)
|
||||
else
|
||||
{
|
||||
string[] files = Directory.GetFiles(targetDir);
|
||||
string[] dirs = Directory.GetDirectories(targetDir);
|
||||
var metadata = bcat.ForgeMetaInfo();
|
||||
var metadatapath = Path.Combine(destpath, "directories");
|
||||
metadatapath = Path.Combine(metadatapath, bcat.GetDefaultBcatFolderName());
|
||||
var wcspath = Path.Combine(metadatapath, "files");
|
||||
|
||||
foreach (string file in files)
|
||||
if (Directory.Exists(metadatapath))
|
||||
DeleteFilesAndDirectory(metadatapath);
|
||||
|
||||
Directory.CreateDirectory(wcspath);
|
||||
File.WriteAllBytes(Path.Combine(metadatapath, "files.meta"), metadata.ToArray());
|
||||
if (bcat.TrySaveAllWondercards(wcspath))
|
||||
{
|
||||
File.SetAttributes(file, FileAttributes.Normal);
|
||||
File.Delete(file);
|
||||
Log($"Saved in {path}{Environment.NewLine}BCAT forge was successful.{Environment.NewLine}Press any key to exit...");
|
||||
Console.ReadKey();
|
||||
}
|
||||
|
||||
foreach (string dir in dirs)
|
||||
DeleteFilesAndDirectory(dir);
|
||||
|
||||
Directory.Delete(targetDir, false);
|
||||
}
|
||||
|
||||
private static async Task TryUpdate()
|
||||
{
|
||||
if (await GitHubUtil.IsUpdateAvailable())
|
||||
else
|
||||
{
|
||||
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 });
|
||||
Log("Internal error. Press any key to exit...");
|
||||
Console.ReadKey();
|
||||
}
|
||||
}
|
||||
|
||||
private static void Log(string msg) => Console.WriteLine(msg);
|
||||
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())
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<?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>
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<?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>
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<?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>
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<?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>
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<?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>
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<?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>
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
<?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>
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<?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>
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<?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>net7.0</TargetFramework>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Authors>Manu098vm</Authors>
|
||||
<Copyright>Copyright (C) 2022 Manu098vm</Copyright>
|
||||
<Copyright>Copyright (C) 2024 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>
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<?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,358 +3,402 @@ using System.Globalization;
|
|||
using System.Text;
|
||||
using Enums;
|
||||
|
||||
namespace SwitchGiftDataManager.Core
|
||||
namespace SwitchGiftDataManager.Core;
|
||||
|
||||
public class BCATManager
|
||||
{
|
||||
public class BCATManager
|
||||
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 const string Version = "1.3.0";
|
||||
Game = game;
|
||||
WCList = new();
|
||||
}
|
||||
|
||||
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)
|
||||
private Wondercard CreateWondercard(ReadOnlySpan<byte> data)
|
||||
{
|
||||
return Game switch
|
||||
{
|
||||
Game = game;
|
||||
WCList = new();
|
||||
}
|
||||
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)),
|
||||
};
|
||||
}
|
||||
|
||||
private Wondercard CreateWondercard(ReadOnlySpan<byte> data)
|
||||
{
|
||||
return Game switch
|
||||
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))
|
||||
{
|
||||
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 game = GetCompatibleGamesFromWC(data);
|
||||
if (game == Game)
|
||||
{
|
||||
var game = GetCompatibleGamesFromWC(data);
|
||||
if (game == Game)
|
||||
var size = (int)Wondercard.GetSize(game);
|
||||
var qty = data.Length / size;
|
||||
for (int i = 0; i < qty; i++)
|
||||
{
|
||||
var size = (int)Wondercard.GetSize(game);
|
||||
var qty = data.Length / size;
|
||||
for (int i = 0; i < qty; i++)
|
||||
var wc = CreateWondercard(data[(i * size)..((i + 1) * size)]);
|
||||
if (wc.IsValid())
|
||||
{
|
||||
var wc = CreateWondercard(data[(i * size)..((i + 1) * size)]);
|
||||
if (wc.IsValid())
|
||||
{
|
||||
WCList.Add(wc);
|
||||
success = true;
|
||||
}
|
||||
WCList.Add(wc);
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
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 >= index && WCList.Count >= index)
|
||||
{
|
||||
var wc = WCList.ElementAt(index);
|
||||
wc.SetID(wcid);
|
||||
wc.UpdateChecksum();
|
||||
if (sort)
|
||||
Sort();
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
public ushort GetWCID(int index)
|
||||
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)
|
||||
{
|
||||
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 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 };
|
||||
}
|
||||
|
||||
public List<ushort>? GetDuplicatedWCID()
|
||||
{
|
||||
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>();
|
||||
}
|
||||
|
||||
public string GetDefaultBcatFolderName() => GetDefaultBcatFolderName(this.Game);
|
||||
public string GetDefaultBcatFileName() => GetDefaultBcatFileName(this.Game);
|
||||
|
||||
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(),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
for (int i = 0; i < WCList.Count; i++)
|
||||
if (!TrySaveWondercard(i, path))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
private 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();
|
||||
}
|
||||
|
||||
public ReadOnlySpan<byte> ForgeMetaInfo(object? data = null)
|
||||
{
|
||||
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 ReadOnlySpan<byte> ForgeWcMetaInfo(Wondercard wc)
|
||||
{
|
||||
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 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();
|
||||
}
|
||||
|
||||
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()
|
||||
};
|
||||
var wc = WCList.ElementAt(index);
|
||||
wc.SetID(wcid);
|
||||
}
|
||||
}
|
||||
|
||||
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 SetIsRepeatable(int index, bool repeatable)
|
||||
{
|
||||
if (WCList is not null && WCList.Count > 0 && WCList.Count >= index - 1 && index >= 0)
|
||||
{
|
||||
var wc = WCList.ElementAt(index);
|
||||
wc.SetRepeatable(repeatable);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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 != 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new List<string> { wcid, el1, el2, el3, el4, el5, el6, el7 };
|
||||
}
|
||||
|
||||
public List<ushort>? GetDuplicatedWCID()
|
||||
{
|
||||
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>();
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
for (int i = 0; i < WCList.Count; i++)
|
||||
if (!TrySaveWondercard(i, path))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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[]))
|
||||
{
|
||||
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);
|
||||
}
|
||||
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 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
|
||||
{
|
||||
Games.LGPE => "normal",
|
||||
Games.SWSH => "normal",
|
||||
Games.BDSP => "99",
|
||||
Games.PLA => "normal",
|
||||
Games.SCVI => "normal",
|
||||
Games.ZA => "normal",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(game)),
|
||||
};
|
||||
}
|
||||
|
||||
public static string GetDefaultBcatFileName(Games game)
|
||||
{
|
||||
return game switch
|
||||
{
|
||||
Games.SWSH => "distribution_internet",
|
||||
Games.BDSP => "99",
|
||||
Games.PLA => "distribution_internet",
|
||||
Games.SCVI => "distribution_internet",
|
||||
Games.ZA => "distribution_internet",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(game)),
|
||||
};
|
||||
}
|
||||
|
||||
private static 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 static string GetPIDString(PIDType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
PIDType.FixedPID => "Fixed PID",
|
||||
PIDType.RandomPID => "Random PID",
|
||||
_ => throw new IndexOutOfRangeException()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,77 +1,76 @@
|
|||
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
|
||||
namespace SwitchGiftDataManager.Core;
|
||||
|
||||
public static class ChecksumCalculator
|
||||
{
|
||||
public static class ChecksumCalculator
|
||||
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)
|
||||
{
|
||||
private const ushort InitialValue = 0xFFFF;
|
||||
var crc16 = InitialValue;
|
||||
|
||||
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 length = bytes.Length;
|
||||
var byteIndex = 0;
|
||||
while (length-- > 0)
|
||||
{
|
||||
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;
|
||||
var tableIndex = crc16 >> 8 ^ bytes[byteIndex++];
|
||||
crc16 = (ushort)(crc16 << 8 ^ ccittFalseCrc16Table[tableIndex]);
|
||||
}
|
||||
|
||||
public static Span<byte> CalcReverseMD5(byte[] data)
|
||||
{
|
||||
var md5 = MD5.Create().ComputeHash(data);
|
||||
return crc16;
|
||||
}
|
||||
|
||||
var tmp1 = md5.AsSpan((md5.Length / 2)..);
|
||||
tmp1.Reverse();
|
||||
public static Span<byte> CalcReverseMD5(byte[] data)
|
||||
{
|
||||
var md5 = MD5.Create().ComputeHash(data);
|
||||
|
||||
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 tmp1 = md5.AsSpan((md5.Length / 2)..);
|
||||
tmp1.Reverse();
|
||||
|
||||
return b.AsSpan();
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,111 +1,123 @@
|
|||
using Enums;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace SwitchGiftDataManager.Core
|
||||
namespace SwitchGiftDataManager.Core;
|
||||
|
||||
public class OtherGift
|
||||
{
|
||||
public class OtherGift
|
||||
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 object? Type { get; set; }
|
||||
public ushort Item { get; set; }
|
||||
public uint Quantity { get; set; }
|
||||
public ushort Opt { get; set; }
|
||||
var str = "";
|
||||
|
||||
public string GetItemName() => GetItemName(Item, Type!, Opt);
|
||||
|
||||
public static string GetItemName(ushort id, object type, ushort opt = 0)
|
||||
if (type.GetType() == typeof(GiftType7))
|
||||
{
|
||||
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)
|
||||
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 = (ClothingType8A)id;
|
||||
var category = (ClothingType8)id;
|
||||
var description = category switch
|
||||
{
|
||||
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 => "",
|
||||
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],
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
if(string.IsNullOrWhiteSpace(description))
|
||||
description = $"{opt:X4}";
|
||||
str = $"[{category}] {description}";
|
||||
}
|
||||
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 = 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();
|
||||
}
|
||||
|
||||
return str;
|
||||
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 = (ClothingType8A)id;
|
||||
var description = category switch
|
||||
{
|
||||
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}";
|
||||
}
|
||||
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)" },
|
||||
};
|
||||
}
|
||||
|
|
@ -1,39 +1,32 @@
|
|||
using Enums;
|
||||
|
||||
namespace SwitchGiftDataManager.Core
|
||||
namespace SwitchGiftDataManager.Core;
|
||||
|
||||
public class PokemonGift
|
||||
{
|
||||
public class PokemonGift
|
||||
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 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; }
|
||||
ShinyType.ShinyForced => true,
|
||||
ShinyType.ShinyPossible => (PID != 0 && TID != 0 && SID != 0) && IsShiny(PID, TID, SID),
|
||||
_ => false,
|
||||
};
|
||||
|
||||
public string GetSpeciesName() => GetSpeciesName(Species);
|
||||
public static string GetSpeciesName(uint species) => Properties.Resources.Species.Split(["\n"], StringSplitOptions.None)[species];
|
||||
|
||||
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 IsShiny(uint pid, uint tid, uint sid) => (sid != 0 || tid != 0) && (sid ^ tid ^ (pid >> 16) ^ (pid & 0xFFFF)) < 16;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
public static bool IsTIDAbusePossible(uint tid, uint sid, PIDType type) => type switch
|
||||
{
|
||||
PIDType.FixedPID => tid == 0 && sid == 0,
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
|
@ -1,131 +1,139 @@
|
|||
using System.Buffers.Binary;
|
||||
using Enums;
|
||||
|
||||
namespace SwitchGiftDataManager.Core
|
||||
namespace SwitchGiftDataManager.Core;
|
||||
|
||||
public class WA8 : Wondercard
|
||||
{
|
||||
internal class WA8 : Wondercard
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
public WA8(ReadOnlySpan<byte> data) : base(data)
|
||||
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
|
||||
IsRepeatable = (Data![FlagOffset] & 1) == 0;
|
||||
Type = (GiftType8A)Data![GiftTypeOffset];
|
||||
Content = Type switch
|
||||
{
|
||||
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
|
||||
Type = (GiftType8A)Data![GiftTypeOffset];
|
||||
Content = Type switch
|
||||
{
|
||||
GiftType8A.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(),
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
GiftType8A.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(),
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
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 != ushort.MinValue) || (type is GiftType8A.Clothing && opt != 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();
|
||||
}
|
||||
}
|
||||
142
SwitchGiftDataManager.Core/Classes/WCManager/WA9.cs
Normal file
142
SwitchGiftDataManager.Core/Classes/WCManager/WA9.cs
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
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,115 +1,123 @@
|
|||
using System.Buffers.Binary;
|
||||
using Enums;
|
||||
|
||||
namespace SwitchGiftDataManager.Core
|
||||
namespace SwitchGiftDataManager.Core;
|
||||
|
||||
public class WB7 : Wondercard
|
||||
{
|
||||
internal class WB7 : Wondercard
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
public WB7(ReadOnlySpan<byte> data) : base(data)
|
||||
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
|
||||
IsRepeatable = (Data![FlagOffset] & 1) == 0;
|
||||
Type = (GiftType7)Data![GiftTypeOffset];
|
||||
Content = Type switch
|
||||
{
|
||||
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
|
||||
Type = (GiftType7)Data![GiftTypeOffset];
|
||||
Content = Type switch
|
||||
{
|
||||
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(),
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
Type = type,
|
||||
Item = item,
|
||||
Quantity = quantity,
|
||||
};
|
||||
|
||||
if (gift.Item != 0)
|
||||
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();
|
||||
}
|
||||
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(),
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
Type = type,
|
||||
Item = item,
|
||||
Quantity = quantity,
|
||||
};
|
||||
|
||||
if (gift.Item != ushort.MinValue)
|
||||
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,117 +1,125 @@
|
|||
using System.Buffers.Binary;
|
||||
using Enums;
|
||||
|
||||
namespace SwitchGiftDataManager.Core
|
||||
namespace SwitchGiftDataManager.Core;
|
||||
|
||||
public class WB8 : Wondercard
|
||||
{
|
||||
internal class WB8 : Wondercard
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
public WB8(ReadOnlySpan<byte> data) : base(data)
|
||||
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
|
||||
IsRepeatable = (Data![FlagOffset] & 1) == 0;
|
||||
Type = (GiftType8B)Data![GiftTypeOffset];
|
||||
Content = Type switch
|
||||
{
|
||||
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
|
||||
Type = (GiftType8B)Data![GiftTypeOffset];
|
||||
Content = Type switch
|
||||
{
|
||||
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(),
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
Type = Type,
|
||||
Item = item,
|
||||
Quantity = quantity,
|
||||
};
|
||||
|
||||
if (gift.Item != 0)
|
||||
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();
|
||||
}
|
||||
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(),
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
Type = Type,
|
||||
Item = item,
|
||||
Quantity = quantity,
|
||||
};
|
||||
|
||||
if (gift.Item != ushort.MinValue)
|
||||
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,131 +1,139 @@
|
|||
using System.Buffers.Binary;
|
||||
using Enums;
|
||||
|
||||
namespace SwitchGiftDataManager.Core
|
||||
namespace SwitchGiftDataManager.Core;
|
||||
|
||||
public class WC8 : Wondercard
|
||||
{
|
||||
internal class WC8 : Wondercard
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
public WC8(ReadOnlySpan<byte> data) : base(data)
|
||||
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
|
||||
IsRepeatable = (Data![FlagOffset] & 1) == 0;
|
||||
Type = (GiftType8)Data![GiftTypeOffset];
|
||||
Content = Type switch
|
||||
{
|
||||
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
|
||||
Type = (GiftType8)Data![GiftTypeOffset];
|
||||
Content = Type switch
|
||||
{
|
||||
GiftType8.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(),
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
GiftType8.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(),
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
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 != ushort.MinValue && opt != 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,131 +1,173 @@
|
|||
using System.Buffers.Binary;
|
||||
using Enums;
|
||||
|
||||
namespace SwitchGiftDataManager.Core
|
||||
namespace SwitchGiftDataManager.Core;
|
||||
|
||||
public class WC9 : Wondercard
|
||||
{
|
||||
internal class WC9 : 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 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)
|
||||
{
|
||||
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;
|
||||
|
||||
public WC9(ReadOnlySpan<byte> data) : base(data)
|
||||
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
|
||||
IsRepeatable = (Data![FlagOffset] & 1) == 0;
|
||||
Type = (GiftType9)Data![GiftTypeOffset];
|
||||
Content = Type switch
|
||||
{
|
||||
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
|
||||
Type = (GiftType9)Data![GiftTypeOffset];
|
||||
Content = Type switch
|
||||
{
|
||||
GiftType9.Pokemon => GetPokemon(),
|
||||
_ => GetItems(),
|
||||
};
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
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();
|
||||
}
|
||||
GiftType9.Pokemon => GetPokemon(),
|
||||
_ => GetItems(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
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 != ushort.MinValue) || (type is GiftType9.Clothing && opt != 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 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,68 +1,74 @@
|
|||
using Enums;
|
||||
using System.Buffers.Binary;
|
||||
|
||||
namespace SwitchGiftDataManager.Core
|
||||
namespace SwitchGiftDataManager.Core;
|
||||
|
||||
public abstract class Wondercard
|
||||
{
|
||||
internal abstract class Wondercard
|
||||
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)
|
||||
{
|
||||
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)
|
||||
Game = (WondercardSize)data.Length switch
|
||||
{
|
||||
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 (!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(),
|
||||
};
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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)),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,152 +1,163 @@
|
|||
namespace Enums {
|
||||
public enum Games : int
|
||||
{
|
||||
None = 0,
|
||||
LGPE = 1,
|
||||
SWSH = 2,
|
||||
BDSP = 3,
|
||||
PLA = 4,
|
||||
SCVI = 5,
|
||||
}
|
||||
namespace Enums;
|
||||
|
||||
public enum WCType
|
||||
{
|
||||
Pokemon,
|
||||
Item,
|
||||
}
|
||||
public enum Games : int
|
||||
{
|
||||
None = 0,
|
||||
LGPE = 1,
|
||||
SWSH = 2,
|
||||
BDSP = 3,
|
||||
PLA = 4,
|
||||
SCVI = 5,
|
||||
ZA = 6,
|
||||
}
|
||||
|
||||
internal enum WondercardSize : ushort
|
||||
{
|
||||
WB7 = 0x310,
|
||||
WC8 = 0x2D0,
|
||||
WB8 = 0x2DC,
|
||||
WA8 = 0x2C8,
|
||||
WC9 = 0x2C8,
|
||||
}
|
||||
public enum WCType
|
||||
{
|
||||
Pokemon,
|
||||
Item,
|
||||
}
|
||||
|
||||
internal enum GiftType7 : byte
|
||||
{
|
||||
Pokemon = 0,
|
||||
Item = 1,
|
||||
Bean = 2,
|
||||
BP = 3,
|
||||
}
|
||||
public enum WondercardSize : ushort
|
||||
{
|
||||
WB7 = 0x310,
|
||||
WC8 = 0x2D0,
|
||||
WB8 = 0x2DC,
|
||||
WA8 = 0x2C8,
|
||||
WC9 = 0x2C8,
|
||||
WA9 = 0x2C8,
|
||||
}
|
||||
|
||||
internal enum GiftType8 : byte
|
||||
{
|
||||
None = 0,
|
||||
Pokemon = 1,
|
||||
Item = 2,
|
||||
BP = 3,
|
||||
Clothing = 4,
|
||||
Money = 5,
|
||||
}
|
||||
public enum GiftType7 : byte
|
||||
{
|
||||
Pokemon = 0,
|
||||
Item = 1,
|
||||
Bean = 2,
|
||||
BP = 3,
|
||||
}
|
||||
|
||||
internal enum GiftType8B : byte
|
||||
{
|
||||
None = 0,
|
||||
Pokemon = 1,
|
||||
Item = 2,
|
||||
BP = 3,
|
||||
Clothing = 4,
|
||||
Money = 5,
|
||||
Underground = 6,
|
||||
}
|
||||
public enum GiftType8 : byte
|
||||
{
|
||||
None = 0,
|
||||
Pokemon = 1,
|
||||
Item = 2,
|
||||
BP = 3,
|
||||
Clothing = 4,
|
||||
Money = 5,
|
||||
}
|
||||
|
||||
internal enum GiftType8A : byte
|
||||
{
|
||||
None = 0,
|
||||
Pokemon = 1,
|
||||
Item = 2,
|
||||
Clothing = 3,
|
||||
}
|
||||
public enum GiftType8B : byte
|
||||
{
|
||||
None = 0,
|
||||
Pokemon = 1,
|
||||
Item = 2,
|
||||
BP = 3,
|
||||
Clothing = 4,
|
||||
Money = 5,
|
||||
Underground = 6,
|
||||
}
|
||||
|
||||
internal enum GiftType9 : byte
|
||||
{
|
||||
None = 0,
|
||||
Pokemon = 1,
|
||||
Item = 2,
|
||||
LP = 3,
|
||||
Clothing = 4,
|
||||
}
|
||||
public enum GiftType8A : byte
|
||||
{
|
||||
None = 0,
|
||||
Pokemon = 1,
|
||||
Item = 2,
|
||||
Clothing = 3,
|
||||
}
|
||||
|
||||
public enum PIDType
|
||||
{
|
||||
RandomPID,
|
||||
FixedPID,
|
||||
}
|
||||
public enum GiftType9 : byte
|
||||
{
|
||||
None = 0,
|
||||
Pokemon = 1,
|
||||
Item = 2,
|
||||
LP = 3,
|
||||
Clothing = 4,
|
||||
}
|
||||
|
||||
public enum ShinyType
|
||||
{
|
||||
ShinyLocked,
|
||||
ShinyPossible,
|
||||
ShinyForced,
|
||||
ShinyTIDAbuse,
|
||||
ShinyHighOdds,
|
||||
}
|
||||
public enum GiftType9A : byte
|
||||
{
|
||||
None = 0,
|
||||
Pokemon = 1,
|
||||
Item = 2,
|
||||
Flag = 3,
|
||||
Clothing = 4,
|
||||
}
|
||||
|
||||
internal enum ShinyType7 : byte
|
||||
{
|
||||
Fixed = 0,
|
||||
ShinyRandom = 1,
|
||||
Shiny = 2,
|
||||
ShinyLocked = 3,
|
||||
}
|
||||
public enum PIDType
|
||||
{
|
||||
RandomPID,
|
||||
FixedPID,
|
||||
}
|
||||
|
||||
internal enum ShinyType8 : byte
|
||||
{
|
||||
ShinyLocked = 0,
|
||||
ShinyRandom = 1,
|
||||
ShinyStar = 2,
|
||||
ShinySquare = 3,
|
||||
Fixed = 4,
|
||||
}
|
||||
public enum ShinyType
|
||||
{
|
||||
ShinyLocked,
|
||||
ShinyPossible,
|
||||
ShinyForced,
|
||||
ShinyTIDAbuse,
|
||||
ShinyHighOdds,
|
||||
}
|
||||
|
||||
internal enum ShinyType9 : 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 ClothingType8: byte
|
||||
{
|
||||
Glasses = 0x06,
|
||||
Hats = 0x07,
|
||||
Jackets = 0x08,
|
||||
Tops = 0x09,
|
||||
Bags = 0x0A,
|
||||
Gloves = 0x0B,
|
||||
Bottoms = 0x0C,
|
||||
Legwear = 0x0D,
|
||||
Shoes = 0x0E,
|
||||
None = 0xFF,
|
||||
}
|
||||
public enum ShinyType8 : 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 ShinyType9 : byte
|
||||
{
|
||||
ShinyLocked = 0,
|
||||
ShinyRandom = 1,
|
||||
ShinyStar = 2,
|
||||
ShinySquare = 3,
|
||||
Fixed = 4,
|
||||
}
|
||||
|
||||
internal enum ClothingType9 : byte
|
||||
{
|
||||
Uniform = 0x00,
|
||||
Legs = 0x01,
|
||||
Foots = 0x02,
|
||||
Gloves = 0x03,
|
||||
Bags = 0x04,
|
||||
Heads = 0x5,
|
||||
Eyes = 0x06,
|
||||
Rotom = 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,
|
||||
}
|
||||
|
|
@ -836,9 +836,9 @@ namespace SwitchGiftDataManager.Core.Properties {
|
|||
///
|
||||
/// [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string SCVIClothingBags {
|
||||
internal static string SCVIClothings {
|
||||
get {
|
||||
return ResourceManager.GetString("SCVIClothingBags", resourceCulture);
|
||||
return ResourceManager.GetString("SCVIClothings", 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="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 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>
|
||||
<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,4 +2398,238 @@ Green Dish
|
|||
Orange Dish
|
||||
Red Dish
|
||||
White Dish
|
||||
Yellow 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
|
||||
File diff suppressed because it is too large
Load Diff
9140
SwitchGiftDataManager.Core/Resources/SCVIClothings.txt
Normal file
9140
SwitchGiftDataManager.Core/Resources/SCVIClothings.txt
Normal file
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>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>
|
||||
<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 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>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Octokit" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
using System.Diagnostics;
|
||||
using SwitchGiftDataManager.Core;
|
||||
using SwitchGiftDataManager.Core;
|
||||
using Octokit;
|
||||
|
||||
namespace SwitchGiftDataManager.Core
|
||||
|
|
|
|||
920
SwitchGiftDataManager.WinForm/MainWindow.Designer.cs
generated
920
SwitchGiftDataManager.WinForm/MainWindow.Designer.cs
generated
|
|
@ -1,414 +1,518 @@
|
|||
namespace SwitchGiftDataManager.WinForm
|
||||
namespace SwitchGiftDataManager.WinForm;
|
||||
|
||||
partial class MainWindow
|
||||
{
|
||||
partial class MainWindow
|
||||
/// <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)
|
||||
{
|
||||
/// <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))
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
components.Dispose();
|
||||
}
|
||||
|
||||
#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;
|
||||
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()
|
||||
{
|
||||
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,448 +1,511 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,64 @@
|
|||
<root>
|
||||
<?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.
|
||||
-->
|
||||
<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">
|
||||
|
|
@ -66,6 +126,12 @@
|
|||
<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
Normal file
66
SwitchGiftDataManager.WinForm/MgdbForm.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
103
SwitchGiftDataManager.WinForm/MgdbForm.cs
Normal file
103
SwitchGiftDataManager.WinForm/MgdbForm.cs
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
1443
SwitchGiftDataManager.WinForm/MgdbForm.resx
Normal file
1443
SwitchGiftDataManager.WinForm/MgdbForm.resx
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -1,15 +0,0 @@
|
|||
<?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>
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<?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>
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<?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,201 +1,200 @@
|
|||
namespace SwitchGiftDataManager.WinForm
|
||||
namespace SwitchGiftDataManager.WinForm;
|
||||
|
||||
partial class SaveWindow
|
||||
{
|
||||
partial class SaveWindow
|
||||
/// <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)
|
||||
{
|
||||
/// <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))
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
components.Dispose();
|
||||
}
|
||||
|
||||
#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;
|
||||
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;
|
||||
}
|
||||
|
|
@ -2,189 +2,188 @@
|
|||
using SwitchGiftDataManager.Core;
|
||||
using Enums;
|
||||
|
||||
namespace SwitchGiftDataManager.WinForm
|
||||
namespace SwitchGiftDataManager.WinForm;
|
||||
|
||||
public partial class SaveWindow : Form
|
||||
{
|
||||
public partial class SaveWindow : Form
|
||||
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)
|
||||
{
|
||||
private BCATManager Package;
|
||||
private Games Game;
|
||||
if(FolderBrowser.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
TxtSourcePath.Text = FolderBrowser.SelectedPath;
|
||||
TxtDestPath.Text = Path.GetDirectoryName(FolderBrowser.SelectedPath);
|
||||
}
|
||||
}
|
||||
|
||||
public SaveWindow(BCATManager bcat, Games game)
|
||||
{
|
||||
InitializeComponent();
|
||||
private void BtnPath_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (FolderBrowser.ShowDialog() == DialogResult.OK)
|
||||
TxtDestPath.Text = FolderBrowser.SelectedPath;
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
|
||||
private void BtnCancel_Click(object sender, EventArgs e) => this.Close();
|
||||
var path = Path.Combine(TxtDestPath.Text, $"Forged_BCAT_{Game}");
|
||||
CopyDirectory(TxtSourcePath.Text, path);
|
||||
|
||||
private void BtnSrcBrowse_Click(object sender, EventArgs e)
|
||||
if (RadioMultiple.Checked)
|
||||
{
|
||||
if(FolderBrowser.ShowDialog() == DialogResult.OK)
|
||||
try
|
||||
{
|
||||
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 wcdata = Package.ConcatenateFiles();
|
||||
var metadata = Package.ForgeMetaInfo(wcdata.ToArray());
|
||||
var metadatapath = Path.Combine(path, "directories");
|
||||
metadatapath = Path.Combine(metadatapath, Package.GetDefaultBcatFolderName());
|
||||
var wcspath = Path.Combine(metadatapath, "files");
|
||||
var wcpath = Path.Combine(metadatapath, "files");
|
||||
|
||||
if (Directory.Exists(metadatapath))
|
||||
DeleteFilesAndDirectory(metadatapath);
|
||||
|
||||
Directory.CreateDirectory(wcspath);
|
||||
Directory.CreateDirectory(wcpath);
|
||||
File.WriteAllBytes(Path.Combine(metadatapath, "files.meta"), metadata.ToArray());
|
||||
if (Package.TrySaveAllWondercards(wcspath))
|
||||
{
|
||||
MessageBox.Show("Done.");
|
||||
this.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Internal error.");
|
||||
this.Close();
|
||||
}
|
||||
File.WriteAllBytes(Path.Combine(wcpath, Package.GetDefaultBcatFileName()), wcdata.ToArray());
|
||||
MessageBox.Show($"Saved in {path}{Environment.NewLine}BCAT forge was successful.");
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
|
||||
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())
|
||||
catch (Exception)
|
||||
{
|
||||
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);
|
||||
MessageBox.Show("Internal Error");
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void DeleteFilesAndDirectory(string targetDir)
|
||||
else
|
||||
{
|
||||
string[] files = Directory.GetFiles(targetDir);
|
||||
string[] dirs = Directory.GetDirectories(targetDir);
|
||||
var metadata = Package.ForgeMetaInfo();
|
||||
var metadatapath = Path.Combine(path, "directories");
|
||||
metadatapath = Path.Combine(metadatapath, Package.GetDefaultBcatFolderName());
|
||||
var wcspath = Path.Combine(metadatapath, "files");
|
||||
|
||||
foreach (string file in files)
|
||||
if (Directory.Exists(metadatapath))
|
||||
DeleteFilesAndDirectory(metadatapath);
|
||||
|
||||
Directory.CreateDirectory(wcspath);
|
||||
File.WriteAllBytes(Path.Combine(metadatapath, "files.meta"), metadata.ToArray());
|
||||
if (Package.TrySaveAllWondercards(wcspath))
|
||||
{
|
||||
File.SetAttributes(file, FileAttributes.Normal);
|
||||
File.Delete(file);
|
||||
MessageBox.Show($"Saved in {path}{Environment.NewLine}BCAT forge was successful.");
|
||||
this.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Internal error.");
|
||||
this.Close();
|
||||
}
|
||||
|
||||
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>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>
|
||||
<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 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,69 +40,61 @@
|
|||
<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>
|
||||
|
||||
<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>
|
||||
<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="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 Name="PostClean" AfterTargets="Clean" Condition="$(ConfigurationName) == Release">
|
||||
<RemoveDir Directories="$(TargetDir)" />
|
||||
<RemoveDir Directories="$(ProjectDir)$(BaseIntermediateOutputPath)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="PostClean" AfterTargets="Clean" Condition="$(ConfigurationName) == Release">
|
||||
<RemoveDir Directories="$(TargetDir)" />
|
||||
<RemoveDir Directories="$(ProjectDir)$(BaseIntermediateOutputPath)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
<?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