/// <summary> /// Writes a string message in the progress text box, playing a sound and displaying a notifiation. /// </summary> /// <param name="message"></param> /// <param name="severity"></param> public void WriteMessage(string message, ExportState severity, string balloonMessage) { progressBox.AppendText(message); progressBox.AppendText("\r\n"); PlayNotificationSound(severity); DisplayNotificationBalloon(balloonMessage); }
private void ExportStateGetOrders() { var originStationData = LocationData.GetLocationIDByName(m_strOriginStation); var destinationStationData = LocationData.GetLocationIDByName(m_strDestinationStation); // Get origin station orders // If the region id is -1 we know it's a player station if (originStationData.Item2 == -1) { m_vOriginStationOrders = RequestManager.GetMarketOrdersByPlayerStation(AccessManager.authInfo, originStationData.Item1); } else { m_vOriginStationOrders = RequestManager.GetMarketOrdersByNPCStation(AccessManager.authInfo, originStationData.Item1, originStationData.Item2, false); } // Get destination station orders if (destinationStationData.Item2 == -1) { m_vDestinationStationOrders = RequestManager.GetMarketOrdersByPlayerStation(AccessManager.authInfo, destinationStationData.Item1); } else { m_vDestinationStationOrders = RequestManager.GetMarketOrdersByNPCStation(AccessManager.authInfo, destinationStationData.Item1, destinationStationData.Item2, true); } m_eExportState = ExportState.FILTER_ORDERS; }
void ExportComplete(SerializationCompletionReason status) { if ((status == SerializationCompletionReason.Succeeded) && (exportingAnchorBytes.Count > MinTrustworthySerializedAnchorDataSize)) { StatusTextDisplay.Instance.SetStatusText( string.Format( "copying {0:N2}MB data", (exportingAnchorBytes.Count / (1024 * 1024)))); if (SharingStage.Instance.ShowDetailedLogs) { Debug.Log("Anchor Manager: Uploading anchor: " + exportingAnchorName); } roomManager.UploadAnchor( currentRoom, new XString(exportingAnchorName), exportingAnchorBytes.ToArray(), exportingAnchorBytes.Count); } else { StatusTextDisplay.Instance.SetStatusText("retrying export"); Debug.LogWarning("Anchor Manager: Failed to upload anchor, trying again..."); currentState = ExportState.WaitingForAnchorLocation; } }
void Update() { if (SharingStage.Instance.IsConnected) { switch (this.currentState) { case ExportState.Start: this.currentState = ExportState.WaitingForAnchorLocation; this.ConnectToRoom(); #if UNITY_WSA && !UNITY_EDITOR this.worldAnchor = GetComponent <WorldAnchor>() ?? gameObject.AddComponent <WorldAnchor>(); StatusTextDisplay.Instance.SetStatusText("waiting for position data"); #endif break; case ExportState.WaitingForAnchorLocation: #if UNITY_WSA && !UNITY_EDITOR if (this.worldAnchor.isLocated) { this.currentState = ExportState.ExportingAnchor; StatusTextDisplay.Instance.SetStatusText("synchronising..."); this.ExportWorldAnchor(); } #endif // UNITY_WSA break; default: break; } } }
private void ExportStatePrintResults() { var finalResults = MarketOrderManager.CalculateProfitWithShippingCost(m_vExportItems, m_dicItemDictionary); finalResults.Sort(delegate(MarketOrder c1, MarketOrder c2) { return(c1.profit.CompareTo(c2.profit)); }); string header = m_strOriginStation + " -> " + m_strDestinationStation + ": "; m_vCurrentResultIDs.Clear(); foreach (var item in finalResults) { m_vCurrentResultIDs.Add(item.type_id); if (m_vPreviousResultIDs.Contains(item.type_id)) { Console.WriteLine(header + m_dicItemDictionary[item.type_id].name + " - Profit: " + (item.profit / 1000000) + "mil - Item Volume: " + m_dicItemDictionary[item.type_id].packaged_volume + " - Export Quantity: " + item.exportQuantity); } else { string newHeader = "*NEW* " + header; Console.WriteLine(newHeader + m_dicItemDictionary[item.type_id].name + " - Profit: " + (item.profit / 1000000) + "mil - Item Volume: " + m_dicItemDictionary[item.type_id].packaged_volume + " - Export Quantity: " + item.exportQuantity); m_vPreviousResultIDs.Add(item.type_id); Console.Beep(); } } m_vPreviousResultIDs.RemoveAll(item => !m_vCurrentResultIDs.Contains(item)); m_eExportState = ExportState.WAIT_TIMER; }
public ModelRoot Convert(PssgFile pssg) { var sceneBuilder = new SceneBuilder(); var state = new ExportState(); // F1 games use lib YYY var parent = pssg.FindNodes("LIBRARY", "type", "NODE").FirstOrDefault(); if (parent is null) { parent = pssg.FindNodes("LIBRARY", "type", "YYY").FirstOrDefault(); state.IsF1 = true; } if (parent is null) { throw new InvalidDataException("Could not find library with scene nodes."); } foreach (var child in parent.ChildNodes) { CreateNode(sceneBuilder, child, null, state); } return(sceneBuilder.ToGltf2()); }
private object ExportGeneric(ExportState state) { var input = this.Data; var type = input.ReadValueU16(LittleEndian); var flags = (GFF.FieldFlags)input.ReadValueU16(LittleEndian); var offset = input.ReadValueU32(LittleEndian); if (state.References.ContainsKey(offset) == true) { return(state.References[offset]); } var def = new GFF.FieldDefinition(); def.Id = 0; def.Offset = 0; if ((flags & GFF.FieldFlags.IsStructure) != 0) { flags &= ~GFF.FieldFlags.IsStructure; def.Type = GFF.FieldType.Structure; def.StructureId = type; } else { def.Type = (GFF.FieldType)type; } def.Flags = flags; var instance = this.ExportField(def, offset, state); state.References.Add(offset, instance); return(instance); }
private void ExportStateCalculateExports() { var exportItemsUnadjusted = MarketOrderManager.CalculateExportItems(m_dicFilteredOriginOrders, m_dicFilteredDestinationOrders); m_vExportItems = MarketOrderManager.CorrectQuantityAvailable(exportItemsUnadjusted); m_eExportState = ExportState.GET_TYPEINFO; }
private void PlayNotificationSound(ExportState severity) { string soundLocation = Path.Combine(Environment.CurrentDirectory, "sounds"); SoundPlayer player = null; switch (severity) { case ExportState.Begin: player = new SoundPlayer(Path.Combine(soundLocation, "begin.wav")); break; case ExportState.Error: case ExportState.ErrorFatal: player = new SoundPlayer(Path.Combine(soundLocation, "error.wav")); break; case ExportState.Success: player = new SoundPlayer(Path.Combine(soundLocation, "success.wav")); break; default: break; } try { if (!muteCheckBox.Checked) { player.Play(); } } catch (FileNotFoundException) { } }
public ExportManager(string originStation, string destinationStation) { m_eExportState = ExportState.WAIT_AUTH; m_strOriginStation = originStation; m_strDestinationStation = destinationStation; m_vCurrentResultIDs = new List <long>(); m_vPreviousResultIDs = new List <long>(); }
private void ExportStateWaitAuth() { while (AccessManager.accessCodeIsValid == false) { Thread.Sleep(2000); } m_eExportState = ExportState.GET_ORDERS; }
private void ExportStateFilterOrders() { m_dicFilteredOriginOrders = MarketOrderManager.GetBestPriceMapping(m_vOriginStationOrders, false); m_dicFilteredDestinationOrders = MarketOrderManager.GetBestPriceMapping(m_vDestinationStationOrders, true); m_eExportState = ExportState.CALCULATE_EXPORTS; // free up memory m_vOriginStationOrders.Clear(); m_vDestinationStationOrders.Clear(); }
/// <summary> /// Initializes a new instance of the ExportConfigurationResult class. /// </summary> /// <param name="id">Export configuration id</param> /// <param name="exportType">Target resource type of export /// configuration. Possible values include: 'BlobStorage', /// 'AppInsights'</param> /// <param name="creationTime">Creation time in ISO 8601 format</param> /// <param name="state">State of the export job. Possible values /// include: 'Enabled', 'Disabled', 'Pending', 'Deleted', /// 'Invalid'</param> /// <param name="lastRunTime">Latest time in ISO 8601 format when /// export completed successfully</param> /// <param name="stateInfo">Additional information about export /// configuration state</param> /// <param name="resourceGroup">resource group for the storage /// account/App Insights resource</param> /// <param name="resourceName">Storage accout or Appinsights resource /// name</param> public ExportConfigurationResult(string id, ExportType exportType, string creationTime, ExportState state, string lastRunTime = default(string), IList <ExportEntity?> exportEntities = default(IList <ExportEntity?>), string stateInfo = default(string), string resourceGroup = default(string), string resourceName = default(string), ExportConfiguration exportConfiguration = default(ExportConfiguration)) { Id = id; ExportType = exportType; CreationTime = creationTime; LastRunTime = lastRunTime; ExportEntities = exportEntities; State = state; StateInfo = stateInfo; ResourceGroup = resourceGroup; ResourceName = resourceName; ExportConfiguration = exportConfiguration; CustomInit(); }
public void ChangeExportState(Guid _guid, ExportState _exportState) { lock (ExcelExportState.lock_on) { if (!state.ContainsKey(_guid)) { throw new FaultException(string.Format("Session GUID [{0}] Not Found", _guid.ToString())); } else { state[_guid].ExportState = _exportState; } } }
private static IMeshBuilder <MaterialBuilder> ConvertMesh(PssgNode mpjnNode, ExportState state) { IEnumerable <PssgNode> primitives = mpjnNode.FindNodes("MATRIXPALETTERENDERINSTANCE"); // RD: Grid primitives = primitives.Concat(mpjnNode.FindNodes("MATRIXPALETTEJOINTRENDERINSTANCE")); // Dirt 2 and beyond var primitiveDatas = new List <PrimitiveData>(); var texCoordSets = 0; foreach (var prim in primitives) { var shaderName = ((string)prim.Attributes["shader"].Value).Substring(1); var material = CreateMaterialBuilder(shaderName, state, out var createdNew); string rdsId = ((string)prim.Attributes["indices"].Value).Substring(1); var rdsNode = prim.File.FindNodes("RENDERDATASOURCE", "id", rdsId).First(); var rds = new RenderDataSourceReader(rdsNode); texCoordSets = Math.Max(texCoordSets, rds.TexCoordSetCount); primitiveDatas.Add(new PrimitiveData(prim, material, createdNew, rds)); } string name = (string)mpjnNode.Attributes["id"].Value; var mb = CreateMeshBuilder(name, texCoordSets); foreach (var prim in primitiveDatas) { if (prim.CreatedNewMaterial) { ConvertMaterial(prim.Node.File, prim.Material, prim.Rds.TexCoordSetCount); } var pb = mb.UsePrimitive(prim.Material); var rds = prim.Rds; var indexOffset = prim.Node.Attributes["indexOffset"].GetValue <uint>(); var indexCount = prim.Node.Attributes["indicesCountFromOffset"].GetValue <uint>(); var triangles = rds.GetTriangles((int)indexOffset, (int)indexCount); foreach (var tri in triangles) { pb.AddTriangle( CreateVertexBuilder(rds, tri.A, state), CreateVertexBuilder(rds, tri.B, state), CreateVertexBuilder(rds, tri.C, state)); } } return(mb); }
private KeyValue ExportStructure(GFF.StructureDefinition def, long offset, ExportState state) { var kv = new KeyValue(GFF.FieldType.Structure, null); kv.StructureId = def.Id; foreach (var fieldDef in def.Fields) { var value = this.ExportField(fieldDef, offset, state); if (value is KeyValue) { kv[fieldDef.Id] = (KeyValue)value; } else { kv[fieldDef.Id] = new KeyValue(fieldDef.Type, value); } } return(kv); }
void OnAnchorUploadCompleted(bool successful, XString failureReason) { if (successful) { StatusTextDisplay.Instance.SetStatusText("synchronised"); if (SharingStage.Instance.ShowDetailedLogs) { Debug.Log("Anchor Manager: Sucessfully uploaded anchor"); } currentState = ExportState.AnchorUploaded; } else { StatusTextDisplay.Instance.SetStatusText("sync data copy failed"); Debug.LogError("Anchor Manager: Upload failed " + failureReason); currentState = ExportState.Failed; } base.FireCompleted(currentState == ExportState.AnchorUploaded); }
internal static string ToSerializedValue(this ExportState value) { switch (value) { case ExportState.Enabled: return("Enabled"); case ExportState.Disabled: return("Disabled"); case ExportState.Pending: return("Pending"); case ExportState.Deleted: return("Deleted"); case ExportState.Invalid: return("Invalid"); } return(null); }
internal static string ToSerializedValue(this ExportState value) { switch (value) { case ExportState.Undefined: return("Undefined"); case ExportState.NotStarted: return("NotStarted"); case ExportState.Running: return("Running"); case ExportState.Succeeded: return("Succeeded"); case ExportState.Failed: return("Failed"); } return(null); }
private void ExportManagerStateMachineDoWork() { switch (m_eExportState) { case ExportState.WAIT_AUTH: ExportStateWaitAuth(); break; case ExportState.GET_ORDERS: ExportStateGetOrders(); break; case ExportState.FILTER_ORDERS: ExportStateFilterOrders(); break; case ExportState.CALCULATE_EXPORTS: ExportStateCalculateExports(); break; case ExportState.GET_TYPEINFO: ExportStateGetTypeInfo(); break; case ExportState.PRINT_RESULTS: ExportStatePrintResults(); break; case ExportState.WAIT_TIMER: // wait 15 minutes before running again Console.WriteLine(m_strOriginStation + " -> " + m_strDestinationStation + ": Thread Going To Sleep."); Thread.Sleep(1000 * 60 * 15); m_eExportState = ExportState.WAIT_AUTH; break; default: Console.WriteLine("ExportManager: Unknown state."); break; } }
private void ExportStateGetTypeInfo() { m_dicItemDictionary = DiskManager.DeserializeTypesFromDisk(); bool saveToDisk = false; foreach (var item in m_vExportItems) { // If we don't have the item information saved to disk, fetch it. if (!m_dicItemDictionary.ContainsKey(item.type_id)) { var itemInfo = RequestManager.GetTypeInfo(AccessManager.authInfo, item.type_id); m_dicItemDictionary.Add(item.type_id, itemInfo); saveToDisk = true; } } if (saveToDisk) { DiskManager.SerializeTypesToDisk(m_dicItemDictionary); } m_eExportState = ExportState.PRINT_RESULTS; }
private void ExecuteExports(object state) { // Outer try/finally is used only to make sure m_exportInProgress state is reset regardless of success or failure of export try { // Dereference file bytes to be exported byte[] fileData = state as byte[]; if (m_enabled && (object)fileData != null) { string filename = null; ExportState[] exportStates = null; ExportDestination[] destinations; try { // Get a temporary file name filename = Path.GetTempFileName(); // Export data to the temporary file File.WriteAllBytes(filename, fileData); lock (this) { // Cache a local copy of export destinations to reduce lock time destinations = m_exportDestinations.ToArray(); } // Define a new export state for each export destination exportStates = new ExportState[destinations.Length]; for (int i = 0; i < exportStates.Length; i++) { exportStates[i] = new ExportState() { SourceFileName = filename, DestinationFileName = destinations[i].DestinationFile }; } // Spool threads to attempt copy of export files for (int i = 0; i < destinations.Length; i++) { ThreadPool.QueueUserWorkItem(CopyFileToDestination, exportStates[i]); } // Wait for exports to complete - even if user specifies to wait indefinitely spooled copy routines // will eventually return since there is a specified maximum retry count if (!WaitHandle.WaitAll(exportStates.Select(exportState => exportState.WaitHandle).ToArray(), m_exportTimeout)) { // Exports failed to complete in specified allowed time, set timeout flag for each export state Array.ForEach(exportStates, exportState => exportState.Timeout = true); OnStatusMessage("Timed out attempting export, waited for {0}.", Ticks.FromMilliseconds(m_exportTimeout).ToElapsedTimeString(2).ToLower()); } } catch (ThreadAbortException) { throw; // This exception is normal, we'll just rethrow this back up the try stack } catch (Exception ex) { OnProcessException(new InvalidOperationException(string.Format("Exception encountered during export preparation: {0}", ex.Message), ex)); } finally { // Dispose the export state wait handles if ((object)exportStates != null) { foreach (ExportState exportState in exportStates) { exportState.Dispose(); } } // Delete the temporary file - we queue this up in case the export threads may still be trying their last copy attempt ThreadPool.QueueUserWorkItem(DeleteTemporaryFile, filename); } } } finally { // Synchronously reset export progress state lock (m_exportInProgressLock) { m_exportInProgress = false; } } }
private static NodeBuilder CreateMeshNode(SceneBuilder sceneBuilder, PssgNode mpjnNode, NodeBuilder parent, ExportState state) { string name = (string)mpjnNode.Attributes["id"].Value; NodeBuilder node = parent.CreateNode(name); node.LocalTransform = GetTransform(mpjnNode); var mesh = ConvertMesh(mpjnNode, state); sceneBuilder.AddRigidMesh(mesh, node); return(node); }
private static void CreateNode(SceneBuilder sceneBuilder, PssgNode node, NodeBuilder?parent, ExportState state) { // only consider a scene node if it has a transform child node if (!node.ChildNodes.Any(c => c.Name == "TRANSFORM")) { return; } NodeBuilder gltfNode; if (parent is null) { string name = (string)node.Attributes["id"].Value; gltfNode = new NodeBuilder(name); gltfNode.LocalTransform = GetTransform(node); } else if (node.Name == "MATRIXPALETTEJOINTNODE") { gltfNode = CreateMeshNode(sceneBuilder, node, parent, state); } else if (node.Name == "MATRIXPALETTENODE") { // do nothing for this node return; } else if (node.Name == "NODE" || node.Name == "MATRIXPALETTEBUNDLENODE") { string name = (string)node.Attributes["id"].Value; gltfNode = parent.CreateNode(name); gltfNode.LocalTransform = GetTransform(node); } else { throw new NotImplementedException($"Support for node {node.Name} not implemented."); } foreach (var child in node.ChildNodes) { CreateNode(sceneBuilder, child, gltfNode, state); } }
private object ExportField(GFF.FieldDefinition def, long offset, ExportState state) { var endian = this.Endian; var input = this.Data; input.Seek(offset + def.Offset, SeekOrigin.Begin); if (def.IsReference == true && def.IsList == true) { var listOffset = input.ReadValueU32(endian); if (listOffset == 0xFFFFFFFF) { return(null); } input.Seek(listOffset, SeekOrigin.Begin); var count = input.ReadValueU32(endian); long itemOffset = input.Position; var list = new List <object>(); for (uint i = 0; i < count; i++) { list.Add(this.ExportGeneric(state)); itemOffset += 8; input.Seek(itemOffset, SeekOrigin.Begin); } return(list); } else if (def.IsList == true) { //var type = GFF.Builtin.ToNativeType(def.Type); var listOffset = input.ReadValueU32(endian); if (listOffset == 0xFFFFFFFF) { /*if (def.Type == GFF.FieldType.UInt8) * { * return new byte[0]; * } * else * { * throw new NotSupportedException(); * }*/ return(null); } input.Seek(listOffset, SeekOrigin.Begin); var count = input.ReadValueU32(endian); switch (def.Type) { case GFF.FieldType.String: { long itemOffset = input.Position; var list = new List <string>(); for (uint i = 0; i < count; i++) { var dataOffset = input.ReadValueU32(endian); if (dataOffset == 0xFFFFFFFF) { list.Add(null); } else { if (this.FileVersion < 1) { input.Seek(dataOffset, SeekOrigin.Begin); var length = input.ReadValueU32(endian); list.Add(input.ReadString(length * 2, true, endian == Endian.Little ? Encoding.Unicode : Encoding.BigEndianUnicode)); } else { list.Add(this.StringTable[(int)dataOffset]); } } itemOffset += 4; input.Seek(itemOffset, SeekOrigin.Begin); } return(list); } case GFF.FieldType.Structure: { long itemOffset = input.Position; var subdef = this.Structures[def.StructureId]; var list = new List <GenericKeyValue>(); for (uint i = 0; i < count; i++) { list.Add(this.ExportStructure( subdef, itemOffset, state)); itemOffset += subdef.DataSize; } return(list); } default: { if (def.Type == GFF.FieldType.UInt8) { var list = new byte[count]; input.Read(list, 0, list.Length); return(list); } else { var type = GFF.Builtin.ToNativeType(def.Type); var list = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(type)); for (uint i = 0; i < count; i++) { list.Add(GFF.Builtin.Deserialize(input, def.Type, endian)); } return(list); } } } } else { if (def.IsReference == true && def.Type == GFF.FieldType.Generic) { return(this.ExportGeneric(state)); } else if (def.IsReference == true) { var referenceOffset = input.ReadValueU32(endian); if (referenceOffset == 0xFFFFFFFF) { return(null); } else if (state.References.ContainsKey(referenceOffset) == true) { return(state.References[referenceOffset]); } input.Seek(referenceOffset, SeekOrigin.Begin); } switch (def.Type) { case GFF.FieldType.Generic: { throw new FormatException(); } case GFF.FieldType.String: { var dataOffset = input.ReadValueU32(endian); if (dataOffset == 0xFFFFFFFF) { return(""); } if (this.FileVersion < 1) { input.Seek(dataOffset, SeekOrigin.Begin); var count = input.ReadValueU32(endian); return(input.ReadString(count * 2, true, endian == Endian.Little ? Encoding.Unicode : Encoding.BigEndianUnicode)); } else { return(this.StringTable[(int)dataOffset]); } } case GFF.FieldType.TalkString: { var tlk = new GFF.Builtins.TalkString(); tlk.Id = input.ReadValueU32(endian); var dataOffset = input.ReadValueU32(endian); if (dataOffset == 0xFFFFFFFF) { tlk.String = null; } else if (dataOffset == 0) { tlk.String = ""; } else { if (this.FileVersion < 1) { input.Seek(dataOffset, SeekOrigin.Begin); var count = input.ReadValueU32(endian); tlk.String = input.ReadString(count * 2, true, endian == Endian.Little ? Encoding.Unicode : Encoding.BigEndianUnicode); } else { tlk.String = this.StringTable[(int)dataOffset]; } } return(tlk); } case GFF.FieldType.Structure: { var subdef = this.Structures[def.StructureId]; return(this.ExportStructure(subdef, input.Position, state)); } default: { return(GFF.Builtin.Deserialize(input, def.Type, endian)); } } } }
private void ExecuteExports() { byte[] fileData = m_fileData; if (m_enabled && (object)fileData != null && m_exportDestinations.Count > 0) { string fileName = null; ExportState[] exportStates = null; ExportDestination[] destinations; try { // Get a temporary file name fileName = Path.GetTempFileName(); // Export data to the temporary file File.WriteAllBytes(fileName, fileData); lock (m_exportDestinationsLock) { // Cache a local copy of export destinations to reduce lock time destinations = m_exportDestinations.ToArray(); } // Define a new export state for each export destination exportStates = new ExportState[destinations.Length]; for (int i = 0; i < exportStates.Length; i++) { exportStates[i] = new ExportState { SourceFileName = fileName, DestinationFileName = destinations[i].DestinationFile }; } // Spool threads to attempt copy of export files for (int i = 0; i < destinations.Length; i++) ThreadPool.QueueUserWorkItem(CopyFileToDestination, exportStates[i]); // Wait for exports to complete - even if user specifies to wait indefinitely spooled copy routines // will eventually return since there is a specified maximum retry count if (!exportStates.Select(exportState => exportState.WaitHandle).WaitAll(m_exportTimeout)) { // Exports failed to complete in specified allowed time, set timeout flag for each export state Array.ForEach(exportStates, exportState => exportState.Timeout = true); OnStatusMessage("Timed out attempting export, waited for {0}.", Ticks.FromMilliseconds(m_exportTimeout).ToElapsedTimeString(2).ToLower()); } } catch (Exception ex) { OnProcessException(new InvalidOperationException($"Exception encountered during export preparation: {ex.Message}", ex)); } finally { // Dispose the export state wait handles if ((object)exportStates != null) { foreach (ExportState exportState in exportStates) exportState.Dispose(); } // Delete the temporary file - wait for the specified retry time in case the export threads may still be trying // their last copy attempt. This is important if the timeouts are synchronized and there is one more export // about to be attempted before the timeout flag is checked. new Action(() => DeleteTemporaryFile(fileName)).DelayAndExecute(m_retryDelayInterval); } } }
private void ExecuteExports() { byte[] fileData = m_fileData; if (m_enabled && (object)fileData != null && m_exportDestinations.Count > 0) { string fileName = null; ExportState[] exportStates = null; ExportDestination[] destinations; try { // Get a temporary file name fileName = Path.GetTempFileName(); // Export data to the temporary file File.WriteAllBytes(fileName, fileData); lock (m_exportDestinationsLock) { // Cache a local copy of export destinations to reduce lock time destinations = m_exportDestinations.ToArray(); } // Define a new export state for each export destination exportStates = new ExportState[destinations.Length]; for (int i = 0; i < exportStates.Length; i++) { exportStates[i] = new ExportState { SourceFileName = fileName, DestinationFileName = destinations[i].DestinationFile }; } // Spool threads to attempt copy of export files for (int i = 0; i < destinations.Length; i++) { ThreadPool.QueueUserWorkItem(CopyFileToDestination, exportStates[i]); } // Wait for exports to complete - even if user specifies to wait indefinitely spooled copy routines // will eventually return since there is a specified maximum retry count if (!exportStates.Select(exportState => exportState.WaitHandle).WaitAll(m_exportTimeout)) { // Exports failed to complete in specified allowed time, set timeout flag for each export state Array.ForEach(exportStates, exportState => exportState.Timeout = true); OnStatusMessage("Timed out attempting export, waited for {0}.", Ticks.FromMilliseconds(m_exportTimeout).ToElapsedTimeString(2).ToLower()); } } catch (Exception ex) { OnProcessException(new InvalidOperationException($"Exception encountered during export preparation: {ex.Message}", ex)); } finally { // Dispose the export state wait handles if ((object)exportStates != null) { foreach (ExportState exportState in exportStates) { exportState.Dispose(); } } // Delete the temporary file - wait for the specified retry time in case the export threads may still be trying // their last copy attempt. This is important if the timeouts are synchronized and there is one more export // about to be attempted before the timeout flag is checked. new Action(() => DeleteTemporaryFile(fileName)).DelayAndExecute(m_retryDelayInterval); } } }
private void CopyFileToDestination(object state) { ExportState exportState = null; Exception exportException = null; int failedExportCount = 0; try { exportState = state as ExportState; if ((object)exportState != null) { // File copy may fail if destination is locked, so we setup to retry this operation // waiting the specified period between attempts for (int attempt = 0; attempt < 1 + m_maximumRetryAttempts; attempt++) { try { // Attempt to copy file to destination, overwriting if it already exists File.Copy(exportState.SourceFileName, exportState.DestinationFileName, true); } catch (Exception ex) { // Stack exception history to provide a full inner exception failure log for each export attempt if ((object)exportException == null) { exportException = ex; } else { exportException = new IOException($"Attempt {attempt + 1} exception: {ex.Message}", exportException); } failedExportCount++; // Abort retry attempts if export has timed out or maximum exports have been attempted if (!m_enabled || exportState.Timeout || attempt >= m_maximumRetryAttempts) { throw exportException; } Thread.Sleep(m_retryDelayInterval); } } // Track successful exports m_totalExports++; } } catch (Exception ex) { string destinationFileName = null; bool timeout = false; if ((object)exportState != null) { destinationFileName = exportState.DestinationFileName; timeout = exportState.Timeout; } OnProcessException(new InvalidOperationException($"Export attempt aborted {(timeout ? "due to timeout with" : "after")} {failedExportCount} exception{(failedExportCount > 1 ? "s" : "")} for \"{destinationFileName.ToNonNullString("[undefined]")}\" - {ex.Message}", ex)); } finally { // Release waiting thread exportState?.WaitHandle?.Set(); // Track total number of failed export attempts Interlocked.Add(ref m_failedExportAttempts, failedExportCount); } }
private object ExportField(GFF.FieldDefinition def, long offset, ExportState state) { var input = this.Data; input.Seek(offset + def.Offset, SeekOrigin.Begin); if (def.IsReference == true && def.IsList == true) { var listOffset = input.ReadValueU32(LittleEndian); if (listOffset == 0xFFFFFFFF) { return null; } input.Seek(listOffset, SeekOrigin.Begin); var count = input.ReadValueU32(LittleEndian); long itemOffset = input.Position; var list = new List<object>(); for (uint i = 0; i < count; i++) { list.Add(this.ExportGeneric(state)); itemOffset += 8; input.Seek(itemOffset, SeekOrigin.Begin); } return list; } else if (def.IsList == true) { //var type = GFF.Builtin.ToNativeType(def.Type); var listOffset = input.ReadValueU32(LittleEndian); if (listOffset == 0xFFFFFFFF) { /*if (def.Type == GFF.FieldType.UInt8) { return new byte[0]; } else { throw new NotSupportedException(); }*/ return null; } input.Seek(listOffset, SeekOrigin.Begin); var count = input.ReadValueU32(LittleEndian); switch (def.Type) { case GFF.FieldType.String: { long itemOffset = input.Position; var list = new List<string>(); for (uint i = 0; i < count; i++) { var dataOffset = input.ReadValueU32(LittleEndian); if (dataOffset == 0xFFFFFFFF) { list.Add(null); } else { if (this.FileVersion < 1) { input.Seek(dataOffset, SeekOrigin.Begin); var length = input.ReadValueU32(LittleEndian); list.Add(input.ReadString(length * 2, true, LittleEndian == true ? Encoding.Unicode : Encoding.BigEndianUnicode)); } else { list.Add(this.StringTable[(int)dataOffset]); } } itemOffset += 4; input.Seek(itemOffset, SeekOrigin.Begin); } return list; } case GFF.FieldType.Structure: { long itemOffset = input.Position; var subdef = this.Structures[def.StructureId]; var list = new List<KeyValue>(); for (uint i = 0; i < count; i++) { list.Add(this.ExportStructure( subdef, itemOffset, state)); itemOffset += subdef.DataSize; } return list; } default: { if (def.Type == GFF.FieldType.UInt8) { var list = new byte[count]; input.Read(list, 0, list.Length); return list; } else { var type = GFF.Builtin.ToNativeType(def.Type); var list = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(type)); for (uint i = 0; i < count; i++) { list.Add(GFF.Builtin.Deserialize(input, def.Type, LittleEndian)); } return list; } } } } else { if (def.IsReference == true && def.Type == GFF.FieldType.Generic) { return this.ExportGeneric(state); } else if (def.IsReference == true) { var referenceOffset = input.ReadValueU32(LittleEndian); if (referenceOffset == 0xFFFFFFFF) { return null; } else if (state.References.ContainsKey(referenceOffset) == true) { return state.References[referenceOffset]; } input.Seek(referenceOffset, SeekOrigin.Begin); } switch (def.Type) { case GFF.FieldType.Generic: { throw new FormatException(); } case GFF.FieldType.String: { var dataOffset = input.ReadValueU32(LittleEndian); if (dataOffset == 0xFFFFFFFF) { return ""; } if (this.FileVersion < 1) { input.Seek(dataOffset, SeekOrigin.Begin); var count = input.ReadValueU32(LittleEndian); return input.ReadString(count * 2, true, LittleEndian == true ? Encoding.Unicode : Encoding.BigEndianUnicode); } else { return this.StringTable[(int)dataOffset]; } } case GFF.FieldType.TalkString: { var tlk = new GFF.Builtins.TalkString(); tlk.Id = input.ReadValueU32(LittleEndian); var dataOffset = input.ReadValueU32(LittleEndian); if (dataOffset == 0xFFFFFFFF) { tlk.String = null; } else if (dataOffset == 0) { tlk.String = ""; } else { if (this.FileVersion < 1) { input.Seek(dataOffset, SeekOrigin.Begin); var count = input.ReadValueU32(LittleEndian); tlk.String = input.ReadString(count * 2, true, LittleEndian == true ? Encoding.Unicode : Encoding.BigEndianUnicode); } else { tlk.String = this.StringTable[(int)dataOffset]; } } return tlk; } case GFF.FieldType.Structure: { var subdef = this.Structures[def.StructureId]; return this.ExportStructure(subdef, input.Position, state); } default: { return GFF.Builtin.Deserialize(input, def.Type, LittleEndian); } } } }
private KeyValue ExportStructure(GFF.StructureDefinition def, long offset, ExportState state) { var kv = new KeyValue(GFF.FieldType.Structure, null); kv.StructureId = def.Id; foreach (var fieldDef in def.Fields) { var value = this.ExportField(fieldDef, offset, state); if (value is KeyValue) { kv[fieldDef.Id] = (KeyValue)value; } else { kv[fieldDef.Id] = new KeyValue(fieldDef.Type, value); } } return kv; }
private object ExportGeneric(ExportState state) { var input = this.Data; var type = input.ReadValueU16(LittleEndian); var flags = (GFF.FieldFlags)input.ReadValueU16(LittleEndian); var offset = input.ReadValueU32(LittleEndian); if (state.References.ContainsKey(offset) == true) { return state.References[offset]; } var def = new GFF.FieldDefinition(); def.Id = 0; def.Offset = 0; if ((flags & GFF.FieldFlags.IsStructure) != 0) { flags &= ~GFF.FieldFlags.IsStructure; def.Type = GFF.FieldType.Structure; def.StructureId = type; } else { def.Type = (GFF.FieldType)type; } def.Flags = flags; var instance = this.ExportField(def, offset, state); state.References.Add(offset, instance); return instance; }
private void ExportFamilies(string path) { foreach (Family fam in loader.families) { string familyDirectory = Path.Combine(path, fam.name); if (!Directory.Exists(familyDirectory)) { Directory.CreateDirectory(familyDirectory); } string filePath = Path.Combine(familyDirectory, "Family_" + fam.name + ".json"); if (File.Exists(filePath)) { File.Delete(filePath); } using (StreamWriter aiModelFileStream = File.CreateText(filePath)) { aiModelFileStream.Write(fam.ToJSON()); aiModelFileStream.Flush(); aiModelFileStream.Close(); } foreach (State state in fam.states) { ExportState exportState = ExportState.CreateFromState(state); string stateFilePath = Path.Combine(familyDirectory, "State_" + state.index + ".json"); if (File.Exists(stateFilePath)) { File.Delete(stateFilePath); } using (StreamWriter stateFileStream = File.CreateText(stateFilePath)) { stateFileStream.Write(exportState.ToJSON()); stateFileStream.Flush(); stateFileStream.Close(); } } foreach (ObjectList objectList in fam.objectLists) { if (objectList == null) { continue; } string objectListJSON = objectList.ToJSON(); string objectListHash = HashUtils.MD5Hash(objectListJSON); string objectListFilePath = Path.Combine(familyDirectory, "ObjectList_" + objectListHash + ".json"); if (File.Exists(objectListFilePath)) { File.Delete(objectListFilePath); } using (StreamWriter aiModelFileStream = File.CreateText(objectListFilePath)) { aiModelFileStream.Write(objectListJSON); aiModelFileStream.Flush(); aiModelFileStream.Close(); } } } }