Compare commits

..

66 Commits
1.3.1 ... main

Author SHA1 Message Date
Manu
ef1c90dbea Initial handling for Flag wondercards
Some checks failed
Linux / build (Release) (push) Has been cancelled
MacOS / build (Release) (push) Has been cancelled
Windows / build (Release) (push) Has been cancelled
2025-11-08 22:54:36 +01:00
Manu
f8fb4485c0
Update README.md
Some checks failed
Linux / build (Release) (push) Has been cancelled
MacOS / build (Release) (push) Has been cancelled
Windows / build (Release) (push) Has been cancelled
2025-10-28 02:50:59 +01:00
Manu
84ac05f77f Safely get clothing key
Some checks are pending
Linux / build (Release) (push) Waiting to run
MacOS / build (Release) (push) Waiting to run
Windows / build (Release) (push) Waiting to run
2025-10-27 18:47:36 +01:00
Manu
81cf6514f8 Compatibility with Legends ZA 2025-10-27 17:26:14 +01:00
Manu
e872275c99 Bump version
Some checks failed
Linux / build (Release) (push) Has been cancelled
MacOS / build (Release) (push) Has been cancelled
Windows / build (Release) (push) Has been cancelled
2025-02-27 18:00:19 +01:00
Manu
91b3c89c63 Update text resources 2025-02-27 17:59:44 +01:00
Manu
900bd9c794 LGPE too cannot redeem wondercards with an ID over 2048
Some checks failed
Linux / build (Release) (push) Has been cancelled
MacOS / build (Release) (push) Has been cancelled
Windows / build (Release) (push) Has been cancelled
2025-02-26 05:22:03 +01:00
Manu
1f23818043 Update workflows
Some checks failed
Linux / build (Release) (push) Has been cancelled
MacOS / build (Release) (push) Has been cancelled
Windows / build (Release) (push) Has been cancelled
2025-02-17 21:59:03 +01:00
Manu
570e76aae8 Update to NET 9; update Readme 2025-02-17 21:22:34 +01:00
Manu
b2cccb5176 Fix WB7 FixedPID 2025-02-17 21:09:36 +01:00
Manu
fe1f9549a8 Update version 2024-10-10 03:18:30 +02:00
Manu
b683b27d06 Clean up comments and add some MgdbForm logs 2024-10-10 03:04:57 +02:00
Manu
65e690eda1
Increase Download Progress Prompt #5 2024-10-10 02:56:48 +02:00
子燏
b70c300df0 Increase Download Progress Prompt 2024-09-26 13:49:41 +08:00
Manu
eb0746a26d Simplify PokemonGift methods 2024-07-16 17:35:20 +02:00
Manu
c9f5783ce4 Update workflows 2024-06-10 15:50:34 +02:00
Manu
58874682c9 Update copyright 2024-06-10 15:46:13 +02:00
Manu
dddb3270f7 Update SCVIClothings.txt 2024-06-10 15:45:23 +02:00
Manu
3e925e0c6b Bump version 2024-01-02 19:01:57 +01:00
Manu
d0568155a9 Update text resources 2024-01-02 18:59:36 +01:00
Manu
c7f52d85ee Update species & items resources 2023-12-18 21:13:52 +01:00
Manu
37d1bcbc24
Update README.md 2023-12-13 20:52:14 +01:00
Manu
de3cdacba6 readme update 2023-12-04 16:04:31 +01:00
Manu
1f97759958 Remove PublishProfiles 2023-12-01 16:18:02 +01:00
Manu
cf6b480f90 Add MgdbForm 2023-12-01 16:13:36 +01:00
Manu
ea2547caf9 Better handle mgdb download 2023-12-01 15:04:29 +01:00
Manu098vm
095ff61113 Update to net8 2023-11-16 15:49:44 +01:00
Manu
bad20714dd Remove unused line 2023-10-14 01:51:13 +02:00
Manu
04babae966 Update version 2023-10-13 18:55:15 +02:00
Manu
0692b19ac3 Update checksums after editings 2023-10-13 18:54:49 +02:00
Manu
cfd46b8077 Properly handle TID/SID methods on both the WinForm and ConsoleApp projects 2023-10-13 17:28:53 +02:00
Manu
bf85d40baf Misc fixes 2023-10-06 20:20:53 +02:00
Manu
fb7d53c1f1 Select TID SID setter method 2023-10-06 20:16:49 +02:00
Manu
9e895d34af ReadUInt16 for WC9 TID/SID 2023-10-06 18:59:32 +02:00
Manu
8991a47be3 Initial handle for new 2.0.1 TID/SID determination 2023-10-06 18:48:33 +02:00
Manu
da897918f8 Add Unreleased Tracksuit 2023-10-06 17:15:26 +02:00
Manu
084dce0e5b Use actual parsed Species Names 2023-10-06 16:25:31 +02:00
Manu
fee2b66c98 Add new Species and Items 2023-10-06 16:17:49 +02:00
Manu
7e05c2fa8a Fix mgdb path for published exe 2023-08-14 21:32:55 +02:00
Manu
c106bf6697
Update README.md 2023-08-14 00:32:24 +02:00
Manu
88dafe1df4 bump version 2023-08-14 00:27:05 +02:00
Manu
8806614c0b fix wcid editing for entities with null ftid 2023-08-10 23:00:23 +02:00
Manu
72d9555755 Add mgdb download 2023-07-24 14:04:03 +02:00
Manu
6faff59266 Edit warning 2023-07-21 20:43:36 +02:00
Manu
3945beb9b3
Update README.md 2023-07-05 12:50:19 +02:00
Manu
1e7e532470
Update README.md 2023-06-10 13:35:11 +02:00
Manu
011eae8ff3 Misc tweaks 2023-06-10 13:34:11 +02:00
Manu
35ba2411fa Bump version 2023-06-06 22:12:56 +02:00
Manu
86170222b5 Improved ending message 2023-06-06 00:13:34 +02:00
Manu
630d186b6a Use decimals 2023-06-06 00:01:17 +02:00
Manu
eab6cb1f71 Handle WCID editing for GiftType9.Pokemon 2023-06-05 23:56:51 +02:00
Manu
32480c8c9b Add IsRepeatable modifier and fix some edgecases exception 2023-06-05 22:28:02 +02:00
Manu
0b0e10b07e Wondercard Accessability Internal -> Public 2023-06-05 11:28:36 +02:00
Manu
9fcc4681cc Updated pop-up message 2023-05-14 14:37:16 +02:00
Manu
e794095307
Update README.md 2023-05-12 14:32:08 +02:00
Manu
8cbe8aef6d Fix resx path 2023-05-12 14:26:33 +02:00
Manu
9c0a6323b9 Fix resx 2023-05-12 14:21:41 +02:00
Manu
7ded7f7cb0 Unified SV Clothing files & added all the currently unreleased SV clothings
Thanks @pasqualenardiello for his researches on the clothing/fashion blocks: https://projectpokemon.org/home/forums/topic/63383-sv-fashion-block-research/

