/// <summary> /// Handles the registering and placement of the VXPlibrary.dll for tooltip creation. /// </summary> private void checkVXPlibrary() { if (File.Exists(Directory.GetCurrentDirectory() + "\\VXPlibrary.dll")) { // VXPlibrary.dll exists, but if it is not registered --> register it registerVXPlibrary(); } else { var ex = new FileNotFoundException("VXPlibrary.dll missing from TQVault directory!"); Log.ErrorException(ex); throw ex; } }
public static void Main() { try { manageCulture(); // Add the event handler for handling UI thread exceptions to the event. Application.ThreadException += new ThreadExceptionEventHandler(MainForm_UIThreadException); // Set the unhandled exception mode to force all Windows Forms errors to go through our handler. Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); // Add the event handler for handling non-UI thread exceptions to the event. AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); } catch (Exception ex) { Log.ErrorException(ex); throw; } }
/// <summary> /// Reads the ARC file table of contents to determine if the file is readable. /// </summary> /// <returns>True if able to read the ToC</returns> public bool Read(ArcFile file) { try { if (!file.FileHasBeenRead) { this.ReadARCToC(file); } return(file.DirectoryEntries != null); } catch (IOException exception) { Log.ErrorException(exception); return(false); } }
/// <summary> /// Validates that the next string is a certain value and throws an exception if it is not. /// </summary> /// <param name="value">value to be validated</param> /// <param name="reader">BinaryReader instance</param> public static void ValidateNextString(string value, BinaryReader reader) { string label = ReadCString(reader); if (!label.ToUpperInvariant().Equals(value.ToUpperInvariant())) { var ex = new ArgumentException(string.Format( CultureInfo.InvariantCulture, "Error reading file at position {2}. Expecting '{0}'. Got '{1}'", value, label, reader.BaseStream.Position - label.Length - 4)); Log.ErrorException(ex); throw ex; } }
public static void Main() { try { // Add the event handler for handling UI thread exceptions to the event. Application.ThreadException += new ThreadExceptionEventHandler(MainForm_UIThreadException); // Set the unhandled exception mode to force all Windows Forms errors to go through our handler. Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); // Add the event handler for handling non-UI thread exceptions to the event. AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); // Configure DI var scol = new ServiceCollection() // Logs .AddSingleton(typeof(ILogger <>), typeof(ILoggerImpl <>)) // States .AddSingleton <SessionContext>() // Providers .AddTransient <IRecordInfoProvider, RecordInfoProvider>() .AddTransient <IArcFileProvider, ArcFileProvider>() .AddTransient <IArzFileProvider, ArzFileProvider>() .AddSingleton <IDatabase, Database>() .AddSingleton <IItemProvider, ItemProvider>() .AddTransient <ILootTableCollectionProvider, LootTableCollectionProvider>() .AddTransient <IStashProvider, StashProvider>() .AddTransient <IPlayerCollectionProvider, PlayerCollectionProvider>() .AddTransient <ISackCollectionProvider, SackCollectionProvider>() .AddSingleton <IItemAttributeProvider, ItemAttributeProvider>() .AddTransient <IDBRecordCollectionProvider, DBRecordCollectionProvider>() // Services .AddTransient <IAddFontToOS, AddFontToOSWin>() .AddSingleton <IGamePathService, GamePathServiceWin>() .AddTransient <IPlayerService, PlayerService>() .AddTransient <IStashService, StashService>() .AddTransient <IVaultService, VaultService>() .AddTransient <ISearchService, SearchService>() .AddTransient <IFontService, FontService>() .AddTransient <ITranslationService, TranslationService>() .AddSingleton <IUIService, UIService>() .AddSingleton <ITQDataService, TQDataService>() .AddTransient <IBitmapService, BitmapService>() // Forms .AddSingleton <MainForm>() .AddTransient <AboutBox>() .AddTransient <CharacterEditDialog>() .AddTransient <ItemProperties>() .AddTransient <ItemSeedDialog>() .AddTransient <ResultsDialog>() .AddTransient <SearchDialog>() .AddTransient <SettingsDialog>() .AddTransient <VaultMaintenanceDialog>() .AddTransient <SplashScreenForm>(); Program.ServiceProvider = scol.BuildServiceProvider(); var gamePathResolver = Program.ServiceProvider.GetService <IGamePathService>(); manageCulture(); SetUILanguage(); SetupGamePaths(gamePathResolver); SetupMapName(gamePathResolver); var mainform = Program.ServiceProvider.GetService <MainForm>(); Application.Run(mainform); } catch (Exception ex) { Log.ErrorException(ex); throw; } }
/// <summary> /// Decompresses an individual record. /// </summary> /// <param name="arzFile">ARZ file which we are decompressing.</param> /// <returns>decompressed DBRecord.</returns> public DBRecordCollection Decompress(ArzFile arzFile) { // record variables have this format: // 0x00 int16 specifies data type: // 0x0000 = int - data will be an int32 // 0x0001 = float - data will be a Single // 0x0002 = string - data will be an int32 that is index into string table // 0x0003 = bool - data will be an int32 // 0x02 int16 specifies number of values (usually 1, but sometimes more (for arrays) // 0x04 int32 key string ID (the id into the string table for this variable name // 0x08 data value byte[] data = this.DecompressBytes(arzFile); int numberOfDWords = data.Length / 4; if (data.Length % 4 != 0) { var ex = new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Error while parsing arz record {0}, data Length = {1} which is not a multiple of 4", this.ID, (int)data.Length)); Log.ErrorException(ex); throw ex; } DBRecordCollection record = new DBRecordCollection(this.ID, this.RecordType); // Create a memory stream to read the binary data using (BinaryReader inReader = new BinaryReader(new MemoryStream(data, false))) { int i = 0; while (i < numberOfDWords) { short dataType = inReader.ReadInt16(); short valCount = inReader.ReadInt16(); int variableID = inReader.ReadInt32(); string variableName = arzFile.Getstring(variableID); if (variableName == null) { var ex = new ArgumentNullException(string.Format(CultureInfo.InvariantCulture, "Error while parsing arz record {0}, variable is NULL", this.ID)); Log.ErrorFormat(CultureInfo.InvariantCulture, "Error in ARZFile - {0}", arzFile.fileName); Log.ErrorException(ex); throw ex; } if (dataType < 0 || dataType > 3) { var ex = new ArgumentOutOfRangeException(string.Format(CultureInfo.InvariantCulture, "Error while parsing arz record {0}, variable {1}, bad dataType {2}", this.ID, variableName, dataType)); Log.ErrorFormat(CultureInfo.InvariantCulture, "Error in ARZFile - {0}", arzFile.fileName); Log.ErrorException(ex); throw ex; } Variable v = new Variable(variableName, (VariableDataType)dataType, valCount); if (valCount < 1) { var ex = new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Error while parsing arz record {0}, variable {1}, bad valCount {2}", this.ID, variableName, valCount)); Log.ErrorFormat(CultureInfo.InvariantCulture, "Error in ARZFile - {0}", arzFile.fileName); Log.ErrorException(ex); throw ex; } // increment our dword count i += 2 + valCount; for (int j = 0; j < valCount; ++j) { switch (v.DataType) { case VariableDataType.Integer: case VariableDataType.Boolean: { int val = inReader.ReadInt32(); v[j] = val; break; } case VariableDataType.Float: { float val = inReader.ReadSingle(); v[j] = val; break; } case VariableDataType.StringVar: { int id = inReader.ReadInt32(); string val = arzFile.Getstring(id); if (val == null) { val = string.Empty; } else { val = val.Trim(); } v[j] = val; break; } default: { int val = inReader.ReadInt32(); v[j] = val; break; } } } record.Set(v); } } return(record); }
/// <summary> /// Reads the ARZ file. /// </summary> /// <returns>true on success</returns> public bool Read(ArzFile file) { StreamWriter outStream = null; if (TQDebug.DatabaseDebugLevel > 2) { outStream = new StreamWriter("arzOut.txt", false); } try { // ARZ header file format // // 0x000000 int32 // 0x000004 int32 start of dbRecord table // 0x000008 int32 size in bytes of dbRecord table // 0x00000c int32 numEntries in dbRecord table // 0x000010 int32 start of string table // 0x000014 int32 size in bytes of string table using (FileStream instream = new FileStream(file.FileName, FileMode.Open, FileAccess.Read, FileShare.Read)) using (BinaryReader reader = new BinaryReader(instream)) { try { int[] header = new int[6]; for (int i = 0; i < 6; ++i) { header[i] = reader.ReadInt32(); if (outStream != null) { outStream.WriteLine("Header[{0}] = {1:n0} (0x{1:X})", i, header[i]); } } int firstTableStart = header[1]; int firstTableCount = header[3]; int secondTableStart = header[4]; this.ReadStringTable(file, secondTableStart, reader, outStream); this.ReadRecordTable(file, firstTableStart, firstTableCount, reader, outStream); // 4 final int32's from file // first int32 is numstrings in the stringtable // second int32 is something ;) // 3rd and 4th are crap (timestamps maybe?) for (int i = 0; i < 4; ++i) { int val = reader.ReadInt32(); if (outStream != null) { outStream.WriteLine("{0:n0} 0x{0:X}", val); } } } catch (IOException ex) { Log.ErrorException(ex); throw; } } } catch (IOException exception) { Log.ErrorException(exception); return(false); } finally { if (outStream != null) { outStream.Close(); } } return(true); }
public static void Main() { try { // Add the event handler for handling UI thread exceptions to the event. Application.ThreadException += new ThreadExceptionEventHandler(MainForm_UIThreadException); // Set the unhandled exception mode to force all Windows Forms errors to go through our handler. Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); // Add the event handler for handling non-UI thread exceptions to the event. AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); #if DEBUG Logger.ChangeRootLogLevel(Level.Debug); //TQDebug.DebugEnabled = true; #endif restart: // Configure DI var scol = new ServiceCollection() // Logs .AddSingleton(typeof(ILogger <>), typeof(ILoggerImpl <>)) // States .AddSingleton <SessionContext>() // Providers .AddTransient <IRecordInfoProvider, RecordInfoProvider>() .AddTransient <IArcFileProvider, ArcFileProvider>() .AddTransient <IArzFileProvider, ArzFileProvider>() .AddSingleton <IDatabase, Database>() .AddSingleton <IItemProvider, ItemProvider>() .AddTransient <ILootTableCollectionProvider, LootTableCollectionProvider>() .AddTransient <IStashProvider, StashProvider>() .AddTransient <IPlayerCollectionProvider, PlayerCollectionProvider>() .AddTransient <ISackCollectionProvider, SackCollectionProvider>() .AddSingleton <IItemAttributeProvider, ItemAttributeProvider>() .AddTransient <IDBRecordCollectionProvider, DBRecordCollectionProvider>() // Services .AddTransient <IAddFontToOS, AddFontToOSWin>() .AddSingleton <IGamePathService, GamePathServiceWin>() .AddTransient <IPlayerService, PlayerService>() .AddTransient <IStashService, StashService>() .AddTransient <IVaultService, VaultService>() .AddTransient <ISearchService, SearchService>() .AddTransient <IFontService, FontService>() .AddTransient <ITranslationService, TranslationService>() .AddSingleton <IUIService, UIService>() .AddSingleton <ITQDataService, TQDataService>() .AddTransient <IBitmapService, BitmapService>() // Forms .AddSingleton <MainForm>() .AddTransient <AboutBox>() .AddTransient <CharacterEditDialog>() .AddTransient <ItemProperties>() .AddTransient <ItemSeedDialog>() .AddTransient <ResultsDialog>() .AddTransient <SearchDialog>() .AddTransient <SettingsDialog>() .AddTransient <VaultMaintenanceDialog>() .AddTransient <SplashScreenForm>(); Program.ServiceProvider = scol.BuildServiceProvider(); var gamePathResolver = Program.ServiceProvider.GetService <IGamePathService>(); try { ManageCulture(); SetUILanguage(); SetupGamePaths(gamePathResolver); SetupMapName(gamePathResolver); } catch (ExGamePathNotFound ex) { using (var fbd = new FolderBrowserDialog() { Description = ex.Message, ShowNewFolderButton = false }) { DialogResult result = fbd.ShowDialog(); if (result == DialogResult.OK && !string.IsNullOrWhiteSpace(fbd.SelectedPath)) { Config.Settings.Default.ForceGamePath = fbd.SelectedPath; Config.Settings.Default.Save(); goto restart; } else { goto exit; } } } var mainform = Program.ServiceProvider.GetService <MainForm>(); Application.Run(mainform); } catch (Exception ex) { Log.ErrorException(ex); MessageBox.Show(Log.FormatException(ex), Resources.GlobalError, MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); } exit :; }
/// <summary> /// Parses the raw binary data for use within TQVault /// </summary> private void ParseRawData(PlayerCollection pc) { // First create a memory stream so we can decode the binary data as needed. using (MemoryStream stream = new MemoryStream(pc.rawData, false)) { using (BinaryReader reader = new BinaryReader(stream)) { // Find the block pairs until we find the block that contains the item data. int blockNestLevel = 0; int currentOffset = 0; int itemOffset = 0; int equipmentOffset = 0; // vaults start at the item data with no crap bool foundItems = pc.IsVault; bool foundEquipment = pc.IsVault; while ((!foundItems || !foundEquipment) && (currentOffset = FindNextBlockDelim(pc, currentOffset)) != -1) { if (pc.rawData[currentOffset] == beginBlockPattern[0]) { // begin block ++blockNestLevel; currentOffset += beginBlockPattern.Length; // skip past the 4 bytes of noise after begin_block currentOffset += 4; // Seek our stream to the correct position stream.Seek(currentOffset, SeekOrigin.Begin); // Now get the string for pc block string blockName = TQData.ReadCString(reader).ToUpperInvariant(); // Assign loc to our new stream position currentOffset = (int)stream.Position; // See if we accidentally got a begin_block or end_block if (blockName.Equals("BEGIN_BLOCK")) { blockName = "(NONAME)"; currentOffset -= beginBlockPattern.Length; } else if (blockName.Equals("END_BLOCK")) { blockName = "(NONAME)"; currentOffset -= endBlockPattern.Length; } else if (blockName.Equals("ITEMPOSITIONSSAVEDASGRIDCOORDS")) { currentOffset += 4; itemOffset = currentOffset; // skip value for itemPositionsSavedAsGridCoords foundItems = true; } else if (blockName.Equals("USEALTERNATE")) { currentOffset += 4; equipmentOffset = currentOffset; // skip value for useAlternate foundEquipment = true; } } else { // end block --blockNestLevel; currentOffset += endBlockPattern.Length; } } if (foundItems) { try { ParseItemBlock(pc, itemOffset, reader); } catch (ArgumentException exception) { var ex = new ArgumentException($"Error parsing player file Item Block- '{pc.PlayerName}'", exception); Log.ErrorException(ex); throw ex; } try { string outfile = string.Concat(Path.Combine(GamePathResolver.TQVaultSaveFolder, pc.PlayerName), " Export.txt"); using (StreamWriter outStream = new StreamWriter(outfile, false)) { outStream.WriteLine("Number of Sacks = {0}", pc.numberOfSacks); int sackNumber = 0; if (pc.sacks != null) { foreach (SackCollection sack in pc.sacks) { if (!sack.IsEmpty) { outStream.WriteLine(); outStream.WriteLine("SACK {0}", sackNumber); int itemNumber = 0; foreach (Item item in sack) { object[] params1 = new object[20]; params1[0] = itemNumber; params1[1] = ItemProvider.GetFriendlyNames(item).FullNameBagTooltip; params1[2] = item.PositionX; params1[3] = item.PositionY; params1[4] = item.Seed; ////params1[5] = outStream.WriteLine(" {0,5:n0} {1}", params1); itemNumber++; } } sackNumber++; } } } } catch (IOException exception) { Log.ErrorFormat(exception, "Error writing Export file - '{0}' Export.txt" , Path.Combine(GamePathResolver.TQVaultSaveFolder, pc.PlayerName) ); } } // Process the equipment block if (foundEquipment && !pc.IsVault) { try { ParseEquipmentBlock(pc, equipmentOffset, reader); } catch (ArgumentException exception) { var ex = new ArgumentException($"Error parsing player file Equipment Block - '{pc.PlayerName}'", exception); Log.ErrorException(ex); throw ex; } try { string outfile = string.Concat(Path.Combine(GamePathResolver.TQVaultSaveFolder, pc.PlayerName), " Equipment Export.txt"); using (StreamWriter outStream = new StreamWriter(outfile, false)) { if (!pc.EquipmentSack.IsEmpty) { int itemNumber = 0; foreach (Item item in pc.EquipmentSack) { object[] params1 = new object[20]; params1[0] = itemNumber; params1[1] = ItemProvider.GetFriendlyNames(item).FullNameBagTooltip; params1[2] = item.PositionX; params1[3] = item.PositionY; params1[4] = item.Seed; outStream.WriteLine(" {0,5:n0} {1}", params1); itemNumber++; } } } } catch (IOException exception) { Log.ErrorFormat(exception, "Error writing Export file - '{0}' Equipment Export.txt" , Path.Combine(GamePathResolver.TQVaultSaveFolder, pc.PlayerName) ); } } if (pc.IsPlayer) { try { pc.PlayerInfo = ReadPlayerInfo(pc); } catch (ArgumentException ex) { var exx = new ArgumentException($"Error parsing player player info Block - '{pc.PlayerName}'", ex); Log.ErrorException(exx); throw exx; } } } } }
/// <summary> /// Loads all of the players, stashes, and vaults. /// Shows a progress dialog. /// Used for the searching function. /// </summary> private void LoadAllFiles() { // Check to see if we failed the last time we tried loading all of the files. // If we did fail then turn it off and skip it. if (!Config.Settings.Default.LoadAllFilesCompleted) { if (MessageBox.Show( Resources.MainFormDisableLoadAllFiles, Resources.MainFormDisableLoadAllFilesCaption, MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, RightToLeftOptions) == DialogResult.Yes) { Config.Settings.Default.LoadAllFilesCompleted = true; Config.Settings.Default.LoadAllFiles = false; Config.Settings.Default.Save(); return; } } string[] vaults = GamePathResolver.GetVaultList(); string[] charactersIT = GamePathResolver.GetCharacterList(); int numIT = charactersIT?.Length ?? 0; int numVaults = vaults?.Length ?? 0; // Since this takes a while, show a progress dialog box. int total = numIT + numVaults - 1; if (total > 0) { // We were successful last time so we reset the flag for this attempt. Config.Settings.Default.LoadAllFilesCompleted = false; Config.Settings.Default.Save(); } else { return; } // Load all of the Immortal Throne player files and stashes. for (int i = 0; i < numIT; ++i) { // Get the player & player's stash try { var result = this.playerService.LoadPlayer(charactersIT[i], true); if (result.PlayerArgumentException != null) { string msg = string.Format(CultureInfo.CurrentUICulture, "{0}\n{1}\n{2}", Resources.MainFormPlayerReadError, result.PlayerFile, result.PlayerArgumentException.Message); MessageBox.Show(msg, Resources.GlobalError, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, RightToLeftOptions); } if (result.StashArgumentException != null) { string msg = string.Format(CultureInfo.CurrentUICulture, "{0}\n{1}\n{2}", Resources.MainFormPlayerReadError, result.StashFile, result.StashArgumentException.Message); MessageBox.Show(msg, Resources.GlobalError, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, RightToLeftOptions); } } catch (IOException exception) { Log.ErrorException(exception); MessageBox.Show(Log.FormatException(exception), Resources.GlobalError, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, RightToLeftOptions); } this.backgroundWorker1.ReportProgress(1); } // Load all of the vaults. for (int i = 0; i < numVaults; ++i) { var result = this.vaultService.LoadVault(vaults[i]); if (result.ArgumentException != null) { string msg = string.Format(CultureInfo.CurrentUICulture, "{0}\n{1}\n{2}", Resources.MainFormPlayerReadError, result.Filename, result.ArgumentException.Message); MessageBox.Show(msg, Resources.GlobalError, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, RightToLeftOptions); } this.backgroundWorker1.ReportProgress(1); } // We made it so set the flag to indicate we were successful. Config.Settings.Default.LoadAllFilesCompleted = true; Config.Settings.Default.Save(); }