PDA

View Full Version : H2V [CODE] H2V Map Data



KantIZBack
February 13th, 2011, 09:13 PM
Hey guys I'm just posting this for any h2v coders that need it. (You don't see much h2v code passed around...)
Update TagList added

EXAMPLE APP INCLUDED FOR INGAME
*Note1* I feel like i need to say this but... Please no flaming if you don't have anything positive or that is not an insult do not post.

*Note2* A majority of this class is re-written from Gravemind and put into a class because it was impossible to navigate the Gravemind code. Without studying it for hours on end like a no-life like me.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
public class H2VIndexHeader
{
#region Fields
public int IndexHeaderSize;
public int Const120;
public int TagStart;
public int TagStartModifier;
public int PrimaryMagic;
public int SecondaryMgicConstant;
public int SecondaryMagic;
public int HaloVersion;
public int MapSize;
public int IndexOffset;
public int IndexSize;
public int MetaTableSize;
public int NonRawSize;
public string BuildDate;
public int SIDMetaTableOffset;
public int SIDCount;
public int SIDTableSize;
public int SIDIndexOffset;
public int SIDTableOffset;
public string MapName;
public string Scenario;
public int TagCount;
public int FileTableOffset;
public int FileTableSize;
public int FileTableIndexOffset;
public int ModelRawTableStart;
public int ModelRawTableSize;
public int Checksum;
#endregion
public void GetMapData(string Filepath)
{
FileStream fs = new FileStream(Filepath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
BinaryReader br = new BinaryReader(fs);
BinaryWriter bw = new BinaryWriter(fs);
#region Header
#region Index Data
br.BaseStream.Position = 4;
HaloVersion = br.ReadInt32();
if (HaloVersion != 8)
{
throw new Exception("InvalidMap Type");
}
MapSize = br.ReadInt32();
br.BaseStream.Position += 4;
IndexOffset = br.ReadInt32();
IndexSize = br.ReadInt32();
MetaTableSize = br.ReadInt32();
NonRawSize = br.ReadInt32();
#endregion


#region Map Data
br.BaseStream.Position = 300;
BuildDate = new string(br.ReadChars(32));
br.BaseStream.Position = 420;
MapName = new string(br.ReadChars(35));
br.BaseStream.Position += 1;
Scenario = new string(br.ReadChars(80));
#endregion


#region SID Data
br.BaseStream.Position = 364;
SIDMetaTableOffset = br.ReadInt32();
SIDCount = br.ReadInt32();
SIDTableSize = br.ReadInt32();
SIDIndexOffset = br.ReadInt32();
SIDTableOffset = br.ReadInt32();
#endregion

#region Tag Data
br.BaseStream.Position = 716;
TagCount = br.ReadInt32();
FileTableOffset = br.ReadInt32();
FileTableSize = br.ReadInt32();
FileTableIndexOffset = br.ReadInt32();
//Model Raw
br.BaseStream.Position = 744;
ModelRawTableStart = br.ReadInt32();
ModelRawTableSize = br.ReadInt32();
Checksum = br.ReadInt32();
#endregion
#endregion

#region Index
br.BaseStream.Position = IndexOffset;
IndexHeaderSize = br.ReadInt32();
Const120 = br.ReadInt32();
TagStartModifier = br.ReadInt32();
TagStart = TagStartModifier + IndexOffset;
PrimaryMagic = br.ReadInt32() - (IndexOffset + 32);
br.BaseStream.Position += 8;
TagCount = br.ReadInt32(); //Incorrect But works
br.BaseStream.Position = TagStart + 8;
SecondaryMgicConstant = br.ReadInt32();
SecondaryMagic = SecondaryMgicConstant - (IndexOffset + IndexSize);
#endregion
br.Close();
fs.Close();
}
public List<string> gettaglist(string Filepath)
//example: List<string example = gettaglist(filepath);
// then do what you want with it
{
FileStream fs = new FileStream(Filepath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
BinaryReader br = new BinaryReader(fs);
BinaryWriter bw = new BinaryWriter(fs);
List<string> sss = new List<string>();
br.BaseStream.Position =TagStart;
for (int i = 0; i < TagCount; i++)
{
int IndexOffset = (int)br.BaseStream.Position;
string Class = new string(br.ReadChars(4));
int Identifier = br.ReadInt32();
int RawMetaOffset = br.ReadInt32();
int MetaOffset = RawMetaOffset - SecondaryMagic;
int MetaSize = br.ReadInt32();
if (MetaSize != 0)
{
sss.Add(/* Add What you want here*/);
}
}
return sss;
}
}




Ingame
Ingame data found by me
process memory from another class don't know whose it is.

using System.Diagnostics;
using System.Runtime.InteropServices;
using System;
using System.Windows.Forms;
using System.Media;
using System.Text;
using System.ComponentModel;
using System.Data;
using System.Threading;
using System.Collections.Generic;
class H2VIngameIndexHeader
{
/*
-------- Example-----------
richTextBox1.Clear();
H2VIngameIndexHeader h2v = new H2VIngameIndexHeader();
foreach (string s in h2v.Header().ToArray())
{
richTextBox1.Text = richTextBox1.Text + s + "\n";
}
*/
ProcessMemory mem = new ProcessMemory("Halo2");
public List<string> Header()
{
mem.StartProcess();
List<string> temlist = new List<string>();
temlist.Add("MapSize: 0x" + mem.ReadInt(true, 0x47CD70).ToString("X"));
temlist.Add("IndexOffset: 0x" + mem.ReadInt(true, 0x47CD78).ToString("X"));
temlist.Add("IndexSize: 0x" + mem.ReadInt(true, 0x47CD7C).ToString("X"));
temlist.Add("MetaTableSize: 0x" + mem.ReadInt(true, 0x47CD80).ToString("X"));
temlist.Add("NonRawSize: 0x" + mem.ReadInt(true, 0x47CD84).ToString("X"));
temlist.Add("Build Date: " + mem.ReadStringAscii(true, 0x47CE94, 24));
temlist.Add("SIDMetaTableOffset: 0x" + mem.ReadInt(true, 0x47CED4).ToString("X"));
temlist.Add("SIDCount: 0x" + mem.ReadInt(true, 0x47CED8).ToString("X"));
temlist.Add("SIDTableSize: 0x" + mem.ReadInt(true, 0x47CEDC).ToString("X"));
temlist.Add("SIDIndexOffset: 0x" + mem.ReadInt(true, 0x47CEE0).ToString("X"));
temlist.Add("SIDTableOffset: 0x" + mem.ReadInt(true, 0x47CEE4).ToString("X"));
temlist.Add("Map Name: " + mem.ReadStringAscii(true, 0x47CF0C, 35));
temlist.Add("Scenario: " + mem.ReadStringAscii(true, 0x47CF30, 80));
temlist.Add("Max Tag Count: 0x" + mem.ReadInt(true, 0x47D034).ToString("X"));
temlist.Add("FileTableOffset: 0x" + mem.ReadInt(true, 0x47D038).ToString("X"));
temlist.Add("FileTableSize: 0x" + mem.ReadInt(true, 0x47D03C).ToString("X"));
temlist.Add("FileTableIndexOffset: 0x" + mem.ReadInt(true, 0x47D040).ToString("X"));
temlist.Add("ModelRawTableStart: 0x" + mem.ReadInt(true, 0x47D050).ToString("X"));
temlist.Add("ModelRawTableSize: 0x" + mem.ReadInt(true, 0x47D054).ToString("X"));
temlist.Add("Checksum: 0x" + mem.ReadInt(true, 0x47D058).ToString("X"));
return temlist;
}
public void Tags(TreeView tree)
{
mem.StartProcess();
int FirstTag = mem.ReadInt(mem.Pointer(true, 0x479E70, 0x13C4008));
for (int x = 0; x < 1504; x++)
{
if (mem.ReadInt(FirstTag + (x * 0x10) + 0xC) != 0)
{
tree.Nodes.Add(ReverseString(mem.ReadStringAscii(F irstTag + (x * 0x10), 4)));
tree.Nodes[tree.Nodes.Count - 1].Nodes.Add("ID: " + mem.ReadInt((FirstTag + 4) + (x * 0x10)).ToString("X"));
tree.Nodes[tree.Nodes.Count - 1].Nodes.Add("Raw Meta: " + mem.ReadInt((FirstTag + 8) + (x * 0x10)).ToString("X"));
tree.Nodes[tree.Nodes.Count - 1].Nodes.Add((mem.ReadInt((FirstTag + 8) + (x * 0x10)) - ((mem.ReadInt(mem.ReadInt(mem.Pointer(true, 0x479E70, 0x13C4008)) + 8)) - (mem.Pointer(true, 0x479E70, 0x13C4000) + mem.ReadInt(true, 0x47CD7C)))).ToString("X"));
tree.Nodes[tree.Nodes.Count - 1].Nodes.Add(mem.ReadInt((FirstTag + 0xC) + (x * 0x10)).ToString("X"));
}
}
}
public void RawByteMeta(string metaoff, string size, RichTextBox box)
{
try
{
mem.StartProcess();
byte[] raw = mem.ReadMem(int.Parse(metaoff, System.Globalization.NumberStyles.AllowHexSpecifie r), int.Parse(size, System.Globalization.NumberStyles.AllowHexSpecifie r));
box.Text = BitConverter.ToString(raw).Replace('-', ' ');
}
catch (Exception ex) { MessageBox.Show(ex.ToString()); }
}
public void RawByteMeta(string metaoff, string size, DataGridView dg)
{

mem.StartProcess();
DataTable dt = new DataTable();
#region columns
dt.Columns.Add("Base");
dt.Columns.Add("1");
dt.Columns.Add("2");
dt.Columns.Add("3");
dt.Columns.Add("4");
dt.Columns.Add("5");
dt.Columns.Add("6");
dt.Columns.Add("7");
dt.Columns.Add("8");
dt.Columns.Add("9");
dt.Columns.Add("A");
dt.Columns.Add("B");
dt.Columns.Add("C");
dt.Columns.Add("D");
dt.Columns.Add("E");
dt.Columns.Add("F");
#endregion
byte[] raw = mem.ReadMem(int.Parse(metaoff, System.Globalization.NumberStyles.AllowHexSpecifie r), int.Parse(size, System.Globalization.NumberStyles.AllowHexSpecifie r));
for (int x = 0; x < raw.Length/ 15; x++)
{
try
{
dt.Rows.Add((int.Parse(metaoff, System.Globalization.NumberStyles.AllowHexSpecifie r) + (x*0xF) - 0xF).ToString("X"),raw[x * 0xF - 0xE].ToString("X"), raw[x * 0xf - 0xD].ToString("X"), raw[x * 0xf - 0xC].ToString("X"), raw[x * 0xf - 0xB].ToString("X"), raw[x * 0xf - 0xA].ToString("X"), raw[x * 0xF - 9].ToString("X"), raw[x * 0xF - 8].ToString("X"), raw[x*0xF - 7].ToString("X"), raw[x * 0xF - 6].ToString("X"), raw[x*0xF - 5].ToString("X"), raw[x*0xF - 4].ToString("X"), raw[x*0xF - 3].ToString("X"), raw[x*0xF - 2].ToString("X"), raw[x*0xF - 1].ToString("X"), raw[x*0xF].ToString("X"));
}
catch (Exception ex) { }
}
dg.DataSource = dt;
}
public static string ReverseString(string s)
{
char[] arr = s.ToCharArray();
Array.Reverse(arr);
return new string(arr);
}
}
internal class ProcessMemory
{
// Fields
protected int BaseAddress;
protected Process[] MyProcess;
protected ProcessModule myProcessModule;
private const uint PAGE_EXECUTE = 16;
private const uint PAGE_EXECUTE_READ = 32;
private const uint PAGE_EXECUTE_READWRITE = 64;
private const uint PAGE_EXECUTE_WRITECOPY = 128;
private const uint PAGE_GUARD = 256;
private const uint PAGE_NOACCESS = 1;
private const uint PAGE_NOCACHE = 512;
private const uint PAGE_READONLY = 2;
private const uint PAGE_READWRITE = 4;
private const uint PAGE_WRITECOPY = 8;
private const uint PROCESS_ALL_ACCESS = 2035711;
protected int processHandle;
protected string ProcessName;
// Methods
public ProcessMemory(string pProcessName)
{
this.ProcessName = pProcessName;
}
public int ReadInt(int pOffset)
{
return BitConverter.ToInt32(this.ReadMem(pOffset, 4), 0);
}
public int Pointer(bool AddToImageAddress, int pOffset, int pOffset2)
{
//look at this shit, it doesnt even have a if statement
if (AddToImageAddress)
return (this.ReadInt(this.ImageAddress() + pOffset) + pOffset2);
else
return (this.ReadInt(pOffset) + pOffset2);
}
public string ReadStringAscii(int pOffset, int pSize)
{
return this.CutString(Encoding.ASCII.GetString(this.ReadM em(pOffset, pSize)));
}
public int ReadInt(bool AddToImageAddress, int pOffset)
{
return BitConverter.ToInt32(this.ReadMem(pOffset, 4, AddToImageAddress), 0);
}
public byte[] ReadMem(int pOffset, int pSize)
{
byte[] buffer = new byte[pSize];
ReadProcessMemory(this.processHandle, pOffset, buffer, pSize, 0);
return buffer;
}
public bool CheckProcess()
{
return (Process.GetProcessesByName(this.ProcessName).Leng th > 0);
}

[DllImport("kernel32.dll")]
public static extern bool CloseHandle(int hObject);
public string CutString(string mystring)
{
char[] chArray = mystring.ToCharArray();
string str = "";
for (int i = 0; i < mystring.Length; i++)
{
if ((chArray[i] == ' ') && (chArray[i + 1] == ' '))
{
return str;
}
if (chArray[i] == '\0')
{
return str;
}
str = str + chArray[i].ToString();
}
return mystring.TrimEnd(new char[] { '0' });
}
public int ImageAddress()
{
this.BaseAddress = 0;
this.myProcessModule = this.MyProcess[0].MainModule;
this.BaseAddress = (int)this.myProcessModule.BaseAddress;
return this.BaseAddress;


}
public int ImageAddress(int pOffset)
{
try
{
this.BaseAddress = 0;
this.myProcessModule = this.MyProcess[0].MainModule;
this.BaseAddress = (int)this.myProcessModule.BaseAddress;
return (pOffset + this.BaseAddress);
}
catch (Exception) { return 0; }
}
public string MyProcessName()
{
return this.ProcessName;
}
public byte[] ReadMem(int pOffset, int pSize, bool AddToImageAddress)
{
byte[] buffer = new byte[pSize];
int lpBaseAddress = AddToImageAddress ? this.ImageAddress(pOffset) : pOffset;
ReadProcessMemory(this.processHandle, lpBaseAddress, buffer, pSize, 0);
return buffer;
}
public string ReadStringAscii(bool AddToImageAddress, int pOffset, int pSize)
{
return this.CutString(Encoding.ASCII.GetString(this.ReadM em(pOffset, pSize, AddToImageAddress)));
}
public bool StartProcess()
{
if (this.ProcessName != "")
{
this.MyProcess = Process.GetProcessesByName(this.ProcessName);
if (this.MyProcess.Length == 0)
{
MessageBox.Show(this.ProcessName + " is not running or has not been found. Please check and try again", "Process Not Found", MessageBoxButtons.OK, MessageBoxIcon.Hand);
return false;
}
this.processHandle = OpenProcess(2035711, false, this.MyProcess[0].Id);
if (this.processHandle == 0)
{
MessageBox.Show(this.ProcessName + " is not running or has not been found. Please check and try again", "Process Not Found", MessageBoxButtons.OK, MessageBoxIcon.Hand);
return false;
}
return true;
}
MessageBox.Show("Define process name first!");
return false;
}
[DllImport("kernel32.dll")]
public static extern int OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll")]
public static extern bool ReadProcessMemory(int hProcess, int lpBaseAddress, byte[] buffer, int size, int lpNumberOfBytesRead);
}

supersniper
February 13th, 2011, 09:39 PM
should've put comments after each line to explain what each part of the class references.

KantIZBack
February 13th, 2011, 09:48 PM
I may do that later once i update it to get the tag/file list.

Patrickssj6
February 13th, 2011, 10:25 PM
A map layout would be far more useful especially that we lost Grenadiac's infos from Halomods.com

KantIZBack
February 13th, 2011, 10:25 PM
Updated with Taglist


EDIT.

That is what it is all going to end up being once i finish the Class

Kornman00
February 14th, 2011, 01:15 AM
http://code.google.com/p/open-sauce/source/browse/BlamLib/BlamLib/Blam/Halo2/CacheFile.cs

supersniper
February 14th, 2011, 02:51 AM
oh shit, after reading through all that, there's a LOT i don't understand about programming, time to google it up.

Resinball
February 14th, 2011, 06:53 AM
Nice work Kant, good to see you back. I smell change in the air...no wait, that was just a fart. Carry on.

Shock120
February 14th, 2011, 07:14 AM
Try learning about H2V custom maps...

supersniper
February 14th, 2011, 07:52 AM
hmm alright let me install h2ek again lol

KantIZBack
February 14th, 2011, 04:27 PM
KM just showed me up bigtime....... dammmmnnnnn

KantIZBack
February 14th, 2011, 09:39 PM
Update Ingame Data class

KantIZBack
February 15th, 2011, 08:33 PM
Ingame tag list


No Tag names are imported into game so no solution for that yet.

Kornman00
February 16th, 2011, 01:46 AM
From Halo 2 and onward, tag names and string id values are just treated as debug data and are never loaded by a shipping build of the game. However, the engine keeps a local copy of the current cache's header loaded into memory along with an associated FILE_HANDLE, so if someone were making a game extension they could easily just load the tag names themselves.

KantIZBack
February 17th, 2011, 04:13 PM
im thinking of just making it so you can open your maps folder's and it will make a taglist just a idea though

KantIZBack
February 17th, 2011, 06:48 PM
Just Figured out how to locate the meta start of a tag ingame, Holy shit i didn't think i could find this one honestly....

KantIZBack
February 17th, 2011, 07:02 PM
Meta offset added to class.

KantIZBack
February 18th, 2011, 08:03 PM
Ingame:

Datatable Hex view of selected tag meta
RichTextBox view of selected tag meta,