Co-Authored-By: Pasquale Nardiello <pasqualeomeglio@gmail.com>
2023-05-12 14:09:57 +02:00
Manu
72583a82e7 Better alignment for csproj files 2023-05-08 00:02:00 +02:00
Manu
b69db55d60 fix csproj 2023-04-30 18:04:43 +02:00
Manu
2f3373db92 bump version 2023-04-30 17:46:25 +02:00
Manu
4c234e6831
Update README.md 2023-04-30 17:40:24 +02:00
Manu
963e8e8455 Fix clothing type detection 2023-04-30 17:26:59 +02:00
Manu
03de3fc875 update gitignore 2023-04-30 11:51:28 +02:00
Manu
65b9defb9a Fix Great Ball Backpack name 2023-04-25 14:44:30 +02:00
Manu
7d063bb85a Update bags text resources, allow custom cards when in debug mode 2023-04-15 13:56:21 +02:00
50 changed files with 15581 additions and 7405 deletions

View File

@ -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
dotnet-version: 9.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
- 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

View File

@ -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
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-
# 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
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

View File

@ -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 }}
- 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
# Create the app package by building and packaging the Windows Application Packaging project
- name: Create the app package
run: msbuild $env:Solution_Name /property:Configuration=Release
# Upload the artifact: https://github.com/marketplace/actions/upload-a-build-artifact
- name: Upload WinForms build artifacts
uses: actions/upload-artifact@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

5
.gitignore vendored
View File

@ -3,3 +3,8 @@
.vscode
**/bin
**/obj
**/PublishProfiles
**.user
**.config
**.pubxml
**.pubxml.user

View File

