public static async Task ReceiveDeltas(HotReloadAgent hotReloadAgent) { Log("Attempting to receive deltas."); // This value is configured by dotnet-watch when the app is to be launched. var namedPipeName = Environment.GetEnvironmentVariable("DOTNET_HOTRELOAD_NAMEDPIPE_NAME") ?? throw new InvalidOperationException("DOTNET_HOTRELOAD_NAMEDPIPE_NAME was not specified."); using var pipeClient = new NamedPipeClientStream(".", namedPipeName, PipeDirection.InOut, PipeOptions.CurrentUserOnly | PipeOptions.Asynchronous); try { await pipeClient.ConnectAsync(5000); Log("Connected."); } catch (TimeoutException) { Log("Unable to connect to hot-reload server."); return; } while (pipeClient.IsConnected) { var update = await UpdatePayload.ReadAsync(pipeClient, default); Log("Attempting to apply deltas."); hotReloadAgent.ApplyDeltas(update.Deltas); pipeClient.WriteByte((byte)ApplyResult.Success); } Log("Stopped received delta updates. Server is no longer connected."); }
public static async Task ReceiveDeltas() { Log("Attempting to receive deltas."); using var pipeClient = new NamedPipeClientStream(".", "netcore-hot-reload", PipeDirection.InOut, PipeOptions.CurrentUserOnly | PipeOptions.Asynchronous); try { await pipeClient.ConnectAsync(5000); Log("Connected."); } catch (TimeoutException) { Log("Unable to connect to hot-reload server."); return; } List <Action>?receiveDeltaNotifications = null; while (pipeClient.IsConnected) { var update = await UpdatePayload.ReadAsync(pipeClient, default); Log("Attempting to apply deltas."); try { foreach (var item in update.Deltas) { var assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.Modules.FirstOrDefault() is Module m && m.ModuleVersionId == item.ModuleId); if (assembly is not null) { System.Reflection.Metadata.AssemblyExtensions.ApplyUpdate(assembly, item.MetadataDelta, item.ILDelta, ReadOnlySpan <byte> .Empty); } } // We want to base this off of mvids, but we'll figure that out eventually. var applyResult = update.ChangedFile is string changedFile && changedFile.EndsWith(".razor", StringComparison.Ordinal) ? ApplyResult.Success : ApplyResult.Success_RefreshBrowser; pipeClient.WriteByte((byte)applyResult); // Defer discovering the receiving deltas until the first hot reload delta. // This should give enough opportunity for AppDomain.GetAssemblies() to be sufficiently populated. receiveDeltaNotifications ??= GetAssembliesReceivingDeltas(); receiveDeltaNotifications.ForEach(r => r.Invoke()); Log("Deltas applied."); } catch (Exception ex) { Log(ex.ToString()); } } Log("Stopped received delta updates. Server is no longer connected."); }
public object DoUpdate([FromBody] UpdatePayload updatePayload) { UpdateInstruction instruction = _UpdateService.GetUpdateInstructionByID(updatePayload.UpdateInstructionID); string ReturnData = _UpdateService.DoScheduledUpdate(instruction); //_backgroundJobs.Enqueue(() => _UpdateService.DoUpdate(instruction)); this.DoAnalytics("DoUpdate", $"Rolling update for '{instruction.Name}'. Schedule number is '{ReturnData}'"); return(ReturnData); }
public async Task <bool> DownloadUo(UpdatePayload payload, ProgressBar pbar) { var filePath = _settings.LocalUltimaPath; if (!Directory.Exists(filePath)) { Directory.CreateDirectory(filePath); } var uri = payload.FullUltimaOnlineDownloadPath; using (var response = _httpClient.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead).Result) { response.EnsureSuccessStatusCode(); using (Stream contentStream = await response.Content.ReadAsStreamAsync(), fileStream = new FileStream(Path.Combine(filePath, "uo.zip"), FileMode.Create, FileAccess.Write, FileShare.None, 8192, true)) { var totalRead = 0L; var totalReads = 0L; var total = payload.FullUltimaOnlineDownloadWeightInKb * 100L; var buffer = new byte[8192]; var isMoreToRead = true; var percentage = 0; do { var read = await contentStream.ReadAsync(buffer, 0, buffer.Length); if (read == 0) { isMoreToRead = false; } else { await fileStream.WriteAsync(buffer, 0, read); totalRead += read; totalReads += 1; var percentageTotal = (int)Math.Round( ((decimal)totalRead / (payload.FullUltimaOnlineDownloadWeightInKb * 10)), 0); if (percentageTotal > percentage) { pbar.Tick(); percentage = percentageTotal; } } }while (isMoreToRead); } } return(true); }
public async Task <IActionResult> Index() { var log = new Log(); log.HostName = _accessor.HttpContext.Connection.RemoteIpAddress.ToString(); log.When = DateTime.Now; log.LogText = "Status endpoint hit"; log.IpAddress = log.HostName; _context.Logs.Add(log); _context.SaveChanges(); _logger.LogInformation("Status being requested"); var config = new ConfigurationBuilder().AddEnvironmentVariables().Build(); if (String.IsNullOrEmpty(config["SECRET_PASSWORD"])) { return(new BadRequestResult()); } var settings = _context.Settings.FirstOrDefault(); if (settings == null) { var newSettings = new Settings() { MessageOfTheDay = "Ultima DMR wita!", RelativeUoUri = "uo.zip", UoSizeInKb = 800000 }; _context.Settings.Add(newSettings); await _context.SaveChangesAsync(); settings = newSettings; } var responseMessage = new UpdatePayload() { FullUltimaOnlineDownloadPath = $"{config["URL_BASE"]}/api/download/uo", FullUltimaOnlineDownloadWeightInKb = settings.UoSizeInKb, MessageOfTheDay = settings.MessageOfTheDay }; var files = _context.UpdateFiles.Select(p => new UpdateFileInfo() { AssociatedMessage = p.AssociatedMessage, Name = p.Name, Revision = p.Revision, SizeInKb = p.SizeInKb, RequiresUnzip = p.RequiresUnzip, Uri = UrlHelper.GetFullUrl(p.RelativeUri, p.Revision), TargetName = p.TargetName }); responseMessage.UpdateFiles = files.ToList(); return(new JsonResult(responseMessage)); }
public void HandleUpdate(HttpListenerContext context) { UpdatePayload payload = null; try { var strm = context.Request.InputStream; var reader = new StreamReader(strm, context.Request.ContentEncoding); string json = reader.ReadToEnd(); payload = JsonUtility.FromJson <UpdatePayload>(json); } catch (Exception ex) { UnityEngine.Debug.Log(ex); } if (payload != null) { var response = new UpdateResponse(); var playerInfo = GetPlayerInfo(payload.privateId); response.timerStart = timerStart; response.timerLength = timerLength; if (playerInfo == null) { response.name = "Audience Member"; response.role = -1; response.judge = null; } else { var judgeInfo = connectedPlayers[curJudge]; bool isJudge = judgeInfo == playerInfo; playerInfo.keepAlive = true; response.name = playerInfo.name; response.judge = judgeInfo.name; response.role = isJudge ? 1 : 0; response.voted = winner != null; if (payload.leaving) { playerInfo.left = true; } if (!isJudge && state == StateID.Insulting && (playerInfo.receivedInsult == null || playerInfo.receivedInsult.Length == 0)) { playerInfo.receivedInsult = WWW.UnEscapeURL(payload.insult); } else if (isJudge && state == StateID.Voting && winner == null && payload.vote > 0) { winner = GetPlayerInfo(payload.vote); winner.wins++; } response.insulted = playerInfo.receivedInsult != null && playerInfo.receivedInsult.Length > 0; } response.running = state != StateID.Waiting; if (state == StateID.Insulting) { } else if (state == StateID.Voting) { response.insults = GetInsultsArray(); } else if (state == StateID.PostGame) { response.insults = GetInsultsArray(); if (winner == null) { do { winner = connectedPlayers[new System.Random().Next(connectedPlayers.Count)]; } while (winner == connectedPlayers[curJudge]); } response.winner = new Insult(); response.winner.caster = winner.name; response.winner.content = winner.receivedInsult; } ServerManager.inst.server.WriteJsonToContext(context, response); } else { print("Invalid payload"); context.Response.StatusCode = (int)HttpStatusCode.BadRequest; } }
/// <summary> /// Master callback deals with the first "line" of every server response /// /// Passed to CreateSSCallback /// CREATE SP OK LF /// CREATE SP FAIL LF /// /// Passed to JoinSSCallback /// JOIN SP OK LF /// JOIN SP FAIL LF /// /// Passed to ChangeCellCallback /// CHANGE SP OK LF /// CHANGE SP FAIL LF /// /// Passed to UndoCallback /// UNDO SP OK LF /// UNDO SP FAIL LF /// UNDO SP WAIT LF /// UNDO SP END LF /// /// Passed to SaveCallback /// SAVE SP OK LF /// SAVE SP FAIL LF /// /// Passed to UpdateCallback /// UPDATE /// /// /// </summary> /// <param name="message"></param> /// <param name="e"></param> /// <param name="payload"></param> private void MasterCallback(String message, Exception e, object o) { if (message != null) { string[] spaceSplit = message.Split(' '); string firstWord = ""; Payload payload = new Payload(0, false); UpdatePayload upPay = new UpdatePayload(); UndoPayload undoPay = new UndoPayload(); if (spaceSplit.Length > 0) firstWord = spaceSplit[0].ToUpper().Trim(); // Check the status string secondWord = ""; if (spaceSplit.Length > 1) secondWord = spaceSplit[1].ToUpper().Trim(); // Deal with Each status if (secondWord.Equals("OK")) { //passed payload = new Payload(1, true); if (firstWord.Equals("CHANGE")) { changePayload.valid = true; changePayload.number = 1; } else if (firstWord.Equals("UNDO")) { undoPay.valid = true; undoPay.number = 1; } } else if (secondWord.Equals("FAIL")) { //failed payload = new Payload(1, false); if (firstWord.Equals("CHANGE")) { changePayload.valid = false; changePayload.number = 1; } else if (firstWord.Equals("UNDO")) { undoPay.valid = false; undoPay.number = 1; } } else if (secondWord.Equals("WAIT")) { if (firstWord.Equals("UNDO")) { //Undo wait message undoPay.valid = false; undoPay.number = (int)SpecialStatus.UNDO_WAIT; } else if (firstWord.Equals("CHANGE")) { //changes wait message changePayload.valid = false; changePayload.number = (int)SpecialStatus.CHANGE_WAIT; changePayload.availability = ChangeStatus.WAITING_TO_SEND; } } else if (firstWord.Equals("UPDATE")) { upPay.number = 1; upPay.valid = true; } else if (secondWord.Equals("END")) { //Undo end message undoPay.valid = false; undoPay.number = (int)SpecialStatus.UNDO_END; } else if (!firstWord.Equals("UPDATE")) { // there was an error // @todo handle error socket.BeginReceive(MasterCallback, payload, CustomNetworking.callbacks.MASTER); } switch (firstWord) { case "CREATE": socket.BeginReceive(CreateSSCallback, payload, CustomNetworking.callbacks.CREATE); Debug.WriteLine("Create Response Recognized"); break; case "JOIN": socket.BeginReceive(JoinSSCallback, payload, CustomNetworking.callbacks.JOIN); Debug.WriteLine("Join Response Recognized"); break; case "CHANGE": socket.BeginReceive(ChangeCellCallback, changePayload, CustomNetworking.callbacks.CHANGE); Debug.WriteLine("Change Response Recognized"); break; case "UNDO": socket.BeginReceive(UndoCallback, undoPay, CustomNetworking.callbacks.UNDO); Debug.WriteLine("Undo Response Recognized"); break; case "SAVE": socket.BeginReceive(SaveCallback, payload, CustomNetworking.callbacks.SAVE); Debug.WriteLine("Save Response Recognized"); break; case "UPDATE": socket.BeginReceive(UpdateCallback, upPay, CustomNetworking.callbacks.UPDATE); Debug.WriteLine("Update Response Recognized"); break; default: socket.BeginReceive(MasterCallback, payload, CustomNetworking.callbacks.MASTER); // If all else fails just call the master Debug.WriteLine("Mastercallback: unrecognized command {0}", message); resetChangePayload(); //clientGUI_SS(message, true); break; } } }
/// <summary> /// To communicate a committed change to other clients, the server should send ///UPDATE LF ///Name:name LF; true 1 ///Version:version LF; true 2 ///Cell:cell LF; true 3 ///Length:length LF; true 4 ///content LF; true 5 /// </summary> /// <param name="message"></param> /// <param name="e"></param> /// <param name="payload"></param> private void UpdateCallback(String message, Exception e, object payload) { if (message != null) { string[] colonSplitup = message.Split(':'); string colonFirstWord = ""; UpdatePayload load = new UpdatePayload(); if (payload is UpdatePayload) { load = (UpdatePayload)payload; } if (colonSplitup.Length > 0) colonFirstWord = colonSplitup[0].ToUpper().Trim(); if (load.valid) { if (colonFirstWord.Equals("NAME") && load.number == 1) { // get name load.number++; socket.BeginReceive(UpdateCallback, load, CustomNetworking.callbacks.UPDATE); Debug.WriteLine("Update name Response Recognized"); } else if (colonFirstWord.Equals("VERSION") && load.number == 2) { // get Version Debug.WriteLine("Update version Response Recognized", message); load.number++; updateVersion(getSecondWord(colonSplitup)); socket.BeginReceive(UpdateCallback, load, CustomNetworking.callbacks.UPDATE); } else if (colonFirstWord.Equals("CELL") && load.number == 3) { // get cell Debug.WriteLine("Update cell Response Recognized"); load.number++; load.cell = getSecondWord(colonSplitup); socket.BeginReceive(UpdateCallback, load, CustomNetworking.callbacks.UPDATE); } else if (colonFirstWord.Equals("LENGTH") && load.number == 4) { // get length load.number++; int length; Int32.TryParse(getSecondWord(colonSplitup), out length); load.contentLength = length; Debug.WriteLine("Update length Response Recognized"); socket.BeginReceive(UpdateCallback, load, CustomNetworking.callbacks.UPDATE); } else if (load.number == 5) { // must be the content load.contents = message; Debug.WriteLine("Update content Response Recognized"); // We need to lock on this, right? e_Cell(load.cell, message.Trim()); socket.BeginReceive(MasterCallback, null, CustomNetworking.callbacks.MASTER); clientGUI_SS("update!", false); if (changePayload.availability == ChangeStatus.WAITING_TO_SEND) { changePayload.availability = ChangeStatus.CANSEND; Debug.WriteLine("Waiting_to_send message being sent {0}", message); ChangeCell(changePayload.cell, changePayload.contents); } } else { // something went wrong // @todo handle error, send error message to gui about bug report or something Debug.WriteLine("Update fail unrecognized command {0}", message); resetChangePayload(); socket.BeginReceive(MasterCallback, null, CustomNetworking.callbacks.MASTER); } } } }