FC2ブログ
--/--/--

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

--:-- | スポンサー広告  TOP

2016/08/03

xplのcheat

いまさらほとんどつかわないだろうけどPS2時代のxploderのぱーさーを一応書いてみた
xplcheateditoerとxplcodeeditoerとそんなにぱさ自体はかわらんけど,
sm38変換のCアプリがwin10だとうごかないのでねたでSRC移植でもしてみようか検討中
xplcheatファイル構造;
ファイルサイズ(コード全体分4byte),CRC32(コード全体)
-----------↓こーど全体--------------
ゲーム名UTF-32NULL文字出るまで,コード数(2byte),コード名UTF-32NULL文字出るまで,コード行数(2byte),{コード内容アドレス4byte+コード内容値4byte}X行数分繰り返し(コード行が0の時は当然無い)
・・・・・・
最後に0xFFFFFFFFのだみー?

//ILspyでデコンパイル
XPLCHEATEDIOR XPLCはコード行が0の時の時1行ダミーを追加している
XPLCODERDIOTE 両方ともSTRINGをUTF32じゃなくてUTF16になおして処理してるっぽい?たぶん旧C#/Cだとアライメントエラーがでるから直してるのかな?PS2だとこぴぺ使わんと2byteローダーしかたぶん使えないk

↓ねたでつくってみただけのC# GITHUB


private void parse_cheat(string file)
{

System.IO.FileStream fs = new System.IO.FileStream(file, System.IO.FileMode.Open, System.IO.FileAccess.Read);
byte[] bs = new byte[fs.Length];
fs.Read(bs, 0, bs.Length);
fs.Close();

int i = 8;
int start = 0;

try
{
treeView1.Nodes.Clear();

while (i < bs.Length - 4){
start = i;
while (true) {
int nullst = BitConverter.ToInt32(bs, i);
if (nullst == 0) {
break;
}
i += 4;
}

//codehex.Text += i.ToString("X");
TreeNode gnode = new TreeNode();
byte[] gname = new byte[255*2];
Array.ConstrainedCopy(bs, start, gname, 0, i - start);
Array.Resize(ref gname, i - start);
gnode.Text= Encoding.GetEncoding(12000).GetString(gname);
gnode.Tag = "";
//gnode.Text += i.ToString("X");
i += 4;
int codenum = BitConverter.ToUInt16(bs, i);
i += 2;

for (int j = 0; j < codenum;) {
start = i;
while (true)
{
int nullst = BitConverter.ToInt32(bs, i);
if (nullst == 0)
{
break;
}
i += 4;
}
TreeNode cnode = new TreeNode();
byte[] cname = new byte[255*4];
Array.ConstrainedCopy(bs, start, cname, 0, i - start);
Array.Resize(ref cname, i - start);
cnode.Text = Encoding.GetEncoding(12000).GetString(cname);
//cnode.Text += i.ToString("X");

i += 4;
int codeline = BitConverter.ToInt16(bs, i);
string code = "";
i += 2;
for (int k = 0; k < codeline; k++) {
code += BitConverter.ToInt32(bs, i).ToString("X8") + " " + BitConverter.ToInt32(bs, i + 4).ToString("X8") + "\r\n";
i += 8;
}
cnode.Tag = code;


gnode.Nodes.Add(cnode);
j++;}


treeView1.Nodes.Add(gnode);
}

}
catch (Exception ex)
{
MessageBox.Show(ex.Message + i.ToString("X") +"," +start.ToString("X"));
}
finally
{

}
}

private void cheat保存ToolStripMenuItem_Click(object sender, EventArgs e)
{

//SaveFileDialogクラスのインスタンスを作成
SaveFileDialog sfd = new SaveFileDialog();
sfd.FileName = Path.GetFileNameWithoutExtension(lastfile);

//はじめに表示されるフォルダを指定する
sfd.InitialDirectory = Application.StartupPath;
//[ファイルの種類]に表示される選択肢を指定する
sfd.Filter = "cheatファイル(*.*;)|*.*";

sfd.Title = "保存先のファイルを選択してください";
//ダイアログボックスを閉じる前に現在のディレクトリを復元するようにする
sfd.RestoreDirectory = true;

byte[] bs = new byte[3 * 1024 * 1024];

int i = 0;
string pg = "";

if (sfd.ShowDialog() == DialogResult.OK)
{
try
{
Regex r = new Regex("[0-9A-Fa-f]{8} [0-9A-Fa-f]{8}");
Match mr;
foreach (TreeNode n in treeView1.Nodes)
{
byte[] gname = Encoding.GetEncoding(12000).GetBytes(n.Text);
Array.ConstrainedCopy(gname, 0, bs, i, gname.Length);
i += 4 + gname.Length;
byte[] count = BitConverter.GetBytes(Convert.ToInt16(n.Nodes.Count));
Array.ConstrainedCopy(count, 0, bs, i, 2);
i += 2;
pg = n.Text;

foreach (TreeNode m in n.Nodes)
{

byte[] cname = Encoding.GetEncoding(12000).GetBytes(m.Text);
Array.ConstrainedCopy(cname, 0, bs, i, cname.Length);
i += 4 + cname.Length;
char lf = Convert.ToChar(13);
string[] st = m.Tag.ToString().Split(lf);

pg = m.Text;

mr = r.Match(rpstringout(m.Tag.ToString()));
byte[] cnum = BitConverter.GetBytes(Convert.ToInt16(st.Length-1));
Array.ConstrainedCopy(cnum, 0, bs, i, 2);
i += 2;
while (mr.Success == true)
{
byte[] code = new byte[4];

pg = mr.Value;

code = BitConverter.GetBytes(Convert.ToInt32(mr.Value.Substring(0, 8), 16));
Array.ConstrainedCopy(code, 0, bs, i, 4);
i += 4;
code = BitConverter.GetBytes(Convert.ToInt32(mr.Value.Substring(9, 8), 16));
Array.ConstrainedCopy(code, 0, bs, i, 4);
i += 4;
mr = mr.NextMatch();
}

}

}
byte[] end = BitConverter.GetBytes(Convert.ToInt32("FFFFFFFF", 16));
Array.ConstrainedCopy(end, 0, bs, i, 4);
i += 4;
Array.Resize(ref bs, i);
byte[] fsize = new byte[4];
byte[] crc = new byte[4];
fsize = BitConverter.GetBytes(Convert.ToInt32(bs.Length));
crc = BitConverter.GetBytes(CRC32.Compute(bs));

System.IO.FileStream fs = new System.IO.FileStream(
sfd.FileName +".test", System.IO.FileMode.Create, System.IO.FileAccess.Write);
fs.Write(fsize, 0,4);
fs.Write(crc, 0, 4);
fs.Write(bs, 0, bs.Length);
fs.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + pg);
}
finally
{
}
}
}

スポンサーサイト

06:47 | CODEFREAKCOMMENT(0)TRACKBACK(0)  TOP

コメント

コメントの投稿



秘密にする

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。