@ -1,10 +1,10 @@
# Switch Gift Data Manager
![image png ff61a0fb0bb9872c3cc1741a5a21a4d6](https://user-images.githubusercontent.com/52102823/200194881-5c97e25c-e4fc-4187-8037-c6785127438e.png)
![immagine](https://github.com/Manu098vm/Switch-Gift-Data-Manager/assets/52102823/2c327c72-d34a-41c2-b912-fe290ea00446)
## 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)
@ -12,7 +12,8 @@ This allows wondercards to be redeemed through the In-Game Mystery Gift Menu. Th
* 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)
* 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
@ -20,52 +21,56 @@ This allows wondercards to be redeemed through the In-Game Mystery Gift Menu. Th
* Pokémon Brilliant Diamond and Shining Pearl
* Pokémon Legends Arceus
* 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
![gplv3-with-text-136x68](https://user-images.githubusercontent.com/52102823/199572700-4e02ed70-74ef-4d67-991e-3168d93aac0d.png)
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

View File

@ -1,11 +1,10 @@
using SwitchGiftDataManager.Core;
using Enums;
namespace SwitchGiftDataManager.CommandLine;
namespace SwitchGiftDataManager.CommandLine
public static class Program
{
public static class Program
{
public static void Main()
{
var msg = $"Switch Gift Data Manager v{BCATManager.Version}";
@ -18,11 +17,12 @@ namespace SwitchGiftDataManager.CommandLine
$"2 - SWSH{Environment.NewLine}" +
$"3 - BDSP{Environment.NewLine}" +
$"4 - PLA{Environment.NewLine}" +
$"5 - SCVI";
$"5 - SCVI{Environment.NewLine}" +
$"6 - ZA";
Log(msg);
Games game = (Games)int.Parse(Console.ReadLine()!);
if (game is Games.None || game > Games.SCVI)
if (game is Games.None || game > Games.ZA)
{
Log("Invalid input. Aborted.");
Console.ReadKey();
@ -52,6 +52,30 @@ namespace SwitchGiftDataManager.CommandLine
}
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))
@ -110,7 +134,7 @@ namespace SwitchGiftDataManager.CommandLine
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...");
Log($"Saved in {path}{Environment.NewLine}BCAT forge was successful.{Environment.NewLine}Press any key to exit...");
Console.ReadKey();
}
catch (Exception)
@ -133,7 +157,7 @@ namespace SwitchGiftDataManager.CommandLine
File.WriteAllBytes(Path.Combine(metadatapath, "files.meta"), metadata.ToArray());
if (bcat.TrySaveAllWondercards(wcspath))
{
Log("Done. Press any key to exit...");
Log($"Saved in {path}{Environment.NewLine}BCAT forge was successful.{Environment.NewLine}Press any key to exit...");
Console.ReadKey();
}
else
@ -232,5 +256,4 @@ namespace SwitchGiftDataManager.CommandLine
}
private static void Log(string msg) => Console.WriteLine(msg);
}
}

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -3,11 +3,11 @@ 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.3.0";
public const string Version = "1.9.0";
private const int FileNameOffset = 0x00;
private const int UnkOffset = 0x20;
@ -35,7 +35,8 @@ namespace SwitchGiftDataManager.Core
Games.BDSP => new WB8(data),
Games.PLA => new WA8(data),
Games.SCVI => new WC9(data),
_ => throw new ArgumentOutOfRangeException(),
Games.ZA => new WA9(data),
_ => throw new ArgumentOutOfRangeException(nameof(Game)),
};
}
@ -92,21 +93,62 @@ namespace SwitchGiftDataManager.Core
public void SetWCID(int index, ushort wcid)
{
if (WCList is not null && WCList.Count >= index && WCList.Count >= index)
if (WCList is not null && WCList.Count > 0 && WCList.Count >= index - 1 && index >= 0)
{
var wc = WCList.ElementAt(index);
wc.SetID(wcid);
wc.UpdateChecksum();
}
}
public ushort GetWCID(int index)
{
if (WCList is not null && WCList.Count >= index && WCList.Count >= 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)
@ -115,20 +157,6 @@ namespace SwitchGiftDataManager.Core
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();
@ -171,7 +199,7 @@ namespace SwitchGiftDataManager.Core
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)
if (qty != 0x0 && qty != ushort.MaxValue)
str = $"{str} x{qty}";
if (el1.Equals(""))
el1 = str;
@ -210,32 +238,6 @@ namespace SwitchGiftDataManager.Core
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)
@ -271,33 +273,16 @@ namespace SwitchGiftDataManager.Core
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(UnkOffset), uint.MaxValue);
BinaryPrimitives.WriteUInt32LittleEndian(metainfo.AsSpan(FileSizeOffset), fileSize);
checksum.ToArray().CopyTo(metainfo, ChecksumOffset);
return ForgeMetaInfoHeader(metainfo);
@ -311,21 +296,36 @@ namespace SwitchGiftDataManager.Core
}
}
private ReadOnlySpan<byte> ForgeWcMetaInfo(Wondercard wc)
private static ReadOnlySpan<byte> ForgeWcMetaInfo(Wondercard wc)
{
var fileName = System.Text.Encoding.UTF8.GetBytes(ForgeWcFileName(wc));
var unknown = 0xFFFFFFFF;
var fileSize = (uint)Wondercard.GetSize(Game);
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), unknown);
BinaryPrimitives.WriteUInt32LittleEndian(data.AsSpan(UnkOffset), uint.MaxValue);
BinaryPrimitives.WriteUInt32LittleEndian(data.AsSpan(FileSizeOffset), fileSize);
checksum.ToArray().CopyTo(data, ChecksumOffset);
return data.AsSpan();
}
private ReadOnlySpan<byte> ForgeMetaInfoHeader(ReadOnlySpan<byte> data)
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];
@ -334,7 +334,52 @@ namespace SwitchGiftDataManager.Core
return filesDotMeta.AsSpan();
}
private string GetShinyString(ShinyType type)
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
{
@ -347,7 +392,7 @@ namespace SwitchGiftDataManager.Core
};
}
private string GetPIDString(PIDType type)
private static string GetPIDString(PIDType type)
{
return type switch
{
@ -356,5 +401,4 @@ namespace SwitchGiftDataManager.Core
_ => throw new IndexOutOfRangeException()
};
}
}
}

View File

@ -1,10 +1,10 @@
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 = {
@ -73,5 +73,4 @@ namespace SwitchGiftDataManager.Core
return b.AsSpan();
}
}
}

View File

