2014-07-19 23:56:40 +00:00
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 ;
2014-07-20 04:28:35 +00:00
using System.Globalization ;
using System.IO ;
using System.Text.RegularExpressions ;
2014-07-19 23:56:40 +00:00
namespace PKHeX
{
public partial class CodeGenerator : Form
{
2014-07-20 04:28:35 +00:00
Form1 m_parent ;
byte [ ] codedata = new Byte [ 232 ] ;
byte [ ] newdata = new Byte [ 232 ] ;
SaveGames . SaveStruct SaveGame = new SaveGames . SaveStruct ( null ) ;
public CodeGenerator ( Form1 frm1 )
2014-07-19 23:56:40 +00:00
{
InitializeComponent ( ) ;
2014-07-20 04:28:35 +00:00
this . CenterToParent ( ) ;
RTB_Code . Clear ( ) ;
TB_Write . Clear ( ) ;
m_parent = frm1 ;
SaveGame = m_parent . SaveGame ;
CB_Box . Items . Clear ( ) ;
for ( int i = 1 ; i < = 31 ; i + + )
CB_Box . Items . Add ( i . ToString ( ) ) ;
CB_Source . SelectedIndex = 0 ;
CB_Slot . SelectedIndex = 0 ;
CB_Box . SelectedIndex = 0 ;
}
private bool loaddata ( )
{
if ( CB_Source . SelectedIndex = = 0 )
{
if ( m_parent . verifiedpkx ( ) )
{
byte [ ] pkx = m_parent . preparepkx ( m_parent . buff ) ;
newdata = new Byte [ 232 ] ;
Array . Copy ( m_parent . encryptArray ( pkx ) , newdata , 232 ) ;
}
else return false ;
}
else if ( CB_Source . SelectedIndex = = 1 )
{
newdata = new Byte [ 0xE8 ] ;
Array . Copy ( m_parent . savefile ,
SaveGame . Box // Box Offset
+ CB_Box . SelectedIndex * ( 232 * 30 ) // Box Shift
+ CB_Slot . SelectedIndex * 232 , // Slot Shift
newdata , 0 , 0xE8 ) ;
2014-07-20 19:51:45 +00:00
if ( newdata . SequenceEqual ( new Byte [ 0xE8 ] ) )
{
System . Media . SystemSounds . Exclamation . Play ( ) ;
return false ;
}
2014-07-20 04:28:35 +00:00
}
else if ( CB_Source . SelectedIndex = = 2 )
{
// Wondercard
newdata = new Byte [ 0x108 ] ;
// Wondercard #
int wcn = CB_Slot . SelectedIndex ;
// copy from save, the chosen wondercard offset, to new data
2014-07-20 07:09:08 +00:00
Array . Copy ( m_parent . savefile , SaveGame . Wondercard + wcn * 0x108 + 0x100 , newdata , 0 , 0x108 ) ;
byte [ ] zerodata = new Byte [ 0x108 ] ;
if ( newdata . SequenceEqual ( zerodata ) )
{
System . Media . SystemSounds . Exclamation . Play ( ) ;
return false ;
}
2014-07-20 04:28:35 +00:00
}
return true ;
}
private void changeDataSource ( object sender , EventArgs e )
{
int sourceindex = CB_Source . SelectedIndex ;
B_Add . Enabled = true ;
if ( sourceindex = = 0 )
{
// Hide Box/Etc
CB_Box . Visible = false ;
L_Box . Visible = false ;
CB_Slot . Visible = false ;
L_Slot . Visible = false ;
2014-07-26 21:56:06 +00:00
2014-07-24 16:42:40 +00:00
TB_Write . Text = ( 0x27A00 - 0x5400 ) . ToString ( "X8" ) ; // Box 1, Slot 1
2014-07-20 04:28:35 +00:00
}
else if ( sourceindex = = 1 )
{
CB_Box . Visible = true ;
L_Box . Visible = true ;
CB_Slot . Visible = true ;
L_Slot . Visible = true ;
L_Slot . Text = "Slot:" ;
CB_Slot . Items . Clear ( ) ;
for ( int i = 1 ; i < = 30 ; i + + )
CB_Slot . Items . Add ( i . ToString ( ) ) ;
CB_Slot . SelectedIndex = 0 ;
2014-07-24 16:42:40 +00:00
TB_Write . Text = ( 0x27A00 - 0x5400 ) . ToString ( "X8" ) ; // Box 1, Slot 1
2014-07-20 04:28:35 +00:00
}
else if ( sourceindex = = 2 )
{
CB_Box . Visible = false ;
L_Box . Visible = false ;
CB_Slot . Visible = true ;
L_Slot . Visible = true ;
L_Slot . Text = "Card:" ;
// Set up cards
CB_Slot . Items . Clear ( ) ;
for ( int i = 1 ; i < = 24 ; i + + )
CB_Slot . Items . Add ( i . ToString ( ) ) ;
CB_Slot . SelectedIndex = 0 ;
2014-07-24 16:42:40 +00:00
TB_Write . Text = ( 0x22000 - 0x5400 ) . ToString ( "X8" ) ; // WC Slot 1
2014-07-20 04:28:35 +00:00
}
}
public static string RemoveTroublesomeCharacters ( TextBox tb )
{
string inString = tb . Text ;
if ( inString = = null ) return null ;
StringBuilder newString = new StringBuilder ( ) ;
char ch ;
for ( int i = 0 ; i < inString . Length ; i + + )
{
ch = inString [ i ] ;
// filter for hex
if ( ( ch < 0x0047 & & ch > 0x002F ) | | ( ch < 0x0067 & & ch > 0x0060 ) )
newString . Append ( ch ) ;
else
System . Media . SystemSounds . Beep . Play ( ) ;
}
if ( newString . Length = = 0 )
newString . Append ( "0" ) ;
uint value = UInt32 . Parse ( newString . ToString ( ) , NumberStyles . HexNumber ) ;
tb . Text = value . ToString ( "X8" ) ;
return newString . ToString ( ) ;
}
private uint getHEXval ( TextBox tb )
{
if ( tb . Text = = null )
return 0 ;
string str = RemoveTroublesomeCharacters ( tb ) ;
return UInt32 . Parse ( str , NumberStyles . HexNumber ) ;
}
2014-07-26 21:56:06 +00:00
2014-07-20 04:28:35 +00:00
private void B_Add_Click ( object sender , EventArgs e )
{
// Add the new code to the textbox.
if ( ! loaddata ( ) ) return ;
uint writeoffset = getHEXval ( TB_Write ) ;
2014-07-24 16:42:40 +00:00
for ( int i = 0 ; i < newdata . Length / 4 ; i + + )
{
RTB_Code . AppendText ( ( writeoffset + i * 4 + 0x20000000 ) . ToString ( "X8" ) + " " ) ;
2014-07-20 04:28:35 +00:00
RTB_Code . AppendText ( BitConverter . ToUInt32 ( newdata , i * 4 ) . ToString ( "X8" ) + "\n" ) ;
}
2014-07-24 16:42:40 +00:00
// Mat's Code - Unfinished
//for (int i = 0; i < newdata.Length / (4); i++)
//{
// // Add Operator
// RTB_Code.AppendText("00000001 "); // 01 00 00 00
// RTB_Code.AppendText((writeoffset + i * 4).ToString("X8") + " ");
// RTB_Code.AppendText(BitConverter.ToUInt32(newdata,i*4).ToString("X8") + "\n");
//}
2014-07-20 04:28:35 +00:00
}
private void B_Clear_Click ( object sender , EventArgs e )
{
RTB_Code . Clear ( ) ;
}
private void B_Load_Click ( object sender , EventArgs e )
{
OpenFileDialog ofd = new OpenFileDialog ( ) ;
ofd . Filter = "Code File|*.bin" ;
if ( ofd . ShowDialog ( ) = = DialogResult . OK )
{
string path = ofd . FileName ;
byte [ ] ncf = File . ReadAllBytes ( path ) ;
uint length = BitConverter . ToUInt32 ( ncf , 0 ) ;
if ( ncf . Length ! = length + 4 )
{
MessageBox . Show ( "Not a valid code file." , "Error" ) ;
return ;
}
if ( RTB_Code . Text . Length > 0 )
{
DialogResult ld = MessageBox . Show ( "Replace current code?" , "Alert" , MessageBoxButtons . YesNo ) ;
if ( ld = = DialogResult . Yes )
RTB_Code . Clear ( ) ;
else if ( ld ! = DialogResult . No )
return ;
}
for ( int i = 4 ; i < = ncf . Length - 12 ; i + = 12 )
{
RTB_Code . AppendText ( BitConverter . ToUInt32 ( ncf , i + 0 * 4 ) . ToString ( "X8" ) + " " ) ;
RTB_Code . AppendText ( BitConverter . ToUInt32 ( ncf , i + 1 * 4 ) . ToString ( "X8" ) + " " ) ;
RTB_Code . AppendText ( BitConverter . ToUInt32 ( ncf , i + 2 * 4 ) . ToString ( "X8" ) + "\n" ) ;
}
}
}
private void B_Save_Click ( object sender , EventArgs e )
{
// Gotta read in the textbox.
if ( RTB_Code . Text . Length < 1 ) return ;
2014-07-20 04:35:06 +00:00
byte [ ] ncf = new Byte [ 4 + ( RTB_Code . Lines . Count ( ) - 1 ) * ( 3 * 4 ) ] ;
2014-07-20 04:28:35 +00:00
Array . Copy ( BitConverter . GetBytes ( ncf . Length - 4 ) , ncf , 4 ) ;
for ( int i = 0 ; i < RTB_Code . Lines . Count ( ) - 1 ; i + + )
{
string line = RTB_Code . Lines [ i ] ;
string [ ] rip = Regex . Split ( line , " " ) ;
// Write the 3 u32's to an array.
Array . Copy ( BitConverter . GetBytes ( UInt32 . Parse ( rip [ 0 ] , NumberStyles . HexNumber ) ) , 0 , ncf , 4 + i * 12 + 0 , 4 ) ;
Array . Copy ( BitConverter . GetBytes ( UInt32 . Parse ( rip [ 1 ] , NumberStyles . HexNumber ) ) , 0 , ncf , 4 + i * 12 + 4 , 4 ) ;
Array . Copy ( BitConverter . GetBytes ( UInt32 . Parse ( rip [ 2 ] , NumberStyles . HexNumber ) ) , 0 , ncf , 4 + i * 12 + 8 , 4 ) ;
}
SaveFileDialog sfd = new SaveFileDialog ( ) ;
sfd . FileName = "code.bin" ;
sfd . Filter = "Code File|*.bin" ;
2014-07-20 04:35:06 +00:00
if ( sfd . ShowDialog ( ) = = DialogResult . OK )
{
string path = sfd . FileName ;
if ( File . Exists ( path ) )
{
// File already exists, save a .bak
byte [ ] backupfile = File . ReadAllBytes ( path ) ;
File . WriteAllBytes ( path + ".bak" , backupfile ) ;
}
File . WriteAllBytes ( path , ncf ) ;
}
2014-07-19 23:56:40 +00:00
}
2014-07-26 21:56:06 +00:00
private void B_Copy_Click ( object sender , EventArgs e )
{
2014-07-28 01:53:06 +00:00
if ( RTB_Code . Text . Length > 0 )
{
Clipboard . SetText ( RTB_Code . Text ) ;
}
else
{
B_Diff . PerformClick ( ) ;
try
{
Clipboard . SetText ( RTB_Code . Text ) ;
MessageBox . Show ( "Code generated and copied to clipboard!\n\nNext time click [Create Diff] first." , "Alert" ) ;
}
catch
{
MessageBox . Show ( "No code created!\n\nClick [Create Diff], then make sure that data appears in the Text Box below.\nIf no code appears, then you didn't save your changes.\n\nBe sure to Set the Pokemon you edited back into a Box/Party slot!" , "Alert" ) ;
}
}
2014-07-26 21:56:06 +00:00
}
private void B_Diff_Click ( object sender , EventArgs e )
{
2014-07-27 03:21:31 +00:00
string result = "" ;
2014-07-26 21:56:06 +00:00
RTB_Code . Clear ( ) ;
byte [ ] cybersav = m_parent . cyberSAV ;
byte [ ] editedsav = m_parent . savefile ;
byte [ ] newcyber = new Byte [ 0x65600 ] ;
Array . Copy ( editedsav , 0x5400 , newcyber , 0 , 0x65600 ) ;
2014-07-27 03:21:31 +00:00
if ( ! m_parent . cybergadget ) Array . Copy ( editedsav , m_parent . savindex * 0x7F000 + 0x5400 , newcyber , 0 , 0x65600 ) ;
2014-07-26 21:56:06 +00:00
2014-07-27 01:00:17 +00:00
int lines = 0 ;
2014-07-26 21:56:06 +00:00
for ( int i = 0 ; i < 0x65400 ; i + = 4 )
{
if ( BitConverter . ToUInt32 ( cybersav , i ) ! = BitConverter . ToUInt32 ( newcyber , i ) )
{
2014-07-27 03:21:31 +00:00
result + = ( ( 0x20000000 + i ) . ToString ( "X8" ) + " " ) ;
result + = ( BitConverter . ToUInt32 ( newcyber , i ) . ToString ( "X8" ) + "\n" ) ;
2014-07-27 01:00:17 +00:00
lines + + ;
2014-07-28 01:30:54 +00:00
if ( ( lines % 128 = = 0 ) & & CHK_Break . Checked )
2014-07-27 03:21:31 +00:00
{ result + = ( "\r\n--- Segment " + ( lines / 128 + 1 ) . ToString ( ) + " ---\r\n\r\n" ) ; }
if ( lines > 10000 ) goto toomany ;
2014-07-26 21:56:06 +00:00
}
}
2014-07-28 01:30:54 +00:00
if ( ( lines / 128 > 0 ) & & CHK_Break . Checked )
2014-07-27 01:00:17 +00:00
{
2014-07-31 22:06:48 +00:00
MessageBox . Show ( ( 1 + ( lines / 128 ) ) . ToString ( ) + " Code Segments\n\nLines: " + lines . ToString ( ) , "Alert" ) ;
2014-07-27 01:00:17 +00:00
}
2014-07-27 03:21:31 +00:00
RTB_Code . Text = result ; return ;
toomany :
{
MessageBox . Show ( "Too many differences. Export your save instead." , "Alert" ) ;
}
2014-07-26 21:56:06 +00:00
}
2014-07-28 22:28:06 +00:00
// Import
public byte [ ] returnArray { get ; set ; }
private void B_Paste_Click ( object sender , EventArgs e )
{
RTB_Code . Text = Clipboard . GetText ( ) ;
}
private void B_Import_Click ( object sender , EventArgs e )
{
// Gotta read in the textbox.
if ( RTB_Code . Text . Length < 1 ) return ;
byte [ ] data = new Byte [ 0 ] ;
// Get Actual Lines
for ( int i = 0 ; i < RTB_Code . Lines . Count ( ) ; i + + )
{
if ( RTB_Code . Lines [ i ] . Length > 0 )
{
if ( RTB_Code . Lines [ i ] . Length < = 2 * 8 & & RTB_Code . Lines [ i ] . Length > 2 * 8 + 2 )
{
MessageBox . Show ( "Invalid code pasted (Type)" , "Error" ) ; return ;
}
else
{
try
{
// Grab Line Data
string line = RTB_Code . Lines [ i ] ;
string [ ] rip = Regex . Split ( line , " " ) ;
Array . Resize ( ref data , data . Length + 4 ) ;
Array . Copy ( BitConverter . GetBytes ( UInt32 . Parse ( rip [ 1 ] , NumberStyles . HexNumber ) ) , 0 , data , data . Length - 4 , 4 ) ;
}
catch
{
MessageBox . Show ( "Invalid code pasted (Content)" , "Error" ) ; return ;
}
}
}
}
// Go over the data
if ( ( data . Length = = 232 - 4 ) | | ( data . Length = = 260 - 4 ) )
{
Array . Resize ( ref data , data . Length + 4 ) ;
Array . Copy ( data , 0 , data , 4 , data . Length ) ;
data [ 0 ] = data [ 1 ] = data [ 2 ] = data [ 3 ] = 0 ;
}
if ( ( data . Length = = 232 ) | | ( data . Length = = 260 ) )
{
this . returnArray = data ;
this . Close ( ) ;
}
else
{
MessageBox . Show ( "Invalid code pasted (Length)" , "Error" ) ; return ;
}
}
2014-07-19 23:56:40 +00:00
}
}