/// <summary> /// 获取jssdk签名配置对象 /// </summary> /// <param name="url">当前页面url</param> /// <param name="jsapi">JsApiEnum,如:JsApiEnum.scanQRCode|JsApiEnum.onMenuShareQQ</param> /// <returns>微信公众平台JsSdk的配置对象</returns> public SignPackage GetSignPackage(string url, JsApiEnum jsapi) { /* * 签名字段 * noncestr=Wm3WZYTPz0wzccnW * jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg * timestamp=1414587457 * url=http://mp.weixin.qq.com?params=value */ string noncestr = this.CreateNonceStr(16); string jsapi_tkcket = this.GetJsApiTicket(); long timestamp = TimeStamp.Now(); Dictionary <string, string> signData = new Dictionary <string, string>() { { "noncestr", noncestr }, { "jsapi_ticket", jsapi_tkcket }, { "timestamp", timestamp.ToString() }, { "url", url } }; SignPackage result = new SignPackage() { AppId = this.appId, Timestamp = timestamp, NonceStr = noncestr, Debug = this._debug, Signature = new Signature().Sign(signData), Url = url, JsApiList = jsapi.ToString().Replace(" ", "").Split(',') }; return(result); }
public CacheItem(string key, object value, int expire) { this._key = key; this._value = value; this._expire = expire; this._insertTime = TimeStamp.Now(); }
public static async void LogMessageToFile(string message, LoggingLevel level) { // Initialization if (fileLoggingSession == null) { fileLoggingSession = new FileLoggingSession("NewTestamentLogSession"); } using (var loggingChannel = new LoggingChannel( "NewTestamentLogSession", new LoggingChannelOptions(new Guid("2e0582f3-d1b6-516a-00e3-9fd79ef95200")))) // Join a provider group { // The Id is generated by hashing the string "SampleProvider". // channel.Id == eff1e128-4903-5093-096a-bdc29b38456f fileLoggingSession.AddLoggingChannel(loggingChannel); // Log messages loggingChannel.LogMessage(message, level); } var file = await fileLoggingSession.CloseAndSaveToFileAsync(); StorageFolder sampleAppDefinedLogFolder = await ApplicationData.Current.LocalFolder.CreateFolderAsync("Logs", CreationCollisionOption.OpenIfExists); string newLogFileName = "Log1-" + TimeStamp.Now() + ".etl"; await file.MoveAsync(sampleAppDefinedLogFolder, newLogFileName); }
static void Main(string[] args) { XmlSerializer s = new XmlSerializer(typeof(OSMResponse)); Stream writer = new FileStream("c:\\tmp\\out.xml", FileMode.Create); OSMResponse resp = new OSMResponse(); resp.version = "0.5"; resp.generator = "OpenStreetMap.NET"; Node n = new Node(); n.lat = 52.50; n.lon = 5.50; n.id = 129834; n.timestamp = TimeStamp.Now(); resp.node.Add(n); n = new Node(); n.lat = 55.50; n.lon = 4.50; n.id = 1294324234; n.timestamp = TimeStamp.Now(); resp.node.Add(n); s.Serialize(writer, resp); Console.ReadKey(); }
private static bool HasInvalidTimestamp(TransactionViewModel transactionViewModel) { if (transactionViewModel.GetAttachmentTimestamp() == 0) { return(transactionViewModel.GetTimestamp() < MinTimestamp && transactionViewModel.GetHash() != Hash.NullHash || transactionViewModel.GetTimestamp() > (TimeStamp.Now() / 1000) + MaxTimestampFuture); } return(transactionViewModel.GetAttachmentTimestamp() < MinTimestampMs || transactionViewModel.GetAttachmentTimestamp() > TimeStamp.Now() + MaxTimestampFutureMs); }
/// <summary> /// /// </summary> /// <param name="trunkTransaction"></param> /// <param name="branchTransaction"></param> /// <param name="minWeightMagnitude"></param> /// <param name="trytes"></param> /// <returns></returns> public AttachToTangleResponse AttachToTangle( string trunkTransaction, string branchTransaction, int minWeightMagnitude, string[] trytes) { var response = new AttachToTangleResponse { Trytes = new List <string>() }; string previousTransaction = null; foreach (var t in trytes) { var txn = new Transaction(t) { TrunkTransaction = previousTransaction ?? trunkTransaction, BranchTransaction = previousTransaction == null ? branchTransaction : trunkTransaction }; if (string.IsNullOrEmpty(txn.Tag) || Regex.IsMatch(txn.Tag, "9*")) { txn.Tag = txn.ObsoleteTag; } txn.AttachmentTimestamp = TimeStamp.Now(); txn.AttachmentTimestampLowerBound = 0; txn.AttachmentTimestampUpperBound = 3_812_798_742_493L; // POW var transactionTrits = Converter.ToTrits(txn.ToTrytes()); if (!_pearlDiver.Search(transactionTrits, minWeightMagnitude, 0)) { throw new IllegalStateException("PearlDiver search failed"); } // Hash var hash = new sbyte[Sponge.HASH_LENGTH]; ICurl curl = SpongeFactory.Create(SpongeFactory.Mode.CURLP81); curl.Reset(); curl.Absorb(transactionTrits); curl.Squeeze(hash); previousTransaction = Converter.ToTrytes(hash); response.Trytes.Add(Converter.ToTrytes(transactionTrits)); } response.Trytes.Reverse(); return(response); }
public bool Expired() { return(TimeStamp.Now() > this._insertTime + _expire); }
private List <string> AttachToTangleStatement( Hash trunkTransaction, Hash branchTransaction, int minWeightMagnitude, List <string> trytes) { lock (_syncRoot) { List <TransactionViewModel> transactionViewModels = new List <TransactionViewModel>(); Hash prevTransaction = null; _pearlDiver = new PearlDiver(); int[] transactionTrits = Converter.AllocateTritsForTrytes(TrytesSize); foreach (string tryte in trytes) { var startTime = DateTime.Now; long timestamp = TimeStamp.Now(); try { Converter.Trits(tryte, transactionTrits, 0); //branch and trunk Array.Copy((prevTransaction ?? trunkTransaction).Trits(), 0, transactionTrits, TransactionViewModel.TrunkTransactionTrinaryOffset, TransactionViewModel.TrunkTransactionTrinarySize); Array.Copy((prevTransaction == null ? branchTransaction : trunkTransaction).Trits(), 0, transactionTrits, TransactionViewModel.BranchTransactionTrinaryOffset, TransactionViewModel.BranchTransactionTrinarySize); //attachment fields: tag and timestamps //tag - copy the obsolete tag to the attachment tag field only if tag isn't set. var tagTrits = ArrayUtils.SubArray(transactionTrits, TransactionViewModel.TagTrinaryOffset, TransactionViewModel.TagTrinarySize); if (Array.TrueForAll(tagTrits, s => s == 0)) { Array.Copy(transactionTrits, TransactionViewModel.ObsoleteTagTrinaryOffset, transactionTrits, TransactionViewModel.TagTrinaryOffset, TransactionViewModel.TagTrinarySize); } Converter.CopyTrits(timestamp, transactionTrits, TransactionViewModel.AttachmentTimestampTrinaryOffset, TransactionViewModel.AttachmentTimestampTrinarySize); Converter.CopyTrits(0, transactionTrits, TransactionViewModel.AttachmentTimestampLowerBoundTrinaryOffset, TransactionViewModel.AttachmentTimestampLowerBoundTrinarySize); Converter.CopyTrits(MaxTimestampValue, transactionTrits, TransactionViewModel.AttachmentTimestampUpperBoundTrinaryOffset, TransactionViewModel.AttachmentTimestampUpperBoundTrinarySize); if (!_pearlDiver.Search(transactionTrits, minWeightMagnitude, 0)) { transactionViewModels.Clear(); break; } //validate PoW - throws exception if invalid TransactionViewModel transactionViewModel = TransactionValidator.Validate(transactionTrits, _instance.TransactionValidator.MinWeightMagnitude); transactionViewModels.Add(transactionViewModel); prevTransaction = transactionViewModel.Hash; } finally { IncreaseEllapsedTimePoW(DateTime.Now - startTime); IncreaseCounterPoW(); if ((GetCounterPoW() % 100) == 0) { string sb = $"Last 100 PoW consumed {GetEllapsedTimePoW().TotalSeconds:F3} seconds processing time."; Log.Info(sb); ResetCounterPow(); ResetEllapsedTimePoW(); } } } List <string> elements = new List <string>(); for (int i = transactionViewModels.Count; i-- > 0;) { elements.Add(Converter.Trytes(transactionViewModels[i].Trits())); } return(elements); } }
// ReSharper disable once UnusedParameter.Local private AbstractResponse Process(string requestString, IPAddress remoteIpAddress) { try { Dictionary <string, object> request = JsonConvert.DeserializeObject <Dictionary <string, object> >(requestString); if (request == null) { return(ExceptionResponse.Create($"Invalid request payload: '{requestString}'")); } var result = request.TryGetValue("command", out var valueObject); if (!result) { return(ErrorResponse.Create("COMMAND parameter has not been specified in the request.")); } string command = (string)valueObject; //TODO(gjc): add remote limit api Log.Debug($"# {Interlocked.Increment(ref _counter)} -> Requesting command '{command}'"); switch (command) { case "attachToTangle": Hash trunkTransaction = new Hash(GetParameterAsStringAndValidate(request, "trunkTransaction", HashSize)); Hash branchTransaction = new Hash(GetParameterAsStringAndValidate(request, "branchTransaction", HashSize)); int minWeightMagnitude = GetParameterAsInt(request, "minWeightMagnitude"); List <string> trytes = GetParameterAsList(request, "trytes", TrytesSize); List <string> elements = AttachToTangleStatement(trunkTransaction, branchTransaction, minWeightMagnitude, trytes); return(AttachToTangleResponse.Create(elements)); case "getNodeInfo": return(GetNodeInfoResponse.Create( Program.MainnetName, Program.Version, Environment.ProcessorCount, 975883432, "1.8.0_151", 5726797824, 3193962496, new Hash("TWRPOZZSMGMUMG9LLARESH9CYOZYSZXSNXMJZUC9B9YSFR9VEDYMQQAJJHBWCITVJVSKHYSHWMHP99999"), 400101, new Hash("TWRPOZZSMGMUMG9LLARESH9CYOZYSZXSNXMJZUC9B9YSFR9VEDYMQQAJJHBWCITVJVSKHYSHWMHP99999"), 400101, 0, 0, TimeStamp.Now(), 5862, 346)); //String name = instance.configuration.booling(Configuration.DefaultConfSettings.TESTNET) ? IRI.TESTNET_NAME : IRI.MAINNET_NAME; //return GetNodeInfoResponse.create(name, IRI.VERSION, Runtime.getRuntime().availableProcessors(), // Runtime.getRuntime().freeMemory(), System.getProperty("java.version"), Runtime.getRuntime().maxMemory(), // Runtime.getRuntime().totalMemory(), instance.milestone.latestMilestone, instance.milestone.latestMilestoneIndex, // instance.milestone.latestSolidSubtangleMilestone, instance.milestone.latestSolidSubtangleMilestoneIndex, // instance.node.howManyNeighbors(), instance.node.queuedTransactionsSize(), // System.currentTimeMillis(), instance.tipsViewModel.size(), // instance.transactionRequester.numberOfTransactionsToRequest()); case "getNeighbors": return(GetNeighborsStatement()); default: { //TODO(gjc):add ixi process return(ErrorResponse.Create($"Command [{command}] is unknown")); } } } catch (ValidationException e) { Log.Info(e, "API Validation failed"); return(ErrorResponse.Create(e.Message)); } catch (Exception e) { Log.Error(e, "API Exception"); return(ErrorResponse.Create(e.Message)); } }
/// <summary> /// /// </summary> /// <param name="seed"></param> /// <param name="security"></param> /// <param name="transfers"></param> /// <param name="remainder"></param> /// <param name="inputs"></param> /// <param name="tips"></param> /// <param name="validateInputs"></param> /// <returns></returns> public List <string> PrepareTransfers( string seed, int security, Transfer[] transfers, string remainder, Input[] inputs, Transaction[] tips, bool validateInputs) { // validate seed if (!InputValidator.IsValidSeed(seed)) { throw new IllegalStateException(Constants.INVALID_SEED_INPUT_ERROR); } if (!InputValidator.IsValidSecurityLevel(security)) { throw new ArgumentException(Constants.INVALID_SECURITY_LEVEL_INPUT_ERROR); } if (remainder != null && !InputValidator.IsAddress(remainder)) { throw new ArgumentException(Constants.INVALID_ADDRESSES_INPUT_ERROR); } // Input validation of transfers object if (!InputValidator.IsValidTransfersCollection(transfers.ToList())) { throw new ArgumentException(Constants.INVALID_TRANSFERS_INPUT_ERROR); } if (inputs != null && !InputValidator.IsValidInputsCollection(inputs)) { throw new ArgumentException(Constants.INVALID_ADDRESSES_INPUT_ERROR); } // Create a new bundle var bundle = new Bundle(); var signatureFragments = new List <string>(); long totalValue = 0; var tag = ""; // // Iterate over all transfers, get totalValue // and prepare the signatureFragments, message and tag // foreach (var transfer in transfers) { // remove the checksum of the address if provided transfer.Address = transfer.Address.RemoveChecksum(); var signatureMessageLength = 1; // If message longer than 2187 trytes, increase signatureMessageLength (add 2nd transaction) if (transfer.Message.Length > Constants.MESSAGE_LENGTH) { // Get total length, message / maxLength (2187 trytes) signatureMessageLength += (int)Math.Floor((double)transfer.Message.Length / Constants.MESSAGE_LENGTH); var msgCopy = transfer.Message; // While there is still a message, copy it while (!string.IsNullOrEmpty(msgCopy)) { var fragment = msgCopy.Substring(0, 2187 > msgCopy.Length ? msgCopy.Length : 2187); msgCopy = msgCopy.Substring(fragment.Length, msgCopy.Length - fragment.Length); // Pad remainder of fragment if (fragment.Length < 2187) { fragment = fragment.PadRight(2187, '9'); } signatureFragments.Add(fragment); } } else { // Else, get single fragment with 2187 of 9's trytes var fragment = transfer.Message.PadRight(Constants.MESSAGE_LENGTH, '9'); signatureFragments.Add(fragment); } // get current timestamp in seconds var timestamp = (long)Math.Floor((double)TimeStamp.Now() / 1000); // If no tag defined, get 27 tryte tag. tag = string.IsNullOrEmpty(transfer.Tag) ? "999999999999999999999999999" : transfer.Tag; // Pad for required 27 tryte length if (tag.Length < Constants.TAG_LENGTH) { tag = tag.PadRight(Constants.TAG_LENGTH, '9'); } // Add first entries to the bundle // Slice the address in case the user provided a checksummed one bundle.AddEntry(signatureMessageLength, transfer.Address, transfer.Value, tag, timestamp); // Sum up total value totalValue += transfer.Value; } // Get inputs if we are sending tokens if (totalValue != 0) { // validate seed if (!InputValidator.IsValidSeed(seed)) { throw new IllegalStateException(Constants.INVALID_SEED_INPUT_ERROR); } // Case 1: user provided inputs // Validate the inputs by calling getBalances if (inputs != null && inputs.Length > 0) { if (!validateInputs) { return(AddRemainder(seed, security, inputs.ToList(), bundle, tag, totalValue, remainder, signatureFragments)); } // Get list if addresses of the provided inputs var inputAddresses = new List <string>(); foreach (var input in inputs) { inputAddresses.Add(input.Address); } List <string> tipHashes = null; if (tips != null) { tipHashes = new List <string>(); foreach (var tx in tips) { tipHashes.Add(tx.CurlHash()); } } var balances = IotaClient.GetBalances(100, inputAddresses, tipHashes); var confirmedInputs = new List <Input>(); long totalBalance = 0; for (var i = 0; i < balances.Balances.Count; i++) { var thisBalance = balances.Balances[i]; totalBalance += thisBalance; // If input has balance, add it to confirmedInputs if (thisBalance > 0) { var inputEl = inputs[i]; inputEl.Balance = thisBalance; confirmedInputs.Add(inputEl); // if we've already reached the intended input value, break out of loop if (totalBalance >= totalValue) { Log.Info("Total balance already reached "); break; } } } // Return not enough balance error if (totalValue > totalBalance) { throw new IllegalStateException(Constants.NOT_ENOUGH_BALANCE_ERROR); } return(AddRemainder(seed, security, confirmedInputs, bundle, tag, totalValue, remainder, signatureFragments)); } // Case 2: Get inputs deterministically // // If no inputs provided, derive the addresses from the seed and // confirm that the inputs exceed the threshold var inputList = GetInputs(seed, security, 0, 0, (int)totalValue).Inputs; return(AddRemainder(seed, security, inputList, bundle, tag, totalValue, remainder, signatureFragments)); } // If no input required, don't sign and simply finalize the bundle bundle.FinalizeBundle(SpongeFactory.Create(SpongeFactory.Mode.KERL)); bundle.AddTrytes(signatureFragments); var bundleTrytes = new List <string>(); bundle.Transactions.ForEach(tx => bundleTrytes.Add(tx.ToTrytes())); bundleTrytes.Reverse(); return(bundleTrytes); }
private List <string> AddRemainder( string seed, int security, List <Input> inputs, Bundle bundle, string tag, long totalValue, string remainderAddress, List <string> signatureFragments) { var totalTransferValue = totalValue; foreach (var input in inputs) { var thisBalance = input.Balance; var toSubtract = 0 - thisBalance; var timestamp = TimeStamp.Now(); // Add input as bundle entry // use input.Security bundle.AddEntry(input.Security, input.Address, toSubtract, tag, timestamp); // If there is a remainder value // Add extra output to send remaining funds to if (thisBalance >= totalTransferValue) { var remainder = thisBalance - totalTransferValue; // If user has provided remainder address // Use it to send remaining funds to if (remainder > 0 && remainderAddress != null) { // Remainder bundle entry bundle.AddEntry(1, remainderAddress, remainder, tag, timestamp); // function for signing inputs return(IotaApiUtils.SignInputsAndReturn( seed, inputs, bundle, signatureFragments, SpongeFactory.Create(SpongeFactory.Mode.KERL))); } if (remainder > 0) { AddressRequest addressRequest = new AddressRequest(seed, security); var res = GenerateNewAddresses(addressRequest); // Remainder bundle entry bundle.AddEntry(1, res.Addresses[0], remainder, tag, timestamp); // function for signing inputs return(IotaApiUtils.SignInputsAndReturn( seed, inputs, bundle, signatureFragments, SpongeFactory.Create(SpongeFactory.Mode.KERL))); } // If there is no remainder, do not add transaction to bundle // simply sign and return return(IotaApiUtils.SignInputsAndReturn( seed, inputs, bundle, signatureFragments, SpongeFactory.Create(SpongeFactory.Mode.KERL))); } // If multiple inputs provided, subtract the totalTransferValue by // the inputs balance totalTransferValue -= thisBalance; } throw new IllegalStateException(Constants.NOT_ENOUGH_BALANCE_ERROR); }
private void JobCreationGUI() { EditorGUILayout.BeginVertical("box"); TileManager.TileWidth = (double)EditorGUILayout.FloatField("TileWidth", (float)TileManager.TileWidth); TileManager.tileRadius = EditorGUILayout.IntField("TileRadius", TileManager.tileRadius); TileManager.LOD = EditorGUILayout.IntField("LOD", TileManager.LOD); TileManager.OriginLatitude = (double)EditorGUILayout.FloatField("OriginLatitude", (float)TileManager.OriginLatitude); TileManager.OriginLongitude = (double)EditorGUILayout.FloatField("OriginLongitude", (float)TileManager.OriginLongitude); EditorGUILayout.EndVertical(); client.method = (SerializationMethod)EditorGUILayout.EnumPopup("SerializationMethod", client.method); if (GUILayout.Button("Send OSM-Job-Messages")) { startTime = TimeStamp.Now(); stopTime = null; done = false; generateLocal = false; client.SendOSMJobMessages( jobQueueName, replyQueueName, statusUpdateQueueName, TileManager.tileRadius, TileManager.TileWidth, TileManager.OriginLongitude, TileManager.OriginLatitude, client.method); } sequential = EditorGUILayout.ToggleLeft("Sequential", sequential); if (GUILayout.Button("Generate Local")) { startTime = TimeStamp.Now(); stopTime = null; done = false; generateLocal = true; if (sequential) { tiles = new List <Tile>(); jobs = 0; for (int i = -TileManager.tileRadius; i <= TileManager.tileRadius; i++) { for (int j = -TileManager.tileRadius; j <= TileManager.tileRadius; j++) { StatusUpdateMessage msg = new StatusUpdateMessage(jobs, i + "," + j); TodoItem worker = msg.AddTodo(Job.Worker); //worker.AddTodo(Job.CreateTile); worker.AddTodo(Job.StartOSMQuery); worker.AddTodo(Job.StartProcedural); worker.AddTodo(Job.ProceduralPreparation); worker.AddTodo(Job.CreateTerrain); worker.AddTodo(Job.MeshPreparation); worker.AddTodo(Job.TileQuad); worker.AddTodo(Job.River); worker.AddTodo(Job.Ways); worker.AddTodo(Job.CreateBuildingMesh); worker.AddTodo(Job.FillMeshDivideMaterials); worker.AddTodo(Job.GarbageCollection); worker.AddTodo(Job.ProceduralDone); SimpleClient.jobStatus.Add(jobs, msg); Tile newTile = Tile.CreateTileGO(i, j, 5); tiles.Add(newTile); newTile.SetJobInfo(jobs, msg); jobs++; } } // Start first Tile-Generation // Next Tile will be started after "GenerationDone" of first Tile tiles[0].ProceduralDoneLocal += GenerationDone; tiles[0].StartQuery(); } else { // Start parallel Generation of Tiles locally TileManager.GenerateLocal(); } } #region ScaleWorkers int newNumberOfWorkers = EditorGUILayout.IntSlider("Number of Workers", numberOfWorkers, 1, 100); if (newNumberOfWorkers != numberOfWorkers) { if (newNumberOfWorkers > numberOfWorkers) { Debug.Log("Scaling UP number of workers (from " + numberOfWorkers + " to " + newNumberOfWorkers + ")"); } else { Debug.Log("Scaling DOWN number of workers (from " + numberOfWorkers + " to " + newNumberOfWorkers + ")"); } numberOfWorkers = newNumberOfWorkers; ScaleWorkers(numberOfWorkers); } #endregion // ScaleWorkers #region DrawOSM-Map if (osmMapRect == null) { osmMapRect = new OSMMapRect(); } osmMapRect.DrawOSMMapRect(new Rect(0, 300, this.position.width, this.position.height - 300)); if (osmMapRect.ShouldRepaint()) { Repaint(); } #endregion // DrawOSM-Map }
private static void CheckDone() { if (stopTime == null) { bool allJobsDone = true; foreach (StatusUpdateMessage item in SimpleClient.jobStatus.Values) { if (item.status != Status.DONE) { allJobsDone = false; break; } } #region Collect Statistics if (allJobsDone && SimpleClient.jobStatus.Count > 0) { stopTime = TimeStamp.Now(); Debug.Log("All Jobs Done"); Debug.Log("Gathering result..."); Dictionary <string, double> result = new Dictionary <string, double>(); foreach (StatusUpdateMessage item in SimpleClient.jobStatus.Values) { foreach (TodoItem cildItem in item.childDict.Values) { foreach (TodoItem childTodo in cildItem.childDict.Values) { if (!result.ContainsKey(childTodo.name)) { result.Add(childTodo.name, 0); } result[childTodo.name] += childTodo.Duration(); } if (!result.ContainsKey(cildItem.name)) { result.Add(cildItem.name, 0); } result[cildItem.name] += cildItem.Duration(); } if (!result.ContainsKey(item.name)) { result.Add(item.name, 0); } result[item.name] += item.Duration(); } StringBuilder sb = new StringBuilder(); sb.Append("StartTime,").Append(startTime).AppendLine(); sb.Append("StopTime,").Append(stopTime).AppendLine(); sb.Append("OriginLon,").Append(TileManager.OriginLongitude).AppendLine(); sb.Append("OriginLat,").Append(TileManager.OriginLatitude).AppendLine(); sb.Append("TileRadius, ").Append(TileManager.tileRadius).AppendLine(); sb.Append("TileWidth,").Append(TileManager.TileWidth).AppendLine(); StatusUpdateMessage msg = SimpleClient.jobStatus[0]; foreach (TodoItem cildItem in msg.childDict.Values) { sb.Append(cildItem.name).Append(", ").Append(result[cildItem.name]).Append("\n"); foreach (TodoItem childTodo in cildItem.childDict.Values) { sb.Append(childTodo.name).Append(", ").Append(result[childTodo.name]).Append("\n"); } } Debug.Log(sb.ToString()); string logPath = Application.dataPath + "/Logs/"; if (!Directory.Exists(logPath)) { Directory.CreateDirectory(logPath); } System.IO.File.WriteAllText(logPath + "Session.txt", sb.ToString()); } #endregion // Collect Statistics } }
private void WorkerStatusGUI() { EditorGUILayout.BeginVertical(); zoomFactor = EditorGUILayout.Slider("Zoom", zoomFactor, 0.000001f, 0.25f); autoScroll = EditorGUILayout.ToggleLeft("AutoScroll", autoScroll); #region StatusBar // Count number of Job-Todos int todoCount = 0; foreach (StatusUpdateMessage item in SimpleClient.jobStatus.Values) { foreach (TodoItem cildItem in item.childDict.Values) { foreach (TodoItem childTodo in cildItem.childDict.Values) { todoCount++; } todoCount++; } todoCount++; } // Calculate %-Step float step; if (SimpleClient.jobStatus.Values.Count > 0) { step = 1f / todoCount; } else { step = 0; } // Determine how many Job-Todos have been done float complete = 0; foreach (StatusUpdateMessage item in SimpleClient.jobStatus.Values) { foreach (TodoItem cildItem in item.childDict.Values) { foreach (TodoItem childTodo in cildItem.childDict.Values) { if (childTodo.status == Status.DONE) { complete += step; } } if (cildItem.status == Status.DONE) { complete += step; } } if (item.status == Status.DONE) { complete += step; } } EditorGUILayout.LabelField("", GUILayout.Height(20)); EditorGUI.ProgressBar(new Rect(0, 90, this.position.width - 200, 20), complete, (int)(complete * 100) + " % "); #endregion // Statusbar #region Timer string timer; if (stopTime == null) { timer = startTime != null?startTime.Duration() : "00:00:00.000"; } else { timer = TimeStamp.Duration(TimeStamp.Duration(startTime, stopTime)); } if (timerFontStyle == null) { timerFontStyle.font = (Font)Resources.Load("digitalmono"); timerFontStyle.fontSize = 34; } EditorGUI.LabelField(new Rect(this.position.width - 190, 85, 180, 20), timer, timerFontStyle); #endregion // Timer EditorGUILayout.EndVertical(); GUILayout.Space(10f); //Rect lastRect = GUILayoutUtility.GetLastRect(); //Debug.Log(lastRect); float panelOffset = 120; float autoScrollPosition = this.position.width - GoldenRatio.LongSideOf(this.position.width); float panelWidth = this.position.width - border; if (startTime != null) { panelWidth = Mathf.Max((float)TimeStamp.DurationInMillis(startTime, TimeStamp.Now()) * zoomFactor + autoScrollPosition, this.position.width - border); } if (stopTime != null) { panelWidth = Mathf.Min((float)TimeStamp.DurationInMillis(startTime, stopTime) * zoomFactor + autoScrollPosition, panelWidth); } int jobCount = SimpleClient.jobStatus.Values.Count; float panelHeight = jobCount * (4 * height + 4 * separator + 2 * padding) + yOffset; using (EditorGUILayout.ScrollViewScope scrollView = new EditorGUILayout.ScrollViewScope(scrollPos, false, false, GUILayout.Width(this.position.width), GUILayout.Height(this.position.height - panelOffset))) { scrollPos = scrollView.scrollPosition; EditorGUILayout.LabelField("", darkgrey, GUILayout.Width(panelWidth), GUILayout.Height(panelHeight)); if (autoScroll) { scrollPos.x = Mathf.Infinity; } float now = xOffset; if (startTime != null) { now = (float)TimeStamp.DurationInMillis(startTime, TimeStamp.Now()) * zoomFactor + xOffset; } if (generateLocal) { float y = 0f; y += yOffset; foreach (StatusUpdateMessage item in SimpleClient.jobStatus.Values) { y += separator; TodoItem worker = item.Get(Job.Worker); DrawJobItemBar(item, y); y += padding; y += height + separator; DrawTodoItemBar(worker, y); foreach (string todo in worker.childTodos) { DrawTodoItemBar(worker.childDict[todo], y); } y += height; y += padding; y += separator; } } else { float y = 0f; y += yOffset; foreach (StatusUpdateMessage item in SimpleClient.jobStatus.Values) { y += separator; TodoItem master = item.Get(Job.Master); TodoItem transfer = item.Get(Job.Transfer); TodoItem worker = item.Get(Job.Worker); DrawJobItemBar(item, y); y += padding; DrawTodoItemBar(master, y); foreach (string todo in master.childTodos) { DrawTodoItemBar(master.childDict[todo], y); } y += height + separator; foreach (string todo in transfer.childTodos) { DrawTodoItemBar(transfer.childDict[todo], y); } y += height + separator; DrawTodoItemBar(worker, y); foreach (string todo in worker.childTodos) { DrawTodoItemBar(worker.childDict[todo], y); } y += height; y += padding; y += separator; } } if (stopTime == null) { CustomGUIUtils.DrawBox(new Rect(now, 0, 1, panelHeight), Color.black); } #region Draw Time indicators if (1000 * zoomFactor > 20) { for (float x = 0; x < panelWidth; x += (1000 * zoomFactor)) { CustomGUIUtils.DrawBox(new Rect(x, 0, 1, panelHeight), Color.grey); } } if (15000 * zoomFactor > 20) { for (float x = 0; x < panelWidth; x += (15000 * zoomFactor)) { CustomGUIUtils.DrawBox(new Rect(x, 0, 1, panelHeight), XKCDColors.LightRed); } } for (float x = 0; x < panelWidth; x += (60000 * zoomFactor)) { CustomGUIUtils.DrawBox(new Rect(x, 0, 1, panelHeight), Color.red); } #endregion // Draw time indicators } Repaint(); }