@ -1,17 +1,18 @@
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 ushort Opt { get; set; }
public uint Opt { get; set; }
public string GetItemName() => GetItemName(Item, Type!, Opt);
public static string GetItemName(ushort id, object type, ushort opt = 0)
public static string GetItemName(ushort id, object type, uint opt = 0)
{
var str = "";
@ -39,7 +40,7 @@ namespace SwitchGiftDataManager.Core
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],
ClothingType8.Footwear => Properties.Resources.SWSHClothingShoes.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
_ => throw new ArgumentOutOfRangeException(),
};
str = $"[{category}] {description}";
@ -67,13 +68,13 @@ namespace SwitchGiftDataManager.Core
var category = (ClothingType8A)id;
var description = category switch
{
ClothingType8A.Heads => Properties.Resources.PLAClothingHeads.Split(new String[] { "\n" }, StringSplitOptions.None)[opt],
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.Shoes => "",
ClothingType8A.Footwear => "",
ClothingType8A.Glasses => "",
ClothingType8A.Eyes => "",
ClothingType8A.Eyewear => "",
_ => throw new ArgumentOutOfRangeException(),
};
if(string.IsNullOrWhiteSpace(description))
@ -90,22 +91,33 @@ namespace SwitchGiftDataManager.Core
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],
_ => "",
};
var description = Properties.Resources.SCVIClothings.Split(new String[] { "\n" }, StringSplitOptions.None)[opt];
if (string.IsNullOrWhiteSpace(description))
description = $"{opt:X4}";
//str = $"[{category}] {description}";
str = $"{description}";
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)" },
};
}

View File

@ -1,9 +1,9 @@
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; }
@ -13,27 +13,20 @@ namespace SwitchGiftDataManager.Core
public string GetSpeciesName() => GetSpeciesName(Species);
public bool IsShiny()
public bool IsShiny() => ShinyType switch
{
if (ShinyType is ShinyType.ShinyForced)
return true;
else if (ShinyType is ShinyType.ShinyPossible && PID != 0 && TID != 0 && SID != 0)
return IsShiny(PID, TID, SID);
ShinyType.ShinyForced => true,
ShinyType.ShinyPossible => (PID != 0 && TID != 0 && SID != 0) && IsShiny(PID, TID, SID),
_ => false,
};
return false;
}
public static string GetSpeciesName(uint species) => Properties.Resources.Species.Split(["\n"], StringSplitOptions.None)[species];
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;
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)
public static bool IsTIDAbusePossible(uint tid, uint sid, PIDType type) => type switch
{
if (type is PIDType.FixedPID)
if (tid == 0)
if (sid == 0)
return true;
return false;
}
}
PIDType.FixedPID => tid == 0 && sid == 0,
_ => false,
};
}

View File

@ -1,11 +1,12 @@
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;
@ -20,6 +21,7 @@ namespace SwitchGiftDataManager.Core
public WA8(ReadOnlySpan<byte> data) : base(data)
{
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
IsRepeatable = (Data![FlagOffset] & 1) == 0;
Type = (GiftType8A)Data![GiftTypeOffset];
Content = Type switch
{
@ -94,7 +96,7 @@ namespace SwitchGiftDataManager.Core
Opt = opt,
};
if ((type is not GiftType8A.Clothing && gift.Item != 0x00) || (type is GiftType8A.Clothing && opt != 0xFFFF))
if ((type is not GiftType8A.Clothing && gift.Item != ushort.MinValue) || (type is GiftType8A.Clothing && opt != ushort.MaxValue))
items.Add(gift);
}
return items;
@ -127,5 +129,11 @@ namespace SwitchGiftDataManager.Core
WCID = wcid;
UpdateChecksum();
}
public override void SetRepeatable(bool repeatable)
{
Data![FlagOffset] = (byte)((Data![FlagOffset] & ~1) | (repeatable ? 0 : 1));
IsRepeatable = repeatable;
UpdateChecksum();
}
}

View 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();
}
}

View File

@ -1,24 +1,26 @@
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 = 0xD4;
private const int PIDOffset = 0x2DC;
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
{
@ -78,7 +80,7 @@ namespace SwitchGiftDataManager.Core
Quantity = quantity,
};
if (gift.Item != 0)
if (gift.Item != ushort.MinValue)
items.Add(gift);
}
return items;
@ -111,5 +113,11 @@ namespace SwitchGiftDataManager.Core
WCID = wcid;
UpdateChecksum();
}
public override void SetRepeatable(bool repeatable)
{
Data![FlagOffset] = (byte)((Data![FlagOffset] & ~1) | (repeatable ? 0 : 1));
IsRepeatable = repeatable;
UpdateChecksum();
}
}

View File

@ -1,11 +1,12 @@
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;
@ -19,6 +20,7 @@ namespace SwitchGiftDataManager.Core
public WB8(ReadOnlySpan<byte> data) : base(data)
{
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
IsRepeatable = (Data![FlagOffset] & 1) == 0;
Type = (GiftType8B)Data![GiftTypeOffset];
Content = Type switch
{
@ -80,7 +82,7 @@ namespace SwitchGiftDataManager.Core
Quantity = quantity,
};
if (gift.Item != 0)
if (gift.Item != ushort.MinValue)
items.Add(gift);
}
return items;
@ -113,5 +115,11 @@ namespace SwitchGiftDataManager.Core
WCID = wcid;
UpdateChecksum();
}
public override void SetRepeatable(bool repeatable)
{
Data![FlagOffset] = (byte)((Data![FlagOffset] & ~1) | (repeatable ? 0 : 1));
IsRepeatable = repeatable;
UpdateChecksum();
}
}

View File

