Initial upload.
Adding base PRC 4.19a files to repository.
This commit is contained in:
BIN
trunk/tools/CharacterCreator.exe
Normal file
BIN
trunk/tools/CharacterCreator.exe
Normal file
Binary file not shown.
797
trunk/tools/HakInstaller/2da.cs
Normal file
797
trunk/tools/HakInstaller/2da.cs
Normal file
@@ -0,0 +1,797 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace NWN.FileTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents a 2da file. It contains all of the functionality
|
||||
/// necessary to merge the 2da files.
|
||||
/// </summary>
|
||||
public class _2DA
|
||||
{
|
||||
#region public properties
|
||||
public const string Empty = "****";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of rows in the 2da.
|
||||
/// </summary>
|
||||
public int Rows { get { return rows.Count; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of columns in the 2da.
|
||||
/// </summary>
|
||||
public int Columns { get { return heading.Count; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the heading row.
|
||||
/// </summary>
|
||||
public string Heading
|
||||
{
|
||||
get { return BuildString(heading); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the schema for the 2da, the schema defines the columns.
|
||||
/// </summary>
|
||||
public StringCollection Schema { get { return heading; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets the index'th row of the 2da.
|
||||
/// </summary>
|
||||
public string this[int index]
|
||||
{
|
||||
get { return BuildString((StringCollection) rows[index]); }
|
||||
set
|
||||
{
|
||||
// Make sure we have a schema.
|
||||
TestForSchema();
|
||||
|
||||
// Parse the line to get the individual cells and throw an exception if
|
||||
// the row's cell count does not match our cell count.
|
||||
StringCollection row = ParseLine(value, false);
|
||||
if (row.Count < heading.Count)
|
||||
throw new InvalidOperationException("Row does not contain enough cells");
|
||||
else if (row.Count > heading.Count)
|
||||
throw new InvalidOperationException("Row contains too many cells");
|
||||
|
||||
// Pad the 2da to make sure it has room for the row, then add it.
|
||||
Pad(index + 1);
|
||||
rows[index] = row;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets a cell from the 2da.
|
||||
/// </summary>
|
||||
public string this[int row, int column]
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((StringCollection) rows[row])[column];
|
||||
}
|
||||
set
|
||||
{
|
||||
// Make sure we have a schema.
|
||||
TestForSchema();
|
||||
|
||||
// Pad the 2da to make sure it has room for the cell, then add it.
|
||||
Pad(row + 1);
|
||||
((StringCollection) rows[row])[column] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the 2da file name w/o any path.
|
||||
/// </summary>
|
||||
public string Name { get { return Path.GetFileName(fileName); } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the 2da name with any specified path information.
|
||||
/// </summary>
|
||||
public string FileName { get { return fileName; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets the 2da offset. All rows in the 2da have their row numbers
|
||||
/// shifted to be relative to this offset, i.e. the first row has a row
|
||||
/// number of offset, the second offset + 1, etc.
|
||||
/// </summary>
|
||||
public int Offset
|
||||
{
|
||||
get { return offset; }
|
||||
set
|
||||
{
|
||||
if (value == offset) return;
|
||||
|
||||
// Adjust all of the row numbers to
|
||||
// the correct index value.
|
||||
int index = value;
|
||||
foreach (StringCollection row in rows)
|
||||
{
|
||||
row[0] = index.ToString();
|
||||
index++;
|
||||
}
|
||||
|
||||
// Save the offset.
|
||||
offset = value;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public methods
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
public _2DA()
|
||||
{
|
||||
heading = new StringCollection();
|
||||
rows = new ArrayList();
|
||||
colSizes = new int[100];
|
||||
offset = 0;
|
||||
fileName = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class constructor
|
||||
/// </summary>
|
||||
/// <param name="schema">The schema for the 2da. The schema defines
|
||||
/// the columns contained in the 2da</param>
|
||||
public _2DA(StringCollection schema) : this()
|
||||
{
|
||||
SetSchema(schema);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class constructor
|
||||
/// </summary>
|
||||
/// <param name="schema">The schema for the 2da. The schema defines
|
||||
/// the columns contained in the 2da</param>
|
||||
public _2DA(string[] schema) : this()
|
||||
{
|
||||
StringCollection schemaColl = new StringCollection();
|
||||
schemaColl.AddRange(schema);
|
||||
SetSchema(schemaColl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the schema for the 2da. Setting the schema also clears the 2da.
|
||||
/// </summary>
|
||||
/// <param name="schema">The schema for the 2da. The schema defines
|
||||
/// the columns contained in the 2da</param>
|
||||
public void SetSchema(string schema)
|
||||
{
|
||||
// Setup the schema for the 2da.
|
||||
heading = ParseSchema(schema);
|
||||
AddRowColumnToSchema(heading);
|
||||
|
||||
// Changing the schema clears the 2da.
|
||||
Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the schema for the 2da. Setting the schema also clears the 2da.
|
||||
/// </summary>
|
||||
/// <param name="schema">The schema for the 2da. The schema defines
|
||||
/// the columns contained in the 2da</param>
|
||||
public void SetSchema(StringCollection schema)
|
||||
{
|
||||
// Setup the schema for the 2da.
|
||||
heading = schema;
|
||||
AddRowColumnToSchema(heading);
|
||||
|
||||
// Changing the schema clears the 2da.
|
||||
Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the schema for the 2da. Setting the schema also clears the 2da.
|
||||
/// </summary>
|
||||
/// <param name="schema">The schema for the 2da. The schema defines
|
||||
/// the columns contained in the 2da</param>
|
||||
public void SetSchema(string[] schema)
|
||||
{
|
||||
// Setup the schema for the 2da.
|
||||
heading = new StringCollection();
|
||||
heading.AddRange(schema);
|
||||
AddRowColumnToSchema(heading);
|
||||
|
||||
// Changing the schema clears the 2da.
|
||||
Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index of a column given it's heading.
|
||||
/// </summary>
|
||||
/// <param name="headingText">The heading text</param>
|
||||
/// <returns>The index of the column or -1 if it's not found</returns>
|
||||
public int GetIndex(string headingText)
|
||||
{
|
||||
// Loop through the headings doing a case-insensetive compare of the
|
||||
// passed heading text, if we find it return the index.
|
||||
for (int i = 0; i < heading.Count; i++)
|
||||
if (0 == string.Compare(headingText, heading[i], true, CultureInfo.InvariantCulture))
|
||||
return i;
|
||||
|
||||
// We didn't find the heading return -1.
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests to see if the specified row is empty.
|
||||
/// </summary>
|
||||
/// <param name="row">The row to test</param>
|
||||
/// <returns>true if the row is empty, false if it is not.</returns>
|
||||
public bool IsEmpty (int row)
|
||||
{
|
||||
// Reality check on row argument.
|
||||
if (row < 0 || row >= rows.Count) return false;
|
||||
|
||||
// Get the row and loop through all of the columns except the first
|
||||
// (which is the row number) checking to see if any are not empty. As
|
||||
// soon as we find a non-empty row return false.
|
||||
StringCollection strings = (StringCollection) rows[row];
|
||||
for (int i = 1; i < strings.Count; i++)
|
||||
if (_2DA.Empty != strings[i])
|
||||
{
|
||||
// We need a special case here. Many 2da's use the label column
|
||||
// to indicate reserved or free rows, purely as an informational
|
||||
// message to someone trying to mod the 2da. If a row has data
|
||||
// in the label column but no other then we want to consider the
|
||||
// row empty as it has no meaningful content.
|
||||
if (0 == string.Compare("label", heading[i], true, CultureInfo.InvariantCulture)) continue;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// All columns but the row number are empty return true.
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests to see if the specified cell is empty.
|
||||
/// </summary>
|
||||
/// <param name="row">The row of the cell</param>
|
||||
/// <param name="column">The column of the cell</param>
|
||||
/// <returns>true if the row is empty, false if it is not.</returns>
|
||||
public bool IsEmpty(int row, int column)
|
||||
{
|
||||
return Empty == this[row, column];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the 2da of all cell data, preserving the schema.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
// Reset the 2da to be empty.
|
||||
offset = 0;
|
||||
rows.Clear();
|
||||
|
||||
// Set the column widths to be the widths of the heading cells.
|
||||
for (int i = 0; i < heading.Count; i++)
|
||||
colSizes[i] = heading[i].Length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pads the 2da to have the specified number of rows. If the 2da already has
|
||||
/// more rows than the specified number nothing is done, if it doesn't then
|
||||
/// blank rows are added to the end to pad.
|
||||
/// </summary>
|
||||
/// <param name="length">The new row count</param>
|
||||
public void Pad(int length)
|
||||
{
|
||||
// Figure out how many rows we need to pad.
|
||||
int numPad = length - rows.Count;
|
||||
if (numPad <= 0) return;
|
||||
|
||||
// Add enough empty rows to pad the 2da.
|
||||
for (int i = 0; i < numPad; i++)
|
||||
{
|
||||
StringCollection empty = EmptyRow(rows.Count);
|
||||
rows.Add(empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies a row from a source 2da to this 2da.
|
||||
/// </summary>
|
||||
/// <param name="source">The source 2da</param>
|
||||
/// <param name="sourceRow">The index of the row in the source 2da</param>
|
||||
/// <param name="row">The index of the row in this 2da</param>
|
||||
public void CopyRow(_2DA source, int sourceRow, int row)
|
||||
{
|
||||
// Get the row from the source 2da and let our overload do all of the
|
||||
// work.
|
||||
StringCollection sourceRowData = (StringCollection) source.rows[sourceRow];
|
||||
CopyRow(sourceRowData, row);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies a row to this 2da.
|
||||
/// </summary>
|
||||
/// <param name="sourceRow"></param>
|
||||
/// <param name="row"></param>
|
||||
public void CopyRow(StringCollection sourceRow, int row)
|
||||
{
|
||||
// Get the target StringCollection, and determine the
|
||||
// number of columns to copy being the minimum between the source
|
||||
// 2da's column count and ours.
|
||||
StringCollection rowData = (StringCollection) rows[row];
|
||||
int columns = System.Math.Min(sourceRow.Count, heading.Count);
|
||||
|
||||
// Copy the row data, adjusting our column widths as necessary.
|
||||
rowData[0] = row.ToString();
|
||||
colSizes[0] = System.Math.Max(colSizes[0], rowData[0].Length);
|
||||
for (int i = 1; i < columns; i++)
|
||||
{
|
||||
rowData[i] = sourceRow[i];
|
||||
colSizes[i] = System.Math.Max(colSizes[i], rowData[i].Length);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the StringCollection containing the row data for the
|
||||
/// given row.
|
||||
/// </summary>
|
||||
/// <param name="row">The row for which to get the row data</param>
|
||||
/// <returns>A StringCollection containing the row data</returns>
|
||||
public StringCollection GetRowData(int row)
|
||||
{
|
||||
return (StringCollection) rows[row];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fixes up a 2da join column by adding the given offset to all of the values
|
||||
/// in the column.
|
||||
/// </summary>
|
||||
/// <param name="column">The index of the column (0 biased)</param>
|
||||
/// <param name="offset">The offset to add to the column values</param>
|
||||
public void Fixup2daColumn(int column, int offset)
|
||||
{
|
||||
// Loop through each row, adding offset to all of the
|
||||
// values in the specified column.
|
||||
foreach (StringCollection row in rows)
|
||||
{
|
||||
if ("****" != row[column])
|
||||
{
|
||||
int val = System.Int32.Parse(row[column]) + offset;
|
||||
row[column] = val.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fixes up a 2da join column by adding the given offset to all of the values
|
||||
/// in the column.
|
||||
/// </summary>
|
||||
/// <param name="column">The index of the column (0 biased)</param>
|
||||
/// <param name="offset">The offset to add to the column values</param>
|
||||
/// <param name="customTlk">If true, indicaets that the tlk offset is for a custom
|
||||
/// tlk, this causes the custom tlk offset to be added to the offset as well.</param>
|
||||
public void FixupTlkColumn(int column, int offset, bool customTlk)
|
||||
{
|
||||
// Custom tlk's have 0x1000000 added to their
|
||||
// value, i.e. entry 0 in the tlk is really
|
||||
// index 0x1000000, etc.
|
||||
if (customTlk) offset += 0x1000000;
|
||||
Fixup2daColumn(column, offset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the 2da.
|
||||
/// </summary>
|
||||
public void Save()
|
||||
{
|
||||
SaveAs(fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the 2da with the given file name.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name of the 2da</param>
|
||||
public void SaveAs(string fileName)
|
||||
{
|
||||
using (StreamWriter writer = new StreamWriter(fileName, false, Encoding.ASCII))
|
||||
{
|
||||
// Write the 2da header.
|
||||
writer.WriteLine(headerString);
|
||||
writer.WriteLine();
|
||||
writer.WriteLine(Heading);
|
||||
|
||||
// Write the row data.
|
||||
for (int i = 0; i < rows.Count; i++)
|
||||
writer.WriteLine(this[i]);
|
||||
}
|
||||
|
||||
this.fileName = fileName;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public static methods
|
||||
/// <summary>
|
||||
/// Compares 2 2da cell values to see if they are the same or not.
|
||||
/// </summary>
|
||||
/// <param name="value1">The first value</param>
|
||||
/// <param name="value2">The second value</param>
|
||||
/// <param name="ignoreCase">True if the comparison should be case-insensitive</param>
|
||||
/// <returns>True if the cells are the same, false if they are different</returns>
|
||||
public static bool CompareCell(string value1, string value2, bool ignoreCase)
|
||||
{
|
||||
return 0 == string.Compare(value1, value2, ignoreCase,
|
||||
CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares rows in 2 different 2da files to see if they are equal or not.
|
||||
/// </summary>
|
||||
/// <param name="twoDA1">The first 2da to test</param>
|
||||
/// <param name="row1">The row in the first 2da to compare</param>
|
||||
/// <param name="twoDA2">The second 2da to test</param>
|
||||
/// <param name="row">The row in the second 2da to compare</param>
|
||||
/// <param name="ignoreCase">True if the comparison should be case insensitive</param>
|
||||
/// <returns>True if the rows are equal false if they are not</returns>
|
||||
public static bool CompareRow(_2DA twoDA1, int row1, _2DA twoDA2, int row2,
|
||||
bool ignoreCase)
|
||||
{
|
||||
// Get the data for each of the rows.
|
||||
StringCollection row1Data = (StringCollection) twoDA1.rows[row1];
|
||||
StringCollection row2Data = (StringCollection) twoDA2.rows[row2];
|
||||
|
||||
// If the rows have different amounts of cells then they are by
|
||||
// definition different.
|
||||
if (row1Data.Count != row2Data.Count) return false;
|
||||
|
||||
// Loop through the rows doing a cell by cell compare, stopping
|
||||
// if we find any differences. We start at column 1 to skip
|
||||
// the row numbrs which would of course be different.
|
||||
for (int i = 1; i < row1Data.Count; i++)
|
||||
if (!CompareCell(row1Data[i], row2Data[i], ignoreCase))
|
||||
return false;
|
||||
|
||||
// The rows are identical return true.
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory method to create C2da objects from 2da files.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name of the 2da file</param>
|
||||
/// <returns>A 2da object for the 2da file.</returns>
|
||||
public static _2DA Load2da (string fileName)
|
||||
{
|
||||
// Open the 2da file.
|
||||
_2DA file = new _2DA(fileName);
|
||||
using(StreamReader reader = new StreamReader(fileName))
|
||||
{
|
||||
file.Read(reader);
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory method to create C2da objects from streams.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream to create the 2da object from</param>
|
||||
/// <returns>A 2da object for the stream.</returns>
|
||||
public static _2DA Load2da(Stream stream)
|
||||
{
|
||||
_2DA file = new _2DA();
|
||||
using (StreamReader reader = new StreamReader(stream, Encoding.ASCII))
|
||||
{
|
||||
file.Read(reader);
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Merges 2 2da objects, saving the results in a 2da file. The method expects that
|
||||
/// the source 2da will have at least enough rows to be contiguous with the merge
|
||||
/// 2da (the source 2da should be padded by calling Pad() if necessary). If the
|
||||
/// source and merge 2da's share some rows, the merge 2da rows will overwrite the
|
||||
/// source 2da rows.
|
||||
/// </summary>
|
||||
/// <param name="source">The source 2da</param>
|
||||
/// <param name="merge">The merge 2da</param>
|
||||
/// <param name="outFile">The name of the output 2da</param>
|
||||
public static void Merge2da (_2DA source, _2DA merge, string outFile)
|
||||
{
|
||||
using(StreamWriter writer = new StreamWriter(outFile, false))
|
||||
{
|
||||
// Write the 2da header.
|
||||
writer.WriteLine(headerString);
|
||||
writer.WriteLine();
|
||||
writer.WriteLine(source.Heading);
|
||||
|
||||
// Make the column sizes in the source and 2da files to be the largest
|
||||
// of each file, to make the columns have the correct width.
|
||||
for (int i = 0; i < source.colSizes.Length; i++)
|
||||
{
|
||||
source.colSizes[i] = System.Math.Max(source.colSizes[i], merge.colSizes[i]);
|
||||
merge.colSizes[i] = source.colSizes[i];
|
||||
}
|
||||
|
||||
// output all of the source strings before our merge.
|
||||
for (int i = 0; i < merge.Offset; i++)
|
||||
{
|
||||
string s = source[i];
|
||||
writer.WriteLine(s);
|
||||
}
|
||||
|
||||
// Test all of the rows that the merge is about to overwrite to make sure they
|
||||
// are really empty. If any are not then generate a warning message for those
|
||||
// rows.
|
||||
int end = System.Math.Min(source.rows.Count, merge.Offset + merge.rows.Count);
|
||||
for (int i = merge.Offset; i < end; i++)
|
||||
if (!source.IsEmpty(i))
|
||||
{
|
||||
//CMain.Warning("Overwriting non-empty row {0} in {1}", i, source.FileName);
|
||||
}
|
||||
|
||||
// output all of the merge strings.
|
||||
for (int i = 0; i < merge.rows.Count; i++)
|
||||
{
|
||||
string s = merge[i];
|
||||
writer.WriteLine(s);
|
||||
}
|
||||
|
||||
// output any remaining source strings, in case the merge is in the middle.
|
||||
for (int i = merge.Offset + merge.rows.Count; i < source.rows.Count; i++)
|
||||
{
|
||||
string s = source[i];
|
||||
writer.WriteLine(s);
|
||||
}
|
||||
|
||||
writer.Flush();
|
||||
writer.Close();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private fields/properties/methods
|
||||
private const string headerString = "2DA V2.0";
|
||||
|
||||
private StringCollection heading;
|
||||
private ArrayList rows;
|
||||
private int[] colSizes;
|
||||
private int offset;
|
||||
private string fileName;
|
||||
|
||||
/// <summary>
|
||||
/// Private constructor, to create objects use the static factory method
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name of the 2da file</param>
|
||||
private _2DA(string fileName) : this()
|
||||
{
|
||||
// Save the name of the 2da file.
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to make sure that a schema has been defined for the 2da, and throws
|
||||
/// an InvalidOperationException if it doesn't.
|
||||
/// </summary>
|
||||
private void TestForSchema()
|
||||
{
|
||||
// If we have no heading row we have no schema throw an exception.
|
||||
if (0 == heading.Count) throw new InvalidOperationException("2da contains no schema.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an empty row for the 2da file.
|
||||
/// </summary>
|
||||
/// <param name="row">The index of the row which is being created</param>
|
||||
/// <returns>The empty row</returns>
|
||||
private StringCollection EmptyRow(int row)
|
||||
{
|
||||
// Create an empty row, and assign it a row number.
|
||||
StringCollection empty = new StringCollection();
|
||||
empty.Add(row.ToString());
|
||||
|
||||
// Adjust the maximum width of our column if it changed.
|
||||
colSizes[0] = System.Math.Max(colSizes[0], empty[0].Length);
|
||||
|
||||
// Fill all other columns with the empty value.
|
||||
int count = heading.Count;
|
||||
for (int i = 1; i < count; i++)
|
||||
{
|
||||
empty.Add(_2DA.Empty);
|
||||
colSizes[i] = System.Math.Max(colSizes[i], _2DA.Empty.Length);
|
||||
}
|
||||
|
||||
// Return the empty row.
|
||||
return empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds a string from the data for the row. The string has padding whitespace
|
||||
/// inserted such that all of the columns in the 2da will line up of the lines are
|
||||
/// output to a text file.
|
||||
/// </summary>
|
||||
/// <param name="row">The row for which to build the string</param>
|
||||
/// <returns></returns>
|
||||
private string BuildString(StringCollection row)
|
||||
{
|
||||
System.Text.StringBuilder b = new System.Text.StringBuilder(4096);
|
||||
int i = 0;
|
||||
foreach (string s in row)
|
||||
{
|
||||
// If this is not the first row add a space separator.
|
||||
if (i > 0) b.Append(' ');
|
||||
|
||||
// If the string contains spaces then wrap it in quotes.
|
||||
string value = s;
|
||||
if (value.IndexOf(' ') >= 0) value = string.Format("\"{0}\"", value);
|
||||
|
||||
// Add the string data and any whitespace padding necessary.
|
||||
b.Append(value);
|
||||
if (value.Length < colSizes[i]) b.Append(' ', colSizes[i] - value.Length);
|
||||
i++;
|
||||
}
|
||||
|
||||
return b.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the empty column for the row numbers to a schema
|
||||
/// </summary>
|
||||
/// <param name="schema">The schema to add the line to</param>
|
||||
private void AddRowColumnToSchema(StringCollection schema)
|
||||
{
|
||||
// If the first entry is not blank then we need to add an empty
|
||||
// column for the row number to the schema.
|
||||
if (string.Empty != schema[0]) schema.Insert(0, string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds the schema for the 2da by parsing the text line.
|
||||
/// </summary>
|
||||
/// <param name="line">The line to parse</param>
|
||||
/// <returns>A string collection containing the schema</returns>
|
||||
private StringCollection ParseSchema(string line)
|
||||
{
|
||||
// Call ParseLine() to parse the schema line into the individual cell values,
|
||||
// then add an extra blank entry for the row number.
|
||||
StringCollection schema = ParseLine(line, true);
|
||||
AddRowColumnToSchema(schema);
|
||||
return schema;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a 2da file line to break the line into each of the column values.
|
||||
/// Parses both the heading line (which contains no row number) and row data
|
||||
/// lines (which do).
|
||||
/// </summary>
|
||||
/// <param name="line">The line to parse</param>
|
||||
/// <param name="headerLine">True if the line is a header line</param>
|
||||
/// <returns>A StringCollection containing the line's data</returns>
|
||||
private StringCollection ParseLine(string line, bool headerLine)
|
||||
{
|
||||
StringCollection coll = new StringCollection();
|
||||
|
||||
// Determine the start index for the column sizes, if it's a header
|
||||
// line we are parsing then the start index is 1 otherwise it's 0
|
||||
int iColSize = headerLine ? 1 : 0;
|
||||
|
||||
try
|
||||
{
|
||||
for (int i= 0;;)
|
||||
{
|
||||
// Skip whitespace, if we skip past the end of the string then an
|
||||
// index out of range exception will be thrown which we catch
|
||||
// to end the parse.
|
||||
while (' ' == line[i] || '\t' == line[i]) i++;
|
||||
|
||||
// OK, hack time. Some 2da's (itemprops.2da is the known case have
|
||||
// a "Label" column as the last column. In this case the "label"
|
||||
// IGNORES the rules about quoting spaces and allows spaces in the name,
|
||||
// we have to catch this case by checking the schema to see if we are
|
||||
// on the last column and it is called "Label".
|
||||
bool isLabelColumn = !headerLine &&
|
||||
coll.Count == heading.Count - 1 &&
|
||||
0 == string.Compare(heading[coll.Count], "LABEL", true, CultureInfo.InvariantCulture);
|
||||
|
||||
// items in a 2da are separated by whitespace, unless quoted.
|
||||
if (isLabelColumn)
|
||||
{
|
||||
// If we are reading the name column just grab the rest of the text to the
|
||||
// end of the line and remove trailing whitespace.
|
||||
string s = line.Substring(i);
|
||||
s = s.Trim();
|
||||
coll.Add(s);
|
||||
i = line.Length;
|
||||
}
|
||||
else if ('"' == line[i])
|
||||
{
|
||||
// Find the end quote then add the substring.
|
||||
int iEndQuote = line.IndexOf('"', i + 1);
|
||||
string s = line.Substring(i + 1, iEndQuote - i - 1);
|
||||
coll.Add (s);
|
||||
|
||||
// If the string we just added is the widest string for this column we've
|
||||
// seen then save that info.
|
||||
colSizes[iColSize] = System.Math.Max(colSizes[iColSize], s.Length);
|
||||
iColSize++;
|
||||
|
||||
// Advance i past what we just added.
|
||||
i = iEndQuote + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find the next whitespace char and add the substring to the collection.
|
||||
int iFirstWhitespace = line.IndexOfAny(new char[]{' ', '\t'}, i);
|
||||
if (-1 == iFirstWhitespace) iFirstWhitespace = line.Length;
|
||||
string s = line.Substring(i, iFirstWhitespace - i);
|
||||
coll.Add(s);
|
||||
|
||||
// If the string we just added is the widest string for this column we've
|
||||
// seen then save that info.
|
||||
colSizes[iColSize] = System.Math.Max(colSizes[iColSize], s.Length);
|
||||
iColSize++;
|
||||
|
||||
// Advance i past what we just added.
|
||||
i = iFirstWhitespace;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.IndexOutOfRangeException)
|
||||
{
|
||||
// We use this exception as the terminating condition of the loop, so no
|
||||
// error.
|
||||
}
|
||||
|
||||
return coll;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads 2da data from the specified stream, initializing the object with
|
||||
/// the 2da data.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader from which to read the data</param>
|
||||
private void Read(StreamReader reader)
|
||||
{
|
||||
// 2da files have the header followed by a line of white space.
|
||||
// Consume that now.
|
||||
reader.ReadLine();
|
||||
reader.ReadLine();
|
||||
|
||||
// Read the header into memory and add an extra
|
||||
// Now read the header and all of the data into memory.
|
||||
for (bool fHeader = true; reader.Peek() > -1; fHeader = false)
|
||||
{
|
||||
string line = reader.ReadLine();
|
||||
line = line.Trim();
|
||||
if (0 == line.Length) continue;
|
||||
|
||||
// Parse the line into the collection of individual strings. If
|
||||
// we have just read in the header row we don't have a heading
|
||||
// for the row number, so add a dummy column to the front of
|
||||
// the array so the header and data rows have the same number of
|
||||
// columns.
|
||||
StringCollection strings = fHeader ?
|
||||
ParseSchema(line) : ParseLine(line, fHeader);
|
||||
|
||||
if (fHeader)
|
||||
heading = strings;
|
||||
else
|
||||
{
|
||||
// Do a reality check on the column count.
|
||||
// Commented out until the CEP team fixes their fucked up 2da.
|
||||
/*
|
||||
if (strings.Count != Columns)
|
||||
throw new InvalidOperationException(
|
||||
string.Format("Row {0} in {1} does not have the correct number of columns",
|
||||
rows.Count, Name));
|
||||
*/
|
||||
|
||||
rows.Add(strings);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
132
trunk/tools/HakInstaller/AboutForm.cs
Normal file
132
trunk/tools/HakInstaller/AboutForm.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
using HakInstaller.Utilities;
|
||||
|
||||
namespace HakInstaller
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for AboutForm.
|
||||
/// </summary>
|
||||
public class AboutForm : System.Windows.Forms.Form
|
||||
{
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.Button button1;
|
||||
private System.Windows.Forms.Label labelCaption;
|
||||
private System.Windows.Forms.PictureBox pictureBox;
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.Container components = null;
|
||||
|
||||
public AboutForm()
|
||||
{
|
||||
//
|
||||
// Required for Windows Form Designer support
|
||||
//
|
||||
InitializeComponent();
|
||||
|
||||
string name = Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().Location);
|
||||
this.Text += name;
|
||||
|
||||
string version = Assembly.GetExecutingAssembly().GetName().Version.ToString();
|
||||
labelCaption.Text = string.Format(labelCaption.Text, version);
|
||||
|
||||
Icon icon = new Icon(typeof(AboutForm), "HakInstaller.ico");
|
||||
icon = new Icon(icon, 32, 32);
|
||||
pictureBox.Image = icon.ToBitmap();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
protected override void Dispose( bool disposing )
|
||||
{
|
||||
if( disposing )
|
||||
{
|
||||
if(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()
|
||||
{
|
||||
this.labelCaption = new System.Windows.Forms.Label();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.button1 = new System.Windows.Forms.Button();
|
||||
this.pictureBox = new System.Windows.Forms.PictureBox();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// labelCaption
|
||||
//
|
||||
this.labelCaption.Location = new System.Drawing.Point(96, 16);
|
||||
this.labelCaption.Name = "labelCaption";
|
||||
this.labelCaption.Size = new System.Drawing.Size(256, 32);
|
||||
this.labelCaption.TabIndex = 0;
|
||||
this.labelCaption.Text = "HakInstaller {0} - Installs custom content in NWN modules";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.Location = new System.Drawing.Point(96, 56);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(256, 16);
|
||||
this.label2.TabIndex = 0;
|
||||
this.label2.Text = "(C) 2004 Bleedingedge (Mark Sironi)";
|
||||
//
|
||||
// button1
|
||||
//
|
||||
this.button1.DialogResult = System.Windows.Forms.DialogResult.OK;
|
||||
this.button1.FlatStyle = System.Windows.Forms.FlatStyle.System;
|
||||
this.button1.Location = new System.Drawing.Point(16, 88);
|
||||
this.button1.Name = "button1";
|
||||
this.button1.Size = new System.Drawing.Size(72, 24);
|
||||
this.button1.TabIndex = 5;
|
||||
this.button1.Text = "&OK";
|
||||
this.button1.Click += new System.EventHandler(this.button1_Click);
|
||||
//
|
||||
// pictureBox
|
||||
//
|
||||
this.pictureBox.Location = new System.Drawing.Point(24, 16);
|
||||
this.pictureBox.Name = "pictureBox";
|
||||
this.pictureBox.Size = new System.Drawing.Size(32, 32);
|
||||
this.pictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
|
||||
this.pictureBox.TabIndex = 6;
|
||||
this.pictureBox.TabStop = false;
|
||||
//
|
||||
// AboutForm
|
||||
//
|
||||
this.AcceptButton = this.button1;
|
||||
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
|
||||
this.ClientSize = new System.Drawing.Size(360, 128);
|
||||
this.ControlBox = false;
|
||||
this.Controls.Add(this.pictureBox);
|
||||
this.Controls.Add(this.button1);
|
||||
this.Controls.Add(this.labelCaption);
|
||||
this.Controls.Add(this.label2);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||
this.Name = "AboutForm";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "About ";
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void button1_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
166
trunk/tools/HakInstaller/AboutForm.resx
Normal file
166
trunk/tools/HakInstaller/AboutForm.resx
Normal file
@@ -0,0 +1,166 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
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">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</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 forserialized 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.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:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<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" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</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>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="labelCaption.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="labelCaption.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="labelCaption.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="label2.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="label2.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="label2.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="button1.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="button1.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="button1.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="pictureBox.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="pictureBox.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="pictureBox.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="$this.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Language" type="System.Globalization.CultureInfo, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>(Default)</value>
|
||||
</data>
|
||||
<data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Localizable" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>8, 8</value>
|
||||
</data>
|
||||
<data name="$this.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.TrayHeight" type="System.Int32, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>80</value>
|
||||
</data>
|
||||
<data name="$this.Name">
|
||||
<value>AboutForm</value>
|
||||
</data>
|
||||
<data name="$this.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
</root>
|
58
trunk/tools/HakInstaller/AssemblyInfo.cs
Normal file
58
trunk/tools/HakInstaller/AssemblyInfo.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
//
|
||||
// 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("HakInstaller")]
|
||||
[assembly: AssemblyDescription("Installs custom content in NWN modules")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("")]
|
||||
[assembly: AssemblyCopyright("(C) 2004 Bleedingedge (Mark Sironi)")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
//
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly: AssemblyVersion("2.5.*")]
|
||||
|
||||
//
|
||||
// In order to sign your assembly you must specify a key to use. Refer to the
|
||||
// Microsoft .NET Framework documentation for more information on assembly signing.
|
||||
//
|
||||
// Use the attributes below to control which key is used for signing.
|
||||
//
|
||||
// Notes:
|
||||
// (*) If no key is specified, the assembly is not signed.
|
||||
// (*) KeyName refers to a key that has been installed in the Crypto Service
|
||||
// Provider (CSP) on your machine. KeyFile refers to a file which contains
|
||||
// a key.
|
||||
// (*) If the KeyFile and the KeyName values are both specified, the
|
||||
// following processing occurs:
|
||||
// (1) If the KeyName can be found in the CSP, that key is used.
|
||||
// (2) If the KeyName does not exist and the KeyFile does exist, the key
|
||||
// in the KeyFile is installed into the CSP and used.
|
||||
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
|
||||
// When specifying the KeyFile, the location of the KeyFile should be
|
||||
// relative to the project output directory which is
|
||||
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
|
||||
// located in the project directory, you would specify the AssemblyKeyFile
|
||||
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
|
||||
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
|
||||
// documentation for more information on this.
|
||||
//
|
||||
[assembly: AssemblyDelaySign(false)]
|
||||
[assembly: AssemblyKeyFile("")]
|
||||
[assembly: AssemblyKeyName("")]
|
570
trunk/tools/HakInstaller/ConflictResolver.cs
Normal file
570
trunk/tools/HakInstaller/ConflictResolver.cs
Normal file
@@ -0,0 +1,570 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using HakInstaller.Utilities;
|
||||
using NWN;
|
||||
using NWN.FileTypes;
|
||||
|
||||
namespace HakInstaller
|
||||
{
|
||||
/// <summary>
|
||||
/// This class impelments logic to resolve file conflicts between content
|
||||
/// being added to the module from HIFs and content that already exists
|
||||
/// in the module. Support is provided for the following:
|
||||
///
|
||||
/// TLK: If there are multiple tlk files between all content the class
|
||||
/// will attempt to generate a single tlk file by merging all non-empty
|
||||
/// rows into one tlk. If multiple tlk files use the same row then
|
||||
/// the merge will fail.
|
||||
///
|
||||
/// 2DA: If HIFs and the module both have copies of the same 2da file
|
||||
/// then the class will attempt to generate a merge hak containing
|
||||
/// merged copies of all of the conflicting 2da's. The merged 2da's
|
||||
/// will be built from the topmost version of the 2da from each HIF and
|
||||
/// the module. If two content sources change the same row in a 2da
|
||||
/// and the rows are not exactly the same then the merge for that 2da
|
||||
/// will fail, but it will still attempt to merge other conflicting 2das.
|
||||
/// </summary>
|
||||
public class ConflictResolver
|
||||
{
|
||||
#region public properties/methods
|
||||
/// <summary>
|
||||
/// Class constructor
|
||||
/// </summary>
|
||||
/// <param name="progress">The interface used to provide progress information
|
||||
/// to the user</param>
|
||||
public ConflictResolver(IHakInstallProgress progress)
|
||||
{
|
||||
this.progress = progress;
|
||||
conflictHak = string.Empty;
|
||||
conflictHakDir = string.Empty;
|
||||
conflictHakMessageShown = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to resolve tlk file conflicts between the module tlk and any
|
||||
/// tlk's defined in the hifs. It does this by attempting to build a
|
||||
/// new tlk file containing all of the tlk entries from all tlks. If there
|
||||
/// are no overlapping entries in the tlks's then this will succeed and
|
||||
/// the name of the new tlk will be returned, if there are overlaps then
|
||||
/// this will fail and string.Empty will be returned.
|
||||
/// </summary>
|
||||
/// <param name="module">The module for which we are resolving conflicts</param>
|
||||
/// <param name="hifTlks">The list of tlk files from the HIFs being
|
||||
/// installed.</param>
|
||||
/// <returns>The name of the merge tlk file, or string.Empty if a merge tlk
|
||||
/// could not be generated.</returns>
|
||||
public string ResolveTlkConflict(Erf module, string[] hifTlks)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Let the user know we are building a merge tlk.
|
||||
progress.SetMessage("Building merge tlk for module\n'{0}'.",
|
||||
Path.GetFileNameWithoutExtension(module.FileName));
|
||||
|
||||
// Create an array to hold all of the tlk objects.
|
||||
Tlk[] tlks = new Tlk[hifTlks.Length];
|
||||
|
||||
// Load all of the tlk's.
|
||||
for (int i = 0; i < hifTlks.Length; i++)
|
||||
tlks[i] = Tlk.LoadTlk(NWNInfo.GetFullFilePath(hifTlks[i]));
|
||||
|
||||
// Generate the name of the new tlk file.
|
||||
string newTlkFileName = GetFileName(module, "tlk");
|
||||
if (null == newTlkFileName)
|
||||
throw new NWNException("Cannot create new tlk file for module {0}", module.FileName);
|
||||
|
||||
// Get the largest entry count in all of the tlk files, we cannot move any of the tlk
|
||||
// entries from where they are so the new tlk file will have as many entries as the
|
||||
// largest source tlk file.
|
||||
int count = 0;
|
||||
foreach (Tlk tlk in tlks)
|
||||
if (tlk.Count > count) count = tlk.Count;
|
||||
|
||||
// Create a new tlk file and add all of the entries from all of the tlk files
|
||||
// to it.
|
||||
Tlk newTlk = new Tlk(count);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
// Check to see which tlk file contains this entry. If multiple tlk
|
||||
// files contain this entry we cannot merge the tlk's
|
||||
Tlk.TlkEntry entry = null;
|
||||
foreach (Tlk tlk in tlks)
|
||||
{
|
||||
// Ignore empty entries.
|
||||
if (i >= tlk.Count || tlk.IsEmpty(i)) continue;
|
||||
|
||||
// If we haven't gotten an entry for this row yet
|
||||
// then save this entry. If we have then we cannot
|
||||
// do the merge.
|
||||
if (null == entry)
|
||||
entry = tlk[i];
|
||||
else
|
||||
{
|
||||
// Check to see if the data in two entries is the same.
|
||||
// If it is then both tlk files have the same string
|
||||
// data in the entry and we can still do the merge. This
|
||||
// is most likely to happen at index 0 where many tlk
|
||||
// files place "Bad Strref".
|
||||
if (0 == string.Compare(entry.Text, tlk[i].Text, true, CultureInfo.InvariantCulture))
|
||||
continue;
|
||||
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
// Save the entry in our new tlk file.
|
||||
if (null != entry) newTlk[i] = entry;
|
||||
}
|
||||
|
||||
// Save the new tlk file and return it's file name.
|
||||
newTlk.SaveAs(NWN.NWNInfo.GetFullFilePath(newTlkFileName));
|
||||
return newTlkFileName;
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
// If an error occurs return string.Empty to indicate we couldn't generate
|
||||
// a merge tlk.
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to resolve tlk file conflicts between the module tlk and any
|
||||
/// tlk's defined in the hifs. It does this by attempting to build a
|
||||
/// new tlk file containing all of the tlk entries from all tlks. If there
|
||||
/// are no overlapping entries in the tlks's then this will succeed and
|
||||
/// the name of the new tlk will be returned, if there are overlaps then
|
||||
/// this will fail and string.Empty will be returned.
|
||||
/// </summary>
|
||||
/// <param name="hakInfos">The HIFs being added to the module</param>
|
||||
/// <param name="module">The module for which we are resolving conflicts</param>
|
||||
/// <param name="moduleInfo">The module info for the module</param>
|
||||
/// <param name="conflicts">The list of files in conflict</param>
|
||||
/// <returns>The name of the merge hak file, or string.Empty if a merge tlk
|
||||
/// could not be generated.</returns>
|
||||
public string ResolveConflicts(HakInfo[] hakInfos, Erf module, ModuleInfo moduleInfo,
|
||||
OverwriteWarningCollection conflicts)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Reset the message shown flag so we show the message once.
|
||||
conflictHakMessageShown = false;
|
||||
|
||||
// Generate the name of the conflict resolution hak and the directory
|
||||
// in which to place the files that will be added to the hak.
|
||||
conflictHak = GetFileName(module, "hak");
|
||||
conflictHakDir = NWN.NWNInfo.GetFullFilePath(conflictHak) + ".temp";
|
||||
|
||||
OverwriteWarningCollection copy = conflicts.Clone();
|
||||
foreach (OverwriteWarning conflict in copy)
|
||||
{
|
||||
// Check to see if we can attempt to resolve the conflict, if
|
||||
// we can then attempt to resolve it, and if the resolution is
|
||||
// successful then remove the conflict from the collection.
|
||||
switch (Path.GetExtension(conflict.File).ToLower())
|
||||
{
|
||||
case ".2da":
|
||||
DisplayConflictHakMessage(module);
|
||||
if (Resolve2daConflict(hakInfos, module, moduleInfo, conflict))
|
||||
conflicts.Remove(conflict);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get all of the files in the conflict hak directory, if there are none
|
||||
// then there is no conflict hak.
|
||||
if (!Directory.Exists(conflictHakDir)) return string.Empty;
|
||||
string[] files = Directory.GetFiles(conflictHakDir);
|
||||
if (0 == files.Length) return string.Empty;
|
||||
|
||||
// We have some resolved conflicts make the merge hak.
|
||||
Erf hak = Erf.New(Erf.ErfType.HAK, "Auto-generated merge hak");
|
||||
foreach (string file in files)
|
||||
hak.AddFile(file, true);
|
||||
hak.SaveAs(NWN.NWNInfo.GetFullFilePath(conflictHak));
|
||||
return conflictHak;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (Directory.Exists(conflictHakDir)) Directory.Delete(conflictHakDir, true);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private fields/properties/methods
|
||||
private bool conflictHakMessageShown;
|
||||
private IHakInstallProgress progress;
|
||||
private string conflictHak;
|
||||
private string conflictHakDir;
|
||||
|
||||
/// <summary>
|
||||
/// Displays the building merge hak message once.
|
||||
/// </summary>
|
||||
/// <param name="module">The module that we are resolving conflicts for</param>
|
||||
private void DisplayConflictHakMessage(Erf module)
|
||||
{
|
||||
if (conflictHakMessageShown) return;
|
||||
|
||||
// Let the user know we are building a merge tlk.
|
||||
progress.SetMessage("Building merge hak for module\n'{0}'.",
|
||||
Path.GetFileNameWithoutExtension(module.FileName));
|
||||
conflictHakMessageShown = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a name for a conflict resolution file (hak or tlk). It generates
|
||||
/// a name that is currently unused on disk.
|
||||
/// </summary>
|
||||
/// <param name="module">The module for which to create a new tlk file</param>
|
||||
/// <param name="extension">The extension of the file to get a name for</param>
|
||||
/// <returns>The tlk file name, or null if the name could not be created</returns>
|
||||
private string GetFileName(Erf module, string extension)
|
||||
{
|
||||
// Use the first 12 characters of the module name as the base. Tlk
|
||||
// files can only have 16 character names max, and we want to save 4
|
||||
// characters for the index.
|
||||
string namePrefix = Path.GetFileNameWithoutExtension(module.FileName);
|
||||
if (namePrefix.Length > 12) namePrefix = namePrefix.Substring(0, 12);
|
||||
namePrefix = namePrefix.Replace(" ", "_");
|
||||
|
||||
for (int i = 1; i <= 9999; i ++)
|
||||
{
|
||||
// Build the name using the name prefix and i, if the file name
|
||||
// does not exist in the tlk directory then return it.
|
||||
string name = string.Format("{0}{1:0000}.{2}", namePrefix, i, extension);
|
||||
if (!File.Exists(NWNInfo.GetFullFilePath(name))) return name;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts a 2da file from the specified hak file, returning a
|
||||
/// 2da object containing the 2da data.
|
||||
/// </summary>
|
||||
/// <param name="hak">The hak from which to extract the 2da</param>
|
||||
/// <param name="fileName">The file name of the 2da</param>
|
||||
/// <returns>A 2da object for the 2da file or null if the hak does not
|
||||
/// contain the 2da file</returns>
|
||||
private _2DA Extract2da(string hak, string fileName)
|
||||
{
|
||||
// Extract the 2da file from the hak and create an in memory copy.
|
||||
MemoryStream stream = Erf.GetFile(NWN.NWNInfo.GetFullFilePath(hak), fileName);
|
||||
return null == stream ? null : _2DA.Load2da(stream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the 2da file from the module by looking at all of the haks in the
|
||||
/// module info and checking each hak for the file.
|
||||
/// </summary>
|
||||
/// <param name="moduleInfo">The module info for the module</param>
|
||||
/// <param name="fileName">The name of the 2da to get</param>
|
||||
/// <returns>A 2da object for the 2da or null if the 2da is not in any
|
||||
/// of the module's haks</returns>
|
||||
private _2DA Get2da(ModuleInfo moduleInfo, string fileName)
|
||||
{
|
||||
// Get the list of haks in the module and loop through all of them
|
||||
// trying to load the 2da, as soon as we get it return it.
|
||||
StringCollection haks = moduleInfo.Haks;
|
||||
if (null == haks) return null;
|
||||
foreach (string hak in haks)
|
||||
{
|
||||
_2DA twoDA = Extract2da(hak + ".hak", fileName);
|
||||
if (null != twoDA) return twoDA;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the 2da file from the HIF by looking at all of the haks in the
|
||||
/// HIF and checking each hak for the file.
|
||||
/// </summary>
|
||||
/// <param name="hakInfo">The HIF</param>
|
||||
/// <param name="fileName">The name of the 2da to get</param>
|
||||
/// <returns>A 2da object for the 2da or null if the 2da is not in any
|
||||
/// of the HIF's haks</returns>
|
||||
private _2DA Get2da(HakInfo hakInfo, string fileName)
|
||||
{
|
||||
// Get the list of haks in the HIF and loop through all of them
|
||||
// trying to load the 2da, as soon as we get it return it.
|
||||
StringCollection haks = hakInfo.ModuleProperties["hak"];
|
||||
if (null == haks) return null;
|
||||
foreach (string hak in haks)
|
||||
{
|
||||
_2DA twoDA = Extract2da(hak, fileName);
|
||||
if (null != twoDA) return twoDA;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to resolve conflicts for a 2da file. It does this be attempting to
|
||||
/// merge all duplicate copies of the 2da file into one merge 2da file.
|
||||
/// </summary>
|
||||
/// <param name="hakInfos">The HIFs being added to the module</param>
|
||||
/// <param name="module">The module</param>
|
||||
/// <param name="moduleInfo">The module info for the module</param>
|
||||
/// <param name="conflict">The 2da file in conflict</param>
|
||||
private bool Resolve2daConflict(HakInfo[] hakInfos, Erf module, ModuleInfo moduleInfo,
|
||||
OverwriteWarning conflict)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create an array list and get the 2da from the module,
|
||||
// adding it to the list if we get it.
|
||||
ArrayList list = new ArrayList();
|
||||
_2DA twoDA = Get2da(moduleInfo, conflict.File);
|
||||
if (null != twoDA) list.Add(twoDA);
|
||||
|
||||
// Now get all of the copies of the 2da from the various HIFs and
|
||||
// add them as well.
|
||||
foreach (HakInfo hakInfo in hakInfos)
|
||||
{
|
||||
twoDA = Get2da(hakInfo, conflict.File);
|
||||
if (null != twoDA) list.Add(twoDA);
|
||||
}
|
||||
|
||||
// Load the BioWare version of the the 2da to use as a baseline, if the
|
||||
// file isn't in the bioware directory then we will have to make due w/o
|
||||
// it just make a blank 2da with the correct schema.
|
||||
_2DA bioware = LoadBioWare2da(conflict.File);
|
||||
|
||||
// At this point we have all relevent copies of the conflicting 2da loaded into
|
||||
// memory, we now need to generate a merge 2da if possible.
|
||||
_2DA merge = Merge2das(bioware, list);
|
||||
if (null == merge) return false;
|
||||
|
||||
// We have successfully merged all of the 2das, save the merge 2da and
|
||||
// return true.
|
||||
if (!Directory.Exists(conflictHakDir)) Directory.CreateDirectory(conflictHakDir);
|
||||
merge.SaveAs(Path.Combine(conflictHakDir, conflict.File));
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads a bioware 2da file.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the 2da to load</param>
|
||||
/// <returns>A _2DA object representing the file.</returns>
|
||||
private _2DA LoadBioWare2da(string name)
|
||||
{
|
||||
Stream stream = NWN.FileTypes.BIF.KeyCollection.GetFile(name);
|
||||
_2DA bioware = _2DA.Load2da(stream);
|
||||
return bioware;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to merge all of the 2da's in the passed array list into 1 merge
|
||||
/// 2da, by combining all of the non-empty rows in each 2da. If 2 2da's have
|
||||
/// changes the same row then the merge will fail.
|
||||
/// </summary>
|
||||
/// <param name="baseline">The bioware baseline version of the 2da</param>
|
||||
/// <param name="list">The list of 2da's to merge</param>
|
||||
/// <returns>The merged 2da or null if the 2da's cannot be merged</returns>
|
||||
private _2DA Merge2das(_2DA baseline, ArrayList list)
|
||||
{
|
||||
// Create a flat list to have a strongly typed list of 2da's.
|
||||
_2DA[] merges = new _2DA[list.Count];
|
||||
list.CopyTo(merges);
|
||||
|
||||
// Figure out the maximum number of rows we have to deal with
|
||||
int rows = baseline.Rows;
|
||||
foreach (_2DA merge in merges)
|
||||
rows = System.Math.Max(rows, merge.Rows);
|
||||
|
||||
// Create the output 2da.
|
||||
_2DA output = new _2DA(baseline.Schema);
|
||||
output.Pad(rows);
|
||||
|
||||
// Loop through all rows attempting to merge each row into the
|
||||
// output 2da.
|
||||
for (int i = 0; i < rows; i++)
|
||||
{
|
||||
StringCollection mergedRow = null;
|
||||
_2DA useForOutput = null;
|
||||
foreach (_2DA merge in merges)
|
||||
{
|
||||
// Make an attempt to filter out junk rows with things
|
||||
// such as "reserved", "deleted", etc in their labels.
|
||||
// These often conflict but are really empty rows.
|
||||
if (IsJunkRow(merge, i)) continue;
|
||||
|
||||
// If we have gone past the end of this 2da or the
|
||||
// row is an empty row then ignore it.
|
||||
if (i >= merge.Rows || merge.IsEmpty(i)) continue;
|
||||
|
||||
// If this is a row from the bioware version of the 2da
|
||||
// and the data is the same as the bioware 2da then
|
||||
// ignore this row in the 2da.
|
||||
if (i < baseline.Rows &&
|
||||
_2DA.CompareRow(baseline, i, merge, i, true)) continue;
|
||||
|
||||
// If we get here we have a non-empty row that differs from
|
||||
// one of the bioware rows. Only 1 2da file per row can
|
||||
// get past this point for use to be able to do a successful
|
||||
// merge, if 2 2da's get here then 2 have changed the same
|
||||
// row and we cannot merge.
|
||||
|
||||
// If we don't have any proposed row data yet then
|
||||
// save this 2da's row data.
|
||||
if (null == useForOutput)
|
||||
{
|
||||
useForOutput = merge;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we get here we have 2 2da's that want to change the same row.
|
||||
// Our only hope for a successful merge is that the data in the
|
||||
// 2 2da's is identical.
|
||||
if (_2DA.CompareRow(useForOutput, i, merge, i, true)) continue;
|
||||
|
||||
// We already have an output 2da, which means that 2 2da's have
|
||||
// changed the same row, attempt to glue all of the merge changes
|
||||
// together. If we cannot generate a merged row then return null.
|
||||
mergedRow = GenerateMergeRow(baseline, list, i);
|
||||
if (null == mergedRow) return null;
|
||||
|
||||
// If we get here we have generated a merge row for all 2da's
|
||||
// so we don't need to look at the data in this row any further
|
||||
// break out of the loopo and use the mergedRow.
|
||||
break;
|
||||
}
|
||||
|
||||
// If we have merge 2da to copy from then copy the
|
||||
// cell data. If we don't have a merge 2da but the row is
|
||||
// withing the baseline 2da then copy the baseline data.
|
||||
// Otherwise don't copy any data.
|
||||
if (null != mergedRow)
|
||||
output.CopyRow(mergedRow, i);
|
||||
else if (null != useForOutput)
|
||||
output.CopyRow(useForOutput, i, i);
|
||||
else if (i < baseline.Rows)
|
||||
output.CopyRow(baseline, i, i);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to generate a merge row by taking all of the alterations made
|
||||
/// to the bioware row from the merge 2da's and incorporating them into 1
|
||||
/// row. This will work unless 2 different 2da's change the same column
|
||||
/// in the row, which will make the merge fail.
|
||||
/// </summary>
|
||||
/// <param name="baseline">The bioware baseline 2da</param>
|
||||
/// <param name="list">The list of 2da's being merged</param>
|
||||
/// <param name="row">The row for which to generate a merge row</param>
|
||||
/// <returns>The merged row, or null if a merge row could not be
|
||||
/// generated.</returns>
|
||||
private StringCollection GenerateMergeRow(_2DA baseline, ArrayList list, int row)
|
||||
{
|
||||
try
|
||||
{
|
||||
// We cannot merge if the row is not in the baseline.
|
||||
if (row > baseline.Rows) return null;
|
||||
|
||||
// Create a copy of the merge row in the baseline 2da.
|
||||
StringCollection resultRow = new StringCollection();
|
||||
StringCollection baselineRow = baseline.GetRowData(row);
|
||||
foreach (string s in baselineRow)
|
||||
resultRow.Add(s);
|
||||
|
||||
// Create a bool array to keep track of which columns
|
||||
// we modify.
|
||||
bool[] writtenTo = new bool[resultRow.Count];
|
||||
for (int i = 0; i < writtenTo.Length; i++)
|
||||
writtenTo[i] = false;
|
||||
|
||||
foreach (_2DA merge in list)
|
||||
{
|
||||
// Get the row from the merge 2da.
|
||||
StringCollection mergeRow = merge.GetRowData(row);
|
||||
|
||||
// If the collections do not have the same length then
|
||||
// fail the merge, the added column may not be at the end.
|
||||
if (mergeRow.Count != resultRow.Count) return null;
|
||||
|
||||
// Loop through all of the columns.
|
||||
for (int i = 1; i < resultRow.Count; i++)
|
||||
{
|
||||
// Ignore empty data cells in the merge row.
|
||||
if (_2DA.Empty == mergeRow[i]) continue;
|
||||
|
||||
// Compare the cell value against the baseline. If it is the
|
||||
// same then ignore it. (the result row starts out as the baseline
|
||||
// so we do not need to set these values, and we need to ignore
|
||||
// them to detect double writes to the same cell)
|
||||
if (_2DA.CompareCell(baselineRow[i], mergeRow[i], true))
|
||||
continue;
|
||||
|
||||
// Compare the cells from the result row and the merge row,
|
||||
// if they are different then we need to copy the merge
|
||||
// row's value into the result row. However, if a previous
|
||||
// merge 2da has modified this column then we have 2 different
|
||||
// 2da's wanting non-bioware default values in the same
|
||||
// column, if that happens there is no way to merge.
|
||||
if (!_2DA.CompareCell(mergeRow[i], resultRow[i], true))
|
||||
{
|
||||
// If we've already changed the bioware default for this
|
||||
// column we cannot merge return null.
|
||||
if (writtenTo[i])
|
||||
return null;
|
||||
else
|
||||
{
|
||||
// Overwrite the bioware default for this column and
|
||||
// save the fact that we have changed this column
|
||||
resultRow[i] = mergeRow[i];
|
||||
writtenTo[i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here we were able to take all of the various 2da
|
||||
// modifications to the bioware row and make 1 merge row with all
|
||||
// of the changes, return it.
|
||||
return resultRow;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the row is a junk row.
|
||||
/// </summary>
|
||||
/// <param name="file">The 2da to test</param>
|
||||
/// <param name="row">The row to test</param>
|
||||
/// <returns>True if the row is a junk row.</returns>
|
||||
private bool IsJunkRow(_2DA file, int row)
|
||||
{
|
||||
if (row >= file.Rows) return false;
|
||||
|
||||
int index = file.GetIndex("LABEL");
|
||||
if (-1 == index) index = file.GetIndex("NAME");
|
||||
if (-1 == index) return false;
|
||||
|
||||
// Check for common labels indicating that it is a junk row.
|
||||
string value = file[row, index].ToLower();
|
||||
if (-1 != value.IndexOf("deleted") ||
|
||||
-1 != value.IndexOf("reserved") ||
|
||||
-1 != value.IndexOf("user")) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
1576
trunk/tools/HakInstaller/Erf.cs
Normal file
1576
trunk/tools/HakInstaller/Erf.cs
Normal file
File diff suppressed because it is too large
Load Diff
2810
trunk/tools/HakInstaller/Gff.cs
Normal file
2810
trunk/tools/HakInstaller/Gff.cs
Normal file
File diff suppressed because it is too large
Load Diff
145
trunk/tools/HakInstaller/GffForm.cs
Normal file
145
trunk/tools/HakInstaller/GffForm.cs
Normal file
@@ -0,0 +1,145 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
using NWN.FileTypes.Gff;
|
||||
|
||||
namespace HakInstaller
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for GffForm.
|
||||
/// </summary>
|
||||
public class GffForm : System.Windows.Forms.Form
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.Container components = null;
|
||||
|
||||
public GffForm(NWN.FileTypes.Gff.Gff gff)
|
||||
{
|
||||
//
|
||||
// Required for Windows Form Designer support
|
||||
//
|
||||
InitializeComponent();
|
||||
|
||||
this.gff = gff;
|
||||
}
|
||||
|
||||
private System.Windows.Forms.TreeView tree;
|
||||
|
||||
private NWN.FileTypes.Gff.Gff gff;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
protected override void Dispose( bool disposing )
|
||||
{
|
||||
if( disposing )
|
||||
{
|
||||
if(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()
|
||||
{
|
||||
this.tree = new System.Windows.Forms.TreeView();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tree
|
||||
//
|
||||
this.tree.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tree.ImageIndex = -1;
|
||||
this.tree.Name = "tree";
|
||||
this.tree.SelectedImageIndex = -1;
|
||||
this.tree.Size = new System.Drawing.Size(536, 390);
|
||||
this.tree.TabIndex = 0;
|
||||
//
|
||||
// GffForm
|
||||
//
|
||||
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
|
||||
this.ClientSize = new System.Drawing.Size(536, 390);
|
||||
this.Controls.AddRange(new System.Windows.Forms.Control[] {
|
||||
this.tree});
|
||||
this.Name = "GffForm";
|
||||
this.Text = "GffForm";
|
||||
this.Load += new System.EventHandler(this.GffForm_Load);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void AddDictNodes (TreeNode parent, GffFieldDictionary dict)
|
||||
{
|
||||
System.Text.StringBuilder b = new System.Text.StringBuilder(1024);
|
||||
foreach (DictionaryEntry entry in dict)
|
||||
{
|
||||
GffField field = (GffField) entry.Value;
|
||||
|
||||
if (field.IsList)
|
||||
{
|
||||
TreeNode node = parent.Nodes.Add(entry.Key.ToString());
|
||||
AddCollNodes(node, ((GffListField) field).Value);
|
||||
}
|
||||
else if (field.IsStruct)
|
||||
{
|
||||
TreeNode node = parent.Nodes.Add(entry.Key.ToString());
|
||||
AddDictNodes(node, ((GffStructField) field).Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
b.Length = 0;
|
||||
b.AppendFormat ("{0} = [{1}]", entry.Key.ToString(), field.ToString());
|
||||
parent.Nodes.Add(b.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddCollNodes(TreeNode parent, GffFieldCollection coll)
|
||||
{
|
||||
System.Text.StringBuilder b = new System.Text.StringBuilder(1024);
|
||||
int i = 0;
|
||||
foreach (GffField field in coll)
|
||||
{
|
||||
string name = "Entry_" + i.ToString();
|
||||
i++;
|
||||
|
||||
if (field.IsList)
|
||||
{
|
||||
TreeNode node = parent.Nodes.Add(name);
|
||||
AddCollNodes(node, ((GffListField) field).Value);
|
||||
}
|
||||
else if (field.IsStruct)
|
||||
{
|
||||
TreeNode node = parent.Nodes.Add(name);
|
||||
AddDictNodes(node, ((GffStructField) field).Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
b.Length = 0;
|
||||
b.AppendFormat ("{0} = [{1}]", name, field.Value.ToString());
|
||||
parent.Nodes.Add(b.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GffForm_Load(object sender, System.EventArgs e)
|
||||
{
|
||||
this.Text = gff.Name;
|
||||
GffFieldDictionary top = gff.TopLevel;
|
||||
|
||||
TreeNode parent = tree.Nodes.Add("Top");
|
||||
AddDictNodes(parent, top);
|
||||
}
|
||||
}
|
||||
}
|
102
trunk/tools/HakInstaller/GffForm.resx
Normal file
102
trunk/tools/HakInstaller/GffForm.resx
Normal file
@@ -0,0 +1,102 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
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">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</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.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:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<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" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</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>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="$this.Name">
|
||||
<value>GffForm</value>
|
||||
</data>
|
||||
</root>
|
450
trunk/tools/HakInstaller/HakInfo.cs
Normal file
450
trunk/tools/HakInstaller/HakInfo.cs
Normal file
@@ -0,0 +1,450 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using HakInstaller.Utilities;
|
||||
|
||||
namespace HakInstaller
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is a dictionary of hak properties. Each property contains
|
||||
/// a string collection of values tied to the property.
|
||||
/// </summary>
|
||||
public class HakPropertyDictionary: DictionaryBase
|
||||
{
|
||||
#region public properties/methods
|
||||
/// <summary>
|
||||
/// Indexer to get the StringCollection for a given property
|
||||
/// </summary>
|
||||
public StringCollection this[string property]
|
||||
{
|
||||
get { return InnerHashtable[property] as StringCollection; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
public HakPropertyDictionary()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new property to the collection, creating a blank StringCollection
|
||||
/// for it.
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
public void Add(string property)
|
||||
{
|
||||
InnerHashtable.Add(property, new StringCollection());
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This class represents a .hif file. This file contains information about
|
||||
/// a 'hak' (hak in this case consisting of a collection of ERF, TLK, and HAK
|
||||
/// files, along with a list of items in the module to modify). It provides
|
||||
/// functionality to read the file into memory and access the various pieces of
|
||||
/// the file.
|
||||
/// </summary>
|
||||
public class HakInfo
|
||||
{
|
||||
#region public properties/methods
|
||||
/// <summary>
|
||||
/// Gets the name of the HIF minus the extension.
|
||||
/// </summary>
|
||||
public string Name
|
||||
{ get { return Path.GetFileNameWithoutExtension(fileInfo.Name); } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the title of the HIF. This is the HIF's title property if
|
||||
/// it has one, or it's file name if it doesn't.
|
||||
/// </summary>
|
||||
public string Title
|
||||
{
|
||||
get
|
||||
{
|
||||
StringCollection title = GetStrings(TitleKey, string.Empty);
|
||||
return null == title || 0 == title.Count || string.Empty == title[0] ?
|
||||
Name : title[0];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the version number of the HIF.
|
||||
/// </summary>
|
||||
public float Version
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
StringCollection version = GetStrings(VersionKey, string.Empty);
|
||||
return (float) Convert.ToDouble(version[0], cultureUSA);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the version of the HIF as a text string.
|
||||
/// </summary>
|
||||
public string VersionText
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return GetStrings(VersionKey, string.Empty)[0];
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the minimum version number of NWN required to install the HIF.
|
||||
/// </summary>
|
||||
public float RequiredNWNVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get the required string array and look for a string that starts with a
|
||||
// digit, that would be the NWN version, return it if we find it.
|
||||
StringCollection required = GetStrings(RequiredNWNVersionKey, string.Empty);
|
||||
foreach (string s in required)
|
||||
{
|
||||
if (Char.IsDigit(s[0])) return (float) Convert.ToDouble(required[0], cultureUSA);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if XP1 is required.
|
||||
/// </summary>
|
||||
public bool IsXP1Required
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get the required string array and look for "XP1" or "Undrentide".
|
||||
StringCollection required = GetStrings(RequiredNWNVersionKey, string.Empty);
|
||||
foreach (string s in required)
|
||||
{
|
||||
if (0 == string.Compare("XP1", s, true, CultureInfo.InvariantCulture) ||
|
||||
0 == string.Compare("Undrentide", s, true, CultureInfo.InvariantCulture))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if XP2 is required.
|
||||
/// </summary>
|
||||
public bool IsXP2Required
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get the required string array and look for "XP1" or "Undrentide".
|
||||
StringCollection required = GetStrings(RequiredNWNVersionKey, string.Empty);
|
||||
foreach (string s in required)
|
||||
{
|
||||
if (0 == string.Compare("XP2", s, true, CultureInfo.InvariantCulture) ||
|
||||
0 == string.Compare("Underdark", s, true, CultureInfo.InvariantCulture))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of ERF files to add to the collection.
|
||||
/// </summary>
|
||||
public StringCollection Erfs { get { return components[ErfKey] as StringCollection; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the dictionary of module properties that must be added/modified.
|
||||
/// </summary>
|
||||
public HakPropertyDictionary ModuleProperties
|
||||
{ get { return components[ModuleKey] as HakPropertyDictionary; } }
|
||||
|
||||
/// <summary>
|
||||
/// Class constructor to load a .hif file from disk.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name of the hif file, hif files should
|
||||
/// all live in the hak directory.</param>
|
||||
public HakInfo(string fileName)
|
||||
{
|
||||
// Force the thread to use the invariant culture to make the install
|
||||
// code work on foreign language versions of windows.
|
||||
CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
|
||||
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
|
||||
try
|
||||
{
|
||||
fileInfo = new FileInfo(fileName);
|
||||
|
||||
InitializeComponents();
|
||||
using(StreamReader reader = new StreamReader(fileName))
|
||||
{
|
||||
// Loop through all of the lines in the file.
|
||||
for (int i = 1; reader.Peek() > -1; i++)
|
||||
{
|
||||
// Read the references line and split off the 2da file name and the references.
|
||||
string line = reader.ReadLine();
|
||||
line = line.Trim();
|
||||
|
||||
// If the line is blank or begins with a '#' ignore it.
|
||||
if (0 == line.Length || '#' == line[0]) continue;
|
||||
|
||||
// Split the line into the type and references. If we don't get both
|
||||
// parts the the line has a syntax error.
|
||||
string[] strings = line.Split(':');
|
||||
if (2 != strings.Length)
|
||||
ThrowException("{0}: line {1}: syntax error", fileName, i.ToString());
|
||||
|
||||
// Save the component type and data.
|
||||
string componentType = strings[0].Trim().ToLower();
|
||||
string data = strings[1].Trim();
|
||||
|
||||
// Check to see if the component has a property. If there is
|
||||
// a '.' in the name then it has a sub type, we need to split
|
||||
// the component type into the type and property.
|
||||
string componentProperty = string.Empty;
|
||||
if (-1 != componentType.IndexOf('.'))
|
||||
{
|
||||
strings = componentType.Split('.');
|
||||
componentType = strings[0];
|
||||
componentProperty = strings[1];
|
||||
}
|
||||
|
||||
// Split the various values, in case this can contain multiple
|
||||
// values, and add each to the collection.
|
||||
strings = data.Split(',');
|
||||
StringCollection coll = GetStrings(componentType, componentProperty);
|
||||
foreach (string s in strings)
|
||||
coll.Add(s.Trim());
|
||||
}
|
||||
}
|
||||
|
||||
// The hak may or may not have a version number in it, if it doesn't add 0 so
|
||||
// we always have a version number for lookup.
|
||||
StringCollection version = GetStrings(VersionKey, string.Empty);
|
||||
if (0 == version.Count) version.Add("0");
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.CurrentThread.CurrentCulture = currentCulture;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the HIF to make sure that it can be installed, returning an error
|
||||
/// message if it cannot.
|
||||
/// </summary>
|
||||
/// <param name="error">The error message if the HIF cannot be installed, or
|
||||
/// string.Empty if the HIF can be installed</param>
|
||||
/// <returns>True if the HIF can be installed, false if it cannot.</returns>
|
||||
public bool Validate(out string error)
|
||||
{
|
||||
error = string.Empty;
|
||||
|
||||
// If the HIF has a minimum required version and the current NWN install isn't
|
||||
// high enough then error out right away.
|
||||
if (RequiredNWNVersion > 0 &&
|
||||
(float) Convert.ToDouble(NWN.NWNInfo.Version, cultureUSA) < RequiredNWNVersion)
|
||||
{
|
||||
error = StringResources.GetString("ValidateNWNVersionError",
|
||||
Title, RequiredNWNVersion, NWN.NWNInfo.Version);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the content requires XP1 then validate it.
|
||||
if (IsXP1Required && !NWN.NWNInfo.IsXP1Installed)
|
||||
{
|
||||
error = StringResources.GetString("ValidateNWNXP1Error", Title);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the content requies XP2 then validate it.
|
||||
if (IsXP2Required && !NWN.NWNInfo.IsXP2Installed)
|
||||
{
|
||||
error = StringResources.GetString("ValidateNWNXP2Error", Title);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Build a list of ALL of the files referenced by the HIF.
|
||||
StringCollection files = new StringCollection();
|
||||
StringCollection strings = this.GetStrings(ErfKey, string.Empty);
|
||||
foreach (string s in strings) files.Add(NWN.NWNInfo.GetFullFilePath(s));
|
||||
strings = GetStrings(ModuleKey, "hak");
|
||||
foreach (string s in strings) files.Add(NWN.NWNInfo.GetFullFilePath(s));
|
||||
strings = GetStrings(ModuleKey, "tlk");
|
||||
foreach (string s in strings) files.Add(NWN.NWNInfo.GetFullFilePath(s));
|
||||
|
||||
// Loop through all of the files checking to see which, if any, are missing.
|
||||
string missingFiles = string.Empty;
|
||||
foreach (string file in files)
|
||||
{
|
||||
// If the file is missing add it to our missing files string.
|
||||
if (!File.Exists(file))
|
||||
{
|
||||
if (0 == missingFiles.Length) missingFiles += "\r\n";
|
||||
missingFiles += "\r\n\t";
|
||||
missingFiles += NWN.NWNInfo.GetPartialFilePath(Path.GetFileName(file));
|
||||
}
|
||||
}
|
||||
|
||||
// If there are missing files then format the error message and return it.
|
||||
if (missingFiles.Length > 0)
|
||||
error = StringResources.GetString("ValidateMissingFilesError", Title, missingFiles);
|
||||
|
||||
return 0 == error.Length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override of ToString() to return the name of the HIF.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region private static fields/properties/methods
|
||||
// Create a CultureInfo for US English to do proper number conversion.
|
||||
private static CultureInfo cultureUSA = new CultureInfo(0x0409);
|
||||
#endregion
|
||||
|
||||
#region private fields/properties/methods
|
||||
/// <summary>
|
||||
/// Gets the string collection for the specified (type, property) from the
|
||||
/// hash table.
|
||||
/// </summary>
|
||||
/// <param name="componentType">The component type</param>
|
||||
/// <param name="componentProperty">The property, or string.Empty if
|
||||
/// the type does not support properties</param>
|
||||
/// <returns>The string collection for the (type, property).</returns>
|
||||
private StringCollection GetStrings(string componentType, string componentProperty)
|
||||
{
|
||||
// Get the value for the given component if we can't find it
|
||||
// then throw an exception.
|
||||
object o = components[componentType];
|
||||
if (null == o) ThrowException("Unknown type {0}", componentType);
|
||||
|
||||
if (string.Empty == componentProperty)
|
||||
{
|
||||
// No sub-type, the value for this component type should be
|
||||
// a string collection.
|
||||
if (!(o is StringCollection)) ThrowException("Type {0} requires a property", componentType);
|
||||
return (StringCollection) o;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the hashtable for the type, if there is no hashtable
|
||||
// then throw an exception.
|
||||
HakPropertyDictionary hash = o as HakPropertyDictionary;
|
||||
if (null == hash) ThrowException("Type {0} cannot have properties", componentType);
|
||||
|
||||
// Get the string collection for the property, if there is no
|
||||
// collection for the property yet then create one.
|
||||
StringCollection coll = hash[componentProperty];
|
||||
if (null == coll)
|
||||
{
|
||||
hash.Add(componentProperty);
|
||||
coll = hash[componentProperty];
|
||||
}
|
||||
return coll;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the components hash table.
|
||||
/// </summary>
|
||||
private void InitializeComponents()
|
||||
{
|
||||
// Create the hashtable then walk the key/value arrays, creating
|
||||
// the proper value objects for the keys.
|
||||
components = new Hashtable();
|
||||
for (int i = 0; i < Keys.Length; i++)
|
||||
{
|
||||
System.Reflection.ConstructorInfo ci = Types[i].GetConstructor(new Type[0]);
|
||||
object val = ci.Invoke(new object[0]);
|
||||
components.Add(Keys[i], val);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws an exception with the specified message.
|
||||
/// </summary>
|
||||
/// <param name="format">Format string</param>
|
||||
/// <param name="args">Format arguments</param>
|
||||
private void ThrowException(string format, params object[] args)
|
||||
{
|
||||
System.Text.StringBuilder b = new System.Text.StringBuilder();
|
||||
b.AppendFormat(format, args);
|
||||
throw new Exception(b.ToString());
|
||||
}
|
||||
|
||||
// Define constants for the various component types.
|
||||
private const string ErfKey = "erf";
|
||||
private const string ModuleKey = "module";
|
||||
private const string VersionKey = "version";
|
||||
private const string RequiredNWNVersionKey = "minnwnversion";
|
||||
private const string TitleKey = "title";
|
||||
|
||||
// Arrays that define the supported component types. Keys is an array of
|
||||
// key values which match what is on the left of the ':' in the hif file.
|
||||
// Types is the type of object that is placed in the hash table for each
|
||||
// key.
|
||||
private string[] Keys = new string[]
|
||||
{
|
||||
VersionKey,
|
||||
RequiredNWNVersionKey,
|
||||
ErfKey,
|
||||
TitleKey,
|
||||
ModuleKey
|
||||
};
|
||||
private Type[] Types = new Type[]
|
||||
{
|
||||
typeof(StringCollection),
|
||||
typeof(StringCollection),
|
||||
typeof(StringCollection),
|
||||
typeof(StringCollection),
|
||||
typeof(HakPropertyDictionary)
|
||||
};
|
||||
|
||||
private Hashtable components;
|
||||
private FileInfo fileInfo;
|
||||
#endregion
|
||||
}
|
||||
}
|
1696
trunk/tools/HakInstaller/HakInstaller.cs
Normal file
1696
trunk/tools/HakInstaller/HakInstaller.cs
Normal file
File diff suppressed because it is too large
Load Diff
22
trunk/tools/HakInstaller/HakInstaller.exe.manifest
Normal file
22
trunk/tools/HakInstaller/HakInstaller.exe.manifest
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<assemblyIdentity
|
||||
version="1.0.0.0"
|
||||
processorArchitecture="X86"
|
||||
name="MJS.HakInstaller.HakInstaller.exe"
|
||||
type="win32"
|
||||
/>
|
||||
<description>Your comment here</description>
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="X86"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
</assembly>
|
BIN
trunk/tools/HakInstaller/HakInstaller.ico
Normal file
BIN
trunk/tools/HakInstaller/HakInstaller.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
35
trunk/tools/HakInstaller/HakInstaller.sln
Normal file
35
trunk/tools/HakInstaller/HakInstaller.sln
Normal file
@@ -0,0 +1,35 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual Studio 2005
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HakInstallerForm", "HakInstallerForm.csproj", "{09E68C4C-1EAD-406F-9C8C-27B3D52F5BE9}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HakInstallerConsole", "HakInstallerConsole.csproj", "{C2B4588A-3CE9-4F86-BF3C-1D371C20D7A9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{09E68C4C-1EAD-406F-9C8C-27B3D52F5BE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{09E68C4C-1EAD-406F-9C8C-27B3D52F5BE9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{09E68C4C-1EAD-406F-9C8C-27B3D52F5BE9}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{09E68C4C-1EAD-406F-9C8C-27B3D52F5BE9}.Debug|x86.Build.0 = Debug|x86
|
||||
{09E68C4C-1EAD-406F-9C8C-27B3D52F5BE9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{09E68C4C-1EAD-406F-9C8C-27B3D52F5BE9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{09E68C4C-1EAD-406F-9C8C-27B3D52F5BE9}.Release|x86.ActiveCfg = Release|x86
|
||||
{09E68C4C-1EAD-406F-9C8C-27B3D52F5BE9}.Release|x86.Build.0 = Release|x86
|
||||
{C2B4588A-3CE9-4F86-BF3C-1D371C20D7A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C2B4588A-3CE9-4F86-BF3C-1D371C20D7A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C2B4588A-3CE9-4F86-BF3C-1D371C20D7A9}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{C2B4588A-3CE9-4F86-BF3C-1D371C20D7A9}.Debug|x86.Build.0 = Debug|x86
|
||||
{C2B4588A-3CE9-4F86-BF3C-1D371C20D7A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C2B4588A-3CE9-4F86-BF3C-1D371C20D7A9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C2B4588A-3CE9-4F86-BF3C-1D371C20D7A9}.Release|x86.ActiveCfg = Release|x86
|
||||
{C2B4588A-3CE9-4F86-BF3C-1D371C20D7A9}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
BIN
trunk/tools/HakInstaller/HakInstaller.suo
Normal file
BIN
trunk/tools/HakInstaller/HakInstaller.suo
Normal file
Binary file not shown.
159
trunk/tools/HakInstaller/HakInstallerConsole.csproj
Normal file
159
trunk/tools/HakInstaller/HakInstallerConsole.csproj
Normal file
@@ -0,0 +1,159 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>
|
||||
</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ProjectType>Local</ProjectType>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{C2B4588A-3CE9-4F86-BF3C-1D371C20D7A9}</ProjectGuid>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ApplicationIcon>HakInstaller.ico</ApplicationIcon>
|
||||
<AssemblyKeyContainerName>
|
||||
</AssemblyKeyContainerName>
|
||||
<AssemblyName>HakInstallerCmdLine</AssemblyName>
|
||||
<AssemblyOriginatorKeyFile>
|
||||
</AssemblyOriginatorKeyFile>
|
||||
<DefaultClientScript>JScript</DefaultClientScript>
|
||||
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
|
||||
<DefaultTargetSchema>IE50</DefaultTargetSchema>
|
||||
<DelaySign>false</DelaySign>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>HakInstaller</RootNamespace>
|
||||
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
|
||||
<StartupObject>
|
||||
</StartupObject>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<NoStdLib>false</NoStdLib>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<Optimize>false</Optimize>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<RemoveIntegerChecks>false</RemoveIntegerChecks>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DebugType>full</DebugType>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<OutputPath>Ship\</OutputPath>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<NoStdLib>false</NoStdLib>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<Optimize>true</Optimize>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<RemoveIntegerChecks>false</RemoveIntegerChecks>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DebugType>none</DebugType>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System">
|
||||
<Name>System</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Data">
|
||||
<Name>System.Data</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing">
|
||||
<Name>System.Drawing</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Windows.Forms">
|
||||
<Name>System.Windows.Forms</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml">
|
||||
<Name>System.XML</Name>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="2da.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="AssemblyInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ConflictResolver.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Erf.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Gff.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="HakInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="HakInstaller.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Key.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="MainConsole.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ModuleInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="NWNInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Tlk.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Utilities.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
64
trunk/tools/HakInstaller/HakInstallerConsole.csproj.user
Normal file
64
trunk/tools/HakInstaller/HakInstallerConsole.csproj.user
Normal file
@@ -0,0 +1,64 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<LastOpenVersion>7.10.3077</LastOpenVersion>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ReferencePath>
|
||||
</ReferencePath>
|
||||
<CopyProjectDestinationFolder>
|
||||
</CopyProjectDestinationFolder>
|
||||
<CopyProjectUncPath>
|
||||
</CopyProjectUncPath>
|
||||
<CopyProjectOption>0</CopyProjectOption>
|
||||
<ProjectView>ProjectFiles</ProjectView>
|
||||
<ProjectTrust>0</ProjectTrust>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<EnableASPDebugging>false</EnableASPDebugging>
|
||||
<EnableASPXDebugging>false</EnableASPXDebugging>
|
||||
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||
<EnableSQLServerDebugging>false</EnableSQLServerDebugging>
|
||||
<RemoteDebugEnabled>false</RemoteDebugEnabled>
|
||||
<RemoteDebugMachine>
|
||||
</RemoteDebugMachine>
|
||||
<StartAction>Project</StartAction>
|
||||
<StartArguments>foo.mod spellprcmerge.hif</StartArguments>
|
||||
<StartPage>
|
||||
</StartPage>
|
||||
<StartProgram>
|
||||
</StartProgram>
|
||||
<StartURL>
|
||||
</StartURL>
|
||||
<StartWorkingDirectory>
|
||||
</StartWorkingDirectory>
|
||||
<StartWithIE>true</StartWithIE>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<EnableASPDebugging>false</EnableASPDebugging>
|
||||
<EnableASPXDebugging>false</EnableASPXDebugging>
|
||||
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||
<EnableSQLServerDebugging>false</EnableSQLServerDebugging>
|
||||
<RemoteDebugEnabled>false</RemoteDebugEnabled>
|
||||
<RemoteDebugMachine>
|
||||
</RemoteDebugMachine>
|
||||
<StartAction>Project</StartAction>
|
||||
<StartArguments>
|
||||
</StartArguments>
|
||||
<StartPage>
|
||||
</StartPage>
|
||||
<StartProgram>
|
||||
</StartProgram>
|
||||
<StartURL>
|
||||
</StartURL>
|
||||
<StartWorkingDirectory>
|
||||
</StartWorkingDirectory>
|
||||
<StartWithIE>true</StartWithIE>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<StartArguments>foo.mod spellprcmerge.hif</StartArguments>
|
||||
<StartWithIE>true</StartWithIE>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<StartWithIE>true</StartWithIE>
|
||||
</PropertyGroup>
|
||||
</Project>
|
237
trunk/tools/HakInstaller/HakInstallerForm.csproj
Normal file
237
trunk/tools/HakInstaller/HakInstallerForm.csproj
Normal file
@@ -0,0 +1,237 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>
|
||||
</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ProjectType>Local</ProjectType>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{09E68C4C-1EAD-406F-9C8C-27B3D52F5BE9}</ProjectGuid>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ApplicationIcon>HakInstaller.ico</ApplicationIcon>
|
||||
<AssemblyKeyContainerName>
|
||||
</AssemblyKeyContainerName>
|
||||
<AssemblyName>HakInstaller</AssemblyName>
|
||||
<AssemblyOriginatorKeyFile>
|
||||
</AssemblyOriginatorKeyFile>
|
||||
<DefaultClientScript>JScript</DefaultClientScript>
|
||||
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
|
||||
<DefaultTargetSchema>IE50</DefaultTargetSchema>
|
||||
<DelaySign>false</DelaySign>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>HakInstaller</RootNamespace>
|
||||
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
|
||||
<StartupObject>
|
||||
</StartupObject>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<NoStdLib>false</NoStdLib>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<Optimize>false</Optimize>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<RemoveIntegerChecks>false</RemoveIntegerChecks>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DebugType>full</DebugType>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<OutputPath>Ship\</OutputPath>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<NoStdLib>false</NoStdLib>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<Optimize>true</Optimize>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<RemoveIntegerChecks>false</RemoveIntegerChecks>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DebugType>none</DebugType>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System">
|
||||
<Name>System</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Data">
|
||||
<Name>System.Data</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing">
|
||||
<Name>System.Drawing</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Windows.Forms">
|
||||
<Name>System.Windows.Forms</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml">
|
||||
<Name>System.XML</Name>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="2da.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="AboutForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="AssemblyInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ConflictResolver.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Erf.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Gff.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="GffForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="HakInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="HakInstaller.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="HifConflictsForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="InstallForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="InstallFormBase.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="InstallProgressForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Key.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="MainForm.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ModuleInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="NWNInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="OverwriteWarningsForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ReplacingFilesForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="SingleHIFInstallForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="SystemMenu.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Tlk.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Utilities.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="AboutForm.resx">
|
||||
<DependentUpon>AboutForm.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="GffForm.resx">
|
||||
<DependentUpon>GffForm.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="HakInstaller.ico" />
|
||||
<EmbeddedResource Include="HifConflictsForm.resx">
|
||||
<DependentUpon>HifConflictsForm.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="InstallForm.resx">
|
||||
<DependentUpon>InstallForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="InstallFormBase.resx">
|
||||
<DependentUpon>InstallFormBase.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="InstallProgressForm.resx">
|
||||
<DependentUpon>InstallProgressForm.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="OverwriteWarningsForm.resx">
|
||||
<DependentUpon>OverwriteWarningsForm.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="ReplacingFilesForm.resx">
|
||||
<DependentUpon>ReplacingFilesForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="SingleHIFInstallForm.resx">
|
||||
<DependentUpon>SingleHIFInstallForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="strings.resx">
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Content Include="HakInstaller.exe.manifest" />
|
||||
<Content Include="strings.xsd" />
|
||||
<None Include="app.config" />
|
||||
<None Include="spellPak.hif" />
|
||||
<None Include="spellPRCMerge.hif" />
|
||||
<None Include="strings.xsx">
|
||||
<DependentUpon>strings.xsd</DependentUpon>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
76
trunk/tools/HakInstaller/HakInstallerForm.csproj.user
Normal file
76
trunk/tools/HakInstaller/HakInstallerForm.csproj.user
Normal file
@@ -0,0 +1,76 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<LastOpenVersion>7.10.3077</LastOpenVersion>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ReferencePath>
|
||||
</ReferencePath>
|
||||
<CopyProjectDestinationFolder>
|
||||
</CopyProjectDestinationFolder>
|
||||
<CopyProjectUncPath>
|
||||
</CopyProjectUncPath>
|
||||
<CopyProjectOption>0</CopyProjectOption>
|
||||
<ProjectView>ProjectFiles</ProjectView>
|
||||
<ProjectTrust>0</ProjectTrust>
|
||||
<PublishUrlHistory>publish\</PublishUrlHistory>
|
||||
<InstallUrlHistory>
|
||||
</InstallUrlHistory>
|
||||
<SupportUrlHistory>
|
||||
</SupportUrlHistory>
|
||||
<UpdateUrlHistory>
|
||||
</UpdateUrlHistory>
|
||||
<BootstrapperUrlHistory>
|
||||
</BootstrapperUrlHistory>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<FallbackCulture>en-US</FallbackCulture>
|
||||
<VerifyUploadedFiles>false</VerifyUploadedFiles>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<EnableASPDebugging>false</EnableASPDebugging>
|
||||
<EnableASPXDebugging>false</EnableASPXDebugging>
|
||||
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||
<EnableSQLServerDebugging>false</EnableSQLServerDebugging>
|
||||
<RemoteDebugEnabled>false</RemoteDebugEnabled>
|
||||
<RemoteDebugMachine>
|
||||
</RemoteDebugMachine>
|
||||
<StartAction>Project</StartAction>
|
||||
<StartArguments>-L1</StartArguments>
|
||||
<StartPage>
|
||||
</StartPage>
|
||||
<StartProgram>
|
||||
</StartProgram>
|
||||
<StartURL>
|
||||
</StartURL>
|
||||
<StartWorkingDirectory>
|
||||
</StartWorkingDirectory>
|
||||
<StartWithIE>true</StartWithIE>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<EnableASPDebugging>false</EnableASPDebugging>
|
||||
<EnableASPXDebugging>false</EnableASPXDebugging>
|
||||
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||
<EnableSQLServerDebugging>false</EnableSQLServerDebugging>
|
||||
<RemoteDebugEnabled>false</RemoteDebugEnabled>
|
||||
<RemoteDebugMachine>
|
||||
</RemoteDebugMachine>
|
||||
<StartAction>Project</StartAction>
|
||||
<StartArguments>"PRC Pack.hif"</StartArguments>
|
||||
<StartPage>
|
||||
</StartPage>
|
||||
<StartProgram>
|
||||
</StartProgram>
|
||||
<StartURL>
|
||||
</StartURL>
|
||||
<StartWorkingDirectory>
|
||||
</StartWorkingDirectory>
|
||||
<StartWithIE>true</StartWithIE>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<StartArguments>-L1</StartArguments>
|
||||
<StartWithIE>true</StartWithIE>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<StartArguments>"PRC Pack.hif"</StartArguments>
|
||||
<StartWithIE>true</StartWithIE>
|
||||
</PropertyGroup>
|
||||
</Project>
|
207
trunk/tools/HakInstaller/HifConflictsForm.cs
Normal file
207
trunk/tools/HakInstaller/HifConflictsForm.cs
Normal file
@@ -0,0 +1,207 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using HakInstaller;
|
||||
using HakInstaller.Utilities;
|
||||
|
||||
namespace HakInstaller
|
||||
{
|
||||
/// <summary>
|
||||
/// This form displays is a comfirmation box asking the user if the
|
||||
/// application should continue with replacing the listed files with
|
||||
/// files from added hak(s).
|
||||
/// </summary>
|
||||
public class HifConflictsForm : System.Windows.Forms.Form
|
||||
{
|
||||
#region public properties/methods
|
||||
/// <summary>
|
||||
/// Class constructor
|
||||
/// </summary>
|
||||
/// <param name="conflicts">The list of file conflicts.</param>
|
||||
public HifConflictsForm(HifConflictCollection conflicts)
|
||||
{
|
||||
//
|
||||
// Required for Windows Form Designer support
|
||||
//
|
||||
InitializeComponent();
|
||||
|
||||
pictureBox.Image = SystemIcons.Exclamation.ToBitmap();
|
||||
|
||||
// There appears to be a bug in the 1.0 version of the framework. On my
|
||||
// 3.2ghz machine, if listBox.Items.Add(conflict) is placed in the
|
||||
// foreach array it hangs, unless you slow it down somehow. Moving
|
||||
// the add outside the loop and changing it to an AddRange() to add all
|
||||
// of the conflicts in one shot makes it work correctly, thus the change
|
||||
// to the code.
|
||||
|
||||
// Add all of the conflicts to the list box.
|
||||
HifConflict[] conflictArray = new HifConflict[conflicts.Count];
|
||||
for (int i = 0; i < conflicts.Count; i++)
|
||||
conflictArray[i] = conflicts[i];
|
||||
listBox.Items.AddRange(conflictArray);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region protected fields/properties/methods
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
protected override void Dispose( bool disposing )
|
||||
{
|
||||
if( disposing )
|
||||
{
|
||||
if(components != null)
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose( disposing );
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region functionality for Win32 PlaySound API
|
||||
[Flags] private enum SoundFlags
|
||||
{
|
||||
Sync = 0x00000000, /* play synchronously (default) */
|
||||
Async = 0x00000001, /* play asynchronously */
|
||||
NoDefault = 0x00000002, /* silence (!default) if sound not found */
|
||||
Memory = 0x00000004, /* pszSound points to a memory file */
|
||||
Loop = 0x00000008, /* loop the sound until next sndPlaySound */
|
||||
NoStop = 0x00000010, /* don't stop any currently playing sound */
|
||||
NoWait = 0x00002000, /* don't wait if the driver is busy */
|
||||
Alias = 0x00010000, /* name is a registry alias */
|
||||
AliasId = 0x00110000, /* alias is a pre d ID */
|
||||
Filename = 0x00020000, /* name is file name */
|
||||
Resource = 0x00040004, /* name is resource name or atom */
|
||||
Purge = 0x00000040, /* purge non-static events for task */
|
||||
Application = 0x00000080 /* look for application specific association */
|
||||
}
|
||||
|
||||
public static void PlaySoundEvent(string sound)
|
||||
{
|
||||
PlaySound(sound, 0,
|
||||
(int) (SoundFlags.Async | SoundFlags.Alias | SoundFlags.NoWait));
|
||||
}
|
||||
|
||||
[DllImport("winmm.dll", EntryPoint="PlaySound",CharSet=CharSet.Auto)]
|
||||
private static extern int PlaySound(String pszSound, int hmod, int flags);
|
||||
#endregion
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Button buttonContinue;
|
||||
private System.Windows.Forms.Button button2;
|
||||
private System.Windows.Forms.PictureBox pictureBox;
|
||||
private System.Windows.Forms.ListBox listBox;
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.Container components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.buttonContinue = new System.Windows.Forms.Button();
|
||||
this.button2 = new System.Windows.Forms.Button();
|
||||
this.pictureBox = new System.Windows.Forms.PictureBox();
|
||||
this.listBox = new System.Windows.Forms.ListBox();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.Location = new System.Drawing.Point(72, 16);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(240, 56);
|
||||
this.label1.TabIndex = 0;
|
||||
this.label1.Text = "Some modules already have some of the content you selected installed. Do you wis" +
|
||||
"h to continue? The install may not work if you continue.";
|
||||
//
|
||||
// buttonContinue
|
||||
//
|
||||
this.buttonContinue.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.buttonContinue.DialogResult = System.Windows.Forms.DialogResult.OK;
|
||||
this.buttonContinue.FlatStyle = System.Windows.Forms.FlatStyle.System;
|
||||
this.buttonContinue.Location = new System.Drawing.Point(16, 158);
|
||||
this.buttonContinue.Name = "buttonContinue";
|
||||
this.buttonContinue.Size = new System.Drawing.Size(80, 24);
|
||||
this.buttonContinue.TabIndex = 2;
|
||||
this.buttonContinue.Text = "C&ontinue";
|
||||
//
|
||||
// button2
|
||||
//
|
||||
this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.button2.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.button2.FlatStyle = System.Windows.Forms.FlatStyle.System;
|
||||
this.button2.Location = new System.Drawing.Point(112, 158);
|
||||
this.button2.Name = "button2";
|
||||
this.button2.Size = new System.Drawing.Size(80, 24);
|
||||
this.button2.TabIndex = 3;
|
||||
this.button2.Text = "&Cancel";
|
||||
//
|
||||
// pictureBox
|
||||
//
|
||||
this.pictureBox.Location = new System.Drawing.Point(24, 16);
|
||||
this.pictureBox.Name = "pictureBox";
|
||||
this.pictureBox.Size = new System.Drawing.Size(32, 32);
|
||||
this.pictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
|
||||
this.pictureBox.TabIndex = 3;
|
||||
this.pictureBox.TabStop = false;
|
||||
//
|
||||
// listBox
|
||||
//
|
||||
this.listBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.listBox.HorizontalScrollbar = true;
|
||||
this.listBox.IntegralHeight = false;
|
||||
this.listBox.Location = new System.Drawing.Point(16, 80);
|
||||
this.listBox.Name = "listBox";
|
||||
this.listBox.Size = new System.Drawing.Size(296, 70);
|
||||
this.listBox.TabIndex = 1;
|
||||
//
|
||||
// HifConflictsForm
|
||||
//
|
||||
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
|
||||
this.ClientSize = new System.Drawing.Size(328, 198);
|
||||
this.ControlBox = false;
|
||||
this.Controls.Add(this.listBox);
|
||||
this.Controls.Add(this.pictureBox);
|
||||
this.Controls.Add(this.buttonContinue);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.button2);
|
||||
this.MinimumSize = new System.Drawing.Size(336, 232);
|
||||
this.Name = "HifConflictsForm";
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Overwriting Existing Content";
|
||||
this.Load += new System.EventHandler(this.ReplacingFilesForm_Load);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region form event handlers
|
||||
/// <summary>
|
||||
/// Handler for the load event.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void ReplacingFilesForm_Load(object sender, System.EventArgs e)
|
||||
{
|
||||
PlaySoundEvent("SystemExclamation");
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region control event handlers
|
||||
#endregion
|
||||
}
|
||||
}
|
175
trunk/tools/HakInstaller/HifConflictsForm.resx
Normal file
175
trunk/tools/HakInstaller/HifConflictsForm.resx
Normal file
@@ -0,0 +1,175 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
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">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</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 forserialized 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.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:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<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" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</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>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="label1.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="label1.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="label1.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="buttonContinue.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="buttonContinue.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="buttonContinue.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="button2.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="button2.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="button2.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="pictureBox.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="pictureBox.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="pictureBox.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="listBox.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="listBox.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="listBox.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="$this.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Language" type="System.Globalization.CultureInfo, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>(Default)</value>
|
||||
</data>
|
||||
<data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Localizable" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>8, 8</value>
|
||||
</data>
|
||||
<data name="$this.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.TrayHeight" type="System.Int32, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>80</value>
|
||||
</data>
|
||||
<data name="$this.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="$this.Name">
|
||||
<value>HifConflictsForm</value>
|
||||
</data>
|
||||
</root>
|
305
trunk/tools/HakInstaller/InstallForm.cs
Normal file
305
trunk/tools/HakInstaller/InstallForm.cs
Normal file
@@ -0,0 +1,305 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using HakInstaller.Utilities;
|
||||
using NWN;
|
||||
|
||||
namespace HakInstaller
|
||||
{
|
||||
/// <summary>
|
||||
/// This is the main form of the HakInstaller application.
|
||||
/// </summary>
|
||||
public class InstallForm : InstallFormBase
|
||||
{
|
||||
#region public methods/properties.
|
||||
/// <summary>
|
||||
/// Class constructor
|
||||
/// </summary>
|
||||
public InstallForm()
|
||||
{
|
||||
//
|
||||
// Required for Windows Form Designer support
|
||||
//
|
||||
InitializeComponent();
|
||||
|
||||
// Add the major/minor version number to the caption, full version
|
||||
// number is available in the about box.
|
||||
Version version = Assembly.GetExecutingAssembly().GetName().Version;
|
||||
string versionText = string.Format("{0}.{1}", version.Major, version.Minor);
|
||||
Text = string.Format(Text, versionText);
|
||||
|
||||
SetLabels(labelVersion, labelPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
protected override void Dispose( bool disposing )
|
||||
{
|
||||
if( disposing )
|
||||
{
|
||||
if (components != null)
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose( disposing );
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
private System.Windows.Forms.Label labelVersion;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Button buttonInstall;
|
||||
private System.Windows.Forms.Button buttonCancel;
|
||||
private System.Windows.Forms.CheckedListBox checkedHaks;
|
||||
private System.Windows.Forms.CheckedListBox checkedModules;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.Label labelPath;
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.Container components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(InstallForm));
|
||||
this.labelVersion = new System.Windows.Forms.Label();
|
||||
this.checkedHaks = new System.Windows.Forms.CheckedListBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.buttonInstall = new System.Windows.Forms.Button();
|
||||
this.buttonCancel = new System.Windows.Forms.Button();
|
||||
this.checkedModules = new System.Windows.Forms.CheckedListBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.labelPath = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// labelVersion
|
||||
//
|
||||
this.labelVersion.Location = new System.Drawing.Point(24, 8);
|
||||
this.labelVersion.Name = "labelVersion";
|
||||
this.labelVersion.Size = new System.Drawing.Size(240, 16);
|
||||
this.labelVersion.TabIndex = 0;
|
||||
//
|
||||
// checkedHaks
|
||||
//
|
||||
this.checkedHaks.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.checkedHaks.CheckOnClick = true;
|
||||
this.checkedHaks.Location = new System.Drawing.Point(24, 96);
|
||||
this.checkedHaks.Name = "checkedHaks";
|
||||
this.checkedHaks.Size = new System.Drawing.Size(248, 169);
|
||||
this.checkedHaks.Sorted = true;
|
||||
this.checkedHaks.TabIndex = 3;
|
||||
this.checkedHaks.ThreeDCheckBoxes = true;
|
||||
this.checkedHaks.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.checkedHaks_ItemCheck);
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.Location = new System.Drawing.Point(24, 72);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(248, 16);
|
||||
this.label1.TabIndex = 2;
|
||||
this.label1.Text = "Select the con&tent you would like to install:";
|
||||
//
|
||||
// buttonInstall
|
||||
//
|
||||
this.buttonInstall.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.buttonInstall.Enabled = false;
|
||||
this.buttonInstall.FlatStyle = System.Windows.Forms.FlatStyle.System;
|
||||
this.buttonInstall.Location = new System.Drawing.Point(24, 280);
|
||||
this.buttonInstall.Name = "buttonInstall";
|
||||
this.buttonInstall.Size = new System.Drawing.Size(72, 24);
|
||||
this.buttonInstall.TabIndex = 6;
|
||||
this.buttonInstall.Text = "&Install";
|
||||
this.buttonInstall.Click += new System.EventHandler(this.buttonInstall_Click);
|
||||
//
|
||||
// buttonCancel
|
||||
//
|
||||
this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.buttonCancel.FlatStyle = System.Windows.Forms.FlatStyle.System;
|
||||
this.buttonCancel.Location = new System.Drawing.Point(112, 280);
|
||||
this.buttonCancel.Name = "buttonCancel";
|
||||
this.buttonCancel.Size = new System.Drawing.Size(72, 24);
|
||||
this.buttonCancel.TabIndex = 7;
|
||||
this.buttonCancel.Text = "&Close";
|
||||
this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click);
|
||||
//
|
||||
// checkedModules
|
||||
//
|
||||
this.checkedModules.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.checkedModules.CheckOnClick = true;
|
||||
this.checkedModules.Location = new System.Drawing.Point(288, 96);
|
||||
this.checkedModules.Name = "checkedModules";
|
||||
this.checkedModules.Size = new System.Drawing.Size(248, 169);
|
||||
this.checkedModules.Sorted = true;
|
||||
this.checkedModules.TabIndex = 5;
|
||||
this.checkedModules.ThreeDCheckBoxes = true;
|
||||
this.checkedModules.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.checkedModules_ItemCheck);
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.Location = new System.Drawing.Point(288, 72);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(248, 16);
|
||||
this.label2.TabIndex = 4;
|
||||
this.label2.Text = "Select the &modules you want the haks installed in:";
|
||||
//
|
||||
// labelPath
|
||||
//
|
||||
this.labelPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.labelPath.Location = new System.Drawing.Point(24, 32);
|
||||
this.labelPath.Name = "labelPath";
|
||||
this.labelPath.Size = new System.Drawing.Size(504, 16);
|
||||
this.labelPath.TabIndex = 1;
|
||||
//
|
||||
// InstallForm
|
||||
//
|
||||
this.AcceptButton = this.buttonInstall;
|
||||
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
|
||||
this.CancelButton = this.buttonCancel;
|
||||
this.ClientSize = new System.Drawing.Size(560, 310);
|
||||
this.Controls.Add(this.labelPath);
|
||||
this.Controls.Add(this.label2);
|
||||
this.Controls.Add(this.checkedModules);
|
||||
this.Controls.Add(this.buttonInstall);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.checkedHaks);
|
||||
this.Controls.Add(this.labelVersion);
|
||||
this.Controls.Add(this.buttonCancel);
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.MinimumSize = new System.Drawing.Size(568, 328);
|
||||
this.Name = "InstallForm";
|
||||
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "NWN Content Installer {0}";
|
||||
this.Load += new System.EventHandler(this.InstallForm_Load);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region form event handlers
|
||||
/// <summary>
|
||||
/// The form's load event handler. Fills in the contents of the form and sets
|
||||
/// it up.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void InstallForm_Load(object sender, System.EventArgs e)
|
||||
{
|
||||
// Fill in the check list boxes.
|
||||
LoadHakInfoList(checkedHaks);
|
||||
LoadModuleList(checkedModules);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region control event handlers
|
||||
/// <summary>
|
||||
/// Event handler for the ItemCheck event on the modules check list box.
|
||||
/// It enables/disables the install button depending on whether at least
|
||||
/// one module and hak have been selected.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void checkedModules_ItemCheck(object sender, System.Windows.Forms.ItemCheckEventArgs e)
|
||||
{
|
||||
// The install button should be enabled if at least one module and hak
|
||||
// has been selectted. Note that this event is fired BEFORE the checked
|
||||
// state of the item changes so we have to check the event args for
|
||||
// it's new state.
|
||||
int adjustment = CheckState.Checked == e.NewValue ? 1 : -1;
|
||||
bool fModuleChecked = checkedModules.CheckedItems.Count + adjustment > 0;
|
||||
bool fHakChecked = checkedHaks.CheckedItems.Count > 0;
|
||||
|
||||
buttonInstall.Enabled = fModuleChecked && fHakChecked;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event handler for the ItemCheck event on the haks check list box.
|
||||
/// It enables/disables the install button depending on whether at least
|
||||
/// one module and hak have been selected.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void checkedHaks_ItemCheck(object sender, System.Windows.Forms.ItemCheckEventArgs e)
|
||||
{
|
||||
// We only support checking 1 hak, so uncheck the previously checked hak if we
|
||||
// are checking a hak.
|
||||
if (CheckState.Checked == e.NewValue && checkedHaks.CheckedIndices.Count > 0)
|
||||
checkedHaks.SetItemChecked(checkedHaks.CheckedIndices[0], false);
|
||||
|
||||
// The install button should be enabled if at least one module and hak
|
||||
// has been selectted. Note that this event is fired BEFORE the checked
|
||||
// state of the item changes so we have to check the event args for
|
||||
// it's new state.
|
||||
int adjustment = CheckState.Checked == e.NewValue ? 1 : -1;
|
||||
bool fModuleChecked = checkedModules.CheckedItems.Count > 0;
|
||||
bool fHakChecked = checkedHaks.CheckedItems.Count + adjustment > 0;
|
||||
|
||||
buttonInstall.Enabled = fModuleChecked && fHakChecked;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for the install button click event. It installs the selected
|
||||
/// haks in the selected modules.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void buttonInstall_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
// Build an array of the checked hif files.
|
||||
HakInfo[] hifs = new HakInfo[checkedHaks.CheckedItems.Count];
|
||||
for (int i = 0; i < checkedHaks.CheckedIndices.Count; i++)
|
||||
hifs[i] = (HakInfo) checkedHaks.CheckedItems[i];
|
||||
|
||||
// Count the total number of .mod/.nwm files selected.
|
||||
int numModules = 0;
|
||||
foreach (Module module in checkedModules.CheckedItems)
|
||||
numModules += module.Modules.Length;
|
||||
|
||||
// Create the modules list and fill it in.
|
||||
string[] modules = new string[numModules];
|
||||
numModules = 0;
|
||||
foreach (Module module in checkedModules.CheckedItems)
|
||||
{
|
||||
module.Modules.CopyTo(modules, numModules);
|
||||
numModules += module.Modules.Length;
|
||||
}
|
||||
|
||||
PerformInstall(hifs, modules);
|
||||
|
||||
// Clear the checked state of all modules.
|
||||
CheckedListBox.CheckedIndexCollection checkedIndeces =
|
||||
checkedModules.CheckedIndices;
|
||||
foreach (int index in checkedIndeces)
|
||||
checkedModules.SetItemChecked(index, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancel button click event, it closes the application.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void buttonCancel_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
Application.Exit();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
267
trunk/tools/HakInstaller/InstallForm.resx
Normal file
267
trunk/tools/HakInstaller/InstallForm.resx
Normal file
@@ -0,0 +1,267 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
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">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</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 forserialized 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.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:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<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" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</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>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="labelVersion.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="labelVersion.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="labelVersion.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="checkedHaks.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="checkedHaks.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="checkedHaks.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="label1.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="label1.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="label1.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="buttonInstall.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="buttonInstall.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="buttonInstall.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="buttonCancel.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="buttonCancel.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="buttonCancel.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="checkedModules.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="checkedModules.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="checkedModules.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="label2.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="label2.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="label2.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="labelPath.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="labelPath.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="labelPath.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="$this.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Language" type="System.Globalization.CultureInfo, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>(Default)</value>
|
||||
</data>
|
||||
<data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Localizable" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>8, 8</value>
|
||||
</data>
|
||||
<data name="$this.Name">
|
||||
<value>InstallForm</value>
|
||||
</data>
|
||||
<data name="$this.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.TrayHeight" type="System.Int32, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>80</value>
|
||||
</data>
|
||||
<data name="$this.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAIAICAAAAAAAACoCAAAJgAAABAQAAAAAAAAaAUAAM4IAAAoAAAAIAAAAEAAAAABAAgAAAAAAAAE
|
||||
AAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwADA3MAA8MqmAAQE
|
||||
BAAICAgADAwMABEREQAWFhYAHBwcACIiIgApKSkAVVVVAE1NTQBCQkIAOTk5AIB8/wBQUP8AkwDWAP/s
|
||||
zADG1u8A1ufnAJCprQAAADMAAABmAAAAmQAAAMwAADMAAAAzMwAAM2YAADOZAAAzzAAAM/8AAGYAAABm
|
||||
MwAAZmYAAGaZAABmzAAAZv8AAJkAAACZMwAAmWYAAJmZAACZzAAAmf8AAMwAAADMMwAAzGYAAMyZAADM
|
||||
zAAAzP8AAP9mAAD/mQAA/8wAMwAAADMAMwAzAGYAMwCZADMAzAAzAP8AMzMAADMzMwAzM2YAMzOZADMz
|
||||
zAAzM/8AM2YAADNmMwAzZmYAM2aZADNmzAAzZv8AM5kAADOZMwAzmWYAM5mZADOZzAAzmf8AM8wAADPM
|
||||
MwAzzGYAM8yZADPMzAAzzP8AM/8zADP/ZgAz/5kAM//MADP//wBmAAAAZgAzAGYAZgBmAJkAZgDMAGYA
|
||||
/wBmMwAAZjMzAGYzZgBmM5kAZjPMAGYz/wBmZgAAZmYzAGZmZgBmZpkAZmbMAGaZAABmmTMAZplmAGaZ
|
||||
mQBmmcwAZpn/AGbMAABmzDMAZsyZAGbMzABmzP8AZv8AAGb/MwBm/5kAZv/MAMwA/wD/AMwAmZkAAJkz
|
||||
mQCZAJkAmQDMAJkAAACZMzMAmQBmAJkzzACZAP8AmWYAAJlmMwCZM2YAmWaZAJlmzACZM/8AmZkzAJmZ
|
||||
ZgCZmZkAmZnMAJmZ/wCZzAAAmcwzAGbMZgCZzJkAmczMAJnM/wCZ/wAAmf8zAJnMZgCZ/5kAmf/MAJn/
|
||||
/wDMAAAAmQAzAMwAZgDMAJkAzADMAJkzAADMMzMAzDNmAMwzmQDMM8wAzDP/AMxmAADMZjMAmWZmAMxm
|
||||
mQDMZswAmWb/AMyZAADMmTMAzJlmAMyZmQDMmcwAzJn/AMzMAADMzDMAzMxmAMzMmQDMzMwAzMz/AMz/
|
||||
AADM/zMAmf9mAMz/mQDM/8wAzP//AMwAMwD/AGYA/wCZAMwzAAD/MzMA/zNmAP8zmQD/M8wA/zP/AP9m
|
||||
AAD/ZjMAzGZmAP9mmQD/ZswAzGb/AP+ZAAD/mTMA/5lmAP+ZmQD/mcwA/5n/AP/MAAD/zDMA/8xmAP/M
|
||||
mQD/zMwA/8z/AP//MwDM/2YA//+ZAP//zABmZv8AZv9mAGb//wD/ZmYA/2b/AP//ZgAhAKUAX19fAHd3
|
||||
dwCGhoYAlpaWAMvLywCysrIA19fXAN3d3QDj4+MA6urqAPHx8QD4+PgA8Pv/AKSgoACAgIAAAAD/AAD/
|
||||
AAAA//8A/wAAAP8A/wD//wAA////AAAAAADdvLUHtfcH97WYtfe197v3u7W1u/e7B93dAAAAAADdu93C
|
||||
3eLi4uLd4t3d4t3i3eLcwuLi3eLdvLvdAAAAvLu84uLi3eLd3Ny73Lvc3bvcu93d3cLi4uLi3bu8AAC7
|
||||
u9zC3eLivLu7tbS7tdy73LW7tdy73d3ivOLdu7UAtbrc4uLi3bu1tbW7tbW7u9a8tbW73LXcvN3i3eG7
|
||||
uge0u7vd4ty73eL///+83LXdwuLi3bu1u7vcu93cwty1tLS73OLivP//4uL/3Ny73eLd3dzC3eK71rvc
|
||||
vNzdu7q0rrrc4t3//7vc3Lvd4uK8/93iu9zc4t3Cu7W73Lu71ZGR3Lvi///d3N273eK83eLd////3dy8
|
||||
3N3d4t21u7W6kbS03OL//9273OLi3dzi/////////93C3Lvcu+K1u7TPkbTc////3dzi3dy7/////927
|
||||
3P//////4rzc3bS1upGu27vd///ivNy73eLi/+Ldu9273OL////////dtbrVrrS0u9z////du9283Lzd
|
||||
4v/d3Ny73N3d////4rzcurS0rrTbu93////i3eLd3P///9y73LXc3Lvc4rW71bvVtJGR1bXbtdzd////
|
||||
/+K1////u92727W73dzdtbrWurvVrs+0uta63Lvd/////9z////d3Na71tvcu9y0tdy11bSRkbTVu9a6
|
||||
1rvctdy7u93//7vcu7vdu7vdtbW61rS61ZHPtLrVu9a73eL//93/4v//3Lzc3dy73N261bW63LS0rpG0
|
||||
1bW61tu84v////////+73d3ivN3cvLS1uta0tbS0rtW0uta6td3i/////////7vcwt7i3bvctbS03LTV
|
||||
tK6utLS03LTcvN3//////93c/////+LdvNy1tNy1urS0kbO0tNW61rrd4v///9284v//////////3LS1
|
||||
utW0tNWurrS0tLS0tN3i//+73P///////////7S127Xbtbq0s66us7S0tLS03eLdu////////////7u0
|
||||
u9W1urXVtLS0rq6zz7S0tLS7td3//////////920tNW0tNu01bS0tLOui7SztLO0tOL///////////+0
|
||||
tLS0tLq0tLS0tLSzz4uurbOttLS03f/////////ctLS0tLS01bS0tLS0rbOtka6zs7S0tLS14v/////d
|
||||
u7S1tNy0tbS1tLS0tLS0rYvP1Yu0tbvcu9y83LzcvNy73bvcB9y73bvcB9y7u9y0i7UA1a7c3d3C3bzi
|
||||
3cLdwt3ivOLdwt3C3eK84t3dtK7PAAAA1a67u93d4t3d3d3i3d3d4t3d3eLd3eLdtZHPzwAAAAAA1a6u
|
||||
i4yui66uroaurq6Grq6uhq6uhq7Pz7UAAADwAAAHwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAHAAAAD4AAABygAAAAQAAAAIAAAAAEACAAAAAAAAAEAAAAA
|
||||
AAAAAAAAAAEAAAABAAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAwMDAAMDcwADwyqYABAQEAAgI
|
||||
CAAMDAwAERERABYWFgAcHBwAIiIiACkpKQBVVVUATU1NAEJCQgA5OTkAgHz/AFBQ/wCTANYA/+zMAMbW
|
||||
7wDW5+cAkKmtAAAAMwAAAGYAAACZAAAAzAAAMwAAADMzAAAzZgAAM5kAADPMAAAz/wAAZgAAAGYzAABm
|
||||
ZgAAZpkAAGbMAABm/wAAmQAAAJkzAACZZgAAmZkAAJnMAACZ/wAAzAAAAMwzAADMZgAAzJkAAMzMAADM
|
||||
/wAA/2YAAP+ZAAD/zAAzAAAAMwAzADMAZgAzAJkAMwDMADMA/wAzMwAAMzMzADMzZgAzM5kAMzPMADMz
|
||||
/wAzZgAAM2YzADNmZgAzZpkAM2bMADNm/wAzmQAAM5kzADOZZgAzmZkAM5nMADOZ/wAzzAAAM8wzADPM
|
||||
ZgAzzJkAM8zMADPM/wAz/zMAM/9mADP/mQAz/8wAM///AGYAAABmADMAZgBmAGYAmQBmAMwAZgD/AGYz
|
||||
AABmMzMAZjNmAGYzmQBmM8wAZjP/AGZmAABmZjMAZmZmAGZmmQBmZswAZpkAAGaZMwBmmWYAZpmZAGaZ
|
||||
zABmmf8AZswAAGbMMwBmzJkAZszMAGbM/wBm/wAAZv8zAGb/mQBm/8wAzAD/AP8AzACZmQAAmTOZAJkA
|
||||
mQCZAMwAmQAAAJkzMwCZAGYAmTPMAJkA/wCZZgAAmWYzAJkzZgCZZpkAmWbMAJkz/wCZmTMAmZlmAJmZ
|
||||
mQCZmcwAmZn/AJnMAACZzDMAZsxmAJnMmQCZzMwAmcz/AJn/AACZ/zMAmcxmAJn/mQCZ/8wAmf//AMwA
|
||||
AACZADMAzABmAMwAmQDMAMwAmTMAAMwzMwDMM2YAzDOZAMwzzADMM/8AzGYAAMxmMwCZZmYAzGaZAMxm
|
||||
zACZZv8AzJkAAMyZMwDMmWYAzJmZAMyZzADMmf8AzMwAAMzMMwDMzGYAzMyZAMzMzADMzP8AzP8AAMz/
|
||||
MwCZ/2YAzP+ZAMz/zADM//8AzAAzAP8AZgD/AJkAzDMAAP8zMwD/M2YA/zOZAP8zzAD/M/8A/2YAAP9m
|
||||
MwDMZmYA/2aZAP9mzADMZv8A/5kAAP+ZMwD/mWYA/5mZAP+ZzAD/mf8A/8wAAP/MMwD/zGYA/8yZAP/M
|
||||
zAD/zP8A//8zAMz/ZgD//5kA///MAGZm/wBm/2YAZv//AP9mZgD/Zv8A//9mACEApQBfX18Ad3d3AIaG
|
||||
hgCWlpYAy8vLALKysgDX19cA3d3dAOPj4wDq6uoA8fHxAPj4+ADw+/8ApKCgAICAgAAAAP8AAP8AAAD/
|
||||
/wD/AAAA/wD/AP//AAD///8AAPfs9+z37Pfs9+z37PfsAOyFX4Vf7OyFX7KBsrqyuuxfhV8H7OxfhV+B
|
||||
soGyurKFhV//7IVfhV+FX2uygbK6X1/s/1+FX+yFX+zsa7KBsl+F7P8HXwfsX+zsX+xrsoFfX4UH/wcH
|
||||
7IoH7F+F7GuyX4Wmhez//wdfB+yFX1/shV9fiqaKX4pfigfsX4WF7KaFhaaKpuwHBwf/7F+FX+yKX1+K
|
||||
pors////BwdfhV/spoWFpoqm7P+8Bwf//wcH7IVfX4qmiuwHB7z///8HpoqmX4WmiqbsvP/////spoqm
|
||||
iqbss7Sz/////we0s7SztLPsAOz37Pfs9+z37Pfs9+z3AIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAAA=
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
351
trunk/tools/HakInstaller/InstallFormBase.cs
Normal file
351
trunk/tools/HakInstaller/InstallFormBase.cs
Normal file
@@ -0,0 +1,351 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using HakInstaller.Utilities;
|
||||
using NWN;
|
||||
|
||||
namespace HakInstaller
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for InstallFormBase.
|
||||
/// </summary>
|
||||
public class InstallFormBase: Form
|
||||
{
|
||||
#region public properties/methods
|
||||
/// <summary>
|
||||
/// Default constructur
|
||||
/// </summary>
|
||||
public InstallFormBase()
|
||||
{
|
||||
// Wire up event handlers
|
||||
Load += new EventHandler(InstallFormBase_Load);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region protected fields/properties/methods
|
||||
/// <summary>
|
||||
/// Sets the proper values for the string labels.
|
||||
/// </summary>
|
||||
/// <param name="labelVersion">The version string</param>
|
||||
/// <param name="labelPath">The path string</param>
|
||||
protected void SetLabels(Label labelVersion, Label labelPath)
|
||||
{
|
||||
// Load strings for XP1 and XP2 installed if they are otherwise use
|
||||
// nothing.
|
||||
string xp1 = NWNInfo.IsXP1Installed ?
|
||||
StringResources.GetString("VersionFormatXP1") : string.Empty;
|
||||
string xp2 = NWNInfo.IsXP1Installed ?
|
||||
StringResources.GetString("VersionFormatXP2") : string.Empty;
|
||||
|
||||
labelVersion.Text = StringResources.GetString("VersionFormat", NWNInfo.Version, xp1, xp2);
|
||||
labelPath.Text = StringResources.GetString("PathFormat", NWNInfo.InstallPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads all of the hack info files into the hak check list box.
|
||||
/// </summary>
|
||||
protected void LoadHakInfoList(CheckedListBox checkedHaks)
|
||||
{
|
||||
// Get all of the modules in the module directory and add them to
|
||||
// the list box.
|
||||
string[] haks = Directory.GetFiles(NWNInfo.GetPathForFile("foo.hif"), "*.hif");
|
||||
foreach (string hak in haks)
|
||||
{
|
||||
// Load the HIF now and perform validation before adding it to the
|
||||
// list of HIFs.
|
||||
HakInfo hif = new HakInfo(hak);
|
||||
string error;
|
||||
if (hif.Validate(out error))
|
||||
checkedHaks.Items.Add(hif);
|
||||
else
|
||||
MessageBox.Show(error, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
|
||||
if (0 == checkedHaks.Items.Count)
|
||||
{
|
||||
MessageBox.Show(StringResources.GetString("NoHIFS"), "Error", MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Error);
|
||||
Close();
|
||||
Hide();
|
||||
Application.Exit();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads all of the modules in the NWN modules directory into the module
|
||||
/// check list box.
|
||||
/// </summary>
|
||||
protected void LoadModuleList(CheckedListBox checkedModules)
|
||||
{
|
||||
// Turn sorting on so all of the user modules get added alphabetically
|
||||
checkedModules.Sorted = true;
|
||||
|
||||
// Get all of the modules in the module directory and add them to
|
||||
// the list box.
|
||||
string[] modules = Directory.GetFiles(NWNInfo.ModulesPath, "*.mod");
|
||||
foreach (string module in modules)
|
||||
{
|
||||
checkedModules.Items.Add(new Module(Path.GetFileName(module)));
|
||||
}
|
||||
|
||||
// Turn off sorting so we can add the OC/XP1/XP2 at the top.
|
||||
checkedModules.Sorted = false;
|
||||
|
||||
// Add the OC/XP1/XP2 modules if appropriate.
|
||||
if (NWNInfo.IsXP2ModsInstalled)
|
||||
checkedModules.Items.Insert(0, new Module(StringResources.GetString("XP2Name"), NWNInfo.XP2Modules));
|
||||
if (NWNInfo.IsXP1ModsInstalled)
|
||||
checkedModules.Items.Insert(0, new Module(StringResources.GetString("XP1Name"), NWNInfo.XP1Modules));
|
||||
if (NWNInfo.IsOCModsInstalled)
|
||||
checkedModules.Items.Insert(0, new Module(StringResources.GetString("OCName"), NWNInfo.OCModules));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks the modules to see if any of the specified hifs are installed already,
|
||||
/// if they are it prompts the user to see if we should continue.
|
||||
/// </summary>
|
||||
/// <param name="hifs">The list of hifs</param>
|
||||
/// <param name="modules">The list of modules</param>
|
||||
/// <returns>True if the user cancels the operation, false if they do not</returns>
|
||||
protected bool CheckForHifConflicts(HakInfo[] hifs, string[] modules)
|
||||
{
|
||||
// Get the list of conflicts if there aren't any then just return false.
|
||||
HifConflictCollection conflicts = HakInstaller.CheckInstalledHifs(hifs, modules);
|
||||
if (null == conflicts) return false;
|
||||
|
||||
// There are conflicts, prompt the user for what to do.
|
||||
HifConflictsForm form = new HifConflictsForm(conflicts);
|
||||
return DialogResult.Cancel == form.ShowDialog(this);
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
//
|
||||
// InstallFormBase
|
||||
//
|
||||
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
|
||||
this.ClientSize = new System.Drawing.Size(292, 266);
|
||||
this.Name = "InstallFormBase";
|
||||
this.Load += new System.EventHandler(this.InstallFormBase_Load);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for the install button click event. It installs the selected
|
||||
/// haks in the selected modules.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
public void PerformInstall(HakInfo[] hifs, string[] modules)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Before starting check for hif conflicts and ask the user if they really want to
|
||||
// continue.
|
||||
if (CheckForHifConflicts(hifs, modules)) return;
|
||||
|
||||
// Create a progress control,
|
||||
InstallProgressForm progress = new InstallProgressForm();
|
||||
ThreadPool.QueueUserWorkItem(new WaitCallback(DoHakInstall),
|
||||
new InstallInfo(hifs, modules, progress));
|
||||
progress.ShowDialog(this);
|
||||
}
|
||||
finally
|
||||
{
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private nested classes
|
||||
private class InstallInfo
|
||||
{
|
||||
#region public properties/methods
|
||||
/// <summary>
|
||||
/// Gets the list of haks to add.
|
||||
/// </summary>
|
||||
public HakInfo[] Hifs { get { return hifs; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of modules to add haks to.
|
||||
/// </summary>
|
||||
public string[] Modules { get { return modules; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the object used to display progress information.
|
||||
/// </summary>
|
||||
public InstallProgressForm Progress { get { return progress; } }
|
||||
|
||||
/// <summary>
|
||||
/// Class constructor
|
||||
/// </summary>
|
||||
/// <param name="hifs">The list of haks to add</param>
|
||||
/// <param name="modules">The list of modules to add haks to</param>
|
||||
/// <param name="progress">The object used to show progress</param>
|
||||
public InstallInfo(HakInfo[] hifs, string[]modules,
|
||||
InstallProgressForm progress)
|
||||
{
|
||||
this.hifs = hifs;
|
||||
this.modules = modules;
|
||||
this.progress = progress;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private fields/properties/methods
|
||||
private InstallProgressForm progress;
|
||||
private HakInfo[] hifs;
|
||||
private string[] modules;
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private fields/properties/methods
|
||||
private SystemMenu systemMenu;
|
||||
|
||||
/// <summary>
|
||||
/// This function performs the install of the haks into the modules. It is
|
||||
/// intended to be called in a background thread using the thread pool, allowing
|
||||
/// a progress dialog to be displayed to the user while the work is being done.
|
||||
/// </summary>
|
||||
/// <param name="o">InstallInfo object containing the install data.</param>
|
||||
protected void DoHakInstall(object o)
|
||||
{
|
||||
// Force the thread to use the invariant culture to make the install
|
||||
// code work on foreign language versions of windows.
|
||||
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
|
||||
|
||||
// Do the hak install and when we're done close the progress form.
|
||||
InstallInfo info = (InstallInfo) o;
|
||||
try
|
||||
{
|
||||
// The OC/XP1/XP2 files can be marked as read only, so we have to undo that
|
||||
// for all modules in the list.
|
||||
foreach (string module in info.Modules)
|
||||
{
|
||||
string file = NWNInfo.GetFullFilePath(module);
|
||||
FileAttributes attrs = File.GetAttributes(file);
|
||||
attrs &= ~FileAttributes.ReadOnly;
|
||||
File.SetAttributes(file, attrs);
|
||||
}
|
||||
|
||||
HakInstaller.InstallHaks(info.Hifs, info.Modules, info.Progress);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MessageBox.Show(info.Progress, e.Message, "Error",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
info.Progress.Close();
|
||||
|
||||
// Reset any .nwm files back to read only to leave them as we found them,
|
||||
// in case the engine wants them marked read only.
|
||||
foreach (string module in info.Modules)
|
||||
{
|
||||
if (0 == string.Compare(".nwm", Path.GetExtension(module), true, CultureInfo.InvariantCulture))
|
||||
{
|
||||
string file = NWNInfo.GetFullFilePath(module);
|
||||
FileAttributes attrs = File.GetAttributes(file);
|
||||
attrs |= FileAttributes.ReadOnly;
|
||||
File.SetAttributes(file, attrs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region menu handlers
|
||||
/// <summary>
|
||||
/// Event handler for the system menu About menu item.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="args"></param>
|
||||
private void OnAbout(object sender, EventArgs args)
|
||||
{
|
||||
AboutForm form = new AboutForm();
|
||||
form.ShowDialog(this);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region form event handlers
|
||||
/// <summary>
|
||||
/// Event handler for the forms' load event, it wires up our system menu items. Doing
|
||||
/// these in the constructor breaks CenterWindow.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void InstallFormBase_Load(object sender, System.EventArgs e)
|
||||
{
|
||||
systemMenu = new SystemMenu(this);
|
||||
|
||||
SystemMenuItem item = new SystemMenuItem("-", systemMenu);
|
||||
systemMenu.Add(item);
|
||||
|
||||
item = new SystemMenuItem("&About", systemMenu);
|
||||
item.Click += new EventHandler(OnAbout);
|
||||
systemMenu.Add(item);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This object defines a 'module' that is displayed in the right checked list box in
|
||||
/// the form. For most modules it refers to a single module, but for the bioware modules
|
||||
/// it refers to a group of modules.
|
||||
/// </summary>
|
||||
public class Module
|
||||
{
|
||||
#region public properties/methods
|
||||
/// <summary>
|
||||
/// Gets the name of the module object, this is the text that should be
|
||||
/// displayed to the user.
|
||||
/// </summary>
|
||||
public string Name { get { return name; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of modules that make up this module object.
|
||||
/// </summary>
|
||||
public string[] Modules { get { return modules; } }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to create a module object for a single module on disk.
|
||||
/// </summary>
|
||||
/// <param name="module">The module</param>
|
||||
public Module(string module)
|
||||
{
|
||||
name = Path.GetFileNameWithoutExtension(module);
|
||||
modules = new string[] { module };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to create a module object for a collection of modules
|
||||
/// </summary>
|
||||
/// <param name="name">The display name for the collection</param>
|
||||
/// <param name="modules">The list of modules.</param>
|
||||
public Module(string name, string[] modules)
|
||||
{
|
||||
this.name = name;
|
||||
this.modules = modules;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override of ToString() to use the Name property.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString() { return Name; }
|
||||
#endregion
|
||||
|
||||
#region private fields/properties/methods
|
||||
string name;
|
||||
private string[] modules;
|
||||
#endregion
|
||||
}
|
||||
}
|
102
trunk/tools/HakInstaller/InstallFormBase.resx
Normal file
102
trunk/tools/HakInstaller/InstallFormBase.resx
Normal file
@@ -0,0 +1,102 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
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">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</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.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:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<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" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</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>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="$this.Name">
|
||||
<value>InstallFormBase</value>
|
||||
</data>
|
||||
</root>
|
222
trunk/tools/HakInstaller/InstallProgressForm.cs
Normal file
222
trunk/tools/HakInstaller/InstallProgressForm.cs
Normal file
@@ -0,0 +1,222 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace HakInstaller
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for InstallProgress.
|
||||
/// </summary>
|
||||
public class InstallProgressForm : System.Windows.Forms.Form,
|
||||
IHakInstallProgress
|
||||
{
|
||||
#region public properties/methods
|
||||
/// <summary>
|
||||
/// Class constructor
|
||||
/// </summary>
|
||||
public InstallProgressForm()
|
||||
{
|
||||
//
|
||||
// Required for Windows Form Designer support
|
||||
//
|
||||
InitializeComponent();
|
||||
|
||||
cancelled = false;
|
||||
builder = new System.Text.StringBuilder();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IHakInstallProgress implementation
|
||||
/// <summary>
|
||||
/// Gets whether the user cancelled the install.
|
||||
/// </summary>
|
||||
bool IHakInstallProgress.IsCancelled { get { return cancelled; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets the number of steps for the progress bar.
|
||||
/// </summary>
|
||||
int IHakInstallProgress.ProgressSteps
|
||||
{
|
||||
get { return progressBar.Maximum; }
|
||||
set
|
||||
{
|
||||
progressBar.Minimum = 1;
|
||||
progressBar.Maximum = value;
|
||||
progressBar.Value = 1;
|
||||
progressBar.Step = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Advances the progress bar 1 step.
|
||||
/// </summary>
|
||||
void IHakInstallProgress.Step()
|
||||
{
|
||||
progressBar.PerformStep();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the currently displayed progress message.
|
||||
/// </summary>
|
||||
/// <param name="format">Format string</param>
|
||||
/// <param name="args">Message arguments</param>
|
||||
void IHakInstallProgress.SetMessage(string format, params object[] args)
|
||||
{
|
||||
builder.Length = 0;
|
||||
builder.AppendFormat(format, args);
|
||||
labelMessage.Text = builder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This methods should ask the user for confirmation of replacing
|
||||
/// the listed files in the module with files from sources in the
|
||||
/// hif files, as this operation may break the module.
|
||||
/// </summary>
|
||||
/// <param name="conflicts">The list of file conflicts</param>
|
||||
/// <returns>true if the files should be replaced, false if adding
|
||||
/// the hak(s) to the module should be aborted</returns>
|
||||
bool IHakInstallProgress.ShouldReplaceFiles(FileConflictCollection conflicts)
|
||||
{
|
||||
// Confirm the file replace operation with the user.
|
||||
ReplacingFilesForm form = new ReplacingFilesForm(conflicts);
|
||||
return DialogResult.OK == form.ShowDialog((Form) this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method should ask the user for confirmation of overwriting
|
||||
/// the listed files. If fatal is true then there is no confirmation,
|
||||
/// it is just an informational message that the operation must be aborted.
|
||||
/// </summary>
|
||||
/// <param name="warnings">The list of warnings</param>
|
||||
/// <param name="fatal">True if the warnings are fatal</param>
|
||||
/// <param name="type">The type of overwrite being confirmed</param>
|
||||
/// <returns>True if the operation should proceed</returns>
|
||||
bool IHakInstallProgress.ShouldOverwrite(OverwriteWarningCollection warnings,
|
||||
bool fatal, OverwriteWarningType type)
|
||||
{
|
||||
OverwriteWarningsForm form = new OverwriteWarningsForm(warnings, fatal, type);
|
||||
return DialogResult.OK == form.ShowDialog((Form) this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays an error message to the user.
|
||||
/// </summary>
|
||||
/// <param name="error">The error message to display</param>
|
||||
void IHakInstallProgress.DisplayErrorMessage(string error)
|
||||
{
|
||||
MessageBox.Show(this, error, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message to the user.
|
||||
/// </summary>
|
||||
/// <param name="error">The message to display</param>
|
||||
void IHakInstallProgress.DisplayMessage(string message)
|
||||
{
|
||||
MessageBox.Show(this, message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region protected fields/properties/methods
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
protected override void Dispose( bool disposing )
|
||||
{
|
||||
if( disposing )
|
||||
{
|
||||
if(components != null)
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose( disposing );
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
private System.Windows.Forms.ProgressBar progressBar;
|
||||
private System.Windows.Forms.Label labelMessage;
|
||||
private System.Windows.Forms.Button buttonCancel;
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.Container components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.progressBar = new System.Windows.Forms.ProgressBar();
|
||||
this.labelMessage = new System.Windows.Forms.Label();
|
||||
this.buttonCancel = new System.Windows.Forms.Button();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// progressBar
|
||||
//
|
||||
this.progressBar.Location = new System.Drawing.Point(16, 56);
|
||||
this.progressBar.Name = "progressBar";
|
||||
this.progressBar.Size = new System.Drawing.Size(344, 16);
|
||||
this.progressBar.TabIndex = 0;
|
||||
//
|
||||
// labelMessage
|
||||
//
|
||||
this.labelMessage.Location = new System.Drawing.Point(16, 16);
|
||||
this.labelMessage.Name = "labelMessage";
|
||||
this.labelMessage.Size = new System.Drawing.Size(344, 32);
|
||||
this.labelMessage.TabIndex = 1;
|
||||
this.labelMessage.Text = "label1";
|
||||
//
|
||||
// buttonCancel
|
||||
//
|
||||
this.buttonCancel.FlatStyle = System.Windows.Forms.FlatStyle.System;
|
||||
this.buttonCancel.Location = new System.Drawing.Point(16, 96);
|
||||
this.buttonCancel.Name = "buttonCancel";
|
||||
this.buttonCancel.Size = new System.Drawing.Size(72, 24);
|
||||
this.buttonCancel.TabIndex = 2;
|
||||
this.buttonCancel.Text = "&Cancel";
|
||||
this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click);
|
||||
//
|
||||
// InstallProgressForm
|
||||
//
|
||||
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
|
||||
this.ClientSize = new System.Drawing.Size(378, 136);
|
||||
this.ControlBox = false;
|
||||
this.Controls.Add(this.buttonCancel);
|
||||
this.Controls.Add(this.labelMessage);
|
||||
this.Controls.Add(this.progressBar);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "InstallProgressForm";
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Installing Haks";
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private fields/properties/methods
|
||||
private bool cancelled;
|
||||
private System.Text.StringBuilder builder;
|
||||
#endregion
|
||||
|
||||
#region event handlers
|
||||
/// <summary>
|
||||
/// Event handler for the cancel button's click event.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void buttonCancel_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
cancelled = true;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
157
trunk/tools/HakInstaller/InstallProgressForm.resx
Normal file
157
trunk/tools/HakInstaller/InstallProgressForm.resx
Normal file
@@ -0,0 +1,157 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
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">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</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 forserialized 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.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:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<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" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</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>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="progressBar.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="progressBar.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="progressBar.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="labelMessage.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="labelMessage.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="labelMessage.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="buttonCancel.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="buttonCancel.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="buttonCancel.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="$this.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Language" type="System.Globalization.CultureInfo, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>(Default)</value>
|
||||
</data>
|
||||
<data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Name">
|
||||
<value>InstallProgressForm</value>
|
||||
</data>
|
||||
<data name="$this.Localizable" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>8, 8</value>
|
||||
</data>
|
||||
<data name="$this.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.TrayHeight" type="System.Int32, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>80</value>
|
||||
</data>
|
||||
<data name="$this.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
</root>
|
398
trunk/tools/HakInstaller/Key.cs
Normal file
398
trunk/tools/HakInstaller/Key.cs
Normal file
@@ -0,0 +1,398 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using NWN.FileTypes.Tools;
|
||||
|
||||
namespace NWN.FileTypes.BIF
|
||||
{
|
||||
/// <summary>
|
||||
/// The class encapsulates a NWN BIF file, allowing access to the files
|
||||
/// within the BIF.
|
||||
/// </summary>
|
||||
internal class Bif
|
||||
{
|
||||
#region public properties/methods
|
||||
/// <summary>
|
||||
/// Class constructor. It caches the list of files in the BIF for quick
|
||||
/// searching.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the BIF</param>
|
||||
public Bif(string name)
|
||||
{
|
||||
// Delay loading the cache until needed.
|
||||
this.name = name;
|
||||
entries = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to extract the specified file ID from the BIF, returning
|
||||
/// the file's data in a Stream.
|
||||
/// </summary>
|
||||
/// <param name="id">The id of the file</param>
|
||||
/// <returns>A stream for the file or null if the BIF does not contain
|
||||
/// the file.</returns>
|
||||
public Stream GetFile(uint id)
|
||||
{
|
||||
id = id & 0xfffff;
|
||||
|
||||
// If we haven't populated the cache then do so now.
|
||||
if (null == entries) Cache();
|
||||
|
||||
// If the file isn't ours then return null.
|
||||
BifEntry entry = entries[id] as BifEntry;
|
||||
if (null == entry) return null;
|
||||
|
||||
// Read the raw data into a memory stream.
|
||||
NWNLogger.Log(1, "Bif.GetFile({0}) found file in BIF {1}", id, name);
|
||||
using (FileStream reader =
|
||||
new FileStream(name, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
// Read the file's data.
|
||||
byte[] buffer = new byte[entry.Size];
|
||||
reader.Seek(entry.Offset, SeekOrigin.Begin);
|
||||
reader.Read(buffer, 0, buffer.Length);
|
||||
|
||||
// Create a memory stream for the data and return it.
|
||||
MemoryStream s = new MemoryStream(buffer, false);
|
||||
return s;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private raw structures for reading bif file data
|
||||
[StructLayout(LayoutKind.Sequential, Pack=1, CharSet=CharSet.Ansi)]
|
||||
private struct RawHeader
|
||||
{
|
||||
#region members
|
||||
public UInt32 FileType;
|
||||
public UInt32 FilerVersion;
|
||||
public UInt32 VariableResourceCount;
|
||||
public UInt32 FixedResourceCount;
|
||||
public UInt32 VariableTableOffset;
|
||||
#endregion
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack=1, CharSet=CharSet.Ansi)]
|
||||
private struct RawEntry
|
||||
{
|
||||
#region members
|
||||
public UInt32 ID;
|
||||
public UInt32 Offset;
|
||||
public UInt32 FileSize;
|
||||
public UInt32 ResourceType;
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private nested classes
|
||||
/// <summary>
|
||||
/// Class that contains the data for a BIF file entry
|
||||
/// </summary>
|
||||
private class BifEntry
|
||||
{
|
||||
public uint Offset;
|
||||
public uint Size;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private fields/properties/methods
|
||||
private string name;
|
||||
private Hashtable entries;
|
||||
|
||||
/// <summary>
|
||||
/// Caches the biff's file entries in our hashtable.
|
||||
/// </summary>
|
||||
private void Cache()
|
||||
{
|
||||
entries = new Hashtable();
|
||||
|
||||
using (FileStream reader =
|
||||
new FileStream(name, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
// Read the file header.
|
||||
RawHeader header = (RawHeader)
|
||||
RawSerializer.Deserialize(typeof(RawHeader), reader);
|
||||
|
||||
// Read all of the variable sized resources from the BIF, storing
|
||||
// their size/offset entries in our hash table. Fixed resources
|
||||
// are not implemented we don't have to worry about them.
|
||||
reader.Seek(header.VariableTableOffset, SeekOrigin.Begin);
|
||||
for (int i = 0; i < header.VariableResourceCount; i++)
|
||||
{
|
||||
// Read the raw entry data.
|
||||
RawEntry rawEntry = (RawEntry)
|
||||
RawSerializer.Deserialize(typeof(RawEntry), reader);
|
||||
|
||||
// Create an entry and add it to our hash table.
|
||||
BifEntry entry = new BifEntry();
|
||||
entry.Offset = rawEntry.Offset;
|
||||
entry.Size = rawEntry.FileSize;
|
||||
entries.Add((uint) (rawEntry.ID & 0xfffff), entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This class encapsulates a NWN KEY file, which contains information
|
||||
/// about files stored in BIF files.
|
||||
/// </summary>
|
||||
internal class Key
|
||||
{
|
||||
/// <summary>
|
||||
/// Class constructor
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the key file to load</param>
|
||||
public Key(string name)
|
||||
{
|
||||
keyFileName = name;
|
||||
bifs = new ArrayList();
|
||||
keys = new Hashtable();
|
||||
|
||||
// Glue the NWN install dir onto the file name and open it.
|
||||
string fileName = Path.Combine(NWN.NWNInfo.InstallPath, name);
|
||||
using (FileStream reader =
|
||||
new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
// Read the file header.
|
||||
RawHeader header = (RawHeader)
|
||||
RawSerializer.Deserialize(typeof(RawHeader), reader);
|
||||
|
||||
// Read all of the BIF file entries from the key file.
|
||||
reader.Seek(header.OffsetToFileTable, SeekOrigin.Begin);
|
||||
RawFileEntry[] files = new RawFileEntry[header.BIFCount];
|
||||
for (int i = 0; i < header.BIFCount; i++)
|
||||
files[i] = (RawFileEntry)
|
||||
RawSerializer.Deserialize(typeof(RawFileEntry), reader);
|
||||
|
||||
// Loop through the BIF file entries making a list of all of
|
||||
// the BIFs this key file covers.
|
||||
byte[] fileNameBuffer = new byte[2048];
|
||||
for (int i = 0; i < header.BIFCount; i++)
|
||||
{
|
||||
// Read the raw name data and convert it to a string.
|
||||
reader.Seek(files[i].FilenameOffset, SeekOrigin.Begin);
|
||||
reader.Read(fileNameBuffer, 0, files[i].FilenameSize);
|
||||
string s = RawSerializer.DeserializeString(fileNameBuffer, 0, files[i].FilenameSize);
|
||||
|
||||
// The path is relative to the install directory, so glue that on before adding
|
||||
// the BIF to our string collection.
|
||||
//if (0 != (1 & files[i].Drives))
|
||||
s = Path.Combine(NWN.NWNInfo.InstallPath, s);
|
||||
//else
|
||||
// throw new NWNException("Uknown data in file entry block in key file {0}", name);
|
||||
bifs.Add(new Bif(s));
|
||||
}
|
||||
|
||||
// Read all of the key entries, i.e. what files are in the BIFs.
|
||||
reader.Seek(header.OffsetToKeyTable, SeekOrigin.Begin);
|
||||
for (int i = 0; i < header.KeyCount; i++)
|
||||
{
|
||||
// Read the raw data.
|
||||
RawKeyEntry key = (RawKeyEntry)
|
||||
RawSerializer.Deserialize(typeof(RawKeyEntry), reader);
|
||||
|
||||
// Build the file name from the ResRef and resource type. Then
|
||||
// add the file name and ID to our hash table. If this booms then
|
||||
// that is because of a resource type we don't know about, for
|
||||
// now we ignore that.
|
||||
ResType resType = (ResType) key.ResourceType;
|
||||
try
|
||||
{
|
||||
string ext = resType.ToString().Substring(3, 3).ToLower();
|
||||
string s = RawSerializer.DeserializeString(key.ResRef, 0, 16);
|
||||
s = string.Format("{0}.{1}", s, ext);
|
||||
keys.Add(s, key.ResID);
|
||||
}
|
||||
catch (Exception) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if the key contains the file, and if it does extracts
|
||||
/// it from it's BIF and returns it's data in a Stream.
|
||||
/// </summary>
|
||||
/// <param name="file">The file to extract</param>
|
||||
/// <returns>A Stream containing the file's data or null if the key
|
||||
/// does not contain the file.</returns>
|
||||
public Stream GetFile(string file)
|
||||
{
|
||||
if (!keys.Contains(file)) return null;
|
||||
|
||||
// The file is ours, check each of our BIFS for the file.
|
||||
// The bottom 20 bits are the index in the bif and the top
|
||||
// 12 bits are the bif index in our bif array.
|
||||
uint id = (uint) keys[file];
|
||||
uint index = id >> 20;
|
||||
Bif bif = (Bif) bifs[(int) index];
|
||||
return bif.GetFile(id & 0xfffff);
|
||||
|
||||
/*
|
||||
* Not totally sure the above code is right so saving this
|
||||
foreach (Bif bif in bifs)
|
||||
{
|
||||
// Try to load the file from the BIF, if successful return it.
|
||||
Stream s = bif.GetFile(id);
|
||||
if (null != s) return s;
|
||||
}
|
||||
|
||||
// If we get here something really bad has happened.
|
||||
throw new NWNException("Cannot extract file {0} from BIFs", file);
|
||||
*/
|
||||
}
|
||||
|
||||
#region private raw structures for reading key file data
|
||||
[StructLayout(LayoutKind.Sequential, Pack=1, CharSet=CharSet.Ansi)]
|
||||
private struct RawHeader
|
||||
{
|
||||
#region members
|
||||
public UInt32 FileType;
|
||||
public UInt32 FilerVersion;
|
||||
public UInt32 BIFCount;
|
||||
public UInt32 KeyCount;
|
||||
public UInt32 OffsetToFileTable;
|
||||
public UInt32 OffsetToKeyTable;
|
||||
public UInt32 BuildYear;
|
||||
public UInt32 BuildDay;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst=32)] private Byte[] Reserved;
|
||||
#endregion
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack=1, CharSet=CharSet.Ansi)]
|
||||
private struct RawFileEntry
|
||||
{
|
||||
#region members
|
||||
public UInt32 FileSize;
|
||||
public UInt32 FilenameOffset;
|
||||
public UInt16 FilenameSize;
|
||||
public UInt16 Drives;
|
||||
#endregion
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack=1, CharSet=CharSet.Ansi)]
|
||||
private struct RawKeyEntry
|
||||
{
|
||||
#region members
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst=16)] public byte[] ResRef;
|
||||
public UInt16 ResourceType;
|
||||
public UInt32 ResID;
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private fields/properties/methods
|
||||
private string keyFileName;
|
||||
private ArrayList bifs;
|
||||
private Hashtable keys;
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This class implements a collection of all of the KEY files installed
|
||||
/// on the user's system. It can be used to extract files from those
|
||||
/// keys.
|
||||
/// </summary>
|
||||
public class KeyCollection
|
||||
{
|
||||
#region public static methods
|
||||
/// <summary>
|
||||
/// Looks in all of the key files for the given file, extracting it
|
||||
/// from it's BIF and returning it's data in a stream.
|
||||
/// </summary>
|
||||
/// <param name="file">The file to extract</param>
|
||||
/// <returns>A Stream containing the file data or null if the file
|
||||
/// cannot be found</returns>
|
||||
public static Stream GetFile(string file)
|
||||
{
|
||||
// Get a lower case copy of just the file name.
|
||||
file = Path.GetFileName(file).ToLower();
|
||||
|
||||
// Loop through all of the keys looking for the file.
|
||||
foreach (Key key in Singleton.keys)
|
||||
{
|
||||
// Ask the key for the file if we get it return it.
|
||||
Stream s = key.GetFile(file);
|
||||
if (null != s) return s;
|
||||
}
|
||||
|
||||
// We couldn't find the file return null.
|
||||
return null;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private static methods
|
||||
private static KeyCollection singleton;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the singleton instance
|
||||
/// </summary>
|
||||
private static KeyCollection Singleton
|
||||
{
|
||||
get
|
||||
{
|
||||
if (null == singleton) singleton = new KeyCollection();
|
||||
return singleton;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private fields/properties/methods
|
||||
private ArrayList keys;
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
private KeyCollection()
|
||||
{
|
||||
keys = new ArrayList();
|
||||
|
||||
// Get a list of the key files for the NWN install and add the files
|
||||
// to a StringCollection, forcing the names to lower case.
|
||||
string[] filesArray = Directory.GetFiles(NWN.NWNInfo.InstallPath, "*.key");
|
||||
StringCollection files = new StringCollection();
|
||||
foreach (string file in filesArray)
|
||||
files.Add(Path.GetFileName(file).ToLower());
|
||||
|
||||
// We need to do the files in a certain order, as we want to check the xp's in
|
||||
// reverse order, then the main game last.
|
||||
ProcessFile(files, "xp3.key");
|
||||
ProcessFile(files, "xp2patch.key");
|
||||
ProcessFile(files, "xp2.key");
|
||||
ProcessFile(files, "xp1patch.key");
|
||||
ProcessFile(files, "xp1.key");
|
||||
|
||||
// Now process whatever is left.
|
||||
foreach (string file in files)
|
||||
{
|
||||
Key key = new Key(file);
|
||||
keys.Add(key);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if the string collection contains the key file, and if it does
|
||||
/// loads it and removes it from the collection.
|
||||
/// </summary>
|
||||
/// <param name="files">The list of files</param>
|
||||
/// <param name="file">The key file to process</param>
|
||||
private void ProcessFile(StringCollection files, string file)
|
||||
{
|
||||
if (files.Contains(file))
|
||||
{
|
||||
// Create the key, add it to our collection, and remove the
|
||||
// file from the list as we've loaded it.
|
||||
Key key = new Key(file);
|
||||
keys.Add(key);
|
||||
files.Remove(file);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
223
trunk/tools/HakInstaller/Main.cs
Normal file
223
trunk/tools/HakInstaller/Main.cs
Normal file
@@ -0,0 +1,223 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using HakInstaller.Utilities;
|
||||
using NWN;
|
||||
|
||||
namespace HakInstaller
|
||||
{
|
||||
/// <summary>
|
||||
/// Class to contain the application's main method.
|
||||
/// </summary>
|
||||
public class MainContainer
|
||||
{
|
||||
#region private static fields/properties/methods
|
||||
private static bool consoleMode = false;
|
||||
private static bool installPathGiven = false;
|
||||
private static StringCollection hifStrings = new StringCollection();
|
||||
private static StringCollection moduleStrings = new StringCollection();
|
||||
|
||||
/// <summary>
|
||||
/// Either displays the message in a message box or on the command line,
|
||||
/// depending on whether the application is running in console mode or not.
|
||||
/// </summary>
|
||||
/// <param name="format">The format string</param>
|
||||
/// <param name="args">The format arguments</param>
|
||||
private static void ShowMessage(string format, params object[] args)
|
||||
{
|
||||
System.Text.StringBuilder b = new System.Text.StringBuilder();
|
||||
b.AppendFormat(format, args);
|
||||
|
||||
if (consoleMode)
|
||||
Console.WriteLine(b.ToString());
|
||||
else
|
||||
MessageBox.Show(b.ToString(), "Error", MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Error);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates all of the files in the collection to make sure that they
|
||||
/// exist.
|
||||
/// </summary>
|
||||
/// <param name="files">The list of files to validate</param>
|
||||
/// <returns>True if all files exist</returns>
|
||||
private static bool ValidateFiles(StringCollection files)
|
||||
{
|
||||
// Make sure all of the source files exist.
|
||||
foreach (string file in files)
|
||||
if (!File.Exists(Path.Combine(NWNInfo.GetPathForFile(file), file)))
|
||||
{
|
||||
ShowMessage("The file {0} does not exist", file);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs the application in console mode, silently adding the haks to
|
||||
/// the modules given on the command line.
|
||||
/// </summary>
|
||||
/// <returns>0 if successful, otherwise -1</returns>
|
||||
private static int ConsoleMode()
|
||||
{
|
||||
// Validate the files, if we fail validation then exit now.
|
||||
if (!ValidateFiles(hifStrings) || !ValidateFiles(moduleStrings))
|
||||
return -1;
|
||||
|
||||
// Convert the string collections to arrays and install the haks
|
||||
// in the modules.
|
||||
string[] hifs = new string[hifStrings.Count];
|
||||
hifStrings.CopyTo(hifs, 0);
|
||||
string[] modules = new string[moduleStrings.Count];
|
||||
moduleStrings.CopyTo(modules, 0);
|
||||
|
||||
try
|
||||
{
|
||||
HakInstaller.InstallHaks(hifs, modules, null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e.Message);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Terminates the application.
|
||||
/// </summary>
|
||||
/// <param name="showHelp">True if help should be displayed.</param>
|
||||
private static void Terminate(bool showHelp)
|
||||
{
|
||||
if (showHelp) Help();
|
||||
throw new EntryPointNotFoundException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays help
|
||||
/// </summary>
|
||||
private static void Help()
|
||||
{
|
||||
Console.WriteLine("HakInstaller: install hak/erf/tlk files in modules");
|
||||
Console.WriteLine("Usage: HakInstaller -n<path> file.hif/mod ...");
|
||||
Console.WriteLine(" -n<path>:Specifies the NWN install path, if this is not given");
|
||||
Console.WriteLine(" then it will be read from the registry.");
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine("One or more .hif and .mod files may be specified on the command");
|
||||
Console.WriteLine("line, if none are given a UI will be displayed allowing you to");
|
||||
Console.WriteLine("choose the hif/mod files. Paths should not be given on the files");
|
||||
Console.WriteLine("they will be searched for in the appropriate subdirectories of");
|
||||
Console.WriteLine("the NWN install path (as either given on the command line or read");
|
||||
Console.WriteLine("from the registry).");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes command line arguments.
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
private static void ProcessArguments(string[] args)
|
||||
{
|
||||
foreach (string arg in args)
|
||||
{
|
||||
// Process any command line switches.
|
||||
if ('-' == arg[0] || '/' == arg[1])
|
||||
{
|
||||
switch (arg[1])
|
||||
{
|
||||
case 'n':
|
||||
case 'N':
|
||||
// The NWN install path was specified on the command line,
|
||||
// save it to override whatever is in the registry.
|
||||
installPathGiven = true;
|
||||
NWNInfo.InstallPath = arg.Substring(2);
|
||||
|
||||
// Make sure that the directory exists.
|
||||
if (!Directory.Exists(NWNInfo.InstallPath))
|
||||
{
|
||||
ShowMessage("The path '{0}' does not exist.", NWNInfo.InstallPath);
|
||||
Terminate(false);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Help();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we get a hif or module on the command line then we
|
||||
// are in console mode.
|
||||
consoleMode = true;
|
||||
|
||||
string extension = Path.GetExtension(arg);
|
||||
if (0 == string.Compare(".hif", extension, true))
|
||||
hifStrings.Add(arg);
|
||||
else if (0 == string.Compare(".mod", extension, true))
|
||||
moduleStrings.Add(arg);
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Unknown file {0}\n", arg);
|
||||
Terminate(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We must have at least one hif and one mod if we are in console mode.
|
||||
if (consoleMode && (0 == hifStrings.Count || 0 == moduleStrings.Count))
|
||||
{
|
||||
Console.WriteLine("Must specify at least one .mod and one .hif file\n");
|
||||
Terminate(true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static int Main(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Process command line arguments.
|
||||
ProcessArguments(args);
|
||||
|
||||
// Make sure NWN is installed before doing anything. If the user
|
||||
// gave an install path on the command line we could be installing on
|
||||
// a remote machine, so do not check for an install on this machine.
|
||||
if (!installPathGiven && !NWNInfo.IsInstalled)
|
||||
{
|
||||
ShowMessage("Neverwinter Nights is not installed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (consoleMode)
|
||||
return ConsoleMode();
|
||||
else
|
||||
{
|
||||
// Requires .NET framework 1.1
|
||||
//Application.EnableVisualStyles();
|
||||
Application.Run(new InstallForm());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
catch (EntryPointNotFoundException)
|
||||
{
|
||||
// Dummy exception thrown to terminate the application by Help(),
|
||||
// don't display anything just return -1.
|
||||
return -1;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ShowMessage(e.Message);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
205
trunk/tools/HakInstaller/MainConsole.cs
Normal file
205
trunk/tools/HakInstaller/MainConsole.cs
Normal file
@@ -0,0 +1,205 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using HakInstaller.Utilities;
|
||||
using NWN;
|
||||
|
||||
namespace HakInstaller
|
||||
{
|
||||
/// <summary>
|
||||
/// Class to contain the application's main method.
|
||||
/// </summary>
|
||||
public class MainConsole
|
||||
{
|
||||
#region private static fields/properties/methods
|
||||
private static bool installPathGiven = false;
|
||||
private static StringCollection hifStrings = new StringCollection();
|
||||
private static StringCollection moduleStrings = new StringCollection();
|
||||
|
||||
/// <summary>
|
||||
/// Validates all of the files in the collection to make sure that they
|
||||
/// exist.
|
||||
/// </summary>
|
||||
/// <param name="files">The list of files to validate</param>
|
||||
/// <returns>True if all files exist</returns>
|
||||
private static bool ValidateFiles(StringCollection files)
|
||||
{
|
||||
// Make sure all of the source files exist.
|
||||
foreach (string file in files)
|
||||
if (!File.Exists(Path.Combine(NWNInfo.GetPathForFile(file), file)))
|
||||
{
|
||||
Console.WriteLine("The file {0} does not exist", file);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs the application in console mode, silently adding the haks to
|
||||
/// the modules given on the command line.
|
||||
/// </summary>
|
||||
/// <returns>0 if successful, otherwise -1</returns>
|
||||
private static int ConsoleMode()
|
||||
{
|
||||
// Validate the files, if we fail validation then exit now.
|
||||
if (!ValidateFiles(hifStrings) || !ValidateFiles(moduleStrings))
|
||||
return -1;
|
||||
|
||||
// Convert the string collections to arrays and install the haks
|
||||
// in the modules.
|
||||
HakInfo[] hifs = new HakInfo[hifStrings.Count];
|
||||
for (int i = 0; i < hifStrings.Count; i++)
|
||||
hifs[i] = new HakInfo(hifStrings[i]);
|
||||
string[] modules = new string[moduleStrings.Count];
|
||||
moduleStrings.CopyTo(modules, 0);
|
||||
|
||||
try
|
||||
{
|
||||
HakInstaller.InstallHaks(hifs, modules, null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e.Message);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Terminates the application.
|
||||
/// </summary>
|
||||
/// <param name="showHelp">True if help should be displayed</param>
|
||||
private static void Terminate(bool showHelp) { Terminate(showHelp, string.Empty); }
|
||||
|
||||
/// <summary>
|
||||
/// Terminates the application, displaying an error message
|
||||
/// </summary>
|
||||
/// <param name="showHelp">True if help should be displayed</param>
|
||||
/// <param name="format">Format string for the error message to display</param>
|
||||
/// <param name="args"></param>
|
||||
private static void Terminate(bool showHelp, string format, params object[] args)
|
||||
{
|
||||
// Display the error message if one was given.
|
||||
if (string.Empty != format) Console.WriteLine(format, args);
|
||||
|
||||
// If showHelp is true then display application help, leaving a blank
|
||||
// line between the help and the error message.
|
||||
if (showHelp)
|
||||
{
|
||||
if (string.Empty != format) Console.WriteLine("");
|
||||
Help();
|
||||
}
|
||||
|
||||
// Throw an EntryPointNotFoundException to terminate the application.
|
||||
throw new EntryPointNotFoundException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays help
|
||||
/// </summary>
|
||||
private static void Help()
|
||||
{
|
||||
Console.WriteLine("HakInstaller: install hak/erf/tlk files in modules");
|
||||
Console.WriteLine("Usage: HakInstaller -n<path> file.hif/mod ...");
|
||||
Console.WriteLine(" -n<path>:Specifies the NWN install path, if this is not given");
|
||||
Console.WriteLine(" then it will be read from the registry.");
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine("One or more .hif and .mod files may be specified on the command");
|
||||
Console.WriteLine("line, if none are given a UI will be displayed allowing you to");
|
||||
Console.WriteLine("choose the hif/mod files. Paths should not be given on the files");
|
||||
Console.WriteLine("they will be searched for in the appropriate subdirectories of");
|
||||
Console.WriteLine("the NWN install path (as either given on the command line or read");
|
||||
Console.WriteLine("from the registry).");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes command line arguments.
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
private static void ProcessArguments(string[] args)
|
||||
{
|
||||
foreach (string arg in args)
|
||||
{
|
||||
// Process any command line switches.
|
||||
if ('-' == arg[0] || '/' == arg[1])
|
||||
{
|
||||
switch (arg[1])
|
||||
{
|
||||
case 'n':
|
||||
case 'N':
|
||||
// The NWN install path was specified on the command line,
|
||||
// save it to override whatever is in the registry.
|
||||
installPathGiven = true;
|
||||
NWNInfo.InstallPath = arg.Substring(2);
|
||||
|
||||
// Make sure that the directory exists.
|
||||
if (!Directory.Exists(NWNInfo.InstallPath))
|
||||
Terminate(false, "The path '{0}' does not exist.", NWNInfo.InstallPath);
|
||||
break;
|
||||
default:
|
||||
Terminate(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add the file to the appropriate collection based on it's
|
||||
// extension.
|
||||
string extension = Path.GetExtension(arg);
|
||||
if (0 == string.Compare(".hif", extension, true))
|
||||
hifStrings.Add(arg);
|
||||
else if (0 == string.Compare(".mod", extension, true))
|
||||
moduleStrings.Add(arg);
|
||||
else
|
||||
Terminate(true, "Unknown file {0}", arg);
|
||||
}
|
||||
}
|
||||
|
||||
// We must have at least one hif and one mod if we are in console mode.
|
||||
if (0 == hifStrings.Count || 0 == moduleStrings.Count)
|
||||
Terminate(true, "Must specify at least one .mod and one .hif file\n");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static int Main(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Process command line arguments.
|
||||
ProcessArguments(args);
|
||||
|
||||
// Make sure NWN is installed before doing anything. If the user
|
||||
// gave an install path on the command line we could be installing on
|
||||
// a remote machine, so do not check for an install on this machine.
|
||||
if (!installPathGiven && !NWNInfo.IsInstalled)
|
||||
{
|
||||
Console.WriteLine("Neverwinter Nights is not installed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ConsoleMode();
|
||||
}
|
||||
catch (EntryPointNotFoundException)
|
||||
{
|
||||
// Dummy exception thrown to terminate the application by Help(),
|
||||
// don't display anything just return -1.
|
||||
return -1;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e.Message);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
166
trunk/tools/HakInstaller/MainForm.cs
Normal file
166
trunk/tools/HakInstaller/MainForm.cs
Normal file
@@ -0,0 +1,166 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using HakInstaller.Utilities;
|
||||
using NWN;
|
||||
using NWN.FileTypes.Tools;
|
||||
|
||||
namespace HakInstaller
|
||||
{
|
||||
/// <summary>
|
||||
/// Class to contain the application's main method.
|
||||
/// </summary>
|
||||
public class MainForm
|
||||
{
|
||||
#region public static properties/methods
|
||||
/// <summary>
|
||||
/// Gets the single hif to use for the installer, or string.Empty if there is no single hif.
|
||||
/// </summary>
|
||||
public static string Hif { get { return hif; } }
|
||||
#endregion
|
||||
|
||||
#region private static fields/properties/methods
|
||||
private static bool installPathGiven = false;
|
||||
private static string hif = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Either displays the message in a message box or on the command line,
|
||||
/// depending on whether the application is running in console mode or not.
|
||||
/// </summary>
|
||||
/// <param name="format">The format string</param>
|
||||
/// <param name="args">The format arguments</param>
|
||||
private static void ShowMessage(string format, params object[] args)
|
||||
{
|
||||
System.Text.StringBuilder b = new System.Text.StringBuilder();
|
||||
b.AppendFormat(format, args);
|
||||
MessageBox.Show(b.ToString(), "Error", MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Error);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Terminates the application.
|
||||
/// </summary>
|
||||
private static void Terminate() { Terminate(string.Empty); }
|
||||
|
||||
/// <summary>
|
||||
/// Terminates the application, displaying an error message
|
||||
/// </summary>
|
||||
/// <param name="format">Format string for the error message to display</param>
|
||||
/// <param name="args"></param>
|
||||
private static void Terminate(string format, params object[] args)
|
||||
{
|
||||
// Display the error message if one was given.
|
||||
if (string.Empty != format) ShowMessage(format, args);
|
||||
|
||||
// Throw an EntryPointNotFoundException to terminate the application.
|
||||
throw new EntryPointNotFoundException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes command line arguments.
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
private static void ProcessArguments(string[] args)
|
||||
{
|
||||
foreach (string arg in args)
|
||||
{
|
||||
// Process any command line switches.
|
||||
if ('-' == arg[0] || '/' == arg[1])
|
||||
{
|
||||
switch (arg[1])
|
||||
{
|
||||
case 'n':
|
||||
case 'N':
|
||||
// The NWN install path was specified on the command line,
|
||||
// save it to override whatever is in the registry.
|
||||
installPathGiven = true;
|
||||
NWNInfo.InstallPath = arg.Substring(2);
|
||||
|
||||
// Make sure that the directory exists.
|
||||
if (!Directory.Exists(NWNInfo.InstallPath))
|
||||
Terminate("The path '{0}' does not exist.", NWNInfo.InstallPath);
|
||||
// the registry values were irrelevant so replace with sensible defaults
|
||||
NWNInfo.Version = "1.69";
|
||||
NWNInfo.IsXP1Installed = true;
|
||||
NWNInfo.IsXP2Installed = true;
|
||||
break;
|
||||
case 'l':
|
||||
case 'L':
|
||||
// Turn logging on and set the minimum severity if it was given.
|
||||
NWNLogger.Logging = true;
|
||||
if (arg.Length > 2) NWNLogger.MinimumLogLevel = Convert.ToInt32(arg.Substring(2));
|
||||
break;
|
||||
default:
|
||||
Terminate("Unknown command line argument {0}", arg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We can take one HIF on the command line, if this argument is a HIF and we
|
||||
// don't have our single HIF yet then save it, otherwise it is an invalid
|
||||
// command.
|
||||
if (0 == string.Compare(".hif", Path.GetExtension(arg), true, CultureInfo.InvariantCulture) &&
|
||||
string.Empty == hif)
|
||||
hif = arg;
|
||||
else
|
||||
Terminate("Unknown command line argument {0}", arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Set the log file name to be our application name.
|
||||
NWNLogger.LogFile = Application.ProductName + ".txt";
|
||||
|
||||
// Process command line arguments.
|
||||
ProcessArguments(args);
|
||||
|
||||
// Make sure NWN is installed before doing anything. If the user
|
||||
// gave an install path on the command line we could be installing on
|
||||
// a remote machine, so do not check for an install on this machine.
|
||||
if (!installPathGiven && !NWNInfo.IsInstalled)
|
||||
Terminate("Neverwinter Nights is not installed");
|
||||
|
||||
// Requires .NET framework 1.1
|
||||
// If we are running as the PRC installer or a single HIF OEM reskin, then
|
||||
// show our single HIF form, otherwise show the generic form.
|
||||
Application.EnableVisualStyles();
|
||||
if (string.Empty != hif)
|
||||
Application.Run(new SingleHIFInstallForm());
|
||||
else
|
||||
Application.Run(new InstallForm());
|
||||
}
|
||||
catch (EntryPointNotFoundException)
|
||||
{
|
||||
// Dummy exception thrown to terminate the application by Help(),
|
||||
// don't display anything just return -1.
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ShowMessage(e.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Turn off logging in case it was on this will flush the file.
|
||||
NWNLogger.Logging = false;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
385
trunk/tools/HakInstaller/ModuleInfo.cs
Normal file
385
trunk/tools/HakInstaller/ModuleInfo.cs
Normal file
@@ -0,0 +1,385 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using NWN.FileTypes.Gff;
|
||||
|
||||
namespace NWN.FileTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// This class defines the functionality for a .IFO file, which contains
|
||||
/// information about the module. This is based on the GFF file format;
|
||||
/// this class derives form Gff and provised IFO specific functionality.
|
||||
/// </summary>
|
||||
public class ModuleInfo: NWN.FileTypes.Gff.Gff
|
||||
{
|
||||
#region public properties/methods
|
||||
public const string FileName = "module.ifo";
|
||||
|
||||
/// <summary>
|
||||
/// Indexer allowing get/set access to any of the module's exposed
|
||||
/// properties. Exposed properties are added to the properties
|
||||
/// dictionary, which provides a translation between a human readable
|
||||
/// name and the property's label.
|
||||
/// </summary>
|
||||
public string this[string property]
|
||||
{
|
||||
get
|
||||
{
|
||||
// Look up the property in our dictionary to get the label name, if it
|
||||
// is not there then throw an exception.
|
||||
GffFieldSchema schema = properties[property];
|
||||
if (null == schema) throw new NWNException("{0} is not a valid module property", property);
|
||||
|
||||
// Look up the field for the label. If we cannot look it up then
|
||||
// it has not been added to the module info file, we need to add
|
||||
// it ourselves.
|
||||
GffField field = GetField(schema);
|
||||
|
||||
// Figure out what to return based on the field's type. Currently
|
||||
// only ResRef and ExoString fields are supported.
|
||||
switch (field.Type)
|
||||
{
|
||||
case GffFieldType.ExoString:
|
||||
case GffFieldType.ResRef:
|
||||
return (string) field.Value;
|
||||
default:
|
||||
throw new InvalidCastException("propety is not a text property");
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
// Look up the property in our dictionary to get the label name, if it
|
||||
// is not there then throw an exception.
|
||||
GffFieldSchema schema = properties[property];
|
||||
if (null == schema) throw new NWNException("{0} is not a valid module property", property);
|
||||
|
||||
// Look up the field for the label. If we cannot look it up then
|
||||
// it has not been added to the module info file, we need to add
|
||||
// it ourselves.
|
||||
GffField field = GetField(schema);
|
||||
|
||||
// Figure out what to do based on the field's type, currently only
|
||||
// ResRef and ExoString types are supported.
|
||||
switch (field.Type)
|
||||
{
|
||||
case GffFieldType.ExoString:
|
||||
case GffFieldType.ResRef:
|
||||
field.Value = value;
|
||||
break;
|
||||
default:
|
||||
throw new InvalidCastException("propety is not a text property");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets the custom tlk property.
|
||||
/// </summary>
|
||||
public string CustomTlk
|
||||
{
|
||||
get
|
||||
{
|
||||
// Get the schema for the field and get it, creating it if it is not there.
|
||||
// Then return the field's value.
|
||||
GffFieldSchema schema = properties["customtlk"];
|
||||
GffExoStringField field = (GffExoStringField) GetField(schema);
|
||||
return field.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
// Get the schema for the field and get it, creating it if it is not there.
|
||||
// Then set the field's value.
|
||||
GffFieldSchema schema = properties["customtlk"];
|
||||
GffExoStringField field = (GffExoStringField) GetField(schema);
|
||||
field.Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of haks currently attached to the module.
|
||||
/// </summary>
|
||||
public StringCollection Haks
|
||||
{
|
||||
get
|
||||
{
|
||||
// Get the hak list field.
|
||||
GffListField listField = (GffListField) GetField(properties[HakList]);
|
||||
GffFieldCollection list = listField.Value;
|
||||
|
||||
// Create a string collection object and loop through all of the
|
||||
// structs in the hak list adding the haks.
|
||||
StringCollection haks = new StringCollection();
|
||||
foreach (GffStructField field in list)
|
||||
{
|
||||
// Get the string entry for the value.
|
||||
GffFieldDictionary dict = field.Value;
|
||||
GffField structValue = dict[HakEntry];
|
||||
haks.Add(structValue.Value.ToString());
|
||||
}
|
||||
|
||||
return haks;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class constructor
|
||||
/// </summary>
|
||||
/// <param name="path">The path to the module info file, this should NOT
|
||||
/// contain the file name</param>
|
||||
public ModuleInfo(string path) : base(Path.Combine(path, FileName))
|
||||
{
|
||||
Construct();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class constructor to create the object from a stream, useful for creating
|
||||
/// the module info object without decompressing the module. The current seek
|
||||
/// position of the stream must point to the start of the module info file.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream to read the file data from.</param>
|
||||
public ModuleInfo(Stream stream) : base(stream)
|
||||
{
|
||||
Construct();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the passed hif name / version number to the list of hifs installed on
|
||||
/// the module. Both arrays must be the same length.
|
||||
/// </summary>
|
||||
/// <param name="hifs">The hifs to add</param>
|
||||
/// <param name="versions">The version numbers of the hifs</param>
|
||||
public void AddInstalledHakInfos(string[] hifs, float[] versions)
|
||||
{
|
||||
// Get the current values if any.
|
||||
string[] currentHifs;
|
||||
float[] currentVersions;
|
||||
GetInstalledHakInfos(out currentHifs, out currentVersions);
|
||||
|
||||
// Create StringCollections for them so we can use IndexOf() for searching.
|
||||
StringCollection colHifs = new StringCollection();
|
||||
colHifs.AddRange(currentHifs);
|
||||
ArrayList colVersions = new ArrayList();
|
||||
colVersions.AddRange(currentVersions);
|
||||
|
||||
// Check for duplicates, pruning duplicates out of the current list.
|
||||
foreach (string hif in hifs)
|
||||
{
|
||||
// Find the hif in the current values, if we don't find it then
|
||||
// skip it.
|
||||
int index = colHifs.IndexOf(hif);
|
||||
if (-1 == index) continue;
|
||||
|
||||
// Remove it from the current list.
|
||||
colHifs.RemoveAt(index);
|
||||
colVersions.RemoveAt(index);
|
||||
}
|
||||
|
||||
// Now build a string with all of the current hifs/version numbers then
|
||||
// all of the added hif/version numbers.
|
||||
System.Text.StringBuilder b = new StringBuilder();
|
||||
for (int i = 0; i < colHifs.Count; i++)
|
||||
{
|
||||
if (b.Length > 0) b.Append(";");
|
||||
b.AppendFormat("{0};{1}", colHifs[i], colVersions[i].ToString());
|
||||
}
|
||||
for (int i = 0; i < hifs.Length; i++)
|
||||
{
|
||||
if (b.Length > 0) b.Append(";");
|
||||
b.AppendFormat("{0};{1}", hifs[i], versions[i].ToString());
|
||||
}
|
||||
|
||||
// Get the schema for the field and get it, creating it if it is not there.
|
||||
// Then save the StringBuilder text as the field's value.
|
||||
GffFieldSchema schema = properties["installedhifs"];
|
||||
GffExoStringField field = (GffExoStringField) GetField(schema);
|
||||
field.Value = b.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of hifs that are currently installed on the module, and their version
|
||||
/// numbers.
|
||||
/// </summary>
|
||||
/// <param name="hifs">Returns the list of hifs</param>
|
||||
/// <param name="versions">Returns the version numbers of the hifs</param>
|
||||
public void GetInstalledHakInfos(out string[] hifs, out float[] versions)
|
||||
{
|
||||
// Get the schema for the field and get it, creating it if it is not there.
|
||||
// Then return the field's value.
|
||||
GffFieldSchema schema = properties["installedhifs"];
|
||||
GffExoStringField field = (GffExoStringField) GetField(schema);
|
||||
|
||||
// Split the string into the list of hif and version numbers. If the
|
||||
// field is empty then we will get back 1 string, an empty string.
|
||||
string[] strings = field.Value.Split(';');
|
||||
|
||||
// Create string arrays for the hif names and version numbers.
|
||||
hifs = new string[strings.Length / 2];
|
||||
versions = new float[strings.Length / 2];
|
||||
|
||||
if (strings.Length > 1)
|
||||
{
|
||||
// Fill in the hif/version arrays with the string values.
|
||||
for (int i = 0, index = 0; i < strings.Length; i += 2, index++)
|
||||
hifs[index] = strings[i];
|
||||
for (int i = 1, index = 0; i < strings.Length; i += 2, index++)
|
||||
versions[index] = (float) Convert.ToDouble(strings[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method adds an array of area files to the module info's area list. It prunes
|
||||
/// duplicates before adding the areas.
|
||||
/// </summary>
|
||||
/// <param name="areas"></param>
|
||||
public void AddAreas(string[] areas)
|
||||
{
|
||||
UpdateList(AreaList, AreaEntry, AreaStructID, GffFieldType.ResRef, areas);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method adds an array of hak files to the module info. It prunes
|
||||
/// duplicates before adding the haks.
|
||||
/// </summary>
|
||||
/// <param name="haks">The list of haks to add</param>
|
||||
public void AddHaks(string[] haks)
|
||||
{
|
||||
UpdateList(HakList, HakEntry, HakStructID, GffFieldType.ExoString, haks);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method adds an array of scripts to the module's cache list. It
|
||||
/// prunes duplicates before adding the scripts.
|
||||
/// </summary>
|
||||
/// <param name="scripts">The list of scripts to add</param>
|
||||
public void AddToCache(string[] scripts)
|
||||
{
|
||||
UpdateList(CacheList, CacheEntry, CacheStructID, GffFieldType.ResRef, scripts);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private fields/properties/methods
|
||||
private const string HakList = "Mod_HakList";
|
||||
private const string HakEntry = "Mod_Hak";
|
||||
private const string CacheList = "Mod_CacheNSSList";
|
||||
private const string CacheEntry = "ResRef";
|
||||
private const string AreaList = "Mod_Area_list";
|
||||
private const string AreaEntry = "Area_Name";
|
||||
|
||||
private const uint HakStructID = 8;
|
||||
private const uint CacheStructID = 9;
|
||||
private const uint AreaStructID = 6;
|
||||
|
||||
private GffSchemaCollection properties;
|
||||
|
||||
/// <summary>
|
||||
/// This method constructs the ModuleInfo object.
|
||||
/// </summary>
|
||||
private void Construct()
|
||||
{
|
||||
// Create our property schema, filling it in with the properties we
|
||||
// manipulate. This is not a complete schema, it is only for the
|
||||
// properties considered 'interesting'.
|
||||
properties = new GffSchemaCollection();
|
||||
properties.Add(new GffFieldSchema("onacquireitem", "Mod_OnAcquirItem", GffFieldType.ResRef));
|
||||
properties.Add(new GffFieldSchema("onactivateitem", "Mod_OnActvtItem", GffFieldType.ResRef));
|
||||
properties.Add(new GffFieldSchema("oncliententer", "Mod_OnClientEntr", GffFieldType.ResRef));
|
||||
properties.Add(new GffFieldSchema("onclientleave", "Mod_OnClientLeav", GffFieldType.ResRef));
|
||||
properties.Add(new GffFieldSchema("oncutsceneabort", "Mod_OnCutsnAbort", GffFieldType.ResRef));
|
||||
properties.Add(new GffFieldSchema("onheartbeat", "Mod_OnHeartbeat", GffFieldType.ResRef));
|
||||
properties.Add(new GffFieldSchema("onmoduleload", "Mod_OnModLoad", GffFieldType.ResRef));
|
||||
properties.Add(new GffFieldSchema("onmodulestart", "Mod_OnModStart", GffFieldType.ResRef));
|
||||
properties.Add(new GffFieldSchema("onplayerchat", "Mod_OnPlrChat", GffFieldType.ResRef));
|
||||
properties.Add(new GffFieldSchema("onplayerdeath", "Mod_OnPlrDeath", GffFieldType.ResRef));
|
||||
properties.Add(new GffFieldSchema("onplayerdying", "Mod_OnPlrDying", GffFieldType.ResRef));
|
||||
properties.Add(new GffFieldSchema("onplayerequipitem", "Mod_OnPlrEqItm", GffFieldType.ResRef));
|
||||
properties.Add(new GffFieldSchema("onplayerlevelup", "Mod_OnPlrLvlUp", GffFieldType.ResRef));
|
||||
properties.Add(new GffFieldSchema("onplayerrest", "Mod_OnPlrRest", GffFieldType.ResRef));
|
||||
properties.Add(new GffFieldSchema("onplayerunequipitem", "Mod_OnPlrUnEqItm", GffFieldType.ResRef));
|
||||
properties.Add(new GffFieldSchema("onplayerrespawn", "Mod_OnSpawnBtnDn", GffFieldType.ResRef));
|
||||
properties.Add(new GffFieldSchema("onunaquireitem", "Mod_OnUnAqreItem", GffFieldType.ResRef));
|
||||
properties.Add(new GffFieldSchema("onuserdefined", "Mod_OnUsrDefined", GffFieldType.ResRef));
|
||||
properties.Add(new GffFieldSchema("customtlk", "Mod_CustomTlk", GffFieldType.ExoString));
|
||||
|
||||
// This field is not part of the bioware schema for a module info file, we add it to keep
|
||||
// track of what HIFs have been installed on a module. The value is a string with
|
||||
// the following format "HIF;Version;HIF;Version;...". We make it a string instead of
|
||||
// a list because a list would require us to assign a structure ID, and worry about
|
||||
// BioWare using the ID later.
|
||||
properties.Add(new GffFieldSchema("installedhifs", "InstalledHIFs", GffFieldType.ExoString));
|
||||
|
||||
// These properties aren't exposed out to the user, so we don't give them real names, we just
|
||||
// use the tag as the ui name.
|
||||
properties.Add(new GffFieldSchema("Mod_Area_list", "Mod_Area_list", GffFieldType.List));
|
||||
properties.Add(new GffFieldSchema("Mod_HakList", "Mod_HakList", GffFieldType.List));
|
||||
properties.Add(new GffFieldSchema("Mod_CacheNSSList", "Mod_CacheNSSList", GffFieldType.List));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method updates the cache and hak list properties in the module
|
||||
/// info, adding the passed array of strings to the appropriate property.
|
||||
/// Both of these lists consist of an array of structures with 1 string
|
||||
/// item in each struture.
|
||||
/// </summary>
|
||||
/// <param name="listTag">The property name for the list</param>
|
||||
/// <param name="entryTag">The property name for each string in the list's
|
||||
/// structures</param>
|
||||
/// <param name="structID">The structure ID of the structures in the list</param>
|
||||
/// <param name="stringType">The data type of the string in the list, either
|
||||
/// ExoString or ResRef</param>
|
||||
/// <param name="values">The array of strings to add, duplicates are pruned</param>
|
||||
private void UpdateList(string listTag, string entryTag, uint structID,
|
||||
GffFieldType stringType, string[] values)
|
||||
{
|
||||
// Get the array of elements in the list.
|
||||
GffListField listField = (GffListField) GetField(properties[listTag]);
|
||||
GffFieldCollection list = listField.Value;
|
||||
|
||||
// Create a string collection containing lower case copies of all of
|
||||
// the strings.
|
||||
StringCollection strings = new StringCollection();
|
||||
strings.AddRange(values);
|
||||
for (int i = 0; i < strings.Count; i ++)
|
||||
strings[i] = strings[i].ToLower();
|
||||
|
||||
// Make a first pass and eliminate any strings that are already
|
||||
// in the module.
|
||||
foreach (GffStructField field in list)
|
||||
{
|
||||
// Get the string entry for the value.
|
||||
GffFieldDictionary dict = field.Value;
|
||||
GffField structValue = dict[entryTag];
|
||||
|
||||
// Check to see if the hak is in the list of haks to add if it is
|
||||
// then remove it.
|
||||
int index = strings.IndexOf((string) structValue.Value);
|
||||
if (-1 != index) strings.RemoveAt(index);
|
||||
}
|
||||
|
||||
// Now loop through all of the remaining strings and add them to the
|
||||
// beginning of the list. We walk the list backwards adding the items
|
||||
// to the beginning of the list's collection, so when we are done
|
||||
// all of the added items are in order at the FRONT of the list.
|
||||
for (int i = strings.Count - 1; i >= 0; i--)
|
||||
{
|
||||
// Create a ExoString field for the hak file name.
|
||||
GffField structValue = GffFieldFactory.CreateField(stringType);
|
||||
structValue.Value = strings[i];
|
||||
|
||||
// Create a GffStructField for the new list element and
|
||||
// save the exoString hak name in it.
|
||||
GffStructField listStruct = (GffStructField)
|
||||
GffFieldFactory.CreateField(GffFieldType.Struct);
|
||||
listStruct.StructureType = structID;
|
||||
listStruct.Value = new GffFieldDictionary();
|
||||
listStruct.Value.Add(entryTag, structValue);
|
||||
|
||||
// Add the structure to the list.
|
||||
list.Insert(0, listStruct);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
279
trunk/tools/HakInstaller/NWNInfo.cs
Normal file
279
trunk/tools/HakInstaller/NWNInfo.cs
Normal file
@@ -0,0 +1,279 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace NWN
|
||||
{
|
||||
/// <summary>
|
||||
/// This class encapsulates various information about the NWN application.
|
||||
/// </summary>
|
||||
public class NWNInfo
|
||||
{
|
||||
#region public static properties/methods
|
||||
/// <summary>
|
||||
/// Gets whether or not NWN is installed on this PC.
|
||||
/// </summary>
|
||||
public static bool IsInstalled { get { return singleton.installed; } }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if XP1 is installed.
|
||||
/// </summary>
|
||||
public static bool IsXP1Installed {
|
||||
get { return singleton.isXP1Installed; }
|
||||
set { singleton.isXP1Installed = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if XP2 is installed.
|
||||
/// </summary>
|
||||
public static bool IsXP2Installed {
|
||||
get { return singleton.isXP2Installed; }
|
||||
set { singleton.isXP2Installed = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the OC modules are installed.
|
||||
/// </summary>
|
||||
public static bool IsOCModsInstalled
|
||||
{
|
||||
get
|
||||
{
|
||||
// Return true if all of the modules are on disk.
|
||||
foreach (string module in ocModules)
|
||||
{
|
||||
string file = Path.Combine(NWMPath, module);
|
||||
if (!File.Exists(file)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the XP1 modules are installed.
|
||||
/// </summary>
|
||||
public static bool IsXP1ModsInstalled
|
||||
{
|
||||
get
|
||||
{
|
||||
// Return true if all of the modules are on disk.
|
||||
foreach (string module in xp1Modules)
|
||||
{
|
||||
string file = Path.Combine(NWMPath, module);
|
||||
if (!File.Exists(file)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the XP2 modules are installed.
|
||||
/// </summary>
|
||||
public static bool IsXP2ModsInstalled
|
||||
{
|
||||
get
|
||||
{
|
||||
// Return true if all of the modules are on disk.
|
||||
foreach (string module in xp2Modules)
|
||||
{
|
||||
string file = Path.Combine(NWMPath, module);
|
||||
if (!File.Exists(file)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of OC modules.
|
||||
/// </summary>
|
||||
public static string[] OCModules { get { return ocModules; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of XP1 modules
|
||||
/// </summary>
|
||||
public static string[] XP1Modules { get { return xp1Modules; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of XP2 modules.
|
||||
/// </summary>
|
||||
public static string[] XP2Modules { get { return xp2Modules; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets the path that NWN is installed in. The path may be set to
|
||||
/// allow for the manipulation of NWN on remote installs or for multiple
|
||||
/// installs. If the path is set to string.Empty, then the value will
|
||||
/// revert back to the install path in the registry.
|
||||
/// </summary>
|
||||
public static string InstallPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Empty == singleton.overridePath ?
|
||||
singleton.installPath : singleton.overridePath;
|
||||
}
|
||||
set
|
||||
{
|
||||
singleton.overridePath = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path for the bioware modules.
|
||||
/// </summary>
|
||||
public static string NWMPath { get { return Path.Combine(InstallPath, "nwm"); } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path for the tools subdirectory.
|
||||
/// </summary>
|
||||
public static string ToolsPath { get { return Path.Combine(InstallPath, "Utils"); } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path for the modules subdirectory.
|
||||
/// </summary>
|
||||
public static string ModulesPath { get { return Path.Combine(InstallPath, "Modules"); } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path for the hak info files.
|
||||
/// </summary>
|
||||
public static string HakInfoPath { get { return HakPath; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path for the hak .
|
||||
/// </summary>
|
||||
public static string HakPath { get { return Path.Combine(InstallPath, "hak"); } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the installed NWN version.
|
||||
/// </summary>
|
||||
public static string Version {
|
||||
get { return singleton.version; }
|
||||
set { singleton.version = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the full path for the specified NWN file.
|
||||
/// </summary>
|
||||
/// <param name="file">The NWM file to get the full path for.</param>
|
||||
/// <returns>The full path to the NWM file.</returns>
|
||||
public static string GetFullFilePath(string file)
|
||||
{
|
||||
return Path.Combine(GetPathForFile(file), file);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the partial path (relative to the NWN install directory) of
|
||||
/// the file, i.e. hak\foo.hak, etc.
|
||||
/// </summary>
|
||||
/// <param name="file">The NWM file to get the full path for.</param>
|
||||
/// <returns>The partial path to the NWM file.</returns>
|
||||
public static string GetPartialFilePath(string file)
|
||||
{
|
||||
// Determine the path based on the file's extension. Hif files are
|
||||
// a new file type (hack info) that we use to store information about
|
||||
// what files are contained in a 'hak'.
|
||||
FileInfo info = new FileInfo(file);
|
||||
switch (info.Extension.ToLower())
|
||||
{
|
||||
case ".tlk":
|
||||
return Path.Combine("tlk", file);
|
||||
case ".erf":
|
||||
return Path.Combine("erf", file);
|
||||
case ".hif":
|
||||
case ".hak":
|
||||
return Path.Combine("hak", file);
|
||||
case ".mod":
|
||||
return Path.Combine("modules", file);
|
||||
case ".nwm":
|
||||
return Path.Combine("nwm", file);
|
||||
default:
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method gets the path that the specified NWN file should be
|
||||
/// installed in. It supports .mod, .nwm, .tlk, .erf, .hak file types.
|
||||
/// </summary>
|
||||
/// <param name="file">The file to get the path for</param>
|
||||
/// <returns>The path that the file should be installed in</returns>
|
||||
public static string GetPathForFile(string file)
|
||||
{
|
||||
// Determine the path based on the file's extension. Hif files are
|
||||
// a new file type (hack info) that we use to store information about
|
||||
// what files are contained in a 'hak'.
|
||||
FileInfo info = new FileInfo(file);
|
||||
switch (info.Extension.ToLower())
|
||||
{
|
||||
case ".tlk":
|
||||
return Path.Combine(InstallPath, "tlk");
|
||||
case ".erf":
|
||||
return Path.Combine(InstallPath, "erf");
|
||||
case ".hif":
|
||||
case ".hak":
|
||||
return Path.Combine(InstallPath, "hak");
|
||||
case ".mod":
|
||||
return Path.Combine(InstallPath, "modules");
|
||||
case ".nwm":
|
||||
return Path.Combine(InstallPath, "nwm");
|
||||
}
|
||||
|
||||
// If we get here the file is something we don't know about, return
|
||||
// string.Empty.
|
||||
return string.Empty;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private fields/properties/methods
|
||||
/// <summary>
|
||||
/// Class constructor implemented as private, since the object is a singleton
|
||||
/// and can only be created internally.
|
||||
/// </summary>
|
||||
private NWNInfo()
|
||||
{
|
||||
RegistryKey key = Registry.LocalMachine.OpenSubKey(regPath);
|
||||
|
||||
// If we were able to open up the NWN registry key then NWW is
|
||||
// installed on the PC, save the important registration information.
|
||||
if (null != key)
|
||||
{
|
||||
installed = true;
|
||||
installPath = key.GetValue(regLocation) as string;
|
||||
version = key.GetValue(regVersion) as string;
|
||||
}
|
||||
|
||||
// Check for the XP1 Guid registry entry, if it's there then
|
||||
// mark XP1 as being installed.
|
||||
key = Registry.LocalMachine.OpenSubKey(regXP1Path);
|
||||
if (null != key && null != key.GetValue(regGuid)) isXP1Installed = true;
|
||||
|
||||
// Check for the XP2 Guid registry entry, if it's there then
|
||||
// mark XP2 as being installed.
|
||||
key = Registry.LocalMachine.OpenSubKey(regXP2Path);
|
||||
if (null != key && null != key.GetValue(regGuid)) isXP2Installed = true;
|
||||
}
|
||||
|
||||
// Module lists for the various modules in the OC/XP1/XP2
|
||||
private static string[] ocModules = new string[] { "Prelude.nwm", "Chapter1.nwm", "Chapter1E.nwm",
|
||||
"Chapter2.nwm", "Chapter2E.nwm", "Chapter3.nwm", "Chapter4.nwm" };
|
||||
private static string[] xp1Modules = new string[]
|
||||
{ "XP1-Chapter 1.nwm", "XP1-Interlude.nwm", "XP1-Chapter 2.nwm" };
|
||||
private static string[] xp2Modules = new string[]
|
||||
{ "XP2_Chapter1.nwm", "XP2_Chapter2.nwm", "XP2_Chapter3.nwm" };
|
||||
|
||||
private const string regPath = @"SOFTWARE\BioWare\NWN\Neverwinter";
|
||||
private const string regXP1Path = @"SOFTWARE\BioWare\NWN\Undrentide";
|
||||
private const string regXP2Path = @"SOFTWARE\BioWare\NWN\Underdark";
|
||||
private const string regGuid = "Guid";
|
||||
private const string regLocation = "Location";
|
||||
private const string regVersion = "Version";
|
||||
|
||||
private static NWNInfo singleton = new NWNInfo();
|
||||
|
||||
private string installPath = string.Empty;
|
||||
private string overridePath = string.Empty;
|
||||
private string version = string.Empty;
|
||||
private bool installed = false;
|
||||
private bool isXP1Installed = false;
|
||||
private bool isXP2Installed = false;
|
||||
#endregion
|
||||
}
|
||||
}
|
244
trunk/tools/HakInstaller/OverwriteWarningsForm.cs
Normal file
244
trunk/tools/HakInstaller/OverwriteWarningsForm.cs
Normal file
@@ -0,0 +1,244 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using HakInstaller;
|
||||
using HakInstaller.Utilities;
|
||||
|
||||
namespace HakInstaller
|
||||
{
|
||||
/// <summary>
|
||||
/// This form displays is a comfirmation box asking the user if the
|
||||
/// application should continue with replacing the listed files with
|
||||
/// files from added hak(s).
|
||||
/// </summary>
|
||||
public class OverwriteWarningsForm : System.Windows.Forms.Form
|
||||
{
|
||||
#region public properties/methods
|
||||
/// <summary>
|
||||
/// Class constructor
|
||||
/// </summary>
|
||||
/// <param name="conflicts">The list of file conflicts.</param>
|
||||
public OverwriteWarningsForm(OverwriteWarningCollection warnings,
|
||||
bool fatal, OverwriteWarningType type)
|
||||
{
|
||||
//
|
||||
// Required for Windows Form Designer support
|
||||
//
|
||||
InitializeComponent();
|
||||
|
||||
pictureBox.Image = SystemIcons.Exclamation.ToBitmap();
|
||||
|
||||
// There appears to be a bug in the 1.0 version of the framework. On my
|
||||
// 3.2ghz machine, if listBox.Items.Add(conflict) is placed in the
|
||||
// foreach array it hangs, unless you slow it down somehow. Moving
|
||||
// the add outside the loop and changing it to an AddRange() to add all
|
||||
// of the conflicts in one shot makes it work correctly, thus the change
|
||||
// to the code.
|
||||
|
||||
// Add all of the conflicts to the list box.
|
||||
ListViewItem[] items = new ListViewItem[warnings.Count];
|
||||
for (int i = 0; i < warnings.Count; i++)
|
||||
items[i] = new ListViewItem(new String[]
|
||||
{ warnings[i].Replacer, warnings[i].File, warnings[i].Source });
|
||||
listView.Items.AddRange(items);
|
||||
|
||||
// Load the appropriate prompt text.
|
||||
labelPrompt.Text = StringResources.GetString(type.ToString());
|
||||
|
||||
// If we have fatal errors then turn off the continue button, the user
|
||||
// can only cancel.
|
||||
if (fatal) buttonContinue.Enabled = false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region protected fields/properties/methods
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
protected override void Dispose( bool disposing )
|
||||
{
|
||||
if( disposing )
|
||||
{
|
||||
if(components != null)
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose( disposing );
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region functionality for Win32 PlaySound API
|
||||
[Flags] private enum SoundFlags
|
||||
{
|
||||
Sync = 0x00000000, /* play synchronously (default) */
|
||||
Async = 0x00000001, /* play asynchronously */
|
||||
NoDefault = 0x00000002, /* silence (!default) if sound not found */
|
||||
Memory = 0x00000004, /* pszSound points to a memory file */
|
||||
Loop = 0x00000008, /* loop the sound until next sndPlaySound */
|
||||
NoStop = 0x00000010, /* don't stop any currently playing sound */
|
||||
NoWait = 0x00002000, /* don't wait if the driver is busy */
|
||||
Alias = 0x00010000, /* name is a registry alias */
|
||||
AliasId = 0x00110000, /* alias is a pre d ID */
|
||||
Filename = 0x00020000, /* name is file name */
|
||||
Resource = 0x00040004, /* name is resource name or atom */
|
||||
Purge = 0x00000040, /* purge non-static events for task */
|
||||
Application = 0x00000080 /* look for application specific association */
|
||||
}
|
||||
|
||||
public static void PlaySoundEvent(string sound)
|
||||
{
|
||||
PlaySound(sound, 0,
|
||||
(int) (SoundFlags.Async | SoundFlags.Alias | SoundFlags.NoWait));
|
||||
}
|
||||
|
||||
[DllImport("winmm.dll", EntryPoint="PlaySound",CharSet=CharSet.Auto)]
|
||||
private static extern int PlaySound(String pszSound, int hmod, int flags);
|
||||
#endregion
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
private System.Windows.Forms.Button buttonContinue;
|
||||
private System.Windows.Forms.Button button2;
|
||||
private System.Windows.Forms.PictureBox pictureBox;
|
||||
private System.Windows.Forms.Label labelPrompt;
|
||||
private System.Windows.Forms.ListView listView;
|
||||
private System.Windows.Forms.ColumnHeader columnFile;
|
||||
private System.Windows.Forms.ColumnHeader columnReplacer;
|
||||
private System.Windows.Forms.ColumnHeader columnSource;
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.Container components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.labelPrompt = new System.Windows.Forms.Label();
|
||||
this.buttonContinue = new System.Windows.Forms.Button();
|
||||
this.button2 = new System.Windows.Forms.Button();
|
||||
this.pictureBox = new System.Windows.Forms.PictureBox();
|
||||
this.listView = new System.Windows.Forms.ListView();
|
||||
this.columnReplacer = new System.Windows.Forms.ColumnHeader();
|
||||
this.columnFile = new System.Windows.Forms.ColumnHeader();
|
||||
this.columnSource = new System.Windows.Forms.ColumnHeader();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// labelPrompt
|
||||
//
|
||||
this.labelPrompt.Location = new System.Drawing.Point(72, 16);
|
||||
this.labelPrompt.Name = "labelPrompt";
|
||||
this.labelPrompt.Size = new System.Drawing.Size(488, 40);
|
||||
this.labelPrompt.TabIndex = 0;
|
||||
this.labelPrompt.Text = "Some modules already have some of the content you selected installed. Do you wis" +
|
||||
"h to continue? The install may not work if you continue.";
|
||||
//
|
||||
// buttonContinue
|
||||
//
|
||||
this.buttonContinue.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.buttonContinue.DialogResult = System.Windows.Forms.DialogResult.OK;
|
||||
this.buttonContinue.FlatStyle = System.Windows.Forms.FlatStyle.System;
|
||||
this.buttonContinue.Location = new System.Drawing.Point(16, 296);
|
||||
this.buttonContinue.Name = "buttonContinue";
|
||||
this.buttonContinue.Size = new System.Drawing.Size(80, 26);
|
||||
this.buttonContinue.TabIndex = 2;
|
||||
this.buttonContinue.Text = "C&ontinue";
|
||||
//
|
||||
// button2
|
||||
//
|
||||
this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.button2.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.button2.FlatStyle = System.Windows.Forms.FlatStyle.System;
|
||||
this.button2.Location = new System.Drawing.Point(112, 296);
|
||||
this.button2.Name = "button2";
|
||||
this.button2.Size = new System.Drawing.Size(80, 26);
|
||||
this.button2.TabIndex = 3;
|
||||
this.button2.Text = "&Cancel";
|
||||
//
|
||||
// pictureBox
|
||||
//
|
||||
this.pictureBox.Location = new System.Drawing.Point(24, 16);
|
||||
this.pictureBox.Name = "pictureBox";
|
||||
this.pictureBox.Size = new System.Drawing.Size(32, 32);
|
||||
this.pictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
|
||||
this.pictureBox.TabIndex = 3;
|
||||
this.pictureBox.TabStop = false;
|
||||
//
|
||||
// listView
|
||||
//
|
||||
this.listView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.listView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
|
||||
this.columnReplacer,
|
||||
this.columnFile,
|
||||
this.columnSource});
|
||||
this.listView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
|
||||
this.listView.Location = new System.Drawing.Point(16, 72);
|
||||
this.listView.MultiSelect = false;
|
||||
this.listView.Name = "listView";
|
||||
this.listView.Size = new System.Drawing.Size(568, 208);
|
||||
this.listView.Sorting = System.Windows.Forms.SortOrder.Ascending;
|
||||
this.listView.TabIndex = 4;
|
||||
this.listView.View = System.Windows.Forms.View.Details;
|
||||
//
|
||||
// columnReplacer
|
||||
//
|
||||
this.columnReplacer.Text = "Overwriter";
|
||||
this.columnReplacer.Width = 150;
|
||||
//
|
||||
// columnFile
|
||||
//
|
||||
this.columnFile.Text = "File";
|
||||
this.columnFile.Width = 150;
|
||||
//
|
||||
// columnSource
|
||||
//
|
||||
this.columnSource.Text = "Source";
|
||||
this.columnSource.Width = 240;
|
||||
//
|
||||
// OverwriteWarningsForm
|
||||
//
|
||||
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
|
||||
this.ClientSize = new System.Drawing.Size(600, 334);
|
||||
this.ControlBox = false;
|
||||
this.Controls.Add(this.listView);
|
||||
this.Controls.Add(this.pictureBox);
|
||||
this.Controls.Add(this.buttonContinue);
|
||||
this.Controls.Add(this.labelPrompt);
|
||||
this.Controls.Add(this.button2);
|
||||
this.MinimumSize = new System.Drawing.Size(608, 368);
|
||||
this.Name = "OverwriteWarningsForm";
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Overwriting Existing Content";
|
||||
this.Load += new System.EventHandler(this.ReplacingFilesForm_Load);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region form event handlers
|
||||
/// <summary>
|
||||
/// Handler for the load event.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void ReplacingFilesForm_Load(object sender, System.EventArgs e)
|
||||
{
|
||||
PlaySoundEvent("SystemExclamation");
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region control event handlers
|
||||
#endregion
|
||||
}
|
||||
}
|
193
trunk/tools/HakInstaller/OverwriteWarningsForm.resx
Normal file
193
trunk/tools/HakInstaller/OverwriteWarningsForm.resx
Normal file
@@ -0,0 +1,193 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
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">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</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 forserialized 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.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:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<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" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</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>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="labelPrompt.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="labelPrompt.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="labelPrompt.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="buttonContinue.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="buttonContinue.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="buttonContinue.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="button2.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="button2.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="button2.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="pictureBox.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="pictureBox.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="pictureBox.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="listView.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="listView.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="listView.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="columnReplacer.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="columnReplacer.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="columnFile.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="columnFile.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="columnSource.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="columnSource.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="$this.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Language" type="System.Globalization.CultureInfo, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>(Default)</value>
|
||||
</data>
|
||||
<data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Localizable" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>8, 8</value>
|
||||
</data>
|
||||
<data name="$this.Name">
|
||||
<value>OverwriteWarningsForm</value>
|
||||
</data>
|
||||
<data name="$this.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.TrayHeight" type="System.Int32, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>80</value>
|
||||
</data>
|
||||
<data name="$this.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
</root>
|
87
trunk/tools/HakInstaller/PRCHif.cs
Normal file
87
trunk/tools/HakInstaller/PRCHif.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using NWN;
|
||||
|
||||
namespace HakInstaller
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for PRCHif.
|
||||
/// </summary>
|
||||
public class PRCHif
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the file name of the PRC hif.
|
||||
/// </summary>
|
||||
public static string PRCHifFileName { get { return "PRC Consortium Pack.hif"; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the full path to the PRC hif.
|
||||
/// </summary>
|
||||
public static string PRCHifFullPath { get { return NWNInfo.GetFullFilePath(PRCHifFileName); } }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a temporary HIF file on disk for the PRC pack.
|
||||
/// </summary>
|
||||
public static void CreatePRCHif()
|
||||
{
|
||||
using (StreamWriter writer = new StreamWriter(PRCHifFullPath, false, Encoding.ASCII))
|
||||
{
|
||||
writer.Write(HIF);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String constant for the PRC hif, the PRC version of the installer uses
|
||||
/// this as its HIF instead of looking for HIF files.
|
||||
/// </summary>
|
||||
private const string HIF =
|
||||
"Title : PRC Pack\r\n" +
|
||||
"Version : 2.0\r\n" +
|
||||
"MinNWNVersion : 1.62, XP1, XP2\r\n" +
|
||||
|
||||
"# Erf for the MMM areas\r\n" +
|
||||
"erf : prc_consortium.erf\r\n" +
|
||||
|
||||
"# Haks used by the prc pack.\r\n" +
|
||||
"module.Hak : prc_2das.hak\r\n" +
|
||||
"module.Hak : prc_craft2das.hak\r\n" +
|
||||
"module.Hak : prc_scripts.hak\r\n" +
|
||||
"module.Hak : prc_textures.hak\r\n" +
|
||||
"module.Hak : prc_misc.hak\r\n" +
|
||||
|
||||
"# Custom tlk used by the prc pack.\r\n" +
|
||||
"module.CustomTlk : prc_consortium.tlk\r\n" +
|
||||
|
||||
"# Events that need to be wired up.\r\n" +
|
||||
"module.OnAcquireItem : prc_onaquire\r\n" +
|
||||
"module.OnActivateItem : prc_onactivate\r\n" +
|
||||
"module.OnClientEnter : prc_onenter\r\n" +
|
||||
"module.OnClientLeave : prc_onleave\r\n" +
|
||||
"module.OnCutsceneAbort : prc_oncutabort\r\n" +
|
||||
"module.OnHeartbeat : prc_onheartbeat\r\n" +
|
||||
"module.OnModuleLoad : prc_onmodload\r\n" +
|
||||
"module.OnPlayerDeath : prc_ondeath\r\n" +
|
||||
"module.OnPlayerDying : prc_ondying\r\n" +
|
||||
"module.OnPlayerEquipItem : prc_equip\r\n" +
|
||||
"module.OnPlayerLevelUp : prc_levelup\r\n" +
|
||||
"module.OnPlayerRest : prc_rest\r\n" +
|
||||
"module.OnPlayerRespawn : prc_onrespawn\r\n" +
|
||||
"module.OnUnaquireItem : prc_onunaquire\r\n" +
|
||||
"module.OnPlayerUnequipItem : prc_unequip\r\n" +
|
||||
"module.OnUserDefined : prc_onuserdef\r\n" +
|
||||
|
||||
"# Cache PRC scripts for better performance.\r\n" +
|
||||
"module.Cache : prc_add_spl_pen\r\n" +
|
||||
"module.Cache : prc_add_spell_dc\r\n" +
|
||||
"module.Cache : prc_set_dmg_type\r\n" +
|
||||
"module.Cache : prc_caster_level\r\n" +
|
||||
"module.Cache : prc_onaquire\r\n" +
|
||||
"module.Cache : prc_onactivate\r\n" +
|
||||
"module.Cache : prc_equip\r\n" +
|
||||
"module.Cache : prc_onheartbeat\r\n" +
|
||||
"module.Cache : prc_onunaquire\r\n" +
|
||||
"module.Cache : prc_onuserdef\r\n";
|
||||
|
||||
}
|
||||
}
|
381
trunk/tools/HakInstaller/ReplacingFilesForm.cs
Normal file
381
trunk/tools/HakInstaller/ReplacingFilesForm.cs
Normal file
@@ -0,0 +1,381 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using HakInstaller;
|
||||
using HakInstaller.Utilities;
|
||||
|
||||
namespace HakInstaller
|
||||
{
|
||||
/// <summary>
|
||||
/// This form displays is a comfirmation box asking the user if the
|
||||
/// application should continue with replacing the listed files with
|
||||
/// files from added hak(s).
|
||||
/// </summary>
|
||||
public class ReplacingFilesForm : System.Windows.Forms.Form
|
||||
{
|
||||
#region public properties/methods
|
||||
/// <summary>
|
||||
/// Class constructor
|
||||
/// </summary>
|
||||
/// <param name="conflicts">The list of file conflicts.</param>
|
||||
public ReplacingFilesForm(FileConflictCollection conflicts)
|
||||
{
|
||||
//
|
||||
// Required for Windows Form Designer support
|
||||
//
|
||||
InitializeComponent();
|
||||
|
||||
// Ignore events while initializing the form.
|
||||
ignoreEvents = true;
|
||||
|
||||
pictureBox.Image = SystemIcons.Exclamation.ToBitmap();
|
||||
|
||||
// There appears to be a bug in the 1.0 version of the framework. On my
|
||||
// 3.2ghz machine, if listBox.Items.Add(conflict) is placed in the
|
||||
// foreach array it hangs, unless you slow it down somehow. Moving
|
||||
// the add outside the loop and changing it to an AddRange() to add all
|
||||
// of the conflicts in one shot makes it work correctly, thus the change
|
||||
// to the code.
|
||||
|
||||
// Add all of the conflicts to the list box.
|
||||
FileConflict[] conflictArray = new FileConflict[conflicts.Count];
|
||||
for (int i = 0; i < conflicts.Count; i++)
|
||||
conflictArray[i] = conflicts[i];
|
||||
listBox.Items.AddRange(conflictArray);
|
||||
|
||||
// Loop through all of the conflicts setting their check state as appropriate.
|
||||
foreach (FileConflict conflict in conflicts)
|
||||
{
|
||||
int index = listBox.Items.IndexOf(conflict);
|
||||
listBox.SetItemChecked(index, conflict.ReplaceFile);
|
||||
}
|
||||
|
||||
ignoreEvents = false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region protected fields/properties/methods
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
protected override void Dispose( bool disposing )
|
||||
{
|
||||
if( disposing )
|
||||
{
|
||||
if(components != null)
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose( disposing );
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region functionality for Win32 PlaySound API
|
||||
[Flags] private enum SoundFlags
|
||||
{
|
||||
Sync = 0x00000000, /* play synchronously (default) */
|
||||
Async = 0x00000001, /* play asynchronously */
|
||||
NoDefault = 0x00000002, /* silence (!default) if sound not found */
|
||||
Memory = 0x00000004, /* pszSound points to a memory file */
|
||||
Loop = 0x00000008, /* loop the sound until next sndPlaySound */
|
||||
NoStop = 0x00000010, /* don't stop any currently playing sound */
|
||||
NoWait = 0x00002000, /* don't wait if the driver is busy */
|
||||
Alias = 0x00010000, /* name is a registry alias */
|
||||
AliasId = 0x00110000, /* alias is a pre d ID */
|
||||
Filename = 0x00020000, /* name is file name */
|
||||
Resource = 0x00040004, /* name is resource name or atom */
|
||||
Purge = 0x00000040, /* purge non-static events for task */
|
||||
Application = 0x00000080 /* look for application specific association */
|
||||
}
|
||||
|
||||
public static void PlaySoundEvent(string sound)
|
||||
{
|
||||
PlaySound(sound, 0,
|
||||
(int) (SoundFlags.Async | SoundFlags.Alias | SoundFlags.NoWait));
|
||||
}
|
||||
|
||||
[DllImport("winmm.dll", EntryPoint="PlaySound",CharSet=CharSet.Auto)]
|
||||
private static extern int PlaySound(String pszSound, int hmod, int flags);
|
||||
#endregion
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Button buttonContinue;
|
||||
private System.Windows.Forms.Button button2;
|
||||
private System.Windows.Forms.PictureBox pictureBox;
|
||||
private System.Windows.Forms.CheckedListBox listBox;
|
||||
private System.Windows.Forms.MenuItem menuItemViewHakFile;
|
||||
private System.Windows.Forms.MenuItem menuItemViewModFile;
|
||||
private System.Windows.Forms.ContextMenu contextMenuView;
|
||||
private System.Windows.Forms.Button buttonSelectAll;
|
||||
private System.Windows.Forms.Button buttonClearAll;
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.Container components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.buttonContinue = new System.Windows.Forms.Button();
|
||||
this.button2 = new System.Windows.Forms.Button();
|
||||
this.pictureBox = new System.Windows.Forms.PictureBox();
|
||||
this.listBox = new System.Windows.Forms.CheckedListBox();
|
||||
this.contextMenuView = new System.Windows.Forms.ContextMenu();
|
||||
this.menuItemViewHakFile = new System.Windows.Forms.MenuItem();
|
||||
this.menuItemViewModFile = new System.Windows.Forms.MenuItem();
|
||||
this.buttonSelectAll = new System.Windows.Forms.Button();
|
||||
this.buttonClearAll = new System.Windows.Forms.Button();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.Location = new System.Drawing.Point(72, 16);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(328, 56);
|
||||
this.label1.TabIndex = 0;
|
||||
this.label1.Text = "The following files in the module are being replaced by files in the hak\'s erfs. " +
|
||||
" This may cause the module to not run properly. Select cancel to abort adding " +
|
||||
"the hak, or check the files that you want to replace in the module and select co" +
|
||||
"ntinue.";
|
||||
//
|
||||
// buttonContinue
|
||||
//
|
||||
this.buttonContinue.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.buttonContinue.DialogResult = System.Windows.Forms.DialogResult.OK;
|
||||
this.buttonContinue.FlatStyle = System.Windows.Forms.FlatStyle.System;
|
||||
this.buttonContinue.Location = new System.Drawing.Point(16, 278);
|
||||
this.buttonContinue.Name = "buttonContinue";
|
||||
this.buttonContinue.Size = new System.Drawing.Size(96, 24);
|
||||
this.buttonContinue.TabIndex = 4;
|
||||
this.buttonContinue.Text = "C&ontinue";
|
||||
//
|
||||
// button2
|
||||
//
|
||||
this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.button2.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.button2.FlatStyle = System.Windows.Forms.FlatStyle.System;
|
||||
this.button2.Location = new System.Drawing.Point(128, 278);
|
||||
this.button2.Name = "button2";
|
||||
this.button2.Size = new System.Drawing.Size(96, 24);
|
||||
this.button2.TabIndex = 5;
|
||||
this.button2.Text = "&Cancel";
|
||||
//
|
||||
// pictureBox
|
||||
//
|
||||
this.pictureBox.Location = new System.Drawing.Point(24, 16);
|
||||
this.pictureBox.Name = "pictureBox";
|
||||
this.pictureBox.Size = new System.Drawing.Size(32, 32);
|
||||
this.pictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
|
||||
this.pictureBox.TabIndex = 3;
|
||||
this.pictureBox.TabStop = false;
|
||||
//
|
||||
// listBox
|
||||
//
|
||||
this.listBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.listBox.ContextMenu = this.contextMenuView;
|
||||
this.listBox.Location = new System.Drawing.Point(16, 80);
|
||||
this.listBox.Name = "listBox";
|
||||
this.listBox.Size = new System.Drawing.Size(296, 184);
|
||||
this.listBox.Sorted = true;
|
||||
this.listBox.TabIndex = 1;
|
||||
this.listBox.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.listBox_ItemCheck);
|
||||
//
|
||||
// contextMenuView
|
||||
//
|
||||
this.contextMenuView.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
|
||||
this.menuItemViewHakFile,
|
||||
this.menuItemViewModFile});
|
||||
this.contextMenuView.Popup += new System.EventHandler(this.contextMenuView_Popup);
|
||||
//
|
||||
// menuItemViewHakFile
|
||||
//
|
||||
this.menuItemViewHakFile.Index = 0;
|
||||
this.menuItemViewHakFile.Text = "View &Hak File";
|
||||
this.menuItemViewHakFile.Click += new System.EventHandler(this.menuItemViewHakFile_Click);
|
||||
//
|
||||
// menuItemViewModFile
|
||||
//
|
||||
this.menuItemViewModFile.Index = 1;
|
||||
this.menuItemViewModFile.Text = "View &Module File";
|
||||
this.menuItemViewModFile.Click += new System.EventHandler(this.menuItemViewModFile_Click);
|
||||
//
|
||||
// buttonSelectAll
|
||||
//
|
||||
this.buttonSelectAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.buttonSelectAll.FlatStyle = System.Windows.Forms.FlatStyle.System;
|
||||
this.buttonSelectAll.Location = new System.Drawing.Point(328, 88);
|
||||
this.buttonSelectAll.Name = "buttonSelectAll";
|
||||
this.buttonSelectAll.Size = new System.Drawing.Size(72, 24);
|
||||
this.buttonSelectAll.TabIndex = 2;
|
||||
this.buttonSelectAll.Text = "&Select All";
|
||||
this.buttonSelectAll.Click += new System.EventHandler(this.buttonSelectAll_Click);
|
||||
//
|
||||
// buttonClearAll
|
||||
//
|
||||
this.buttonClearAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.buttonClearAll.FlatStyle = System.Windows.Forms.FlatStyle.System;
|
||||
this.buttonClearAll.Location = new System.Drawing.Point(328, 128);
|
||||
this.buttonClearAll.Name = "buttonClearAll";
|
||||
this.buttonClearAll.Size = new System.Drawing.Size(75, 24);
|
||||
this.buttonClearAll.TabIndex = 3;
|
||||
this.buttonClearAll.Text = "Clear &All";
|
||||
this.buttonClearAll.Click += new System.EventHandler(this.buttonClearAll_Click);
|
||||
//
|
||||
// ReplacingFilesForm
|
||||
//
|
||||
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
|
||||
this.ClientSize = new System.Drawing.Size(416, 310);
|
||||
this.ControlBox = false;
|
||||
this.Controls.Add(this.buttonClearAll);
|
||||
this.Controls.Add(this.buttonSelectAll);
|
||||
this.Controls.Add(this.listBox);
|
||||
this.Controls.Add(this.pictureBox);
|
||||
this.Controls.Add(this.buttonContinue);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.button2);
|
||||
this.MinimumSize = new System.Drawing.Size(424, 344);
|
||||
this.Name = "ReplacingFilesForm";
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Replace Files?";
|
||||
this.Load += new System.EventHandler(this.ReplacingFilesForm_Load);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private fields/properties/methods
|
||||
private bool ignoreEvents;
|
||||
#endregion
|
||||
|
||||
#region form event handlers
|
||||
/// <summary>
|
||||
/// Handler for the load event.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void ReplacingFilesForm_Load(object sender, System.EventArgs e)
|
||||
{
|
||||
PlaySoundEvent("SystemExclamation");
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region control event handlers
|
||||
/// <summary>
|
||||
/// Handler for the list box's item check event.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void listBox_ItemCheck(object sender, System.Windows.Forms.ItemCheckEventArgs e)
|
||||
{
|
||||
if (ignoreEvents) return;
|
||||
|
||||
// Update the ReplaceFile property of the FileConflict object being clicked on
|
||||
// based on the new state of the check.
|
||||
FileConflict conflict = (FileConflict) listBox.Items[e.Index];
|
||||
conflict.ReplaceFile = CheckState.Checked == e.NewValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for the view hak file menu pick, just runs wordpad to view
|
||||
/// the file (only works for text files obviously).
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void menuItemViewHakFile_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
// Just run wordpad to view the file.
|
||||
FileConflict conflict = (FileConflict) listBox.SelectedItem;
|
||||
string args = "\"" + conflict.HakFile + "\"";
|
||||
System.Diagnostics.Process.Start("wordpad.exe", args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for the view module file menu pick, just runs wordpad to view
|
||||
/// the file (only works for text files obviously).
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void menuItemViewModFile_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
// Just run notepad to view the file.
|
||||
FileConflict conflict = (FileConflict) listBox.SelectedItem;
|
||||
string args = "\"" + conflict.ModuleFile + "\"";
|
||||
System.Diagnostics.Process.Start("wordpad.exe", args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler ofr the context menu's popup event, enables/disables menu items
|
||||
/// and sets their text appropriately.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void contextMenuView_Popup(object sender, System.EventArgs e)
|
||||
{
|
||||
int index = listBox.SelectedIndex;
|
||||
FileConflict conflict = index >= 0 ? (FileConflict) listBox.SelectedItem : null;
|
||||
|
||||
// Menu picks are only enabled if a script source ".NSS" file is selected.
|
||||
bool enabled = index >= 0 &&
|
||||
0 == string.Compare(Path.GetExtension(conflict.FileName), ".nss", true, CultureInfo.InvariantCulture);
|
||||
|
||||
menuItemViewHakFile.Enabled = enabled;
|
||||
menuItemViewModFile.Enabled = enabled;
|
||||
|
||||
// Glue the selected file name onto the menu picks if they are enabled.
|
||||
if (enabled)
|
||||
{
|
||||
menuItemViewHakFile.Text = StringResources.GetString("ViewHakFileFormat",
|
||||
listBox.SelectedItem.ToString());
|
||||
menuItemViewModFile.Text = StringResources.GetString("ViewModFileFormat",
|
||||
listBox.SelectedItem.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
menuItemViewHakFile.Text = StringResources.GetString("ViewHakFile");
|
||||
menuItemViewModFile.Text = StringResources.GetString("ViewModFile");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for the select all button, selects all files for replacing
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void buttonSelectAll_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
listBox.BeginUpdate();
|
||||
for (int i = 0; i < listBox.Items.Count; i++)
|
||||
listBox.SetItemChecked(i, true);
|
||||
listBox.EndUpdate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for the clear all button, clears all files to prevent replacement.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void buttonClearAll_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
listBox.BeginUpdate();
|
||||
for (int i = 0; i < listBox.Items.Count; i++)
|
||||
listBox.SetItemChecked(i, false);
|
||||
listBox.EndUpdate();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
214
trunk/tools/HakInstaller/ReplacingFilesForm.resx
Normal file
214
trunk/tools/HakInstaller/ReplacingFilesForm.resx
Normal file
@@ -0,0 +1,214 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
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">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</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 forserialized 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.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:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<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" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</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>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="label1.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="label1.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="label1.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="buttonContinue.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="buttonContinue.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="buttonContinue.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="button2.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="button2.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="button2.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="pictureBox.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="pictureBox.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="pictureBox.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="listBox.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="listBox.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="listBox.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="contextMenuView.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="contextMenuView.Location" type="System.Drawing.Point, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</data>
|
||||
<data name="contextMenuView.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="menuItemViewHakFile.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="menuItemViewHakFile.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="menuItemViewModFile.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="menuItemViewModFile.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="buttonSelectAll.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="buttonSelectAll.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="buttonSelectAll.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="buttonClearAll.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="buttonClearAll.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="buttonClearAll.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="$this.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Language" type="System.Globalization.CultureInfo, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>(Default)</value>
|
||||
</data>
|
||||
<data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Localizable" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>8, 8</value>
|
||||
</data>
|
||||
<data name="$this.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.Name">
|
||||
<value>ReplacingFilesForm</value>
|
||||
</data>
|
||||
<data name="$this.TrayHeight" type="System.Int32, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>80</value>
|
||||
</data>
|
||||
<data name="$this.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
</root>
|
BIN
trunk/tools/HakInstaller/Ship/HakInstaller.exe
Normal file
BIN
trunk/tools/HakInstaller/Ship/HakInstaller.exe
Normal file
Binary file not shown.
BIN
trunk/tools/HakInstaller/Ship/HakInstaller.vshost.exe
Normal file
BIN
trunk/tools/HakInstaller/Ship/HakInstaller.vshost.exe
Normal file
Binary file not shown.
BIN
trunk/tools/HakInstaller/Ship/HakInstallerCmdLine.exe
Normal file
BIN
trunk/tools/HakInstaller/Ship/HakInstallerCmdLine.exe
Normal file
Binary file not shown.
135
trunk/tools/HakInstaller/Ship/PRC Pack.hif
Normal file
135
trunk/tools/HakInstaller/Ship/PRC Pack.hif
Normal file
@@ -0,0 +1,135 @@
|
||||
# HIF files may consist of any of the following tags. All tags are optional.
|
||||
# Tags that support multiple data items may have the data comma separated and/or
|
||||
# may have multiple entries. If a multiple entries are given for a tag that only
|
||||
# supports 1 value then the fist value in the file is used. Blank lines are ignored
|
||||
# as are lines starting with a '#'.
|
||||
#
|
||||
# Tag format is
|
||||
#
|
||||
# <tag> : <value1>, <value2>, ..., <valuen>
|
||||
#
|
||||
# All white space is optional, and tags may also be given on multiple lines
|
||||
# as follows:
|
||||
#
|
||||
# <tag> : <value1>
|
||||
# <tag> : <value2>
|
||||
# ...
|
||||
# <tag> : <valuen>
|
||||
#
|
||||
# The following tags are supported:
|
||||
#
|
||||
# Title : Allows you to specify the title for the HIF, if the installer is run in
|
||||
# single HIF mode then the installer's title bar will have the HIF's title,
|
||||
# or file name if the HIF has no title. The format of the title is
|
||||
# <HIF TITLE> Module Updater <HIF VERSION>
|
||||
# Version : Allows you to specify the version number for your content. Modules
|
||||
# that the HIF is added to are tagged with the version number.
|
||||
# MinNWNVersion : Allows you to specify the minimum version of NWN that is required,
|
||||
# and whether your content requies XP1 or XP2. For the NWN version use the
|
||||
# standard format, i.e. 1.62, 1.31, etc. For the Expansions use XP1 or
|
||||
# Undrentide for SoU and XP2 or Underdark for HotU. If you list multiple
|
||||
# requirements separate them by commas. For example:
|
||||
# MinNWNVersion : 1.62, XP1, XP2
|
||||
# will make your content require NWN 1.62 or later and both expansions.
|
||||
# erf : Imports the listed erf files into the module
|
||||
# module.Hak : haks to add to the module
|
||||
# module.CustomTlk : Custom tlk file for the module, only 1 value.
|
||||
# module.Cache : Adds the given scripts the module's script cache.
|
||||
# module.Areas: Adds the given ResRefs to the module's area list.
|
||||
# module.OnAcquireItem : Assigns script(s) to handle this module event
|
||||
# module.OnActivateItem : Assigns script(s) to handle this module event
|
||||
# module.OnClientEnter : Assigns script(s) to handle this module event
|
||||
# module.OnClientLeave : Assigns script(s) to handle this module event
|
||||
# module.OnCutsceneAbort : Assigns script(s) to handle this module event
|
||||
# module.OnHeartbeat : Assigns script(s) to handle this module event
|
||||
# module.OnModuleLoad : Assigns script(s) to handle this module event
|
||||
# module.OnModuleStart : Assigns script(s) to handle this module event
|
||||
# module.OnPlayerDeath : Assigns script(s) to handle this module event
|
||||
# module.OnPlayerDying : Assigns script(s) to handle this module event
|
||||
# module.OnPlayerEquipItem : Assigns script(s) to handle this module event
|
||||
# module.OnPlayerLevelUp : Assigns script(s) to handle this module event
|
||||
# module.OnPlayerRest : Assigns script(s) to handle this module event
|
||||
# module.OnPlayerUnEquipItem : Assigns script(s) to handle this module event
|
||||
# module.OnPlayerRespawn : Assigns script(s) to handle this module event
|
||||
# module.OnUnaquireItem : Assigns script(s) to handle this module event
|
||||
# module.OnUserDefined : Assigns script(s) to handle this module event
|
||||
|
||||
# Title for the HIF.
|
||||
Title : PRC
|
||||
|
||||
# Add the PRC pack version and specify at least 1.62 to install.
|
||||
Version : 3.7.0Alpha
|
||||
MinNWNVersion: 1.67
|
||||
|
||||
# ERF with the required areas.
|
||||
erf : prc_consortium.erf
|
||||
|
||||
# Haks used by the prc pack.
|
||||
#commented out since its not actually needed in a module and causing CEP conflicts.
|
||||
# module.Hak : prc_include.hak
|
||||
module.Hak : prc_2das.hak
|
||||
module.Hak : prc_scripts.hak
|
||||
module.Hak : prc_newspellbook.hak
|
||||
module.Hak : prc_spells.hak
|
||||
module.Hak : prc_epicspells.hak
|
||||
module.Hak : prc_psionics.hak
|
||||
module.Hak : prc_race.hak
|
||||
module.Hak : prc_textures.hak
|
||||
module.Hak : prc_misc.hak
|
||||
module.Hak : prc_craft2das.hak
|
||||
|
||||
# Custom tlk used by the prc pack.
|
||||
module.CustomTlk : prc_consortium.tlk
|
||||
|
||||
# Events that need to be wired up.
|
||||
module.OnAcquireItem : prc_onaquire
|
||||
module.OnActivateItem : prc_onactivate
|
||||
module.OnClientEnter : prc_onenter
|
||||
module.OnClientLeave : prc_onleave
|
||||
module.OnCutsceneAbort : prc_oncutabort
|
||||
module.OnHeartbeat : prc_onheartbeat
|
||||
module.OnModuleLoad : prc_onmodload
|
||||
module.OnPlayerChat : prc_onplayerchat
|
||||
module.OnPlayerDeath : prc_ondeath
|
||||
module.OnPlayerDying : prc_ondying
|
||||
module.OnPlayerEquipItem : prc_equip
|
||||
module.OnPlayerLevelUp : prc_levelup
|
||||
module.OnPlayerRest : prc_rest
|
||||
module.OnPlayerRespawn : prc_onrespawn
|
||||
module.OnUnaquireItem : prc_onunaquire
|
||||
module.OnPlayerUnequipItem : prc_unequip
|
||||
module.OnUserDefined : prc_onuserdef
|
||||
|
||||
# Cache PRC scripts for better performance.
|
||||
module.Cache : prc_onaquire
|
||||
module.Cache : prc_onactivate
|
||||
module.Cache : prc_onenter
|
||||
module.Cache : prc_onleave
|
||||
module.Cache : prc_oncutabort
|
||||
module.Cache : prc_onheartbeat
|
||||
module.Cache : prc_onmodload
|
||||
module.Cache : prc_ondeath
|
||||
module.Cache : prc_ondying
|
||||
module.Cache : prc_equip
|
||||
module.Cache : prc_levelup
|
||||
module.Cache : prc_rest
|
||||
module.Cache : prc_onplayerchat
|
||||
module.Cache : prc_onrespawn
|
||||
module.Cache : prc_onunaquire
|
||||
module.Cache : prc_unequip
|
||||
module.Cache : prc_onuserdef
|
||||
module.Cache : prc_onhitcast
|
||||
# Cache bioware summon AI scripts
|
||||
module.Cache : nw_ch_ac5
|
||||
module.Cache : nw_ch_ace
|
||||
module.Cache : nw_ch_ac3
|
||||
module.Cache : nw_ch_ac4
|
||||
module.Cache : nw_ch_ac6
|
||||
module.Cache : nw_ch_ac7
|
||||
module.Cache : nw_ch_ac8
|
||||
module.Cache : nw_ch_ac1
|
||||
module.Cache : nw_ch_ac2
|
||||
module.Cache : nw_ch_aca
|
||||
module.Cache : nw_ch_summon_9
|
||||
module.Cache : nw_ch_acb
|
||||
module.Cache : nw_ch_acd
|
284
trunk/tools/HakInstaller/Ship/readme.txt
Normal file
284
trunk/tools/HakInstaller/Ship/readme.txt
Normal file
@@ -0,0 +1,284 @@
|
||||
IMPORTANT NOTES
|
||||
===============
|
||||
|
||||
This tool REQUIRES version 1.0 of the Microsoft .NET Framework,
|
||||
this is available for download at:
|
||||
|
||||
http://www.microsoft.com/downloads/details.aspx?familyid=D7158DEE-A83F-4E21-B05A-009D06457787&displaylang=en
|
||||
|
||||
|
||||
GENERAL INFORMATION
|
||||
===================
|
||||
|
||||
HakInstaller is a tool that allows you to easily add player based haks
|
||||
to modules. A player based hak is a hak whose contents are intended
|
||||
for the player, rather than the module designer. For example the PRC
|
||||
Consortium's PRC pack. I wrote this tool because I got sick of having
|
||||
to add these haks to module after module as I played them, and having
|
||||
to remember to do all of the steps correctly (often forgetting one).
|
||||
Two versions of the tool are included, a windowed version and a command
|
||||
line version. The command line version is suitable for being invoked
|
||||
from batch files (or even NWNX) whereas the full UI version is more
|
||||
suitable to the individual player.
|
||||
|
||||
The application takes a 'hak' (in this case a 'hak' is a collection of
|
||||
one or more hak, erf, and tlk files, and adds/merges them (as appropriate)
|
||||
to a module, and also sets up any required module event that the hak
|
||||
may need to handle to work correctly. If the module already has scripts
|
||||
attached to the events, then the tool will create a new script that
|
||||
executes both the old script and the haks's script. In a nutshell, this
|
||||
allows you to add haks to a module by pressing a button and letting the
|
||||
tool do all the work, rather than you having to go through a checklist
|
||||
of steps, possibly missing one.
|
||||
|
||||
The tool gets the configuration information for a hak from hif files
|
||||
(hak information), these files are text files that contain configuration
|
||||
information, THEY SHOULD BE PLACED IN YOUR NWN HAK DIRECTORY, the tool
|
||||
will look for them there. The tool comes with hif files for the PRC
|
||||
Consortium's PRC pack, my spell pak, and the PRC merge version of my
|
||||
spell pak, but there is nothing to stop anyone else from making hif
|
||||
definitions for other haks.
|
||||
|
||||
If all you want to do is use the tool to add the PRC pack or spell pak
|
||||
to modules, just copy the hif files into NWN's hak directory and double
|
||||
click HakInstaller.exe.
|
||||
|
||||
To use the windows UI version just double click on HakInstaller.exe,
|
||||
it will present you with a list of haks that have hif files on the left
|
||||
and a list of all of your installed modules on the right, check the haks
|
||||
that you want to install and check the modules you want them installed
|
||||
in and click install, it will then add/merge the hak content to all of
|
||||
your selected modules. If there are any file conflicts (for example,
|
||||
suppose you merge the prc pack hak into a module that has changed some
|
||||
spell scripts, a warning dialog will be displayed showing you the files
|
||||
that are going to be overwritten asking for your permission to overwrite
|
||||
them. You can check the files you want to overwrite in the module (by
|
||||
default they are all checked) and you can view the hak / module scripts
|
||||
in wordpad to compare them. To view a script file, select it then right
|
||||
click in the list box, you will get a menu.
|
||||
|
||||
To use the command line version run it from the command line, passing it
|
||||
all the .hif and .mod files you want to use on the command line. It will
|
||||
then do the same thing as the windows UI version, except that it will not
|
||||
warn you about overwriting files, it will just overwrite them.
|
||||
|
||||
Both versions of the tool read your NWN installation information from
|
||||
the windows registry, if you are running the tools on a PC other than the
|
||||
one that NWN is installed on (or you are running them under mono on linux)
|
||||
then you must use the -n<path> command line option to specify the install
|
||||
path of NWN.
|
||||
|
||||
|
||||
FOR CONTENT CREATORS
|
||||
====================
|
||||
|
||||
While my utility was designed for the spell pak (now deceased) and PRC
|
||||
pack, anyone making player based haks can take advantage of the tool to
|
||||
install their content into modules. All you need to do is write the
|
||||
HIF describing the content of your 'hak' and package that along with
|
||||
the installer (just give me credit for the installer) in your shipping
|
||||
file (zip, rar, whatever).
|
||||
|
||||
To facilitate this, version 2.0 (and later) support running in single HIF
|
||||
mode; this is done by passing a HIF on the command line. If this is done
|
||||
the list box of HIFs will not be shown, instead the application will reskin
|
||||
to just list modules and the title of the application will be your HIFs
|
||||
Title, or the file name if the HIF has no title.
|
||||
|
||||
To make support easier the installer will validate all of the files described
|
||||
in your hif are present on disk, if for some reason they aren't then an
|
||||
error message will be displayed and the HIF will not be added to the list of
|
||||
HIFs (if in single HIF mode the application will just exit).
|
||||
|
||||
You can also specify a minimum NWN version, and whether you require XP1 and
|
||||
XP2 installed, if the installed version of NWN does not meet the requirements
|
||||
you specify then the install will fail as above.
|
||||
|
||||
The tool supports tlk file merging between the module's tlk file (if it has
|
||||
one) and any tlk files contained in the HIF. You may specify multiple tlk
|
||||
files in the hif, at run time the tool will attempt to build a single tlk file
|
||||
by merging all of the HIF tlk files with the module tlk file. If this is
|
||||
successful then that tlk file will be used for the module, if it fails for any
|
||||
reason (most likely entries being used in duplicate tlk files) it will display
|
||||
an error message and abort adding the content to the module. In order for the
|
||||
merge to succeed, none of the tlk files can have strings at the same location,
|
||||
for example if tlk1.tlk contains "foo" at entry 100 and "tlk2.tlk" contains
|
||||
"bar" at entry 100 then the merge will fail. The lone exception to this is
|
||||
that multiple tlk files may have "Bad Strref" at location 0, it will ignore
|
||||
all of the duplicates in this case.
|
||||
|
||||
The tool supports 2da file merging between the module's haks (if any) and
|
||||
any 2da's contained in the HIF. The tool will attempt to generate a merge
|
||||
hak (and place it at the top of the hak list) containing merged copies of
|
||||
all of the conflicting 2da's. If for some reason any of the 2da's cannot
|
||||
be successfully merged the tool will still attempt to merge any other conflicting
|
||||
2da's.
|
||||
|
||||
If a merge hak and/or tlk were generated it will tell the user so that they
|
||||
can delete the files when they are finished with the module.
|
||||
|
||||
|
||||
VERSION HISTORY
|
||||
===============
|
||||
|
||||
2.5 - Added support for 1.69 patch XP3.bif/key also for the OnPlayerChat
|
||||
event.
|
||||
|
||||
2.2 - Enhanced the 2da merging logic. The installer can now merge changes
|
||||
made by multiple haks to the same row as long as the row is a modified bioware
|
||||
row and no 2 haks change the same column with a different value. Various
|
||||
bug fixes.
|
||||
|
||||
2.0 - Various bug fixes.
|
||||
|
||||
2.0 Beta 2 - Various bug fixes, CEP HIF.
|
||||
|
||||
2.0 - Added Title, Version, and MinNWNVersion keywords to the HIF scripts.
|
||||
Changes to support a single HIF skin if a HIF is passed on the command line,
|
||||
allowing content creators to use the installer as their dedicated "install"
|
||||
program to update modules. Added HIF content checking, the installer now
|
||||
validates that all files described in the HIF are actually present on disk,
|
||||
displaying an error message (and not installing the HIF) if they are not.
|
||||
Added the ability of HIFs to specify a minimum required version of NWN, the
|
||||
HIF will not install if the user's version of NWN is less than the required
|
||||
version.
|
||||
|
||||
Added support for merging conflicting tlk files and creating a merge tlk file
|
||||
to be used by the module.
|
||||
|
||||
Added support for merging conflicting 2da files across all HIFs and creating
|
||||
a merge hak containing merged versions of the 2da's.
|
||||
|
||||
2.4 - Synced version with module updater, fixed bug to make the installer work
|
||||
with 2da items with spaces in them.
|
||||
|
||||
1.41 - Recompiled for .NET Framework 1.1. Fixed a bug adding heartbeat
|
||||
events.
|
||||
|
||||
1.4 - Added support for adding areas to modules in the HIF. Added support
|
||||
for BMU music files in erfs/haks/modules.
|
||||
|
||||
1.32 Fixed duplicate key bug.
|
||||
|
||||
1.31 Fixed a bug that caused the window to not come up centered. Changed
|
||||
the content check list box to be single selection, since this was causing
|
||||
some confusion.
|
||||
|
||||
1.3 Changed to add any areas in added content to the module's area list to fix
|
||||
a bug introduced in 1.62. Added support for the OC/XP1/XP2. Changed the
|
||||
installer check to see if content has already been installed in modules, and
|
||||
warn the user before continuing. Added extensive overwrite checking, it
|
||||
will now check the module and all it's haks vs. the content being added
|
||||
to make sure nobody overwrites anybody else. Fixed the bug with GFF
|
||||
versions. Fixed the bug with "imput string is not in the correct format".
|
||||
|
||||
1.22 Fixed a bug that cause an exception if you did not overwrite replaced
|
||||
files.
|
||||
|
||||
1.21 Updates HIF files for PRC pack 1.9
|
||||
|
||||
1.2 Changed the replace file dialog so that you can selectively replace files,
|
||||
and view script files (.NSS) in wordpad.
|
||||
|
||||
1.1 Fixed a bug that made certain ExoLoc strings crash the application.
|
||||
|
||||
1.0 Initial version
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
APPENDIX 1 - SAMPLE HIF FILE
|
||||
============================
|
||||
|
||||
The sample hif files contain comments in them that document the layout and
|
||||
syntax of a hif file, this appendix assumes that you have already looked
|
||||
at one of the sample hif files, I will go over the prc_consortium.hif file
|
||||
here and show what is happening.
|
||||
|
||||
First, here is the contents of the hif file (minus the giant comment at the
|
||||
top describing the format of hif files):
|
||||
|
||||
# Custom Content title and version number.
|
||||
Title : PRC Pack
|
||||
Version : 2.0
|
||||
|
||||
# Specify that the user must have both expansions installed and 1.62
|
||||
MinNWNVersion : 1.62, XP1, XP2
|
||||
|
||||
# Import there ERF files into the module.
|
||||
erf : prc_consortium.erf
|
||||
|
||||
# Haks and custom tlk's used by the module.
|
||||
module.Hak : prc_consortium.hak
|
||||
module.CustomTlk : prc_consortium.tlk
|
||||
|
||||
# Events that need to be wired up.
|
||||
module.OnClientEnter : prc_onenter
|
||||
module.OnPlayerLevelUp : prc_levelup
|
||||
module.OnPlayerEquipItem : prc_equip
|
||||
module.OnPlayerUnequipItem : prc_unequip
|
||||
|
||||
# Cache PRC scripts for better performance.
|
||||
module.Cache : screen_targets
|
||||
module.Cache : prc_caster_level
|
||||
module.Cache : set_damage_type
|
||||
module.Cache : change_metamagic
|
||||
module.Cache : add_spell_dc
|
||||
module.Cache : add_spell_penetr
|
||||
module.Cache : add_damage
|
||||
module.Cache : add_damageshield
|
||||
module.Cache : add_randdamage
|
||||
module.Cache : add_healing
|
||||
module.Cache : add_hitpoints
|
||||
|
||||
|
||||
First there is a single erf given, prc_consortium.erf. The tool merges the
|
||||
contents of all erf files into the module, so all of the files in
|
||||
prc_consortium.erf will be added to the module.
|
||||
|
||||
It will then add prc_consortium.hak to the module's hak list (if multiple
|
||||
haks are specified they will be added in the order they are in the hif
|
||||
file, which means hak files listed first will take precedence over hak files
|
||||
listed later).
|
||||
|
||||
prc_consortium.tlk will be set as the module's custom tlk file.
|
||||
|
||||
The scripts prc_onenter, prc_levelup, prc_equip, and prc_unequip will be added
|
||||
to the OnClientEnter, OnPlayerLevelUp, OnPlayerEquipItem, and OnPlayerUnequipItem
|
||||
module events. If any of these events already have scripts attached, then
|
||||
the tool will create a new script, naming it "hif_<EventName>" (truncating to
|
||||
16 characters) and will then add ExecuteScript() calls to execute the old
|
||||
script and the appropriate PRC script.
|
||||
|
||||
You will notice that the above steps are what the PRC pack's read me tell you to
|
||||
do to each module you add the pack to.
|
||||
|
||||
One final step has been added, which is a speed optomization. The scripts
|
||||
screen_targets, prc_caster_level, set_damage_type, change_metamagic,
|
||||
add_spell_dc, add_spell_penetr, add_damage, add_damageshield, add_randdamage,
|
||||
add_healing, and add_hitpoints will be added to the module's script cache.
|
||||
This step is not strictly required to get the PRC pack to work, however it
|
||||
will increase the speed at which the pack runs. These scripts are called
|
||||
internally when any spell (or some feats) are used, adding them to the cache
|
||||
prevents the NWN engine from having to load them each time you cast a spell.
|
||||
|
||||
CAVEATS
|
||||
|
||||
The tool does not update the palette files, so any blueprint templates imported
|
||||
from erf's will not show up in the toolset until you right click in the
|
||||
appropriate custom palette and do a refresh.
|
||||
|
||||
The tool DOES NOT rebuild the module like the BioWare toolset
|
||||
does whenever you add a hak. If a hak/erf that the hif is importing contains
|
||||
a modified BioWare script include file, then the module will not work properly
|
||||
without being recompiled in the toolset. For haks like this you will still
|
||||
have to open the module in the toolset after HakInstaller is done and do a
|
||||
rebuild of the module. For example if you use the tool to import a hif that
|
||||
overwrote the include file for the default combat AI, none of the changes would
|
||||
take effect on any of the module's creatures until you opened the module in
|
||||
the toolset and did a build (the include file is there but since no scrips have
|
||||
been recompiled none of them know about the changes).
|
273
trunk/tools/HakInstaller/SingleHIFInstallForm.cs
Normal file
273
trunk/tools/HakInstaller/SingleHIFInstallForm.cs
Normal file
@@ -0,0 +1,273 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using HakInstaller.Utilities;
|
||||
using NWN;
|
||||
|
||||
namespace HakInstaller
|
||||
{
|
||||
/// <summary>
|
||||
/// This is the main form of the HakInstaller application.
|
||||
/// </summary>
|
||||
public class SingleHIFInstallForm : InstallFormBase
|
||||
{
|
||||
#region public methods/properties.
|
||||
/// <summary>
|
||||
/// Class constructor
|
||||
/// </summary>
|
||||
public SingleHIFInstallForm()
|
||||
{
|
||||
//
|
||||
// Required for Windows Form Designer support
|
||||
//
|
||||
InitializeComponent();
|
||||
|
||||
SetLabels(labelVersion, labelPath);
|
||||
|
||||
// Validate our HIF to make sure we can really install.
|
||||
ValidateHIF();
|
||||
|
||||
// Save the HIF title as the title for our form.
|
||||
Text = StringResources.GetString("SingleHIFTitle", hif.Title,
|
||||
hif.VersionText);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
protected override void Dispose( bool disposing )
|
||||
{
|
||||
if( disposing )
|
||||
{
|
||||
if (components != null)
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose( disposing );
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
private System.Windows.Forms.Label labelVersion;
|
||||
private System.Windows.Forms.Button buttonInstall;
|
||||
private System.Windows.Forms.Button buttonCancel;
|
||||
private System.Windows.Forms.CheckedListBox checkedModules;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.Label labelPath;
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.Container components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(SingleHIFInstallForm));
|
||||
this.labelVersion = new System.Windows.Forms.Label();
|
||||
this.buttonInstall = new System.Windows.Forms.Button();
|
||||
this.buttonCancel = new System.Windows.Forms.Button();
|
||||
this.checkedModules = new System.Windows.Forms.CheckedListBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.labelPath = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// labelVersion
|
||||
//
|
||||
this.labelVersion.Location = new System.Drawing.Point(24, 8);
|
||||
this.labelVersion.Name = "labelVersion";
|
||||
this.labelVersion.Size = new System.Drawing.Size(240, 16);
|
||||
this.labelVersion.TabIndex = 0;
|
||||
//
|
||||
// buttonInstall
|
||||
//
|
||||
this.buttonInstall.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.buttonInstall.Enabled = false;
|
||||
this.buttonInstall.FlatStyle = System.Windows.Forms.FlatStyle.System;
|
||||
this.buttonInstall.Location = new System.Drawing.Point(24, 280);
|
||||
this.buttonInstall.Name = "buttonInstall";
|
||||
this.buttonInstall.Size = new System.Drawing.Size(64, 24);
|
||||
this.buttonInstall.TabIndex = 6;
|
||||
this.buttonInstall.Text = "&Install";
|
||||
this.buttonInstall.Click += new System.EventHandler(this.buttonInstall_Click);
|
||||
//
|
||||
// buttonCancel
|
||||
//
|
||||
this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.buttonCancel.FlatStyle = System.Windows.Forms.FlatStyle.System;
|
||||
this.buttonCancel.Location = new System.Drawing.Point(104, 280);
|
||||
this.buttonCancel.Name = "buttonCancel";
|
||||
this.buttonCancel.Size = new System.Drawing.Size(64, 24);
|
||||
this.buttonCancel.TabIndex = 7;
|
||||
this.buttonCancel.Text = "&Close";
|
||||
this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click);
|
||||
//
|
||||
// checkedModules
|
||||
//
|
||||
this.checkedModules.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.checkedModules.CheckOnClick = true;
|
||||
this.checkedModules.Location = new System.Drawing.Point(24, 96);
|
||||
this.checkedModules.Name = "checkedModules";
|
||||
this.checkedModules.Size = new System.Drawing.Size(320, 169);
|
||||
this.checkedModules.Sorted = true;
|
||||
this.checkedModules.TabIndex = 5;
|
||||
this.checkedModules.ThreeDCheckBoxes = true;
|
||||
this.checkedModules.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.checkedModules_ItemCheck);
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.Location = new System.Drawing.Point(24, 72);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(328, 16);
|
||||
this.label2.TabIndex = 4;
|
||||
this.label2.Text = "Select the &modules you want to update to use the PRC pack:";
|
||||
//
|
||||
// labelPath
|
||||
//
|
||||
this.labelPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.labelPath.Location = new System.Drawing.Point(24, 32);
|
||||
this.labelPath.Name = "labelPath";
|
||||
this.labelPath.Size = new System.Drawing.Size(320, 16);
|
||||
this.labelPath.TabIndex = 1;
|
||||
//
|
||||
// SingleHIFInstallForm
|
||||
//
|
||||
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
|
||||
this.CancelButton = this.buttonCancel;
|
||||
this.ClientSize = new System.Drawing.Size(368, 318);
|
||||
this.Controls.Add(this.labelPath);
|
||||
this.Controls.Add(this.label2);
|
||||
this.Controls.Add(this.checkedModules);
|
||||
this.Controls.Add(this.buttonInstall);
|
||||
this.Controls.Add(this.labelVersion);
|
||||
this.Controls.Add(this.buttonCancel);
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.MinimumSize = new System.Drawing.Size(376, 352);
|
||||
this.Name = "SingleHIFInstallForm";
|
||||
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "title goes here";
|
||||
this.SizeChanged += new System.EventHandler(this.InstallForm_SizeChanged);
|
||||
this.Load += new System.EventHandler(this.InstallForm_Load);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private fields/properties/methods
|
||||
private HakInfo hif;
|
||||
|
||||
/// <summary>
|
||||
/// Validates the single HIF and throws an EntryPointNotFoundException
|
||||
/// to exit the application if it does not validate.
|
||||
/// </summary>
|
||||
private void ValidateHIF()
|
||||
{
|
||||
hif = new HakInfo(NWNInfo.GetFullFilePath(MainForm.Hif));
|
||||
|
||||
// Validate the PRC pack HIF, if validation fails then display
|
||||
// the error message and exit the app.
|
||||
string error;
|
||||
if (!hif.Validate(out error))
|
||||
{
|
||||
MessageBox.Show(error, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
throw new EntryPointNotFoundException();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region form event handlers
|
||||
/// <summary>
|
||||
/// The form's load event handler. Fills in the contents of the form and sets
|
||||
/// it up.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void InstallForm_Load(object sender, System.EventArgs e)
|
||||
{
|
||||
// Fill in the check list boxes.
|
||||
LoadModuleList(checkedModules);
|
||||
}
|
||||
|
||||
private void InstallForm_SizeChanged(object sender, System.EventArgs e)
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region control event handlers
|
||||
/// <summary>
|
||||
/// Event handler for the ItemCheck event on the modules check list box.
|
||||
/// It enables/disables the install button depending on whether at least
|
||||
/// one module and hak have been selected.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void checkedModules_ItemCheck(object sender, System.Windows.Forms.ItemCheckEventArgs e)
|
||||
{
|
||||
// The install button should be enabled if at least one module and hak
|
||||
// has been selectted. Note that this event is fired BEFORE the checked
|
||||
// state of the item changes so we have to check the event args for
|
||||
// it's new state.
|
||||
int adjustment = CheckState.Checked == e.NewValue ? 1 : -1;
|
||||
bool fModuleChecked = checkedModules.CheckedItems.Count + adjustment > 0;
|
||||
|
||||
buttonInstall.Enabled = fModuleChecked;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for the install button click event. It installs the selected
|
||||
/// haks in the selected modules.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void buttonInstall_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
// Count the total number of .mod/.nwm files selected.
|
||||
int numModules = 0;
|
||||
foreach (Module module in checkedModules.CheckedItems)
|
||||
numModules += module.Modules.Length;
|
||||
|
||||
// Create the modules list and fill it in.
|
||||
string[] modules = new string[numModules];
|
||||
numModules = 0;
|
||||
foreach (Module module in checkedModules.CheckedItems)
|
||||
{
|
||||
module.Modules.CopyTo(modules, numModules);
|
||||
numModules += module.Modules.Length;
|
||||
}
|
||||
|
||||
PerformInstall(new HakInfo[1] { hif }, modules);
|
||||
|
||||
// Clear the checked state of all modules.
|
||||
CheckedListBox.CheckedIndexCollection checkedIndeces =
|
||||
checkedModules.CheckedIndices;
|
||||
foreach (int index in checkedIndeces)
|
||||
checkedModules.SetItemChecked(index, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancel button click event, it closes the application.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void buttonCancel_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
Application.Exit();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
249
trunk/tools/HakInstaller/SingleHIFInstallForm.resx
Normal file
249
trunk/tools/HakInstaller/SingleHIFInstallForm.resx
Normal file
@@ -0,0 +1,249 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
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">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</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 forserialized 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.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:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<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" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</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>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="labelVersion.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="labelVersion.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="labelVersion.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="buttonInstall.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="buttonInstall.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="buttonInstall.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="buttonCancel.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="buttonCancel.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="buttonCancel.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="checkedModules.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="checkedModules.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="checkedModules.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="label2.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="label2.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="label2.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="labelPath.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="labelPath.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="labelPath.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="$this.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Language" type="System.Globalization.CultureInfo, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>(Default)</value>
|
||||
</data>
|
||||
<data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Name">
|
||||
<value>SingleHIFInstallForm</value>
|
||||
</data>
|
||||
<data name="$this.Localizable" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>8, 8</value>
|
||||
</data>
|
||||
<data name="$this.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.TrayHeight" type="System.Int32, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>80</value>
|
||||
</data>
|
||||
<data name="$this.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAIAICAAAAAAAACoCAAAJgAAABAQAAAAAAAAaAUAAM4IAAAoAAAAIAAAAEAAAAABAAgAAAAAAAAE
|
||||
AAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwADA3MAA8MqmAAQE
|
||||
BAAICAgADAwMABEREQAWFhYAHBwcACIiIgApKSkAVVVVAE1NTQBCQkIAOTk5AIB8/wBQUP8AkwDWAP/s
|
||||
zADG1u8A1ufnAJCprQAAADMAAABmAAAAmQAAAMwAADMAAAAzMwAAM2YAADOZAAAzzAAAM/8AAGYAAABm
|
||||
MwAAZmYAAGaZAABmzAAAZv8AAJkAAACZMwAAmWYAAJmZAACZzAAAmf8AAMwAAADMMwAAzGYAAMyZAADM
|
||||
zAAAzP8AAP9mAAD/mQAA/8wAMwAAADMAMwAzAGYAMwCZADMAzAAzAP8AMzMAADMzMwAzM2YAMzOZADMz
|
||||
zAAzM/8AM2YAADNmMwAzZmYAM2aZADNmzAAzZv8AM5kAADOZMwAzmWYAM5mZADOZzAAzmf8AM8wAADPM
|
||||
MwAzzGYAM8yZADPMzAAzzP8AM/8zADP/ZgAz/5kAM//MADP//wBmAAAAZgAzAGYAZgBmAJkAZgDMAGYA
|
||||
/wBmMwAAZjMzAGYzZgBmM5kAZjPMAGYz/wBmZgAAZmYzAGZmZgBmZpkAZmbMAGaZAABmmTMAZplmAGaZ
|
||||
mQBmmcwAZpn/AGbMAABmzDMAZsyZAGbMzABmzP8AZv8AAGb/MwBm/5kAZv/MAMwA/wD/AMwAmZkAAJkz
|
||||
mQCZAJkAmQDMAJkAAACZMzMAmQBmAJkzzACZAP8AmWYAAJlmMwCZM2YAmWaZAJlmzACZM/8AmZkzAJmZ
|
||||
ZgCZmZkAmZnMAJmZ/wCZzAAAmcwzAGbMZgCZzJkAmczMAJnM/wCZ/wAAmf8zAJnMZgCZ/5kAmf/MAJn/
|
||||
/wDMAAAAmQAzAMwAZgDMAJkAzADMAJkzAADMMzMAzDNmAMwzmQDMM8wAzDP/AMxmAADMZjMAmWZmAMxm
|
||||
mQDMZswAmWb/AMyZAADMmTMAzJlmAMyZmQDMmcwAzJn/AMzMAADMzDMAzMxmAMzMmQDMzMwAzMz/AMz/
|
||||
AADM/zMAmf9mAMz/mQDM/8wAzP//AMwAMwD/AGYA/wCZAMwzAAD/MzMA/zNmAP8zmQD/M8wA/zP/AP9m
|
||||
AAD/ZjMAzGZmAP9mmQD/ZswAzGb/AP+ZAAD/mTMA/5lmAP+ZmQD/mcwA/5n/AP/MAAD/zDMA/8xmAP/M
|
||||
mQD/zMwA/8z/AP//MwDM/2YA//+ZAP//zABmZv8AZv9mAGb//wD/ZmYA/2b/AP//ZgAhAKUAX19fAHd3
|
||||
dwCGhoYAlpaWAMvLywCysrIA19fXAN3d3QDj4+MA6urqAPHx8QD4+PgA8Pv/AKSgoACAgIAAAAD/AAD/
|
||||
AAAA//8A/wAAAP8A/wD//wAA////AAAAAADdvLUHtfcH97WYtfe197v3u7W1u/e7B93dAAAAAADdu93C
|
||||
3eLi4uLd4t3d4t3i3eLcwuLi3eLdvLvdAAAAvLu84uLi3eLd3Ny73Lvc3bvcu93d3cLi4uLi3bu8AAC7
|
||||
u9zC3eLivLu7tbS7tdy73LW7tdy73d3ivOLdu7UAtbrc4uLi3bu1tbW7tbW7u9a8tbW73LXcvN3i3eG7
|
||||
uge0u7vd4ty73eL///+83LXdwuLi3bu1u7vcu93cwty1tLS73OLivP//4uL/3Ny73eLd3dzC3eK71rvc
|
||||
vNzdu7q0rrrc4t3//7vc3Lvd4uK8/93iu9zc4t3Cu7W73Lu71ZGR3Lvi///d3N273eK83eLd////3dy8
|
||||
3N3d4t21u7W6kbS03OL//9273OLi3dzi/////////93C3Lvcu+K1u7TPkbTc////3dzi3dy7/////927
|
||||
3P//////4rzc3bS1upGu27vd///ivNy73eLi/+Ldu9273OL////////dtbrVrrS0u9z////du9283Lzd
|
||||
4v/d3Ny73N3d////4rzcurS0rrTbu93////i3eLd3P///9y73LXc3Lvc4rW71bvVtJGR1bXbtdzd////
|
||||
/+K1////u92727W73dzdtbrWurvVrs+0uta63Lvd/////9z////d3Na71tvcu9y0tdy11bSRkbTVu9a6
|
||||
1rvctdy7u93//7vcu7vdu7vdtbW61rS61ZHPtLrVu9a73eL//93/4v//3Lzc3dy73N261bW63LS0rpG0
|
||||
1bW61tu84v////////+73d3ivN3cvLS1uta0tbS0rtW0uta6td3i/////////7vcwt7i3bvctbS03LTV
|
||||
tK6utLS03LTcvN3//////93c/////+LdvNy1tNy1urS0kbO0tNW61rrd4v///9284v//////////3LS1
|
||||
utW0tNWurrS0tLS0tN3i//+73P///////////7S127Xbtbq0s66us7S0tLS03eLdu////////////7u0
|
||||
u9W1urXVtLS0rq6zz7S0tLS7td3//////////920tNW0tNu01bS0tLOui7SztLO0tOL///////////+0
|
||||
tLS0tLq0tLS0tLSzz4uurbOttLS03f/////////ctLS0tLS01bS0tLS0rbOtka6zs7S0tLS14v/////d
|
||||
u7S1tNy0tbS1tLS0tLS0rYvP1Yu0tbvcu9y83LzcvNy73bvcB9y73bvcB9y7u9y0i7UA1a7c3d3C3bzi
|
||||
3cLdwt3ivOLdwt3C3eK84t3dtK7PAAAA1a67u93d4t3d3d3i3d3d4t3d3eLd3eLdtZHPzwAAAAAA1a6u
|
||||
i4yui66uroaurq6Grq6uhq6uhq7Pz7UAAADwAAAHwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAHAAAAD4AAABygAAAAQAAAAIAAAAAEACAAAAAAAAAEAAAAA
|
||||
AAAAAAAAAAEAAAABAAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAwMDAAMDcwADwyqYABAQEAAgI
|
||||
CAAMDAwAERERABYWFgAcHBwAIiIiACkpKQBVVVUATU1NAEJCQgA5OTkAgHz/AFBQ/wCTANYA/+zMAMbW
|
||||
7wDW5+cAkKmtAAAAMwAAAGYAAACZAAAAzAAAMwAAADMzAAAzZgAAM5kAADPMAAAz/wAAZgAAAGYzAABm
|
||||
ZgAAZpkAAGbMAABm/wAAmQAAAJkzAACZZgAAmZkAAJnMAACZ/wAAzAAAAMwzAADMZgAAzJkAAMzMAADM
|
||||
/wAA/2YAAP+ZAAD/zAAzAAAAMwAzADMAZgAzAJkAMwDMADMA/wAzMwAAMzMzADMzZgAzM5kAMzPMADMz
|
||||
/wAzZgAAM2YzADNmZgAzZpkAM2bMADNm/wAzmQAAM5kzADOZZgAzmZkAM5nMADOZ/wAzzAAAM8wzADPM
|
||||
ZgAzzJkAM8zMADPM/wAz/zMAM/9mADP/mQAz/8wAM///AGYAAABmADMAZgBmAGYAmQBmAMwAZgD/AGYz
|
||||
AABmMzMAZjNmAGYzmQBmM8wAZjP/AGZmAABmZjMAZmZmAGZmmQBmZswAZpkAAGaZMwBmmWYAZpmZAGaZ
|
||||
zABmmf8AZswAAGbMMwBmzJkAZszMAGbM/wBm/wAAZv8zAGb/mQBm/8wAzAD/AP8AzACZmQAAmTOZAJkA
|
||||
mQCZAMwAmQAAAJkzMwCZAGYAmTPMAJkA/wCZZgAAmWYzAJkzZgCZZpkAmWbMAJkz/wCZmTMAmZlmAJmZ
|
||||
mQCZmcwAmZn/AJnMAACZzDMAZsxmAJnMmQCZzMwAmcz/AJn/AACZ/zMAmcxmAJn/mQCZ/8wAmf//AMwA
|
||||
AACZADMAzABmAMwAmQDMAMwAmTMAAMwzMwDMM2YAzDOZAMwzzADMM/8AzGYAAMxmMwCZZmYAzGaZAMxm
|
||||
zACZZv8AzJkAAMyZMwDMmWYAzJmZAMyZzADMmf8AzMwAAMzMMwDMzGYAzMyZAMzMzADMzP8AzP8AAMz/
|
||||
MwCZ/2YAzP+ZAMz/zADM//8AzAAzAP8AZgD/AJkAzDMAAP8zMwD/M2YA/zOZAP8zzAD/M/8A/2YAAP9m
|
||||
MwDMZmYA/2aZAP9mzADMZv8A/5kAAP+ZMwD/mWYA/5mZAP+ZzAD/mf8A/8wAAP/MMwD/zGYA/8yZAP/M
|
||||
zAD/zP8A//8zAMz/ZgD//5kA///MAGZm/wBm/2YAZv//AP9mZgD/Zv8A//9mACEApQBfX18Ad3d3AIaG
|
||||
hgCWlpYAy8vLALKysgDX19cA3d3dAOPj4wDq6uoA8fHxAPj4+ADw+/8ApKCgAICAgAAAAP8AAP8AAAD/
|
||||
/wD/AAAA/wD/AP//AAD///8AAPfs9+z37Pfs9+z37PfsAOyFX4Vf7OyFX7KBsrqyuuxfhV8H7OxfhV+B
|
||||
soGyurKFhV//7IVfhV+FX2uygbK6X1/s/1+FX+yFX+zsa7KBsl+F7P8HXwfsX+zsX+xrsoFfX4UH/wcH
|
||||
7IoH7F+F7GuyX4Wmhez//wdfB+yFX1/shV9fiqaKX4pfigfsX4WF7KaFhaaKpuwHBwf/7F+FX+yKX1+K
|
||||
pors////BwdfhV/spoWFpoqm7P+8Bwf//wcH7IVfX4qmiuwHB7z///8HpoqmX4WmiqbsvP/////spoqm
|
||||
iqbss7Sz/////we0s7SztLPsAOz37Pfs9+z37Pfs9+z3AIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAAA=
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
202
trunk/tools/HakInstaller/SystemMenu.cs
Normal file
202
trunk/tools/HakInstaller/SystemMenu.cs
Normal file
@@ -0,0 +1,202 @@
|
||||
//
|
||||
// This code was pulled from www.developerfusion.com
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows;
|
||||
using System.Collections;
|
||||
|
||||
namespace System
|
||||
{
|
||||
public class SystemMenu : ArrayList
|
||||
{
|
||||
|
||||
public const int BYPOSITION = 0x400;
|
||||
public const int REMOVE = 0x1000;
|
||||
public const int CHECKED = 0x8;
|
||||
public const int APPEND = 0x100;
|
||||
public const int SEPERATOR = 0x800;
|
||||
public const int GRAYED = 0x1;
|
||||
public const int DISABLED = 0x2;
|
||||
public const int BITMAP = 0x4;
|
||||
public const int RADIOCHECK = 0x200;
|
||||
public const int BREAK = 0x40;
|
||||
public const int BARBREAK = 0x20;
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int GetSystemMenu(int HWND);
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int AppendMenu(int MenuHandle, int Props, int FlagsW, string text);
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int RemoveMenu(int MenuHandle, int pos, int Flags);
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int GetMenuItemID(int Menuhandle, int pos);
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int ModifyMenu(int MHandle, int pos,int flags,int newPos,string text);
|
||||
|
||||
private Form form;
|
||||
private int SystemMenuHandle;
|
||||
|
||||
public int Handle
|
||||
{
|
||||
get { return SystemMenuHandle; }
|
||||
}
|
||||
|
||||
public SystemMenu(Form f) : base(0)
|
||||
{
|
||||
form = f;
|
||||
SystemMenuHandle = GetSystemMenu(form.Handle.ToInt32());
|
||||
}
|
||||
|
||||
public void Add(SystemMenuItem MI)
|
||||
{
|
||||
base.Add(MI);
|
||||
if(MI.Text == "-")
|
||||
{
|
||||
AppendMenu(SystemMenuHandle,SystemMenu.SEPERATOR,MI.MenuID,null);
|
||||
}
|
||||
else
|
||||
{
|
||||
AppendMenu(SystemMenuHandle,MI.Flags,MI.MenuID,MI.Text);
|
||||
}
|
||||
}
|
||||
|
||||
public void Remove(SystemMenuItem MI)
|
||||
{
|
||||
base.Remove(MI);
|
||||
RemoveMenu(SystemMenuHandle, MI.MenuID, 0);
|
||||
}
|
||||
|
||||
public void ModifyMenuPosition(int pos, int flags, string text)
|
||||
{
|
||||
ModifyMenu(this.Handle, pos, flags|SystemMenu.BYPOSITION, pos, text);
|
||||
}
|
||||
|
||||
public new SystemMenuItem this[int index]
|
||||
{
|
||||
get { return (SystemMenuItem)base[index]; }
|
||||
set
|
||||
{
|
||||
if(value!=null)
|
||||
{
|
||||
SystemMenuItem MI = (SystemMenuItem)value;
|
||||
ModifyMenu(this.Handle, this[index].MenuID, MI.Flags, MI.MenuID, MI.Text); }
|
||||
base[index] = (object)value;
|
||||
}
|
||||
}
|
||||
|
||||
}// end of class SystemMenu
|
||||
|
||||
public class SystemMenuItem : MenuItem
|
||||
{
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int GetSystemMenu(int HWND);
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int AppendMenu(int MenuHandle, int Props, int FlagsW, string text);
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int RemoveMenu(int MenuHandle, int pos, int Flags);
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int GetMenuItemID(int Menuhandle, int pos);
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int ModifyMenu(int MHandle, int pos,int flags,int newPos,string text);
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int CheckMenuItem(int HMenu, int pos, int flags);
|
||||
|
||||
private int flags = 0;
|
||||
public int Flags
|
||||
{
|
||||
get { return flags; }
|
||||
}
|
||||
|
||||
private SystemMenu menu;
|
||||
public SystemMenuItem(string text, SystemMenu SM)
|
||||
{
|
||||
base.Text = text;
|
||||
menu = SM;
|
||||
if(text == "-")
|
||||
this.flags = SystemMenu.SEPERATOR;
|
||||
}
|
||||
|
||||
public new int MenuID
|
||||
{
|
||||
get { return base.MenuID; }
|
||||
}
|
||||
|
||||
public SystemMenuItem CloneMenu(int should_be_null)
|
||||
{
|
||||
should_be_null = 0;
|
||||
return new SystemMenuItem(this.Text, menu);
|
||||
}
|
||||
|
||||
public new bool Checked
|
||||
{
|
||||
get { return base.Checked; }
|
||||
set
|
||||
{
|
||||
base.Checked = value;
|
||||
if(base.Checked)
|
||||
{
|
||||
flags = (flags|SystemMenu.CHECKED);
|
||||
CheckMenuItem(menu.Handle, this.MenuID, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
flags = (flags&(~SystemMenu.CHECKED));
|
||||
CheckMenuItem(menu.Handle, this.MenuID, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public new string Text
|
||||
{
|
||||
get { return base.Text; }
|
||||
set
|
||||
{
|
||||
base.Text = value;
|
||||
ModifyMenu(menu.Handle, this.MenuID, this.flags, this.MenuID, base.Text);
|
||||
}
|
||||
}
|
||||
|
||||
public new bool Break
|
||||
{
|
||||
get { return base.Break; }
|
||||
set
|
||||
{
|
||||
base.Break = value;
|
||||
if(base.Break)
|
||||
{
|
||||
flags = flags|SystemMenu.BREAK;
|
||||
ModifyMenu(menu.Handle, this.MenuID, this.flags, this.MenuID, base.Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
flags = flags&(~SystemMenu.BREAK);
|
||||
ModifyMenu(menu.Handle, this.MenuID, this.flags, this.MenuID, base.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public new bool BarBreak
|
||||
{
|
||||
get { return base.BarBreak; }
|
||||
set
|
||||
{
|
||||
base.BarBreak = value;
|
||||
if(base.BarBreak)
|
||||
{
|
||||
flags = flags|SystemMenu.BARBREAK;
|
||||
ModifyMenu(menu.Handle, this.MenuID, this.flags, this.MenuID, base.Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
flags = flags&(~SystemMenu.BARBREAK);
|
||||
ModifyMenu(menu.Handle, this.MenuID, this.flags, this.MenuID, base.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}//end of class SystemMenuItem
|
||||
}
|
632
trunk/tools/HakInstaller/Tlk.cs
Normal file
632
trunk/tools/HakInstaller/Tlk.cs
Normal file
@@ -0,0 +1,632 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NWN.FileTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents a tlk file. It contains all of the functionality necessary to
|
||||
/// merge tlk files.
|
||||
/// </summary>
|
||||
public class Tlk
|
||||
{
|
||||
#region public nested classes
|
||||
/// <summary>
|
||||
/// Flags for the ResRef data.
|
||||
/// </summary>
|
||||
[Flags] public enum ResRefFlags: int
|
||||
{
|
||||
None = 0x0000,
|
||||
TextPresent = 0x0001,
|
||||
SoundPresent = 0x0002,
|
||||
SoundLengthPresent = 0x0004,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This class defines an entry in the tlk file. It contains all of the data for
|
||||
/// the entry.
|
||||
/// </summary>
|
||||
public class TlkEntry
|
||||
{
|
||||
#region public properties/methods
|
||||
/// <summary>
|
||||
/// Gets/sets the entrie's flags
|
||||
/// </summary>
|
||||
public ResRefFlags Flags { get { return flags; } set { flags = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets the sound ResRef
|
||||
/// </summary>
|
||||
public string SoundResRef
|
||||
{
|
||||
get { return soundResRef; }
|
||||
set
|
||||
{
|
||||
soundResRef = value;
|
||||
if (string.Empty != soundResRef)
|
||||
flags |= ResRefFlags.SoundPresent;
|
||||
else
|
||||
flags &= ~ResRefFlags.SoundPresent;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets the volume variance.
|
||||
/// </summary>
|
||||
public int VolumnVariance { get { return volumeVariance; } set { volumeVariance = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets the pitch variance.
|
||||
/// </summary>
|
||||
public int PitchVariance { get { return pitchVariance; } set { pitchVariance = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets the sound length.
|
||||
/// </summary>
|
||||
public float SoundLength
|
||||
{
|
||||
get { return soundLength; }
|
||||
set
|
||||
{
|
||||
soundLength = value;
|
||||
if (0 != soundLength)
|
||||
flags |= ResRefFlags.SoundLengthPresent;
|
||||
else
|
||||
flags &= ~ResRefFlags.SoundLengthPresent;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets the entry text.
|
||||
/// </summary>
|
||||
public string Text
|
||||
{
|
||||
get { return text; }
|
||||
set
|
||||
{
|
||||
text = value;
|
||||
if (string.Empty != text)
|
||||
flags |= ResRefFlags.TextPresent;
|
||||
else
|
||||
flags &= ~ResRefFlags.TextPresent;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the tlk entry is empty.
|
||||
/// </summary>
|
||||
public bool IsEmpty { get { return flags == ResRefFlags.None; } }
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
public TlkEntry()
|
||||
{
|
||||
flags = ResRefFlags.None;
|
||||
volumeVariance = 0;
|
||||
pitchVariance = 0;
|
||||
soundLength = 0;
|
||||
soundResRef = string.Empty;;
|
||||
this.text = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constuctor to create an entry for a string.
|
||||
/// </summary>
|
||||
/// <param name="text">The text.</param>
|
||||
public TlkEntry(string text)
|
||||
{
|
||||
flags = ResRefFlags.TextPresent;
|
||||
volumeVariance = 0;
|
||||
pitchVariance = 0;
|
||||
soundLength = 0;
|
||||
soundResRef = string.Empty;
|
||||
this.text = text;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private fields/properties/methods
|
||||
private ResRefFlags flags;
|
||||
public int volumeVariance;
|
||||
public int pitchVariance;
|
||||
public float soundLength;
|
||||
public string soundResRef;
|
||||
public string text;
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public properties
|
||||
/// <summary>
|
||||
/// Gets the tlk key to be used in dictionary lookups, this is a lower case version
|
||||
/// of the name.
|
||||
/// </summary>
|
||||
public string Key { get { return name.ToLower(); } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the tlk file, the name does not include any path information.
|
||||
/// </summary>
|
||||
public string Name { get { return name; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of entries in the tlk file.
|
||||
/// </summary>
|
||||
public int Count { get { return header.stringCount; } }
|
||||
|
||||
/// <summary>
|
||||
/// Does a lookup in the tlk file, returning the entry for the specified index.
|
||||
/// </summary>
|
||||
public TlkEntry this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
// If the index is out of range return null.
|
||||
if (index >= header.stringCount || index < 0) return null;
|
||||
|
||||
// Create a TlkEntry for the entry
|
||||
TlkEntry entry = new TlkEntry();
|
||||
entry.PitchVariance = resRefs[index].pitchVariance;
|
||||
entry.SoundLength = resRefs[index].soundLength;
|
||||
entry.VolumnVariance = resRefs[index].volumeVariance;
|
||||
entry.SoundResRef = resRefs[index].soundResRef;
|
||||
entry.Text = strings[index];
|
||||
entry.Flags = (ResRefFlags) resRefs[index].flags;
|
||||
|
||||
// Return the created entry.
|
||||
return entry;
|
||||
}
|
||||
set
|
||||
{
|
||||
// Make sure the index is within range.
|
||||
if (index >= header.stringCount || index < 0) throw new IndexOutOfRangeException();
|
||||
|
||||
resRefs[index].pitchVariance = value.PitchVariance;
|
||||
resRefs[index].soundLength = value.SoundLength;
|
||||
resRefs[index].volumeVariance = value.VolumnVariance;
|
||||
resRefs[index].soundResRef = value.SoundResRef;
|
||||
resRefs[index].flags = (int) value.Flags;
|
||||
strings[index] = value.Text;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public methods
|
||||
/// <summary>
|
||||
/// Default constructor.
|
||||
/// </summary>
|
||||
/// <param name="count">The initial number of entries in the tlk file.</param>
|
||||
public Tlk(int count)
|
||||
{
|
||||
name = string.Empty;
|
||||
header = new TlkHeader();
|
||||
resRefs = new RawResRef[count];
|
||||
strings = new string[count];
|
||||
|
||||
header.fileType = tlkFile;
|
||||
header.fileVersion = tlkVersion;
|
||||
header.stringCount = count;
|
||||
header.stringOffset = 0;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
resRefs[i] = new RawResRef();
|
||||
resRefs[i].flags = (int) ResRefFlags.None;
|
||||
resRefs[i].offsetToString = 0;
|
||||
resRefs[i].pitchVariance = 0;
|
||||
resRefs[i].soundLength = 0;
|
||||
resRefs[i].soundResRef = string.Empty;
|
||||
resRefs[i].stringSize = 0;
|
||||
resRefs[i].volumeVariance = 0;
|
||||
|
||||
strings[i] = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the index'th entry is empty.
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the entry to test</param>
|
||||
/// <returns>True if the entry is empty false if it is not</returns>
|
||||
public bool IsEmpty(int index)
|
||||
{
|
||||
if (index >= header.stringCount || index < 0) throw new ArgumentOutOfRangeException();
|
||||
return (int) ResRefFlags.None == resRefs[index].flags || string.Empty == strings[index];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pads the tlk to have at least the specified number of entries. If the tlk file
|
||||
/// has less entries than what is given, blank entries are inserted to pad.
|
||||
/// </summary>
|
||||
/// <param name="length">The new number of entries</param>
|
||||
public void Pad(int length)
|
||||
{
|
||||
// If the tlk file is larger than the pad count then do nothing.
|
||||
if (header.stringCount >= length) return;
|
||||
|
||||
// Add blank entries to the tlk file to pad.
|
||||
RawResRef[] padded = new RawResRef[length];
|
||||
resRefs.CopyTo(padded, 0);
|
||||
for (int i = resRefs.Length; i < padded.Length; i++)
|
||||
{
|
||||
padded[i].flags = 0;
|
||||
padded[i].offsetToString = 0;
|
||||
padded[i].pitchVariance = 0;
|
||||
padded[i].stringSize = 0;
|
||||
padded[i].volumeVariance = 0;
|
||||
padded[i].soundLength = 0.0f;
|
||||
padded[i].soundResRef = string.Empty;
|
||||
}
|
||||
|
||||
string[] paddedStrings = new string[length];
|
||||
paddedStrings.CopyTo(strings, 0);
|
||||
for (int i = strings.Length; i < paddedStrings.Length; i++)
|
||||
paddedStrings[i] = string.Empty;
|
||||
|
||||
// Save the new RawResRef array and update the number of entries in
|
||||
// the header.
|
||||
header.stringCount = length;
|
||||
resRefs = padded;
|
||||
strings = paddedStrings;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the tlk file, the tlk file must have been given a name or this will
|
||||
/// throw an InvalidOperationException.
|
||||
/// </summary>
|
||||
public void Save()
|
||||
{
|
||||
if (string.Empty == name) throw new InvalidOperationException();
|
||||
SaveAs(name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the tlk file under the specified file name.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name in which to save the file.</param>
|
||||
public void SaveAs(string fileName)
|
||||
{
|
||||
using (FileStream writer =
|
||||
new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
|
||||
{
|
||||
// Figure out how big of a buffer we need to store all of the string data.
|
||||
int count = 0;
|
||||
foreach (string s in strings)
|
||||
count += s.Length;
|
||||
|
||||
// Copy all of the string data to a byte array.
|
||||
int stringDataIndex = 0;
|
||||
byte[] stringData = new byte[count];
|
||||
for (int i = 0; i < resRefs.Length; i++)
|
||||
{
|
||||
// Ignore entries w/o strings.
|
||||
if (0 == ((int) ResRefFlags.TextPresent & resRefs[i].flags) ||
|
||||
string.Empty == strings[i])
|
||||
{
|
||||
// Blank the string size and offset just in case to keep
|
||||
// the tlk file clean.
|
||||
resRefs[i].stringSize = 0;
|
||||
resRefs[i].offsetToString = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Copy the string bytes to the byte array.
|
||||
for (int j = 0; j < strings[i].Length; j++)
|
||||
stringData[stringDataIndex + j] = (byte) strings[i][j];
|
||||
|
||||
// Save the string offset and size in the ResRef structure.
|
||||
resRefs[i].offsetToString = stringDataIndex;
|
||||
resRefs[i].stringSize = strings[i].Length;
|
||||
|
||||
// Increment the buffer index to the next free byte.
|
||||
stringDataIndex += strings[i].Length;
|
||||
}
|
||||
|
||||
// Set the offset to the string data in the header and write the header out.
|
||||
header.stringOffset = headerSize + (resRefs.Length * RawResRefSize);
|
||||
byte[] buffer = RawSerialize(header);
|
||||
writer.Write(buffer, 0, buffer.Length);
|
||||
|
||||
// Write all of the ResRef entries out.
|
||||
for (int i = 0; i < resRefs.Length; i++)
|
||||
{
|
||||
buffer = RawSerialize(resRefs[i]);
|
||||
writer.Write(buffer, 0, buffer.Length);
|
||||
}
|
||||
|
||||
// Write the raw string data out.
|
||||
writer.Write(stringData, 0, stringData.Length);
|
||||
}
|
||||
|
||||
this.name = fileName;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public static methods
|
||||
/// <summary>
|
||||
/// Creates a Tlk object for the specified tlk file.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The tlk file</param>
|
||||
/// <returns>A Tlk object representing the tlk file</returns>
|
||||
public static Tlk LoadTlk(string fileName)
|
||||
{
|
||||
// Open the tlk file.
|
||||
Tlk tlk = new Tlk();
|
||||
using (FileStream reader =
|
||||
new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
// Save the name of the tlk file.
|
||||
FileInfo info = new FileInfo(fileName);
|
||||
tlk.name = info.Name;
|
||||
|
||||
// Read the header and decode it.
|
||||
byte[] buffer = new byte[Tlk.headerSize];
|
||||
if (reader.Read(buffer, 0, buffer.Length) != buffer.Length)
|
||||
ThrowException("Tlk file {0} is corrupt", fileName);
|
||||
tlk.DeserializeHeader(buffer);
|
||||
|
||||
// Do a reality check on the tlk file.
|
||||
if (tlk.header.fileType != tlkFile)
|
||||
ThrowException("{0} is not a tlk file", fileName);
|
||||
if (tlk.header.fileVersion != tlkVersion)
|
||||
ThrowException("{0} is an unsupported tlk file", fileName);
|
||||
|
||||
// Read the RawResRef array and decode it.
|
||||
int size = tlk.header.stringCount * Tlk.RawResRefSize;
|
||||
buffer = new byte[size];
|
||||
if (reader.Read(buffer, 0, buffer.Length) != buffer.Length)
|
||||
ThrowException("Tlk file {0} is corrupt", fileName);
|
||||
tlk.DeserializeRawResRefs(buffer);
|
||||
|
||||
// Read the raw string data.
|
||||
buffer = new byte[reader.Length - tlk.header.stringOffset];
|
||||
if (reader.Read(buffer, 0, buffer.Length) != buffer.Length)
|
||||
ThrowException("Tlk file {0} is corrupt", fileName);
|
||||
|
||||
// Load the strings from the raw bytes into our string array.
|
||||
tlk.strings = new string[tlk.header.stringCount];
|
||||
for (int i = 0; i < tlk.header.stringCount; i++)
|
||||
tlk.strings[i] = tlk.GetStringFromBuffer(buffer, i);
|
||||
}
|
||||
|
||||
return tlk;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Merges 2 tlk objects, saving the results in the specified tlk file. The merge tlk file
|
||||
/// is just added to the end of the source tlk file. Unlike 2da merging, the merge tlk
|
||||
/// does not overwrite any entries in the source tlk. Tlk entries are not row critical like
|
||||
/// 2da rows (since tlk strings are not saved in character files), so exact positioning of
|
||||
/// them is not as critical.
|
||||
/// </summary>
|
||||
/// <param name="source">The source tlk</param>
|
||||
/// <param name="merge">The merge tlk</param>
|
||||
/// <param name="outFile">The name of the output tlk file</param>
|
||||
/// <returns>The offset of the first entry of the merge tlk in the output file. This offset
|
||||
/// can be used to fixup 2da entries that refer to the merge tlk.</returns>
|
||||
public static int MergeTlk(Tlk source, Tlk merge, string outFile)
|
||||
{
|
||||
/*
|
||||
// Open the output tlk.
|
||||
using (FileStream writer =
|
||||
new FileStream(outFile, FileMode.Create, FileAccess.Write, FileShare.None))
|
||||
{
|
||||
// Build a RawResRef array containing both the source and merge RawResRef arrays. Then
|
||||
// loop through all of the merge entries and fixup the string offsets to point
|
||||
// past the source data to the merge data, which we will glue on the end of the
|
||||
// source data.
|
||||
RawResRef[] outResRefs = new RawResRef[source.resRefs.Length + merge.resRefs.Length];
|
||||
source.resRefs.CopyTo(outResRefs, 0);
|
||||
merge.resRefs.CopyTo(outResRefs, source.resRefs.Length);
|
||||
for (int i = source.resRefs.Length; i < outResRefs.Length; i++)
|
||||
{
|
||||
if (0 != (outResRefs[i].flags & (int) ResRefFlags.textPresent))
|
||||
outResRefs[i].offsetToString += source.stringBytes.Length;
|
||||
}
|
||||
|
||||
// Build a header with a string count of all of the source + merge strings, then
|
||||
// write it out.
|
||||
TlkHeader headerOut = source.header;
|
||||
headerOut.stringCount += merge.header.stringCount;
|
||||
headerOut.stringOffset = headerSize + (outResRefs.Length * RawResRefSize);
|
||||
byte[] headerBytes = RawSerialize(headerOut);
|
||||
writer.Write(headerBytes, 0, headerBytes.Length);
|
||||
|
||||
// Write the RawResRef data.
|
||||
for (int i = 0; i < outResRefs.Length; i++)
|
||||
{
|
||||
byte[] bytes = RawSerialize(outResRefs[i]);
|
||||
writer.Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
// Write the source and merge string data out to the file.
|
||||
writer.Write(source.stringBytes, 0, source.stringBytes.Length);
|
||||
writer.Write(merge.stringBytes, 0, merge.stringBytes.Length);
|
||||
|
||||
writer.Flush();
|
||||
writer.Close();
|
||||
}
|
||||
|
||||
// Return the number of strings in the source tlk. Since we glued the merge
|
||||
// tlk onto the end of the source tlk, this value will be the fixup value we need
|
||||
// to correct 2da tlk references.
|
||||
return source.header.stringCount;
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private methods
|
||||
/// <summary>
|
||||
/// Private constructor, instances of this class must
|
||||
/// </summary>
|
||||
private Tlk()
|
||||
{
|
||||
header = new TlkHeader();
|
||||
resRefs = null;
|
||||
strings = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index'th string from the raw string buffer.
|
||||
/// </summary>
|
||||
/// <param name="buffer">The raw string buffer</param>
|
||||
/// <param name="index">Index of the string to get</param>
|
||||
/// <returns>The index'th string</returns>
|
||||
private string GetStringFromBuffer(byte[] buffer, int index)
|
||||
{
|
||||
// If the index is out of range or the text present flag is not set then
|
||||
// return an empty string.
|
||||
if (index >= header.stringCount ||
|
||||
0 == (resRefs[index].flags & (int) ResRefFlags.TextPresent)) return string.Empty;;
|
||||
|
||||
// Can't find a converter to build a string from a byte array, so we
|
||||
// need a local char array to do the dirty work.
|
||||
int offset = resRefs[index].offsetToString;
|
||||
char[] chars = new char[resRefs[index].stringSize];
|
||||
for (int i = 0; i < chars.Length; i++)
|
||||
chars[i] = (char) buffer[i + offset];
|
||||
|
||||
return new string(chars);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes the header from the given byte array.
|
||||
/// </summary>
|
||||
/// <param name="bytes">The byte array containing the header</param>
|
||||
private void DeserializeHeader(byte[] bytes)
|
||||
{
|
||||
// Alloc a hglobal to store the bytes.
|
||||
IntPtr buffer = Marshal.AllocHGlobal(bytes.Length);
|
||||
try
|
||||
{
|
||||
// Copy the data to unprotected memory, then convert it to a TlkHeader
|
||||
// structure
|
||||
Marshal.Copy(bytes, 0, buffer, bytes.Length);
|
||||
object o = Marshal.PtrToStructure(buffer, typeof(TlkHeader));
|
||||
header = (TlkHeader) o;
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Free the hglobal before exiting.
|
||||
Marshal.FreeHGlobal(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes the RawResRef array from the given byte array.
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
private void DeserializeRawResRefs(byte[] bytes)
|
||||
{
|
||||
// Alloc a hglobal to store the bytes.
|
||||
IntPtr buffer = Marshal.AllocHGlobal(RawResRefSize);
|
||||
try
|
||||
{
|
||||
// Create a RawResRef array for all of the entries and loop
|
||||
// through the array populating it.
|
||||
resRefs = new RawResRef[header.stringCount];
|
||||
for (int i = 0; i < resRefs.Length; i++)
|
||||
{
|
||||
// Copy the bytes of the i'th RawResRef to unprotected memory
|
||||
// and convert it to a RawResRef structure.
|
||||
Marshal.Copy(bytes, i * RawResRefSize, buffer, RawResRefSize);
|
||||
object o = Marshal.PtrToStructure(buffer, typeof(RawResRef));
|
||||
resRefs[i] = (RawResRef) o;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Free the hglobal before exiting.
|
||||
Marshal.FreeHGlobal(buffer);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private static methods
|
||||
/// <summary>
|
||||
/// Throws an NWNException exception
|
||||
/// </summary>
|
||||
/// <param name="format">The message format string</param>
|
||||
/// <param name="args">Message arguments</param>
|
||||
private static void ThrowException(string format, params object[] args)
|
||||
{
|
||||
throw new NWNException(format, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method serializes an arbitrary object to a byte array for storage in
|
||||
/// a tlk file. The object should have it's data mapped to proper positions
|
||||
/// or the serialization won't work.
|
||||
/// </summary>
|
||||
/// <param name="o">The object to serialize</param>
|
||||
/// <returns></returns>
|
||||
private static byte[] RawSerialize(object o)
|
||||
{
|
||||
// Allocate a hglobal to store the object's data.
|
||||
int rawsize = Marshal.SizeOf(o);
|
||||
IntPtr buffer = Marshal.AllocHGlobal(rawsize);
|
||||
try
|
||||
{
|
||||
// Copy the object to unprotected memory, then copy that to a byte array.
|
||||
Marshal.StructureToPtr(o, buffer, false);
|
||||
byte[] rawdata = new byte[rawsize];
|
||||
Marshal.Copy(buffer, rawdata, 0, rawsize);
|
||||
return rawdata;
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Free the hglobal before exiting
|
||||
Marshal.FreeHGlobal(buffer);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private nested structures/classes
|
||||
/// <summary>
|
||||
/// Structure to store the header of the tlk file. This is mapped directly over the
|
||||
/// bytes loaded from the tlk file, so we need to declare the mapping explicitly.
|
||||
/// Using LayoutKind.Sequential should work, but I had problems with it so used
|
||||
/// Explicit to force the issue. fileType and fileVersions are really strings, but
|
||||
/// .NET insists on null terminating strings, and these strings are not null terminated.
|
||||
/// They are both 4 bytes so using Int32 works.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Explicit, Pack=1, CharSet=CharSet.Ansi)] private struct TlkHeader
|
||||
{
|
||||
[FieldOffsetAttribute(0)] public Int32 fileType;
|
||||
[FieldOffsetAttribute(4)] public Int32 fileVersion;
|
||||
[FieldOffsetAttribute(8)] public Int32 language;
|
||||
[FieldOffsetAttribute(12)] public Int32 stringCount;
|
||||
[FieldOffsetAttribute(16)] public Int32 stringOffset;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Structure to represent a RawResRef entry in a tlk file. This is mapped directly over the
|
||||
/// bytes loaded from the tlk file, so we need to declare the mapping explicitly.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack=1, CharSet=CharSet.Ansi)] private struct RawResRef
|
||||
{
|
||||
public Int32 flags;
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=16)] public String soundResRef;
|
||||
public Int32 volumeVariance;
|
||||
public Int32 pitchVariance;
|
||||
public Int32 offsetToString;
|
||||
public Int32 stringSize;
|
||||
public float soundLength;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private fields
|
||||
private const int headerSize = 20;
|
||||
private const int RawResRefSize = 40;
|
||||
private const Int32 tlkFile = 0x204b4c54;
|
||||
private const Int32 tlkVersion = 0x302e3356;
|
||||
|
||||
private string name;
|
||||
private TlkHeader header;
|
||||
private RawResRef[] resRefs;
|
||||
private string[] strings;
|
||||
#endregion
|
||||
}
|
||||
}
|
58
trunk/tools/HakInstaller/Utilities.cs
Normal file
58
trunk/tools/HakInstaller/Utilities.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using System.Text;
|
||||
|
||||
namespace HakInstaller.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is used to manipulate the assembly's string resources.
|
||||
/// </summary>
|
||||
public class StringResources
|
||||
{
|
||||
#region public static properties/methods
|
||||
/// <summary>
|
||||
/// Gets the specified string from the string resource file.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the string to load</param>
|
||||
/// <returns>The string value</returns>
|
||||
public static string GetString(string name)
|
||||
{
|
||||
return singleton.rm.GetString(name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the specified format string from the string resource file, formatting
|
||||
/// it with the passed string arguments.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the format string to load</param>
|
||||
/// <param name="args">The string format arguments</param>
|
||||
/// <returns>The formatted string value</returns>
|
||||
public static string GetString(string name, params object[] args)
|
||||
{
|
||||
// Get the format string from the resource file and
|
||||
// format it with the passed arguments.
|
||||
string format = singleton.rm.GetString(name);
|
||||
singleton.builder.Length = 0;
|
||||
singleton.builder.AppendFormat(format, args);
|
||||
return singleton.builder.ToString();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private fields/properties/methods
|
||||
/// <summary>
|
||||
/// Class constructor made private because class is a singleton.
|
||||
/// </summary>
|
||||
private StringResources()
|
||||
{
|
||||
builder = new StringBuilder();
|
||||
rm = new ResourceManager("HakInstaller.strings", Assembly.GetExecutingAssembly());
|
||||
}
|
||||
|
||||
private static StringResources singleton = new StringResources();
|
||||
|
||||
private StringBuilder builder;
|
||||
private ResourceManager rm;
|
||||
#endregion
|
||||
}
|
||||
}
|
67
trunk/tools/HakInstaller/spellPRCMerge.hif
Normal file
67
trunk/tools/HakInstaller/spellPRCMerge.hif
Normal file
@@ -0,0 +1,67 @@
|
||||
# HIF files may consist of any of the following tags. All tags are optional.
|
||||
# Tags that support multiple data items may have the data comma separated and/or
|
||||
# may have multiple entries. If a multiple entries are given for a tag that only
|
||||
# supports 1 value then the fist value in the file is used. Blank lines are ignored
|
||||
# as are lines starting with a '#'.
|
||||
#
|
||||
# Tag format is
|
||||
#
|
||||
# <tag> : <value1>, <value2>, ..., <valuen>
|
||||
#
|
||||
# All white space is optional, and tags may also be given on multiple lines
|
||||
# as follows:
|
||||
#
|
||||
# <tag> : <value1>
|
||||
# <tag> : <value2>
|
||||
# ...
|
||||
# <tag> : <valuen>
|
||||
#
|
||||
# The following tags are supported:
|
||||
#
|
||||
# erf : Imports the listed erf files into the module
|
||||
# module.Hak : haks to add to the module
|
||||
# module.CustomTlk : Custom tlk file for the module, only 1 value.
|
||||
# module.Cache : Adds the given scripts the module's script cache.
|
||||
# module.OnAcquireItem : Assigns script(s) to handle this module event
|
||||
# module.OnActivateItem : Assigns script(s) to handle this module event
|
||||
# module.OnClientEnter : Assigns script(s) to handle this module event
|
||||
# module.OnClientLeave : Assigns script(s) to handle this module event
|
||||
# module.OnCutsceneAbort : Assigns script(s) to handle this module event
|
||||
# module.OnHeartbeat : Assigns script(s) to handle this module event
|
||||
# module.OnModuleLoad : Assigns script(s) to handle this module event
|
||||
# module.OnModuleStart : Assigns script(s) to handle this module event
|
||||
# module.OnPlayerDeath : Assigns script(s) to handle this module event
|
||||
# module.OnPlayerDying : Assigns script(s) to handle this module event
|
||||
# module.OnPlayerEquipItem : Assigns script(s) to handle this module event
|
||||
# module.OnPlayerLevelUp : Assigns script(s) to handle this module event
|
||||
# module.OnPlayerRest : Assigns script(s) to handle this module event
|
||||
# module.OnPlayerUnEquipItem : Assigns script(s) to handle this module event
|
||||
# module.OnPlayerRespawn : Assigns script(s) to handle this module event
|
||||
# module.OnUnaquireItem : Assigns script(s) to handle this module event
|
||||
# module.OnUserDefined : Assigns script(s) to handle this module event
|
||||
|
||||
# Import there ERF files into the module.
|
||||
erf : spellpak.erf, prc_consortium.erf
|
||||
|
||||
# Haks and custom tlk's used by the module.
|
||||
module.Hak : spellPRCMerge.hak, spellPak.hak, prc_consortium.hak
|
||||
module.CustomTlk : spellsPRCMerge.tlk
|
||||
|
||||
# Events that need to be wired up.
|
||||
module.OnClientEnter : prc_onenter
|
||||
module.OnPlayerLevelUp : prc_levelup
|
||||
module.OnPlayerEquipItem : prc_equip
|
||||
module.OnPlayerUnequipItem : prc_unequip
|
||||
|
||||
# Cache PRC scripts for better performance.
|
||||
module.Cache : screen_targets
|
||||
module.Cache : prc_caster_level
|
||||
module.Cache : set_damage_type
|
||||
module.Cache : change_metamagic
|
||||
module.Cache : add_spell_dc
|
||||
module.Cache : add_spell_penetr
|
||||
module.Cache : add_damage
|
||||
module.Cache : add_damageshield
|
||||
module.Cache : add_randdamage
|
||||
module.Cache : add_healing
|
||||
module.Cache : add_hitpoints
|
61
trunk/tools/HakInstaller/spellPak.hif
Normal file
61
trunk/tools/HakInstaller/spellPak.hif
Normal file
@@ -0,0 +1,61 @@
|
||||
# HIF files may consist of any of the following tags. All tags are optional.
|
||||
# Tags that support multiple data items may have the data comma separated and/or
|
||||
# may have multiple entries. If a multiple entries are given for a tag that only
|
||||
# supports 1 value then the fist value in the file is used. Blank lines are ignored
|
||||
# as are lines starting with a '#'.
|
||||
#
|
||||
# Tag format is
|
||||
#
|
||||
# <tag> : <value1>, <value2>, ..., <valuen>
|
||||
#
|
||||
# All white space is optional, and tags may also be given on multiple lines
|
||||
# as follows:
|
||||
#
|
||||
# <tag> : <value1>
|
||||
# <tag> : <value2>
|
||||
# ...
|
||||
# <tag> : <valuen>
|
||||
#
|
||||
# The following tags are supported:
|
||||
#
|
||||
# erf : Imports the listed erf files into the module
|
||||
# module.Hak : haks to add to the module
|
||||
# module.CustomTlk : Custom tlk file for the module, only 1 value.
|
||||
# module.Cache : Adds the given scripts the module's script cache.
|
||||
# module.OnAcquireItem : Assigns script(s) to handle this module event
|
||||
# module.OnActivateItem : Assigns script(s) to handle this module event
|
||||
# module.OnClientEnter : Assigns script(s) to handle this module event
|
||||
# module.OnClientLeave : Assigns script(s) to handle this module event
|
||||
# module.OnCutsceneAbort : Assigns script(s) to handle this module event
|
||||
# module.OnHeartbeat : Assigns script(s) to handle this module event
|
||||
# module.OnModuleLoad : Assigns script(s) to handle this module event
|
||||
# module.OnModuleStart : Assigns script(s) to handle this module event
|
||||
# module.OnPlayerDeath : Assigns script(s) to handle this module event
|
||||
# module.OnPlayerDying : Assigns script(s) to handle this module event
|
||||
# module.OnPlayerEquipItem : Assigns script(s) to handle this module event
|
||||
# module.OnPlayerLevelUp : Assigns script(s) to handle this module event
|
||||
# module.OnPlayerRest : Assigns script(s) to handle this module event
|
||||
# module.OnPlayerUnEquipItem : Assigns script(s) to handle this module event
|
||||
# module.OnPlayerRespawn : Assigns script(s) to handle this module event
|
||||
# module.OnUnaquireItem : Assigns script(s) to handle this module event
|
||||
# module.OnUserDefined : Assigns script(s) to handle this module event
|
||||
|
||||
# Import there ERF files into the module.
|
||||
erf : spellpak.erf
|
||||
|
||||
# Haks and custom tlk's used by the module.
|
||||
module.Hak : spellPak.hak
|
||||
module.CustomTlk : spellPak.tlk
|
||||
|
||||
# Cache PRC scripts for better performance.
|
||||
module.Cache : screen_targets
|
||||
module.Cache : prc_caster_level
|
||||
module.Cache : set_damage_type
|
||||
module.Cache : change_metamagic
|
||||
module.Cache : add_spell_dc
|
||||
module.Cache : add_spell_penetr
|
||||
module.Cache : add_damage
|
||||
module.Cache : add_damageshield
|
||||
module.Cache : add_randdamage
|
||||
module.Cache : add_healing
|
||||
module.Cache : add_hitpoints
|
99
trunk/tools/HakInstaller/strings.resx
Normal file
99
trunk/tools/HakInstaller/strings.resx
Normal file
@@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<root xmlns="http://tempuri.org/strings.xsd">
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<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" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</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>1.0.0.0</value>
|
||||
</resheader>
|
||||
<resheader name="Reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="Writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="VersionFormat">
|
||||
<value>NWN{1}{2} version {0} installed.</value>
|
||||
</data>
|
||||
<data name="PathFormat">
|
||||
<value>Install Path: {0}</value>
|
||||
</data>
|
||||
<data name="ViewHakFile">
|
||||
<value>View Hak File</value>
|
||||
</data>
|
||||
<data name="ViewModFile">
|
||||
<value>View Module File</value>
|
||||
</data>
|
||||
<data name="ViewHakFileFormat">
|
||||
<value>View Hak {0}</value>
|
||||
</data>
|
||||
<data name="ViewModFileFormat">
|
||||
<value>View Module {0}</value>
|
||||
</data>
|
||||
<data name="XP2Name">
|
||||
<value>Hordes of the Underdark Campaign</value>
|
||||
</data>
|
||||
<data name="XP1Name">
|
||||
<value>Shadows of Undrentide Campaign</value>
|
||||
</data>
|
||||
<data name="OCName">
|
||||
<value>Neverwinter Original Campaign</value>
|
||||
</data>
|
||||
<data name="HifsOverwritesModule">
|
||||
<value>Some module content is going to get overwritten by haks being installed into the module. The module may not play correctly, do you wish to continue?</value>
|
||||
</data>
|
||||
<data name="ModuleOverwritesHifs">
|
||||
<value>Some content being added will be ignored because it is contained in haks already in the module. The module may not play correctly, do you wish to continue?</value>
|
||||
</data>
|
||||
<data name="ValidateNWNVersionError">
|
||||
<value>The {0} custom content cannot be installed because it requires at least version {1} of NWN, and you are currently running version {2}.</value>
|
||||
</data>
|
||||
<data name="ValidateMissingFilesError">
|
||||
<value>The {0} custom content cannot be installed because the following files are missing: {1}</value>
|
||||
</data>
|
||||
<data name="NoHIFS">
|
||||
<value>There is no custom content to install. The installer will now close.</value>
|
||||
</data>
|
||||
<data name="ValidateNWNXP1Error">
|
||||
<value>The {0} custom content cannot be installed because it requires the Shadows of Undrentide expansion.</value>
|
||||
</data>
|
||||
<data name="ValidateNWNXP2Error">
|
||||
<value>The {0} custom content cannot be installed because it requires the Hordes of the Underdark expansion.</value>
|
||||
</data>
|
||||
<data name="SingleHIFTitle">
|
||||
<value>{0} {1} Module Updater</value>
|
||||
</data>
|
||||
<data name="VersionFormatXP1">
|
||||
<value>, SoU</value>
|
||||
</data>
|
||||
<data name="VersionFormatXP2">
|
||||
<value>, HotU</value>
|
||||
</data>
|
||||
</root>
|
28
trunk/tools/HakInstaller/strings.xsd
Normal file
28
trunk/tools/HakInstaller/strings.xsd
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0"?>
|
||||
<xs:schema id="root" targetNamespace="http://tempuri.org/strings.xsd" xmlns:mstns="http://tempuri.org/strings.xsd" xmlns="http://tempuri.org/strings.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="qualified" elementFormDefault="qualified">
|
||||
<xs:element name="root" msdata:IsDataSet="true" msdata:EnforceConstraints="False">
|
||||
<xs:complexType>
|
||||
<xs:choice maxOccurs="unbounded">
|
||||
<xs:element name="data">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="value" type="xs:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xs:element name="comment" type="xs:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xs:sequence>
|
||||
<xs:attribute name="name" form="unqualified" type="xs:string" />
|
||||
<xs:attribute name="type" form="unqualified" type="xs:string" />
|
||||
<xs:attribute name="mimetype" form="unqualified" type="xs:string" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="resheader">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="value" type="xs:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xs:sequence>
|
||||
<xs:attribute name="name" form="unqualified" type="xs:string" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:choice>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
3
trunk/tools/HakInstaller/strings.xsx
Normal file
3
trunk/tools/HakInstaller/strings.xsx
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--This file is auto-generated by the XML Schema Designer. It holds layout information for components on the designer surface.-->
|
||||
<XSDDesignerLayout />
|
2
trunk/tools/HakInstaller/update.bat
Normal file
2
trunk/tools/HakInstaller/update.bat
Normal file
@@ -0,0 +1,2 @@
|
||||
copy /y ship\*.exe C:\Games\NeverwinterNights\utils
|
||||
copy /y ship\HakInstaller.exe C:\Development\nwnprc\CompiledResources\PRCModuleUpdater.exe
|
BIN
trunk/tools/NPC blueprint maker PRC.mod
Normal file
BIN
trunk/tools/NPC blueprint maker PRC.mod
Normal file
Binary file not shown.
BIN
trunk/tools/NPC blueprint maker.mod
Normal file
BIN
trunk/tools/NPC blueprint maker.mod
Normal file
Binary file not shown.
BIN
trunk/tools/NWNTools.rar
Normal file
BIN
trunk/tools/NWNTools.rar
Normal file
Binary file not shown.
BIN
trunk/tools/NWNTools169compat.7z
Normal file
BIN
trunk/tools/NWNTools169compat.7z
Normal file
Binary file not shown.
BIN
trunk/tools/Precacher.mod
Normal file
BIN
trunk/tools/Precacher.mod
Normal file
Binary file not shown.
BIN
trunk/tools/Rar.exe
Normal file
BIN
trunk/tools/Rar.exe
Normal file
Binary file not shown.
BIN
trunk/tools/cat.exe
Normal file
BIN
trunk/tools/cat.exe
Normal file
Binary file not shown.
67
trunk/tools/cls_feat_2da.c
Normal file
67
trunk/tools/cls_feat_2da.c
Normal file
@@ -0,0 +1,67 @@
|
||||
// -------------------------
|
||||
// CLS_FEAT_2DA by WodahsEht
|
||||
// -------------------------
|
||||
// Basically this utility goes through any specified cls_feat_*.2da and determines which feats
|
||||
// are duplicated. It's not exactly the fastest algorithm possible but it shouldn't take long at
|
||||
// all to parse all 2da's in one fell swoop.
|
||||
//
|
||||
// If you want to parse all 2da's at one time, add this line to a batch file:
|
||||
// for %%a in (..\2das\cls_feat_*.2da) do cls_feat_2da.exe %%a
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
char featnum[1000][20];
|
||||
int i, j, k;
|
||||
char find[20];
|
||||
FILE *input2da;
|
||||
|
||||
input2da = fopen(argv[1],"r");
|
||||
|
||||
if (input2da == NULL)
|
||||
{
|
||||
printf("Error, invalid file name.\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
while (i != -1 && !feof(input2da))
|
||||
{
|
||||
fscanf(input2da, "%s", &find);
|
||||
if (strcmp(find, "OnMenu") == 0)
|
||||
i = -1;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
while (!feof(input2da))
|
||||
{
|
||||
fscanf(input2da, "%*s");
|
||||
fscanf(input2da, "%*s");
|
||||
fscanf(input2da, "%s", &featnum[i]);
|
||||
fscanf(input2da, "%*s");
|
||||
fscanf(input2da, "%*s");
|
||||
fscanf(input2da, "%*s");
|
||||
i++;
|
||||
}
|
||||
|
||||
fclose(input2da);
|
||||
|
||||
i--;
|
||||
|
||||
i = (i > 1000) ? 1000 : i;
|
||||
|
||||
for (j = 0 ; j <= i ; j++)
|
||||
{
|
||||
for (k = j - 1 ; k >= 0 ; k--)
|
||||
{
|
||||
if (strcmp(featnum[j], featnum[k]) == 0 &&
|
||||
strcmp(featnum[j], "****") != 0 &&
|
||||
strcmp(featnum[k], "****") != 0)
|
||||
printf("Lines %i and %i have the same feat number.\n", j/* + 4*/, k/* + 4*/); // Busquishage - Ornedan
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
BIN
trunk/tools/cls_feat_2da.exe
Normal file
BIN
trunk/tools/cls_feat_2da.exe
Normal file
Binary file not shown.
4
trunk/tools/compile_jar.bat
Normal file
4
trunk/tools/compile_jar.bat
Normal file
@@ -0,0 +1,4 @@
|
||||
javac prc\prc\*.java prc\prc\autodoc\*.java prc\prc\makedep\*.java prc\prc\utils\*.java
|
||||
cd prc
|
||||
jar -cvfm ..\prc.jar ..\manifest.txt *.*
|
||||
pause
|
BIN
trunk/tools/cygiconv-2.dll
Normal file
BIN
trunk/tools/cygiconv-2.dll
Normal file
Binary file not shown.
BIN
trunk/tools/cygintl-2.dll
Normal file
BIN
trunk/tools/cygintl-2.dll
Normal file
Binary file not shown.
BIN
trunk/tools/cygintl-3.dll
Normal file
BIN
trunk/tools/cygintl-3.dll
Normal file
Binary file not shown.
BIN
trunk/tools/cygintl-8.dll
Normal file
BIN
trunk/tools/cygintl-8.dll
Normal file
Binary file not shown.
BIN
trunk/tools/cygpcre-0.dll
Normal file
BIN
trunk/tools/cygpcre-0.dll
Normal file
Binary file not shown.
BIN
trunk/tools/cygwin1.dll
Normal file
BIN
trunk/tools/cygwin1.dll
Normal file
Binary file not shown.
BIN
trunk/tools/cygxml2-2.dll
Normal file
BIN
trunk/tools/cygxml2-2.dll
Normal file
Binary file not shown.
BIN
trunk/tools/cygz.dll
Normal file
BIN
trunk/tools/cygz.dll
Normal file
Binary file not shown.
BIN
trunk/tools/diff.exe
Normal file
BIN
trunk/tools/diff.exe
Normal file
Binary file not shown.
BIN
trunk/tools/erf-1.2.1.zip
Normal file
BIN
trunk/tools/erf-1.2.1.zip
Normal file
Binary file not shown.
BIN
trunk/tools/erf.exe
Normal file
BIN
trunk/tools/erf.exe
Normal file
Binary file not shown.
131
trunk/tools/fileend.c
Normal file
131
trunk/tools/fileend.c
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
fileend.c
|
||||
|
||||
generates switches for use with PRCGetFileEnd()
|
||||
|
||||
By: Flaming_Sword
|
||||
Created: Sept 5, 2006
|
||||
Modified: June 12, 2009
|
||||
|
||||
USE: Run with path to directory containing 2das to create fileends for,
|
||||
will otherwise use default relative path to 2das
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
//#define DEBUG
|
||||
|
||||
#define MIN(x, y) (x <= y) ? x : y
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *sFile;
|
||||
char *sTemp = (char *) malloc(65536 * sizeof(char));
|
||||
char sDir[] = "../2das/";
|
||||
char *pt;
|
||||
char sName[20];
|
||||
char sPath[256];
|
||||
FILE *fp;
|
||||
DIR *dp;
|
||||
int nCount, i, add_slash = 0;
|
||||
struct dirent *ep;
|
||||
|
||||
if(argc < 1) return;
|
||||
if(argc > 1)
|
||||
{
|
||||
for(i = 0; argv[1][i] != '\0'; i++)
|
||||
{
|
||||
if(argv[1][i] == '\\')
|
||||
argv[1][i] = '/';
|
||||
}
|
||||
if(argv[1][i - 1] != '/')
|
||||
{
|
||||
add_slash = 1;
|
||||
}
|
||||
}
|
||||
if(argc == 1 || argv[1] == NULL)
|
||||
{
|
||||
pt = sDir;
|
||||
}
|
||||
else
|
||||
{
|
||||
pt = argv[1];
|
||||
}
|
||||
dp = opendir(pt);
|
||||
|
||||
printf(" //START AUTO-GENERATED FILEENDS\n");
|
||||
if (dp != NULL)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf(" //found dir %s\n", sDir);
|
||||
#endif
|
||||
while (ep = readdir (dp))
|
||||
{
|
||||
memset(sPath, 0, sizeof(sPath));
|
||||
memcpy(sPath, pt, MIN(sizeof(sPath), strlen(pt)));
|
||||
if(add_slash)
|
||||
strcat(sPath, "/");
|
||||
sFile = ep->d_name;
|
||||
strcat(sPath, sFile);
|
||||
#ifdef DEBUG
|
||||
printf("//%s\n", sPath);
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
printf("//null compare\n");
|
||||
#endif
|
||||
if(strstr(sFile, ".2da") == NULL && strstr(sFile, "2DA") == NULL)
|
||||
continue;
|
||||
#ifdef DEBUG
|
||||
printf("//file open\n");
|
||||
#endif
|
||||
fp = fopen(sPath, "r");
|
||||
if(fp == NULL)
|
||||
{
|
||||
printf(" //error opening %s\n", sFile);
|
||||
continue;
|
||||
}
|
||||
nCount = 0;
|
||||
#ifdef DEBUG
|
||||
printf("//fgets\n");
|
||||
#endif
|
||||
fgets(sTemp, 65535, fp);
|
||||
#ifdef DEBUG
|
||||
printf("//comp\n");
|
||||
#endif
|
||||
if(strncmp(sTemp, "2DA", 3))
|
||||
{
|
||||
fclose(fp);
|
||||
#ifdef DEBUG
|
||||
printf("//sTemp = %s\n", sTemp);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
nCount++;
|
||||
for(i = 0; i < 20; i++)
|
||||
sName[i] = sFile[i];
|
||||
while(fgets(sTemp, 65536, fp))
|
||||
{
|
||||
nCount++;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("//print\n");
|
||||
#endif
|
||||
printf(" SetPRCSwitch(%cPRC_FILE_END_%s%c, %d);\n", 34, strtok(sName, "."), 34, nCount - 4);
|
||||
fclose(fp);
|
||||
}
|
||||
(void) closedir (dp);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Directory %s not found\n", argv[1]);
|
||||
}
|
||||
|
||||
printf(" //END AUTO-GENERATED FILEENDS\n");
|
||||
free(sTemp);
|
||||
return 0;
|
||||
}
|
BIN
trunk/tools/generate_fileends.exe
Normal file
BIN
trunk/tools/generate_fileends.exe
Normal file
Binary file not shown.
BIN
trunk/tools/grep.exe
Normal file
BIN
trunk/tools/grep.exe
Normal file
Binary file not shown.
BIN
trunk/tools/icons/prc.ico
Normal file
BIN
trunk/tools/icons/prc.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
BIN
trunk/tools/icons/prc_vista.ico
Normal file
BIN
trunk/tools/icons/prc_vista.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 51 KiB |
BIN
trunk/tools/icons/prcicon_16.psd
Normal file
BIN
trunk/tools/icons/prcicon_16.psd
Normal file
Binary file not shown.
BIN
trunk/tools/icons/prcicon_256.psd
Normal file
BIN
trunk/tools/icons/prcicon_256.psd
Normal file
Binary file not shown.
BIN
trunk/tools/icons/prcicon_48.psd
Normal file
BIN
trunk/tools/icons/prcicon_48.psd
Normal file
Binary file not shown.
61
trunk/tools/java character creator.nsi
Normal file
61
trunk/tools/java character creator.nsi
Normal file
@@ -0,0 +1,61 @@
|
||||
; Java Launcher
|
||||
;--------------
|
||||
|
||||
;You want to change the next four lines
|
||||
Name "CharacterCreator"
|
||||
Caption "PRC/CODI Java Characer Creator"
|
||||
Icon "prc.ico"
|
||||
OutFile "CharacterCreator.exe"
|
||||
|
||||
SilentInstall silent
|
||||
AutoCloseWindow true
|
||||
ShowInstDetails nevershow
|
||||
|
||||
;You want to change the next two lines too
|
||||
!define JAR "CC.jar"
|
||||
|
||||
Section ""
|
||||
Call GetJRE
|
||||
Pop $R0
|
||||
|
||||
; change for your purpose (-jar etc.)
|
||||
StrCpy $0 '"$R0" -Xmx200M -Xms200M -jar ${JAR}'
|
||||
|
||||
|
||||
SetOutPath $EXEDIR
|
||||
ExecWait $0
|
||||
SectionEnd
|
||||
|
||||
Function GetJRE
|
||||
;
|
||||
; Find JRE (javaw.exe)
|
||||
; 1 - in .\jre directory (JRE Installed with application) [removed as it's not for this]
|
||||
; 2 - in JAVA_HOME environment variable
|
||||
; 3 - in the registry
|
||||
; 4 - assume javaw.exe in current dir or PATH
|
||||
|
||||
Push $R0
|
||||
Push $R1
|
||||
|
||||
; ClearErrors
|
||||
; StrCpy $R0 "$EXEDIR\jre\bin\javaw.exe"
|
||||
; IfFileExists $R0 JreFound
|
||||
; StrCpy $R0 ""
|
||||
|
||||
ClearErrors
|
||||
ReadEnvStr $R0 "JAVA_HOME"
|
||||
StrCpy $R0 "$R0\bin\javaw.exe"
|
||||
IfErrors 0 JreFound
|
||||
|
||||
ClearErrors
|
||||
ReadRegStr $R1 HKLM "SOFTWARE\JavaSoft\Java Runtime Environment" "CurrentVersion"
|
||||
ReadRegStr $R0 HKLM "SOFTWARE\JavaSoft\Java Runtime Environment\$R1" "JavaHome"
|
||||
StrCpy $R0 "$R0\bin\javaw.exe"
|
||||
|
||||
IfErrors 0 JreFound
|
||||
StrCpy $R0 "javaw.exe"
|
||||
|
||||
JreFound:
|
||||
Pop $R1
|
||||
Exch $R0
|
||||
FunctionEnd
|
BIN
trunk/tools/letoscript/Moneo.exe
Normal file
BIN
trunk/tools/letoscript/Moneo.exe
Normal file
Binary file not shown.
Binary file not shown.
9
trunk/tools/letoscript/SQL Support/NO LINUX BINARIES.txt
Normal file
9
trunk/tools/letoscript/SQL Support/NO LINUX BINARIES.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
There are currently no Linux binaries of Moneo (or .SOs) with SQL support.
|
||||
|
||||
This is due in large part to the absence of SCO/RCO hooking in the Linux port of NWNX2, making the point of SQL in LetoScript nearly moot.
|
||||
|
||||
If you're running Linux, and you'd like to try and compile with SQL support, jump into LetoScript.inc and uncomment the {$DEFINE LETOSCRIPT_SQL} flag there. I suggest trying with the {$DEFINE LETOSCRIPT_SQL_LETO} flag for SQLite3 support, just as a test, and then (if you can get Zeos functioning in your Kylix), you could try with {$DEFINE LETOSCRIPT_SQL_ZEOS} for full MySQL support. If you get either working, I'd be interested in hearing about your experience:
|
||||
|
||||
http://weathersong.infopop.cc
|
||||
|
||||
dragon@weathersong.net
|
Binary file not shown.
105
trunk/tools/letoscript/golem.ls
Normal file
105
trunk/tools/letoscript/golem.ls
Normal file
@@ -0,0 +1,105 @@
|
||||
$abbrev;
|
||||
$lowHD;
|
||||
$highHD;
|
||||
$sizeplus;
|
||||
$j;
|
||||
for($j = 1; $j<= 7; $j++)
|
||||
{
|
||||
if($j == 1)
|
||||
{
|
||||
$abbrev = 'clay';
|
||||
$lowHD = 12;
|
||||
$highHD = 33;
|
||||
$sizeplus = 19;
|
||||
}
|
||||
if($j == 2)
|
||||
{
|
||||
$abbrev = 'fles';
|
||||
$lowHD = 10;
|
||||
$highHD = 27;
|
||||
$sizeplus = 19;
|
||||
}
|
||||
if($j == 3)
|
||||
{
|
||||
$abbrev = 'ston';
|
||||
$lowHD = 15;
|
||||
$highHD = 42;
|
||||
$sizeplus = 22;
|
||||
}
|
||||
if($j == 4)
|
||||
{
|
||||
$abbrev = 'adam';
|
||||
$lowHD = 55;
|
||||
$highHD = 108;
|
||||
$sizeplus = 83;
|
||||
}
|
||||
if($j == 5)
|
||||
{
|
||||
$abbrev = 'demo';
|
||||
$lowHD = 5;
|
||||
$highHD = 0;
|
||||
}
|
||||
if($j == 6)
|
||||
{
|
||||
$abbrev = 'iron';
|
||||
$lowHD = 19;
|
||||
$highHD = 54;
|
||||
$sizeplus = 25;
|
||||
}
|
||||
if($j == 7)
|
||||
{
|
||||
$abbrev = 'mith';
|
||||
$lowHD = 37;
|
||||
$highHD = 72;
|
||||
$sizeplus = 55;
|
||||
}
|
||||
|
||||
print $abbrev;
|
||||
print ' ';
|
||||
print $lowHD;
|
||||
print ' ';
|
||||
print $highHD;
|
||||
print "\n";
|
||||
|
||||
if($highHD > 80)
|
||||
{
|
||||
$highHD = 80;
|
||||
}
|
||||
|
||||
%file = "..\\..\\others\\prc_con_$abbrev.utc" or die $!;
|
||||
$i;
|
||||
$sizeadded = 0;
|
||||
$count = 0;
|
||||
for($i=$lowHD; $i<=$highHD; $i = $i+1)
|
||||
{
|
||||
/ClassList/[0]/ClassLevel = /ClassList/[0]/ClassLevel+1;
|
||||
if($i%2 == 0)
|
||||
{
|
||||
/HitPoints = /HitPoints+5;
|
||||
/CurrentHitPoints = /CurrentHitPoints+5;
|
||||
/MaxHitPoints = /MaxHitPoints+5;
|
||||
}
|
||||
else
|
||||
{
|
||||
/HitPoints = /HitPoints+6;
|
||||
/CurrentHitPoints = /CurrentHitPoints+6;
|
||||
/MaxHitPoints = /MaxHitPoints+6;
|
||||
}
|
||||
if($i>=$sizeplus and $sizeadded == 0)
|
||||
{
|
||||
add Name => /FeatList/Feat, Value => 2293, Type => gffWord, SetIfExists => TRUE;
|
||||
$sizeadded = 1;
|
||||
print "Added size \n";
|
||||
}
|
||||
if($count%5 == 0)
|
||||
{
|
||||
$name = "prc_con_"+$abbrev+"_$i";
|
||||
/TemplateResRef = $name;
|
||||
$name = "$name.utc";
|
||||
%file = ">..\\..\\others\\$name";
|
||||
print "Written to file $name\n";
|
||||
}
|
||||
$count = $count+1;
|
||||
}
|
||||
close %file;
|
||||
}
|
1
trunk/tools/letoscript/golems.bat
Normal file
1
trunk/tools/letoscript/golems.bat
Normal file
@@ -0,0 +1 @@
|
||||
Moneo.exe golem.ls -> test.log
|
40
trunk/tools/letoscript/prc recipe merchant maker.ls
Normal file
40
trunk/tools/letoscript/prc recipe merchant maker.ls
Normal file
@@ -0,0 +1,40 @@
|
||||
%store = '.\prc_merchant.utm' or die $!;
|
||||
meta dir=> '..\..\Craft2das' or die $!;
|
||||
$name = 'prc_recipe';
|
||||
$i = 0;
|
||||
$max = 1000;
|
||||
$x = 0;
|
||||
$y = 0;
|
||||
$count = 0;
|
||||
add Name => /StoreList/[2]/ItemList, Type=>gffList;
|
||||
/ResRef = $name;
|
||||
/LocName = $name;
|
||||
/Tag = $name;
|
||||
|
||||
|
||||
for($i=0; $i<=$max; $i++)
|
||||
{
|
||||
$resref = lookup 'item_to_ireq', $i, 'RECIPE_TAG';
|
||||
if($resref eq '')
|
||||
{
|
||||
print "no entry\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
add /StoreList/[2]/ItemList/InventoryRes, $resref, gffResRef;
|
||||
add /StoreList/[2]/ItemList/[_]/Infinite, 1, gffByte;
|
||||
add /StoreList/[2]/ItemList/[_]/Repos_PosX, $x, gffByte;
|
||||
add /StoreList/[2]/ItemList/[_]/Repos_Posy, $y, gffByte;
|
||||
$x++;
|
||||
if($x>9)
|
||||
{
|
||||
$x = 0;
|
||||
$y++;
|
||||
}
|
||||
/StoreList/[2]/ItemList/[_].id = $count;
|
||||
$count++;
|
||||
}
|
||||
print "$resref $x $y /StoreList/[2]/ItemList/[_]/InventoryRes /StoreList/[2]/ItemList/[_]/Infinite /StoreList/[2]/ItemList/[_]/Repos_PosX /StoreList/[2]/ItemList/[_]/Repos_Posy \n";
|
||||
}
|
||||
|
||||
%store = ">..\\..\\others\\$name.utm";
|
1
trunk/tools/letoscript/prc revipe merchant maker.bat
Normal file
1
trunk/tools/letoscript/prc revipe merchant maker.bat
Normal file
@@ -0,0 +1 @@
|
||||
Moneo.exe "prc recipe merchant maker.ls" -> test.log
|
1
trunk/tools/letoscript/prc scroll merchant maker.bat
Normal file
1
trunk/tools/letoscript/prc scroll merchant maker.bat
Normal file
@@ -0,0 +1 @@
|
||||
Moneo.exe "prc recipe merchant maker.ls" -> test.log
|
31
trunk/tools/letoscript/prc scroll merchant maker.ls
Normal file
31
trunk/tools/letoscript/prc scroll merchant maker.ls
Normal file
@@ -0,0 +1,31 @@
|
||||
%store = '.\prc_merchant.utm' or die $!;
|
||||
meta dir=> '..\..\Craft2das' or die $!;
|
||||
$name = 'prc_recipe';
|
||||
$i = 0;
|
||||
$max = 776;
|
||||
$x = 0;
|
||||
$y = 0;
|
||||
|
||||
add Name => /StoreList/[2]/ItemList, Type=>gffList;
|
||||
/ResRef = $name;
|
||||
/LocName = $name;
|
||||
/Tag = $name;
|
||||
|
||||
|
||||
for($i=0; $i<=$max; $i++)
|
||||
{
|
||||
$resref = lookup 'item_to_ireq', $i, 'RECIPE_TAG';
|
||||
add /StoreList/[2]/ItemList/InventoryRes, $resref, gffResRef;
|
||||
add /StoreList/[2]/ItemList/[_]/Infinite, 1, gffByte;
|
||||
add /StoreList/[2]/ItemList/[_]/Repos_PosX, $x, gffByte;
|
||||
add /StoreList/[2]/ItemList/[_]/Repos_Posy, $y, gffByte;
|
||||
$x++;
|
||||
if($x>9)
|
||||
{
|
||||
$x = 0;
|
||||
$y++;
|
||||
}
|
||||
print "$resref $x $y /StoreList/[2]/ItemList/InventoryRes /StoreList/[2]/ItemList/[_]/Infinite /StoreList/[2]/ItemList/[_]/Repos_PosX /StoreList/[2]/ItemList/[_]/Repos_Posy \n";
|
||||
}
|
||||
|
||||
%store = ">$name.utm";
|
BIN
trunk/tools/letoscript/prc_merchant.utm
Normal file
BIN
trunk/tools/letoscript/prc_merchant.utm
Normal file
Binary file not shown.
BIN
trunk/tools/linux/erf
Normal file
BIN
trunk/tools/linux/erf
Normal file
Binary file not shown.
BIN
trunk/tools/linux/tlk2xml
Normal file
BIN
trunk/tools/linux/tlk2xml
Normal file
Binary file not shown.
BIN
trunk/tools/linux/tlktools
Normal file
BIN
trunk/tools/linux/tlktools
Normal file
Binary file not shown.
BIN
trunk/tools/linux/xml2tlk
Normal file
BIN
trunk/tools/linux/xml2tlk
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user