mirror of
https://github.com/suloku/BW_tool.git
synced 2026-09-07 00:25:38 -05:00
First commit:
- BW/BW2 save file detection - Checksum verifier (no DLC yet) - Checksum updater (no DLC yet) - Block dumper /injector (only first save) - Block dumper decryption is hardcoded for entralink forest block right now Todo: - Add BW offset tables - Add per-block decryption with known decrypted blocks - Add boxes to specify encryption address, size and seed address (for use without editing source) - Add BW2 DLC blocks - Insert hidden grotto and swarm form - A lot more...
This commit is contained in:
18
BW_tool.sln
Normal file
18
BW_tool.sln
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
# SharpDevelop 5.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BW_tool", "BW_tool\BW_tool.csproj", "{41ABAC38-D34B-489D-A450-3E9FADD07419}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{41ABAC38-D34B-489D-A450-3E9FADD07419}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{41ABAC38-D34B-489D-A450-3E9FADD07419}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{41ABAC38-D34B-489D-A450-3E9FADD07419}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{41ABAC38-D34B-489D-A450-3E9FADD07419}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
82
BW_tool/BW_tool.csproj
Normal file
82
BW_tool/BW_tool.csproj
Normal file
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{41ABAC38-D34B-489D-A450-3E9FADD07419}</ProjectGuid>
|
||||
<ProjectTypeGuids>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>BW_tool</RootNamespace>
|
||||
<AssemblyName>BW_tool</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DebugSymbols>True</DebugSymbols>
|
||||
<DebugType>Full</DebugType>
|
||||
<Optimize>False</Optimize>
|
||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DebugSymbols>False</DebugSymbols>
|
||||
<DebugType>None</DebugType>
|
||||
<Optimize>True</Optimize>
|
||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CSharp">
|
||||
<RequiredTargetFramework>4.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Data.DataSetExtensions">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Xml.Linq">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Dumper.cs" />
|
||||
<Compile Include="Dumper.Designer.cs">
|
||||
<DependentUpon>Dumper.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="MainForm.cs" />
|
||||
<Compile Include="MainForm.Designer.cs">
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SAV\FileIO.cs" />
|
||||
<Compile Include="SAV\SAV5.cs" />
|
||||
<Compile Include="SAV\PKX5.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="SAV" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Dumper.resx">
|
||||
<DependentUpon>Dumper.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="MainForm.resx">
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
193
BW_tool/Dumper.Designer.cs
generated
Normal file
193
BW_tool/Dumper.Designer.cs
generated
Normal file
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Created by SharpDevelop.
|
||||
* User: suloku
|
||||
* Date: 02/03/2016
|
||||
* Time: 0:19
|
||||
*
|
||||
* To change this template use Tools | Options | Coding | Edit Standard Headers.
|
||||
*/
|
||||
namespace BW_tool
|
||||
{
|
||||
partial class Dumper
|
||||
{
|
||||
/// <summary>
|
||||
/// Designer variable used to keep track of non-visual components.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
private System.Windows.Forms.Button dump_but;
|
||||
private System.Windows.Forms.Button inject_but;
|
||||
private System.Windows.Forms.Button dump_dec_but;
|
||||
private System.Windows.Forms.Button inject_crypt_but;
|
||||
private System.Windows.Forms.ComboBox selectedblock;
|
||||
|
||||
/// <summary>
|
||||
/// Disposes resources used by the form.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing) {
|
||||
if (components != null) {
|
||||
components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is required for Windows Forms designer support.
|
||||
/// Do not change the method contents inside the source code editor. The Forms designer might
|
||||
/// not be able to load this method if it was changed manually.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.dump_but = new System.Windows.Forms.Button();
|
||||
this.inject_but = new System.Windows.Forms.Button();
|
||||
this.dump_dec_but = new System.Windows.Forms.Button();
|
||||
this.inject_crypt_but = new System.Windows.Forms.Button();
|
||||
this.selectedblock = new System.Windows.Forms.ComboBox();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// dump_but
|
||||
//
|
||||
this.dump_but.Location = new System.Drawing.Point(254, 39);
|
||||
this.dump_but.Name = "dump_but";
|
||||
this.dump_but.Size = new System.Drawing.Size(75, 23);
|
||||
this.dump_but.TabIndex = 1;
|
||||
this.dump_but.Text = "Dump";
|
||||
this.dump_but.UseVisualStyleBackColor = true;
|
||||
this.dump_but.Click += new System.EventHandler(this.Dump_butClick);
|
||||
//
|
||||
// inject_but
|
||||
//
|
||||
this.inject_but.Location = new System.Drawing.Point(353, 39);
|
||||
this.inject_but.Name = "inject_but";
|
||||
this.inject_but.Size = new System.Drawing.Size(75, 23);
|
||||
this.inject_but.TabIndex = 2;
|
||||
this.inject_but.Text = "Inject";
|
||||
this.inject_but.UseVisualStyleBackColor = true;
|
||||
this.inject_but.Click += new System.EventHandler(this.Inject_butClick);
|
||||
//
|
||||
// dump_dec_but
|
||||
//
|
||||
this.dump_dec_but.Location = new System.Drawing.Point(204, 68);
|
||||
this.dump_dec_but.Name = "dump_dec_but";
|
||||
this.dump_dec_but.Size = new System.Drawing.Size(125, 23);
|
||||
this.dump_dec_but.TabIndex = 3;
|
||||
this.dump_dec_but.Text = "Dump and Decrypt";
|
||||
this.dump_dec_but.UseVisualStyleBackColor = true;
|
||||
this.dump_dec_but.Click += new System.EventHandler(this.Dump_dec_butClick);
|
||||
//
|
||||
// inject_crypt_but
|
||||
//
|
||||
this.inject_crypt_but.Location = new System.Drawing.Point(353, 68);
|
||||
this.inject_crypt_but.Name = "inject_crypt_but";
|
||||
this.inject_crypt_but.Size = new System.Drawing.Size(125, 23);
|
||||
this.inject_crypt_but.TabIndex = 4;
|
||||
this.inject_crypt_but.Text = "Inject and Recrypt";
|
||||
this.inject_crypt_but.UseVisualStyleBackColor = true;
|
||||
this.inject_crypt_but.Click += new System.EventHandler(this.Inject_crypt_butClick);
|
||||
//
|
||||
// selectedblock
|
||||
//
|
||||
this.selectedblock.FormattingEnabled = true;
|
||||
this.selectedblock.Items.AddRange(new object[] {
|
||||
"00 - Box Names",
|
||||
"01 - Box 1",
|
||||
"02 - Box 2",
|
||||
"03 - Box 3",
|
||||
"04 - Box 4",
|
||||
"05 - Box 5",
|
||||
"06 - Box 6",
|
||||
"07 - Box 7",
|
||||
"08 - Box 8",
|
||||
"09 - Box 9",
|
||||
"10 - Box 10",
|
||||
"11 - Box 11",
|
||||
"12 - Box 12",
|
||||
"13 - Box 13",
|
||||
"14 - Box 14",
|
||||
"15 - Box 15",
|
||||
"16 - Box 16",
|
||||
"17 - Box 17",
|
||||
"18 - Box 18",
|
||||
"19 - Box 19",
|
||||
"20 - Box 20",
|
||||
"21 - Box 21",
|
||||
"22 - Box 22",
|
||||
"23 - Box 23",
|
||||
"24 - Box 24",
|
||||
"25 - Inventory",
|
||||
"26 - Party Pokemon",
|
||||
"27 - Trainer Data",
|
||||
"28 - Trainer Position",
|
||||
"29 - Unity Tower and survey stuff",
|
||||
"30 - Pal Pad Player Data (30d)",
|
||||
"31 - Pal Pad Friend Data",
|
||||
"32 - C-Gear",
|
||||
"33 - Card Signature Block & ????",
|
||||
"34 - Mystery Gift",
|
||||
"35 - Dream World Stuff (Catalog)",
|
||||
"36 - Chatter",
|
||||
"37 - Adventure data http://projectpokemon.org/forums/showthread.php?24589-B2W2-Ge" +
|
||||
"neral-ROM-Info&p=167300&viewfull=1#post167300",
|
||||
"38 - Trainer Card Records",
|
||||
"39 - Unknown",
|
||||
"40 - (40d)",
|
||||
"41 - Unknown",
|
||||
"42 - Contains flags and references for downloaded data (Musical)",
|
||||
"43 - Fused Reshiram/Zekrom Storage",
|
||||
"44 - Unknown",
|
||||
"45 - Const Data Block and Event Flag Block (0x35E is the split)",
|
||||
"46 - Unknown",
|
||||
"47 - Tournament Block",
|
||||
"48 - Unknown",
|
||||
"49 - Battle Box Block",
|
||||
"50 - Daycare Block (50d)",
|
||||
"51 - Strength Boulder Status Block",
|
||||
"52 - Badge Flags, Money, Trainer Sayings",
|
||||
"53 - Entralink (Level & Powers etc)",
|
||||
"54 - Pokedex",
|
||||
"55 - Swarm and other overworld info - 2C - swarm, 2D - repel steps, 2E repel type" +
|
||||
"",
|
||||
"56 - Unknown",
|
||||
"57 - Unknown",
|
||||
"58 - Unknown",
|
||||
"59 - Online Records",
|
||||
"60 - Entralink Forest - encrypted (60d)",
|
||||
"61 - Unknown",
|
||||
"62 - Unknown",
|
||||
"63 - Unknown",
|
||||
"64 - Unknown",
|
||||
"65 - Unknown",
|
||||
"66 - Hollow/Rival Block",
|
||||
"67 - Join Avenue Block",
|
||||
"68 - Medal data",
|
||||
"69 - Key-related data",
|
||||
"70 - Unknown (70d)",
|
||||
"71 - Unknown",
|
||||
"72 - Unknown",
|
||||
"73 - Checksum Block (73d)"});
|
||||
this.selectedblock.Location = new System.Drawing.Point(12, 12);
|
||||
this.selectedblock.MaxDropDownItems = 10;
|
||||
this.selectedblock.Name = "selectedblock";
|
||||
this.selectedblock.Size = new System.Drawing.Size(692, 21);
|
||||
this.selectedblock.TabIndex = 5;
|
||||
//
|
||||
// Dumper
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(716, 103);
|
||||
this.Controls.Add(this.selectedblock);
|
||||
this.Controls.Add(this.inject_crypt_but);
|
||||
this.Controls.Add(this.dump_dec_but);
|
||||
this.Controls.Add(this.inject_but);
|
||||
this.Controls.Add(this.dump_but);
|
||||
this.Name = "Dumper";
|
||||
this.Text = "Block Dumper&Injector";
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
86
BW_tool/Dumper.cs
Normal file
86
BW_tool/Dumper.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Created by SharpDevelop.
|
||||
* User: suloku
|
||||
* Date: 02/03/2016
|
||||
* Time: 0:19
|
||||
*
|
||||
* To change this template use Tools | Options | Coding | Edit Standard Headers.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
|
||||
namespace BW_tool
|
||||
{
|
||||
/// <summary>
|
||||
/// Description of Form1.
|
||||
/// </summary>
|
||||
public partial class Dumper : Form
|
||||
{
|
||||
public Dumper()
|
||||
{
|
||||
//
|
||||
// The InitializeComponent() call is required for Windows Forms designer support.
|
||||
//
|
||||
InitializeComponent();
|
||||
selectedblock.SelectedIndex = 0;
|
||||
selectedblock.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||
|
||||
//
|
||||
// TODO: Add constructor code after the InitializeComponent() call.
|
||||
//
|
||||
}
|
||||
public string binaryfilter = "Binary data|*.bin|All Files (*.*)|*.*";
|
||||
void Dump_butClick(object sender, EventArgs e)
|
||||
{
|
||||
SaveFileDialog saveFD = new SaveFileDialog();
|
||||
//saveFD.InitialDirectory = "c:\\";
|
||||
saveFD.Filter = binaryfilter;
|
||||
if (saveFD.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
System.IO.FileStream saveFile;
|
||||
saveFile = new FileStream(saveFD.FileName, FileMode.Create);
|
||||
//Write file
|
||||
saveFile.Write(MainForm.save.getBlock((int)selectedblock.SelectedIndex), 0, MainForm.save.getBlockLength((int)selectedblock.SelectedIndex));
|
||||
saveFile.Close();
|
||||
MessageBox.Show("File Saved.", "Save file");
|
||||
}
|
||||
}
|
||||
public byte[] injectfile;
|
||||
void Inject_butClick(object sender, EventArgs e)
|
||||
{
|
||||
string path = null;
|
||||
FileIO.load_file(ref injectfile, ref path, binaryfilter);
|
||||
MainForm.save.setBlock( injectfile, (int)selectedblock.SelectedIndex);
|
||||
//MessageBox.Show(injectfile.Length.ToString());
|
||||
}
|
||||
void Dump_dec_butClick(object sender, EventArgs e)
|
||||
{
|
||||
SaveFileDialog saveFD = new SaveFileDialog();
|
||||
//saveFD.InitialDirectory = "c:\\";
|
||||
saveFD.Filter = binaryfilter;
|
||||
if (saveFD.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
System.IO.FileStream saveFile;
|
||||
saveFile = new FileStream(saveFD.FileName, FileMode.Create);
|
||||
//Write file
|
||||
saveFile.Write(MainForm.save.getBlockDec((int)selectedblock.SelectedIndex), 0, MainForm.save.getBlockLength((int)selectedblock.SelectedIndex));
|
||||
saveFile.Close();
|
||||
MessageBox.Show("File Saved.", "Save file");
|
||||
}
|
||||
}
|
||||
void Inject_crypt_butClick(object sender, EventArgs e)
|
||||
{
|
||||
string path = null;
|
||||
FileIO.load_file(ref injectfile, ref path, binaryfilter);
|
||||
MainForm.save.setBlockCrypt( injectfile, (int)selectedblock.SelectedIndex);
|
||||
//MessageBox.Show(injectfile.Length.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
120
BW_tool/Dumper.resx
Normal file
120
BW_tool/Dumper.resx
Normal file
@@ -0,0 +1,120 @@
|
||||
<?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">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
125
BW_tool/MainForm.Designer.cs
generated
Normal file
125
BW_tool/MainForm.Designer.cs
generated
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Created by SharpDevelop.
|
||||
* User: suloku
|
||||
* Date: 01/03/2016
|
||||
* Time: 20:03
|
||||
*
|
||||
* To change this template use Tools | Options | Coding | Edit Standard Headers.
|
||||
*/
|
||||
namespace BW_tool
|
||||
{
|
||||
partial class MainForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Designer variable used to keep track of non-visual components.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
private System.Windows.Forms.Button loadsave_but;
|
||||
private System.Windows.Forms.TextBox savegamename;
|
||||
private System.Windows.Forms.Button save_but;
|
||||
private System.Windows.Forms.Label versiontext;
|
||||
private System.Windows.Forms.Button dumper_but;
|
||||
private System.Windows.Forms.Button chk_but;
|
||||
|
||||
/// <summary>
|
||||
/// Disposes resources used by the form.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing) {
|
||||
if (components != null) {
|
||||
components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is required for Windows Forms designer support.
|
||||
/// Do not change the method contents inside the source code editor. The Forms designer might
|
||||
/// not be able to load this method if it was changed manually.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.loadsave_but = new System.Windows.Forms.Button();
|
||||
this.savegamename = new System.Windows.Forms.TextBox();
|
||||
this.save_but = new System.Windows.Forms.Button();
|
||||
this.versiontext = new System.Windows.Forms.Label();
|
||||
this.dumper_but = new System.Windows.Forms.Button();
|
||||
this.chk_but = new System.Windows.Forms.Button();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// loadsave_but
|
||||
//
|
||||
this.loadsave_but.Location = new System.Drawing.Point(12, 12);
|
||||
this.loadsave_but.Name = "loadsave_but";
|
||||
this.loadsave_but.Size = new System.Drawing.Size(132, 23);
|
||||
this.loadsave_but.TabIndex = 0;
|
||||
this.loadsave_but.Text = "Load Savegame";
|
||||
this.loadsave_but.UseVisualStyleBackColor = true;
|
||||
this.loadsave_but.Click += new System.EventHandler(this.Loadsave_butClick);
|
||||
//
|
||||
// savegamename
|
||||
//
|
||||
this.savegamename.Location = new System.Drawing.Point(12, 41);
|
||||
this.savegamename.Name = "savegamename";
|
||||
this.savegamename.Size = new System.Drawing.Size(484, 20);
|
||||
this.savegamename.TabIndex = 1;
|
||||
//
|
||||
// save_but
|
||||
//
|
||||
this.save_but.Location = new System.Drawing.Point(421, 12);
|
||||
this.save_but.Name = "save_but";
|
||||
this.save_but.Size = new System.Drawing.Size(75, 23);
|
||||
this.save_but.TabIndex = 2;
|
||||
this.save_but.Text = "Save";
|
||||
this.save_but.UseVisualStyleBackColor = true;
|
||||
this.save_but.Click += new System.EventHandler(this.Save_butClick);
|
||||
//
|
||||
// versiontext
|
||||
//
|
||||
this.versiontext.Location = new System.Drawing.Point(150, 17);
|
||||
this.versiontext.Name = "versiontext";
|
||||
this.versiontext.Size = new System.Drawing.Size(100, 18);
|
||||
this.versiontext.TabIndex = 3;
|
||||
//
|
||||
// dumper_but
|
||||
//
|
||||
this.dumper_but.Location = new System.Drawing.Point(12, 80);
|
||||
this.dumper_but.Name = "dumper_but";
|
||||
this.dumper_but.Size = new System.Drawing.Size(92, 23);
|
||||
this.dumper_but.TabIndex = 4;
|
||||
this.dumper_but.Text = "Block dumper";
|
||||
this.dumper_but.UseVisualStyleBackColor = true;
|
||||
this.dumper_but.Click += new System.EventHandler(this.Dumper_butClick);
|
||||
//
|
||||
// chk_but
|
||||
//
|
||||
this.chk_but.Location = new System.Drawing.Point(316, 12);
|
||||
this.chk_but.Name = "chk_but";
|
||||
this.chk_but.Size = new System.Drawing.Size(99, 23);
|
||||
this.chk_but.TabIndex = 5;
|
||||
this.chk_but.Text = "Verify Checksums";
|
||||
this.chk_but.UseVisualStyleBackColor = true;
|
||||
this.chk_but.Click += new System.EventHandler(this.Chk_butClick);
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(503, 119);
|
||||
this.Controls.Add(this.chk_but);
|
||||
this.Controls.Add(this.dumper_but);
|
||||
this.Controls.Add(this.versiontext);
|
||||
this.Controls.Add(this.save_but);
|
||||
this.Controls.Add(this.savegamename);
|
||||
this.Controls.Add(this.loadsave_but);
|
||||
this.Name = "MainForm";
|
||||
this.Text = "Gen V save tool";
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
74
BW_tool/MainForm.cs
Normal file
74
BW_tool/MainForm.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Created by SharpDevelop.
|
||||
* User: suloku
|
||||
* Date: 01/03/2016
|
||||
* Time: 20:03
|
||||
*
|
||||
* To change this template use Tools | Options | Coding | Edit Standard Headers.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
|
||||
namespace BW_tool
|
||||
{
|
||||
/// <summary>
|
||||
/// Description of MainForm.
|
||||
/// </summary>
|
||||
public partial class MainForm : Form
|
||||
{
|
||||
public MainForm()
|
||||
{
|
||||
//
|
||||
// The InitializeComponent() call is required for Windows Forms designer support.
|
||||
//
|
||||
InitializeComponent();
|
||||
|
||||
//
|
||||
// TODO: Add constructor code after the InitializeComponent() call.
|
||||
//
|
||||
}
|
||||
public string dsfilter = "NDS save data|*.sav;*.dsv|All Files (*.*)|*.*";
|
||||
public byte[] savebuffer;
|
||||
public static SAV5 save;
|
||||
|
||||
|
||||
void Loadsave_butClick(object sender, EventArgs e)
|
||||
{
|
||||
versiontext.Text = "";
|
||||
string path = null;
|
||||
if(FileIO.load_file(ref savebuffer, ref path, dsfilter) == 1)
|
||||
{
|
||||
savegamename.Text = path;
|
||||
save = new SAV5(savebuffer);
|
||||
if (save.B2W2) versiontext.Text = "Black/White 2";
|
||||
else if (save.BW) versiontext.Text = "Black/White 1";
|
||||
else versiontext.Text = "Invalid file";
|
||||
|
||||
}else{
|
||||
savegamename.Text = "";
|
||||
}
|
||||
}
|
||||
void Save_butClick(object sender, EventArgs e)
|
||||
{
|
||||
if (save.Edited)
|
||||
FileIO.save_data(save.Data);
|
||||
else MessageBox.Show("Save has not been edited");
|
||||
}
|
||||
void Dumper_butClick(object sender, EventArgs e)
|
||||
{
|
||||
Form dumper = new Dumper();
|
||||
dumper.Show();
|
||||
}
|
||||
void Chk_butClick(object sender, EventArgs e)
|
||||
{
|
||||
save.chkCheck();
|
||||
}
|
||||
}
|
||||
}
|
||||
120
BW_tool/MainForm.resx
Normal file
120
BW_tool/MainForm.resx
Normal file
@@ -0,0 +1,120 @@
|
||||
<?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">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
31
BW_tool/Program.cs
Normal file
31
BW_tool/Program.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Created by SharpDevelop.
|
||||
* User: suloku
|
||||
* Date: 01/03/2016
|
||||
* Time: 20:03
|
||||
*
|
||||
* To change this template use Tools | Options | Coding | Edit Standard Headers.
|
||||
*/
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace BW_tool
|
||||
{
|
||||
/// <summary>
|
||||
/// Class with program entry point.
|
||||
/// </summary>
|
||||
internal sealed class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// Program entry point.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new MainForm());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
31
BW_tool/Properties/AssemblyInfo.cs
Normal file
31
BW_tool/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
#region Using directives
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
#endregion
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("BW_tool")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("BW_tool")]
|
||||
[assembly: AssemblyCopyright("Copyright 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// This sets the default COM visibility of types in the assembly to invisible.
|
||||
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The assembly version has following format :
|
||||
//
|
||||
// Major.Minor.Build.Revision
|
||||
//
|
||||
// You can specify all the values or you can use the default the Revision and
|
||||
// Build Numbers by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("1.0.*")]
|
||||
98
BW_tool/SAV/FileIO.cs
Normal file
98
BW_tool/SAV/FileIO.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Created by SharpDevelop.
|
||||
* User: suloku
|
||||
* Date: 02/03/2016
|
||||
* Time: 8:01
|
||||
*
|
||||
* To change this template use Tools | Options | Coding | Edit Standard Headers.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
|
||||
namespace BW_tool
|
||||
{
|
||||
/// <summary>
|
||||
/// Description of FileIO.
|
||||
/// </summary>
|
||||
public class FileIO
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads data into a complete array, throwing an EndOfStreamException
|
||||
/// if the stream runs out of data first, or if an IOException
|
||||
/// naturally occurs.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream to read data from</param>
|
||||
/// <param name="data">The array to read bytes into. The array
|
||||
/// will be completely filled from the stream, so an appropriate
|
||||
/// size must be given.</param>
|
||||
private static void ReadWholeArray (Stream stream, ref byte[] data)
|
||||
{
|
||||
int offset=0;
|
||||
int remaining = data.Length;
|
||||
while (remaining > 0)
|
||||
{
|
||||
int read = stream.Read(data, offset, remaining);
|
||||
if (read <= 0)
|
||||
throw new EndOfStreamException
|
||||
(String.Format("End of stream reached with {0} bytes left to read", remaining));
|
||||
remaining -= read;
|
||||
offset += read;
|
||||
}
|
||||
}
|
||||
private static void _read_data(ref byte [] buffer, string path)
|
||||
{
|
||||
System.IO.FileStream saveFile;
|
||||
saveFile = new FileStream(path, FileMode.Open);
|
||||
if (saveFile.Length < 1){
|
||||
MessageBox.Show("Invalid file length", "Error");
|
||||
return;
|
||||
}
|
||||
buffer = new byte[saveFile.Length];
|
||||
//MessageBox.Show(buffer.Length.ToString());
|
||||
ReadWholeArray(saveFile, ref buffer);
|
||||
saveFile.Close();
|
||||
return;
|
||||
}
|
||||
public static int load_file(ref byte[] buffer, ref string path, string filter)
|
||||
{
|
||||
OpenFileDialog openFD = new OpenFileDialog();
|
||||
//openFD.InitialDirectory = "c:\\";
|
||||
openFD.Filter = filter;
|
||||
if (openFD.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
#region filename
|
||||
path = openFD.FileName;
|
||||
//MessageBox.Show(path.ToString());
|
||||
#endregion
|
||||
_read_data(ref buffer, path);
|
||||
return 1;
|
||||
}else{
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
public static void save_data(byte[] buffer)
|
||||
{ //if (savegamename.Text.Length < 1) return;
|
||||
if (buffer == null) return;
|
||||
SaveFileDialog saveFD = new SaveFileDialog();
|
||||
//saveFD.InitialDirectory = "c:\\";
|
||||
saveFD.Filter = "NDS save data|*.sav;*.dsv|All Files (*.*)|*.*";
|
||||
if (saveFD.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
System.IO.FileStream saveFile;
|
||||
saveFile = new FileStream(saveFD.FileName, FileMode.Create);
|
||||
//Write file
|
||||
saveFile.Write(buffer, 0, buffer.Length);
|
||||
saveFile.Close();
|
||||
MessageBox.Show("File Saved.", "Save file");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
103
BW_tool/SAV/PKX5.cs
Normal file
103
BW_tool/SAV/PKX5.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Text;
|
||||
using System.Linq;
|
||||
|
||||
namespace BW_tool
|
||||
{
|
||||
public class PKX5
|
||||
{
|
||||
// C# PKX Function Library
|
||||
// No WinForm object related code, only to calculate information.
|
||||
// May require re-referencing to main form for string array referencing.
|
||||
// Relies on Util for some common operations.
|
||||
|
||||
/* // Data
|
||||
internal static uint LCRNG(uint seed)
|
||||
{
|
||||
const uint a = 0x41C64E6D;
|
||||
const uint c = 0x00006073;
|
||||
|
||||
return seed * a + c;
|
||||
}
|
||||
internal static uint LCRNG(ref uint seed)
|
||||
{
|
||||
const uint a = 0x41C64E6D;
|
||||
const uint c = 0x00006073;
|
||||
|
||||
return seed = seed * a + c;
|
||||
}
|
||||
|
||||
internal static byte[] decryptArray(byte[] ekx, int start_offset, int length, int seed_offset)
|
||||
{
|
||||
byte[] pkx = (byte[])ekx.Clone();
|
||||
|
||||
uint pv = BitConverter.ToUInt32(pkx, seed_offset);
|
||||
uint sv = (pv >> 0xD & 0x1F) % 24;
|
||||
|
||||
uint seed = pv;
|
||||
|
||||
// Decrypt Blocks with RNG Seed
|
||||
for (int i = start_offset; i < length-4; i += 2)
|
||||
BitConverter.GetBytes((ushort)(BitConverter.ToUInt16(pkx, i) ^ LCRNG(ref seed) >> 16)).CopyTo(pkx, i);
|
||||
|
||||
return pkx;
|
||||
}
|
||||
*/
|
||||
internal static UInt32 LCRNG(UInt32 seed)
|
||||
// --------------------------------------------------
|
||||
{
|
||||
UInt32 a = 0x41c64e6d;
|
||||
UInt32 c = 0x00006073;
|
||||
return (UInt32)(((UInt64)seed * (UInt64)a + (UInt64)c)&0x00000000FFFFFFFF);
|
||||
}
|
||||
internal static byte[] cryptoArray(byte[] ekx, int start_offset, int length, int seed_offset)
|
||||
// --------------------------------------------------
|
||||
{
|
||||
byte[] buffer_dec = (byte[])ekx.Clone();
|
||||
|
||||
UInt32 pv = BitConverter.ToUInt32(buffer_dec, seed_offset);
|
||||
byte sv = (byte)((((pv & 0x3e000) >> 0xd) % 24)&0x000000FF);
|
||||
|
||||
UInt32 seed = pv;
|
||||
UInt16 tmp;
|
||||
|
||||
for (Int32 i = start_offset; i < length-4; i += 0x2)
|
||||
{
|
||||
tmp = BitConverter.ToUInt16(buffer_dec, i);
|
||||
|
||||
seed = LCRNG(seed);
|
||||
tmp ^= (UInt16)((seed >> 16)&0x0000FFFF);
|
||||
Array.Copy(BitConverter.GetBytes(tmp), 0, buffer_dec, i, 2);
|
||||
}
|
||||
return buffer_dec;
|
||||
}
|
||||
|
||||
// SAV Manipulation
|
||||
/// <summary>Calculates the CRC16-CCITT checksum over an input byte array.</summary>
|
||||
/// <param name="chunk">Input byte array</param>
|
||||
/// <returns>Checksum</returns>
|
||||
//adapted from Gocario's PHBank (www.github.com/gocario/phbank)
|
||||
internal static ushort ccitt16(byte[] data)
|
||||
// --------------------------------------------------
|
||||
{
|
||||
int len = data.Length;
|
||||
UInt16 crc = 0xFFFF;
|
||||
|
||||
for (UInt32 i = 0; i < len; i++)
|
||||
{
|
||||
crc ^= ((UInt16)((data[i] << 8)&0x0000FFFF));
|
||||
|
||||
for (UInt32 j = 0; j < 0x8; j++)
|
||||
{
|
||||
if ((crc & 0x8000) > 0)
|
||||
crc = (UInt16)(((UInt16)((crc << 1)&0x0000FFFF ) ^ 0x1021) &0x0000FFFF);
|
||||
else
|
||||
crc <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
}
|
||||
}
|
||||
329
BW_tool/SAV/SAV5.cs
Normal file
329
BW_tool/SAV/SAV5.cs
Normal file
@@ -0,0 +1,329 @@
|
||||
//Base file from kaphotic's pkhex
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
|
||||
namespace BW_tool
|
||||
{
|
||||
public class BlockInfo
|
||||
{
|
||||
public int Offset;
|
||||
public int Length;
|
||||
public int ID;
|
||||
public int updtcnt;
|
||||
public int Checksum;
|
||||
public bool encrypted;
|
||||
public int seed;
|
||||
}
|
||||
public class SAV5 : PKX5
|
||||
{
|
||||
private static int[] BlockTableBW2 =
|
||||
{0x00000, 0x00400, 0x01400, 0x02400, 0x03400, 0x04400, 0x05400, //6
|
||||
0x06400, 0x07400, 0x08400, 0x09400, 0x0A400, 0x0B400, 0x0C400, //13
|
||||
0x0D400, 0x0E400, 0x0F400, 0x10400, 0x11400, 0x12400, 0x13400, //20
|
||||
0x14400, 0x15400, 0x16400, 0x17400, 0x18400, 0x18E00, 0x19400, //27
|
||||
0x19500, 0x19600, 0x1AA00, 0x1B200, 0x1C000, 0x1C100, 0x1C800, //34
|
||||
0x1D300, 0x1D500, 0x1D900, 0x1DA00, 0x1DC00, 0x1DD00, 0x1E200, //41
|
||||
0x1F700, 0x1FA00, 0x1FB00, 0x1FF00, 0x20400, 0x20500, 0x20800, //48
|
||||
0x20900, 0x20D00, 0x20F00, 0x21100, 0x21200, 0x21400, 0x21900, //55
|
||||
0x21A00, 0x21B00, 0x21D00, 0x22900, 0x22A00, 0x23300, 0x23600, //62
|
||||
0x23700, 0x23800, 0x23A00, 0x23B00, 0x23C00, 0x25300, 0x25800, //69
|
||||
0x25900, 0x25A00, 0x25E00, 0x25F00}; //73
|
||||
|
||||
private static int[] BlockTableLengthBW2 =
|
||||
{0x3E0, 0xFF0, 0xFF0, 0xFF0, 0xFF0, 0xFF0, 0xFF0, //6
|
||||
0xFF0, 0xFF0, 0xFF0, 0xFF0, 0xFF0, 0xFF0, 0xFF0, //13
|
||||
0xFF0, 0xFF0, 0xFF0, 0xFF0, 0xFF0, 0xFF0, 0xFF0, //20
|
||||
0xFF0, 0xFF0, 0xFF0, 0xFF0, 0x9EC, 0X534, 0xB0, //27
|
||||
0xA8, 0x1338, 0x7C4, 0xD54, 0X94, 0x658, 0xA94, //34
|
||||
0x1AC, 0x3EC, 0x5C, 0x1E0, 0xA8, 0x460, 0x1400, //41
|
||||
0x2A4, 0xE0, 0x34C, 0x4E0, 0xF8, 0x2FC, 0x94, //48
|
||||
0x35C, 0x1D4, 0x1E0, 0xF0, 0x1B4, 0x4DC, 0x34, //55
|
||||
0X3C, 0x1AC, 0xB90, 0xAC, 0x850, 0x284, 0x10, //62
|
||||
0xA8, 0x16C, 0x80, 0xFC, 0x16A8, 0x498, 0x60, //69
|
||||
0xFC, 0x3E4, 0xF0, 0x94};
|
||||
|
||||
internal const int SIZERAW = 0x80000; // 512KB
|
||||
internal const int SIZE1 = 0x24000; // B/W
|
||||
internal const int SIZE2 = 0x26000; // B2/W2
|
||||
|
||||
// Global Settings
|
||||
// Save Data Attributes
|
||||
public byte[] Data;
|
||||
public bool Edited;
|
||||
public readonly bool Exportable;
|
||||
public readonly byte[] BAK;
|
||||
public string FileName, FilePath;
|
||||
public BlockInfo[] blocks = new BlockInfo[74];
|
||||
public bool B2W2;
|
||||
public bool BW;
|
||||
public SAV5(byte[] data)
|
||||
{
|
||||
Data = (byte[])(data ?? new byte[SIZERAW]).Clone();
|
||||
BAK = (byte[])Data.Clone();
|
||||
Exportable = !Data.SequenceEqual(new byte[Data.Length]);
|
||||
|
||||
// Get Version
|
||||
// Validate Checksum over the Checksum Block to find BW or B2W2
|
||||
ushort chk2 = BitConverter.ToUInt16(Data, SIZE2 - 0x100 + 0x94 + 0xE);
|
||||
ushort actual2 = ccitt16(Data.Skip(SIZE2 - 0x100).Take(0x94).ToArray());
|
||||
B2W2 = chk2 == actual2;
|
||||
ushort chk1 = BitConverter.ToUInt16(Data, SIZE1 - 0x100 + 0x8C + 0xE);
|
||||
ushort actual1 = ccitt16(Data.Skip(SIZE1 - 0x100).Take(0x8C).ToArray());
|
||||
BW = chk1 == actual1;
|
||||
|
||||
if (!BW && !B2W2 && data != null){
|
||||
Data = null; // Invalid/Not G5 Save File
|
||||
}else if (B2W2)
|
||||
{
|
||||
|
||||
//Build blockinfos
|
||||
int i;
|
||||
for (i=0;i<74;i++)
|
||||
{
|
||||
blocks[i] = new BlockInfo();
|
||||
blocks[i].Offset=BlockTableBW2[i];
|
||||
blocks[i].Length=BlockTableLengthBW2[i];
|
||||
blocks[i].ID= i;
|
||||
blocks[i].updtcnt=blocks[i].Offset+blocks[i].Length;
|
||||
if (i != 73)
|
||||
{
|
||||
blocks[i].Checksum=blocks[i].Offset+blocks[i].Length+2;
|
||||
}
|
||||
else
|
||||
{
|
||||
blocks[i].Checksum=0x25FA2;
|
||||
}
|
||||
|
||||
blocks[i].encrypted=false;
|
||||
blocks[i].seed=blocks[i].Offset+blocks[i].Length-4;
|
||||
|
||||
}
|
||||
|
||||
// Different Offsets for different games.
|
||||
BattleBox = B2W2 ? 0x20A00 : 0x20900;
|
||||
}
|
||||
}
|
||||
|
||||
private const int Box = 0x400;
|
||||
private const int Party = 0x18E00;
|
||||
private readonly int BattleBox;
|
||||
private const int Trainer = 0x19400;
|
||||
private const int Wondercard = 0x1C800;
|
||||
private const int wcSeed = 0x1D290;
|
||||
|
||||
public byte[] getData(int Offset, int Length)
|
||||
{
|
||||
return Data.Skip(Offset).Take(Length).ToArray();
|
||||
}
|
||||
public byte[] getBlock(int index)
|
||||
{
|
||||
if (B2W2)
|
||||
{
|
||||
if (index <73)
|
||||
{
|
||||
return Data.Skip(blocks[index].Offset).Take(blocks[index+1].Offset-blocks[index].Offset).ToArray();
|
||||
}
|
||||
else if (index == 73)
|
||||
{
|
||||
return Data.Skip(blocks[index].Offset).Take(SIZE2-blocks[index].Offset).ToArray();
|
||||
}
|
||||
else return null;
|
||||
}
|
||||
else return null;
|
||||
}
|
||||
public byte[] getBlockDec(int index)
|
||||
{
|
||||
byte[] decrypt = new byte[getBlockLength(index)];
|
||||
|
||||
if (B2W2)
|
||||
{
|
||||
if (index <73)
|
||||
{
|
||||
//MessageBox.Show(decrypt.Length.ToString());
|
||||
//MessageBox.Show((blocks[index].Length-4).ToString());
|
||||
decrypt = PKX5.cryptoArray(Data.Skip(blocks[index].Offset).Take(blocks[index+1].Offset-blocks[index].Offset).ToArray(), 0, blocks[index].Length, blocks[index].Length-4);
|
||||
//MessageBox.Show((blocks[index].Length-4).ToString());
|
||||
return decrypt;
|
||||
}
|
||||
else if (index == 73)
|
||||
{
|
||||
return Data.Skip(blocks[index].Offset).Take(SIZE2-blocks[index].Offset).ToArray();
|
||||
}
|
||||
else return null;
|
||||
}
|
||||
else return null;
|
||||
}
|
||||
public int getBlockLength(int index)
|
||||
{
|
||||
if (B2W2){
|
||||
if (index < 73)
|
||||
return blocks[index+1].Offset-blocks[index].Offset;
|
||||
else if (index == 73)
|
||||
return SIZE2-blocks[index].Offset;
|
||||
else return -1;
|
||||
}
|
||||
else return -1;
|
||||
}
|
||||
public void setBlock(byte[] input, int index)
|
||||
{
|
||||
if (getBlockLength(index) != input.Length)
|
||||
{
|
||||
MessageBox.Show("Block has invalid size!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (B2W2)
|
||||
{
|
||||
if (index <74)
|
||||
{
|
||||
//Recalculate checksum before applying to savedata
|
||||
ushort crc = ccitt16(input.Take(blocks[index].Length).ToArray());
|
||||
if (crc != BitConverter.ToUInt16(input, blocks[index].Checksum-blocks[index].Offset) )
|
||||
{
|
||||
Array.Copy(BitConverter.GetBytes(crc), 0, input, blocks[index].Checksum-blocks[index].Offset, 2);
|
||||
MessageBox.Show("Block's checksum updated");
|
||||
}else
|
||||
{
|
||||
MessageBox.Show("Checksum doesn't need update");
|
||||
}
|
||||
|
||||
|
||||
|
||||
input.CopyTo(Data, blocks[index].Offset);
|
||||
input.CopyTo(Data, blocks[index].Offset+SIZE2);
|
||||
Edited = true;
|
||||
}
|
||||
else return;
|
||||
}
|
||||
else return;
|
||||
}
|
||||
public void setBlockCrypt(byte[] input, int index)
|
||||
{
|
||||
if (getBlockLength(index) != input.Length)
|
||||
{
|
||||
MessageBox.Show("Block has invalid size!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (B2W2)
|
||||
{
|
||||
if (index <74)
|
||||
{
|
||||
//Recalculate checksum before applying to savedata
|
||||
ushort crc = ccitt16(input.Take(blocks[index].Length).ToArray());
|
||||
if (crc != BitConverter.ToUInt16(input, blocks[index].Checksum-blocks[index].Offset) )
|
||||
{
|
||||
Array.Copy(BitConverter.GetBytes(crc), 0, input, blocks[index].Checksum-blocks[index].Offset, 2);
|
||||
MessageBox.Show("Block's checksum updated");
|
||||
}else
|
||||
{
|
||||
MessageBox.Show("Checksum doesn't need update");
|
||||
}
|
||||
|
||||
|
||||
|
||||
input.CopyTo(Data, blocks[index].Offset);
|
||||
input.CopyTo(Data, blocks[index].Offset+SIZE2);
|
||||
Edited = true;
|
||||
}
|
||||
else return;
|
||||
}
|
||||
else return;
|
||||
}
|
||||
public void setData(byte[] input, int Offset)
|
||||
{
|
||||
input.CopyTo(Data, Offset);
|
||||
Edited = true;
|
||||
}
|
||||
public void chkCheck()
|
||||
{
|
||||
int i = 0;
|
||||
string badblocks;
|
||||
badblocks = "Found bad checksums in MAIN save at blocks: ";
|
||||
bool badcheck = false;
|
||||
if (B2W2)
|
||||
{
|
||||
//Main save checksums
|
||||
for(i=0; i<74; i++)
|
||||
{
|
||||
ushort crc = ccitt16(Data.Skip(blocks[i].Offset).Take(blocks[i].Length).ToArray());
|
||||
if ( crc != BitConverter.ToUInt16(Data, blocks[i].Checksum) )
|
||||
{
|
||||
//Array.Copy(BitConverter.GetBytes(crc), 0, input, blocks[index].Checksum-blocks[index].Offset, 2);
|
||||
//MessageBox.Show("Block's checksum is wrong " + i.ToString());
|
||||
if (!badcheck)
|
||||
{
|
||||
badcheck = true;
|
||||
badblocks = badblocks + i.ToString();
|
||||
}else
|
||||
{
|
||||
badblocks = badblocks + ", " + i.ToString();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//MessageBox.Show("Checksum doesn't need update " + i.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
if(badcheck)
|
||||
MessageBox.Show(badblocks);
|
||||
else
|
||||
MessageBox.Show("All 74 checksums OK in MAIN save");
|
||||
|
||||
//Backup save checksums
|
||||
badcheck = false;
|
||||
badblocks = "Found bad checksums in BACKUP save at blocks: ";
|
||||
for(i=0; i<74; i++)
|
||||
{
|
||||
ushort crc = ccitt16(Data.Skip(blocks[i].Offset+SIZE2).Take(blocks[i].Length).ToArray());
|
||||
if ( crc != BitConverter.ToUInt16(Data, blocks[i].Checksum+SIZE2) )
|
||||
{
|
||||
//Array.Copy(BitConverter.GetBytes(crc), 0, input, blocks[index].Checksum-blocks[index].Offset, 2);
|
||||
//MessageBox.Show("Block's checksum is wrong " + i.ToString());
|
||||
if (!badcheck)
|
||||
{
|
||||
badcheck = true;
|
||||
badblocks = badblocks + i.ToString();
|
||||
}else
|
||||
{
|
||||
badblocks = badblocks + ", " + i.ToString();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//MessageBox.Show("Checksum doesn't need update " + i.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
if(badcheck)
|
||||
MessageBox.Show(badblocks);
|
||||
else
|
||||
MessageBox.Show("All 74 checksums OK in BACKUP save");
|
||||
|
||||
return;
|
||||
}
|
||||
else if (BW)
|
||||
{
|
||||
MessageBox.Show("Not yet implemented for BW 1");
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Invalid file");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
6
BW_tool/app.config
Normal file
6
BW_tool/app.config
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
|
||||
</startup>
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user