@ -1,11 +1,12 @@
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;
@ -20,6 +21,7 @@ namespace SwitchGiftDataManager.Core
public WC8(ReadOnlySpan<byte> data) : base(data)
{
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
IsRepeatable = (Data![FlagOffset] & 1) == 0;
Type = (GiftType8)Data![GiftTypeOffset];
Content = Type switch
{
@ -94,7 +96,7 @@ namespace SwitchGiftDataManager.Core
Opt = opt,
};
if (gift.Item != 0x00 && opt != 0xFFFF)
if (gift.Item != ushort.MinValue && opt != ushort.MaxValue)
items.Add(gift);
}
return items;
@ -127,5 +129,11 @@ namespace SwitchGiftDataManager.Core
WCID = wcid;
UpdateChecksum();
}
public override void SetRepeatable(bool repeatable)
{
Data![FlagOffset] = (byte)((Data![FlagOffset] & ~1) | (repeatable ? 0 : 1));
IsRepeatable = repeatable;
UpdateChecksum();
}
}

View File

@ -1,24 +1,36 @@
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)
{
WCID = BinaryPrimitives.ReadUInt16LittleEndian(data[WondercardIDOffset..]);
IsRepeatable = (Data![FlagOffset] & 1) == 0;
Type = (GiftType9)Data![GiftTypeOffset];
Content = Type switch
{
@ -29,11 +41,13 @@ namespace SwitchGiftDataManager.Core
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 = (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 tid = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(TIDOffset));
var sid = BinaryPrimitives.ReadUInt16LittleEndian(Data.AsSpan(SIDOffset));
var pidtype = (ShinyType9)Data![ShinyTypeOffset] switch
{
ShinyType9.ShinyLocked => PIDType.RandomPID,
@ -94,7 +108,7 @@ namespace SwitchGiftDataManager.Core
Opt = opt,
};
if ((type is not GiftType9.Clothing && gift.Item != 0x00) || (type is GiftType9.Clothing && opt != 0xFFFF))
if ((type is not GiftType9.Clothing && gift.Item != ushort.MinValue) || (type is GiftType9.Clothing && opt != ushort.MaxValue))
items.Add(gift);
}
return items;
@ -114,6 +128,28 @@ namespace SwitchGiftDataManager.Core
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);
@ -127,5 +163,11 @@ namespace SwitchGiftDataManager.Core
WCID = wcid;
UpdateChecksum();
}
public override void SetRepeatable(bool repeatable)
{
Data![FlagOffset] = (byte)((Data![FlagOffset] & ~1) | (repeatable ? 0 : 1));
IsRepeatable = repeatable;
UpdateChecksum();
}
}

View File

@ -1,15 +1,15 @@
using Enums;
using System.Buffers.Binary;
namespace SwitchGiftDataManager.Core
namespace SwitchGiftDataManager.Core;
public abstract class Wondercard
{
internal abstract class Wondercard
{
public static int GenOffset = 0x0F;
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; }
@ -21,7 +21,9 @@ namespace SwitchGiftDataManager.Core
WondercardSize.WB7 => Games.LGPE,
WondercardSize.WC8 => Games.SWSH,
WondercardSize.WB8 => Games.BDSP,
WondercardSize.WC9 => data[GenOffset] != 0 ? Games.PLA : Games.SCVI,
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();
@ -35,12 +37,14 @@ namespace SwitchGiftDataManager.Core
if (Content is null)
return false;
#if DEBUG
if (!IsChecksumValid())
UpdateChecksum();
#endif
if (!IsChecksumValid())
return false;
//if (!IsChecksumValid())
//UpdateChecksum();
return true;
}
@ -52,6 +56,8 @@ namespace SwitchGiftDataManager.Core
public abstract void SetID(ushort wcid);
public abstract void SetRepeatable(bool repeatable);
public static WondercardSize GetSize(Games game)
{
return game switch
@ -61,8 +67,8 @@ namespace SwitchGiftDataManager.Core
Games.BDSP => WondercardSize.WB8,
Games.PLA => WondercardSize.WA8,
Games.SCVI => WondercardSize.WC9,
_ => throw new ArgumentOutOfRangeException(),
Games.ZA => WondercardSize.WA9,
_ => throw new ArgumentOutOfRangeException(nameof(game)),
};
}
}
}

View File

@ -1,49 +1,52 @@
namespace Enums {
public enum Games : int
{
namespace Enums;
public enum Games : int
{
None = 0,
LGPE = 1,
SWSH = 2,
BDSP = 3,
PLA = 4,
SCVI = 5,
}
ZA = 6,
}
public enum WCType
{
public enum WCType
{
Pokemon,
Item,
}
}
internal enum WondercardSize : ushort
{
public enum WondercardSize : ushort
{
WB7 = 0x310,
WC8 = 0x2D0,
WB8 = 0x2DC,
WA8 = 0x2C8,
WC9 = 0x2C8,
}
WA9 = 0x2C8,
}
internal enum GiftType7 : byte
{
public enum GiftType7 : byte
{
Pokemon = 0,
Item = 1,
Bean = 2,
BP = 3,
}
}
internal enum GiftType8 : byte
{
public enum GiftType8 : byte
{
None = 0,
Pokemon = 1,
Item = 2,
BP = 3,
Clothing = 4,
Money = 5,
}
}
internal enum GiftType8B : byte
{
public enum GiftType8B : byte
{
None = 0,
Pokemon = 1,
Item = 2,
@ -51,68 +54,77 @@
Clothing = 4,
Money = 5,
Underground = 6,
}
}
internal enum GiftType8A : byte
{
public enum GiftType8A : byte
{
None = 0,
Pokemon = 1,
Item = 2,
Clothing = 3,
}
}
internal enum GiftType9 : byte
{
public enum GiftType9 : byte
{
None = 0,
Pokemon = 1,
Item = 2,
LP = 3,
Clothing = 4,
}
}
public enum PIDType
{
public enum GiftType9A : byte
{
None = 0,
Pokemon = 1,
Item = 2,
Flag = 3,
Clothing = 4,
}
public enum PIDType
{
RandomPID,
FixedPID,
}
}
public enum ShinyType
{
public enum ShinyType
{
ShinyLocked,
ShinyPossible,
ShinyForced,
ShinyTIDAbuse,
ShinyHighOdds,
}
}
internal enum ShinyType7 : byte
{
public enum ShinyType7 : byte
{
Fixed = 0,
ShinyRandom = 1,
Shiny = 2,
ShinyLocked = 3,
}
}
internal enum ShinyType8 : byte
{
public enum ShinyType8 : byte
{
ShinyLocked = 0,
ShinyRandom = 1,
ShinyStar = 2,
ShinySquare = 3,
Fixed = 4,
}
}
internal enum ShinyType9 : byte
{
public enum ShinyType9 : byte
{
ShinyLocked = 0,
ShinyRandom = 1,
ShinyStar = 2,
ShinySquare = 3,
Fixed = 4,
}
}
internal enum ClothingType8: byte
{
public enum ClothingType8: byte
{
Glasses = 0x06,
Hats = 0x07,
Jackets = 0x08,
@ -121,32 +133,31 @@
Gloves = 0x0B,
Bottoms = 0x0C,
Legwear = 0x0D,
Shoes = 0x0E,
Footwear = 0x0E,
None = 0xFF,
}
}
internal enum ClothingType8A: byte
{
Heads = 0x00,
public enum ClothingType8A: byte
{
Headwear = 0x00,
Tops = 0x01,
Bottoms = 0x02,
Outfit = 0x03,
Shoes = 0x5,
Footwear = 0x5,
Glasses = 0x06,
Eyes = 0x08,
Eyewear = 0x08,
None = 0xFF,
}
}
internal enum ClothingType9 : byte
{
public enum ClothingType9 : byte
{
Uniform = 0x00,
Legs = 0x01,
Foots = 0x02,
Legwear = 0x01,
Footwear = 0x02,
Gloves = 0x03,
Bags = 0x04,
Heads = 0x5,
Eyes = 0x06,
Rotom = 0x08,
Headwear = 0x5,
Eyewear = 0x06,
PhoneCase = 0x08,
None = 0xFF,
}
}

View File

@ -836,9 +836,9 @@ namespace SwitchGiftDataManager.Core.Properties {
///
/// [rest of string was truncated]&quot;;.
/// </summary>
internal static string SCVIClothingBags {
internal static string SCVIClothings {
get {
return ResourceManager.GetString("SCVIClothingBags", resourceCulture);
return ResourceManager.GetString("SCVIClothings", resourceCulture);
}
}

View File

@ -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>

View File

@ -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
@ -2399,3 +2399,237 @@ Orange Dish
Red Dish
White Dish
Yellow Dish
Fairy Feather
Syrupy Apple
Unremarkable Teacup
Masterpiece Teacup
Teal Mask
Cornerstone Mask
Wellspring Mask
Hearthflame Mask
Teal Style Card
Crystal Cluster
Health Mochi
Muscle Mochi
Resist Mochi
Genius Mochi
Clever Mochi
Swift Mochi
Simple Chairs
Academy Chairs
Academy Chairs
Whimsical Chairs
Leafy Chairs
Spooky Chairs
Plaid Chairs (Y)
Plaid Chairs (B)
Plaid Chairs (R)
B&W Grass Chairs
Battle Chairs
Monstrous Chairs
Striped Chairs
Diamond Chairs
Polka-Dot Chairs
Lilac Chairs
Mint Chairs
Peach Chairs
Yellow Chairs
Blue Chairs
Pink Chairs
Ekans Fang
Sandshrew Claw
Cleffa Fur
Vulpix Fur
Poliwag Slime
Bellsprout Vine
Geodude Fragment
Koffing Gas
Munchlax Fang
Sentret Fur
Hoothoot Feather
Spinarak Thread
Aipom Hair
Yanma Spike
Gligar Fang
Slugma Lava
Swinub Hair
Poochyena Fang
Lotad Leaf
Seedot Stem
Nosepass Fragment
Volbeat Fluid
Illumise Fluid
Corphish Shell
Feebas Scales
Duskull Fragment
Chingling Fragment
Timburr Sweat
Sewaddle Leaf
Ducklett Feather
Litwick Soot
Mienfoo Claw
Vullaby Feather
Carbink Jewel
Phantump Twig
Grubbin Thread
Cutiefly Powder
Jangmo-o Scales
Cramorant Down
Morpeko Snack
Poltchageist Powder
Fresh-Start Mochi
Roto-Stick
Glimmering Charm
Metal Alloy
Indigo Style Card
Oddish Leaf
Tentacool Stinger
Doduo Down
Seel Fur
Exeggcute Shell
Tyrogue Sweat
Rhyhorn Fang
Horsea Ink
Elekid Fur
Magby Hair
Lapras Teardrop
Porygon Fragment
Chinchou Sparks
Snubbull Hair
Skarmory Feather
Smeargle Paint
Plusle Fur
Minun Fur
Trapinch Shell
Beldum Claw
Cranidos Spike
Shieldon Claw
Blitzle Mane Hair
Drilbur Claw
Cottonee Fluff
Scraggy Sweat
Minccino Fur
Solosis Gel
Joltik Thread
Golett Shard
Espurr Fur
Inkay Ink
Pikipek Feather
Dewpider Thread
Comfey Flower
Minior Shell
Milcery Cream
Duraludon Tarnish
Articuno Treat
Zapdos Treat
Moltres Treat
Raikou Treat
Entei Treat
Suicune Treat
Lugia Treat
Ho-Oh Treat
Latias Treat
Latios Treat
Kyogre Treat
Groudon Treat
Rayquaza Treat
Cobalion Treat
Terrakion Treat
Virizion Treat
Reshiram Treat
Zekrom Treat
Kyurem Treat
Solgaleo Treat
Lunala Treat
Necrozma Treat
Kubfu Treat
Glastrier Treat
Spectrier Treat
Indigo Disk
Fiery Pick
Stellar Tera Shard
Mythical Pecha Berry
Blueberry Tablecloth
Blueberry Chairs
Synchro Machine
Meteorite
Scarlet Book
Violet Book
Briars 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
Lidas 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2,11 +2,11 @@
<PropertyGroup>
<OutputType>Library</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>

View File

@ -1,5 +1,4 @@
using System.Diagnostics;
using SwitchGiftDataManager.Core;
using SwitchGiftDataManager.Core;
using Octokit;
namespace SwitchGiftDataManager.Core

View File

@ -1,7 +1,7 @@
namespace SwitchGiftDataManager.WinForm
namespace SwitchGiftDataManager.WinForm;
partial class MainWindow
{
partial class MainWindow
{
/// <summary>
/// Required designer variable.
/// </summary>
@ -28,359 +28,456 @@
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
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 = 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
//
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);
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
//
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);
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
//
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);
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
//
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);
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
//
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);
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
//
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);
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
//
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);
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
//
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);
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
//
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";
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
//
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);
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
//
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";
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
//
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);
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
//
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);
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
//
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);
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
//
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);
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
//
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);
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
//
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);
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
//
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);
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
//
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);
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
//
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:";
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
//
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";
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
//
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);
BtnRemove.Name = "BtnRemove";
BtnRemove.Size = new Size(154, 24);
BtnRemove.Text = "Remove";
BtnRemove.Click += 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);
BtnRemoveAll.Name = "BtnRemoveAll";
BtnRemoveAll.Size = new Size(154, 24);
BtnRemoveAll.Text = "Remove All";
BtnRemoveAll.Click += BtnRemoveAll_Click;
//
// OpenFileDialogWC
//
this.OpenFileDialogWC.Multiselect = true;
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);
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
//
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);
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
@ -410,5 +507,12 @@
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;
}

View File

@ -2,17 +2,22 @@ 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
namespace SwitchGiftDataManager.WinForm;
public partial class MainWindow : Form
{
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 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()
@ -20,6 +25,10 @@ namespace SwitchGiftDataManager.WinForm
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()
@ -51,12 +60,14 @@ namespace SwitchGiftDataManager.WinForm
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()
@ -68,6 +79,7 @@ namespace SwitchGiftDataManager.WinForm
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 (*.*)|*.*",
};
}
@ -81,6 +93,7 @@ namespace SwitchGiftDataManager.WinForm
Games.BDSP => BtnBDSP,
Games.PLA => BtnPLA,
Games.SCVI => BtnSCVI,
Games.ZA => BtnZA,
_ => throw new ArgumentOutOfRangeException(),
};
EditSelectedButton(btn);
@ -104,6 +117,7 @@ namespace SwitchGiftDataManager.WinForm
Games.BDSP => PackageBDSP.GetListNames(),
Games.PLA => PackagePLA.GetListNames(),
Games.SCVI => PackageSCVI.GetListNames(),
Games.ZA => PackageZA.GetListNames(),
_ => throw new ArgumentOutOfRangeException(),
};
@ -136,6 +150,7 @@ namespace SwitchGiftDataManager.WinForm
Games.BDSP => PackageBDSP,
Games.PLA => PackagePLA,
Games.SCVI => PackageSCVI,
Games.ZA => PackageZA,
_ => throw new ArgumentOutOfRangeException(),
};
}
@ -182,6 +197,8 @@ namespace SwitchGiftDataManager.WinForm
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;
@ -192,26 +209,14 @@ namespace SwitchGiftDataManager.WinForm
}
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 repeatable = ChkRepeatable.Checked;
var isBefore201 = cmbRedemptionMethod.SelectedIndex == 0;
if (wcid != list.GetWCID(ListBoxWC.SelectedIndex))
{
var index = list.GetIndex(wcid);
if (index == -1)
{
@ -227,11 +232,17 @@ namespace SwitchGiftDataManager.WinForm
return;
}
}
catch (Exception ex)
if (repeatable != list.GetIsRepeatable(ListBoxWC.SelectedIndex))
{
MessageBox.Show(ex.ToString());
return;
list.SetIsRepeatable(ListBoxWC.SelectedIndex, repeatable);
BtnApply.Enabled = false;
}
if (list.GetRequiresMethodSelection(ListBoxWC.SelectedIndex))
{
list.SetIsBefore201(ListBoxWC.SelectedIndex, isBefore201);
BtnApply.Enabled = false;
}
}
@ -261,7 +272,7 @@ namespace SwitchGiftDataManager.WinForm
void FileDragEnter(object sender, DragEventArgs e)
{
if(e.Data is not null && CurrentGame is not Games.None)
if (e.Data is not null && CurrentGame is not Games.None)
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.Copy;
}
@ -296,6 +307,36 @@ namespace SwitchGiftDataManager.WinForm
}
}
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;
@ -306,7 +347,7 @@ namespace SwitchGiftDataManager.WinForm
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.";
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));
@ -345,7 +386,8 @@ namespace SwitchGiftDataManager.WinForm
if (ListBoxWC.SelectedIndex > -1)
{
var list = GetCurrentList();
var content = list.GetContentToString(ListBoxWC.SelectedIndex);
var index = ListBoxWC.SelectedIndex;
var content = list.GetContentToString(index);
var nItem = content.Count();
if (nItem >= 1)
LblInfo1.Text = content.ElementAt(1);
@ -363,6 +405,14 @@ namespace SwitchGiftDataManager.WinForm
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
@ -378,9 +428,9 @@ namespace SwitchGiftDataManager.WinForm
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 ((CurrentGame is Games.BDSP or Games.LGPE && wcid >= 2048) || (CurrentGame is Games.SWSH && e.Index >= 129))
{
if(!curr.Contains('\u2757'))
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));
@ -397,7 +447,7 @@ namespace SwitchGiftDataManager.WinForm
handled = true;
}
}
if(!handled)
if (!handled)
g.DrawString(curr, e.Font!, new SolidBrush(e.ForeColor), new PointF(e.Bounds.X, e.Bounds.Y));
}
}
@ -420,6 +470,7 @@ namespace SwitchGiftDataManager.WinForm
LblInfo6.Visible = true;
LblInfo7.Visible = true;
GrpContent.Enabled = true;
ChkRepeatable.Enabled = true;
}
private void DisableContent()
@ -441,8 +492,20 @@ namespace SwitchGiftDataManager.WinForm
LblInfo6.Visible = false;
LblInfo7.Text = "";
LblInfo7.Visible = false;
GrpContent.Enabled = 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();
}
}

View File

@ -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>

View 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;
}
}

View 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();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -1,7 +1,7 @@
namespace SwitchGiftDataManager.WinForm
namespace SwitchGiftDataManager.WinForm;
partial class SaveWindow
{
partial class SaveWindow
{
/// <summary>
/// Required designer variable.
/// </summary>
@ -197,5 +197,4 @@
private GroupBox groupBox2;
private Button BtnSrcBrowse;
private TextBox TxtSourcePath;
}
}

View File

@ -2,10 +2,10 @@
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;
@ -79,7 +79,7 @@ namespace SwitchGiftDataManager.WinForm
Directory.CreateDirectory(wcpath);
File.WriteAllBytes(Path.Combine(metadatapath, "files.meta"), metadata.ToArray());
File.WriteAllBytes(Path.Combine(wcpath, Package.GetDefaultBcatFileName()), wcdata.ToArray());
MessageBox.Show("Done");
MessageBox.Show($"Saved in {path}{Environment.NewLine}BCAT forge was successful.");
this.Close();
}
catch (Exception)
@ -102,7 +102,7 @@ namespace SwitchGiftDataManager.WinForm
File.WriteAllBytes(Path.Combine(metadatapath, "files.meta"), metadata.ToArray());
if (Package.TrySaveAllWondercards(wcspath))
{
MessageBox.Show("Done.");
MessageBox.Show($"Saved in {path}{Environment.NewLine}BCAT forge was successful.");
this.Close();
}
else
@ -186,5 +186,4 @@ namespace SwitchGiftDataManager.WinForm
Directory.Delete(targetDir, false);
}
}
}

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net7.0-windows</TargetFramework>
<TargetFramework>net9.0-windows7.0</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
@ -10,7 +10,7 @@
<ApplicationIcon>Resources\icon.ico</ApplicationIcon>
<Authors>Manu098vm</Authors>
<AssemblyName>$(MSBuildProjectName)</AssemblyName>
<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>
@ -92,14 +92,6 @@
</None>
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="$(ConfigurationName) == Release and '$(OS)' == 'Windows_NT'">
<Move SourceFiles="$(OUTDIR)\SwitchGiftDataManager.WinForm.exe" DestinationFiles="$(OUTDIR)\Switch Gift Data Manager.exe" />
</Target>
<Target Name="PostPublish" AfterTargets="Publish" Condition="$(ConfigurationName) == Release and '$(OS)' == 'Windows_NT'">
<Move SourceFiles="$(OUTDIR)\publish\SwitchGiftDataManager.WinForm.exe" DestinationFiles="$(OUTDIR)\publish\Switch Gift Data Manager.exe" />
</Target>
<Target Name="PostClean" AfterTargets="Clean" Condition="$(ConfigurationName) == Release">
<RemoveDir Directories="$(TargetDir)" />
<RemoveDir Directories="$(ProjectDir)$(BaseIntermediateOutputPath)" />

View File

@ -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>