private async Task <bool> ReceiveAndProcess() { WebSocketReceiveResult result; string msg = ""; byte[] buf = new byte[bufferSize]; try { int maxBufferSize = RacetimeChannel.maxBufferSize; int read = 0; int free = buf.Length; do { if (free < 1) { var newSize = buf.Length + (bufferSize); if (newSize > maxBufferSize) { throw new InternalBufferOverflowException(); } var newBuf = new byte[newSize]; Array.Copy(buf, 0, newBuf, 0, read); buf = newBuf; free = buf.Length - read; } result = await ws.ReceiveAsync(new ArraySegment <byte>(buf, read, free), websocket_cts.Token); if (websocket_cts.IsCancellationRequested) { return(false); } read += result.Count; free -= result.Count; }while (!result.EndOfMessage); msg = Encoding.UTF8.GetString(buf, 0, read); RawMessageReceived?.Invoke(this, msg); } catch (InternalBufferOverflowException) { //flush socket while (!(result = await ws.ReceiveAsync(new ArraySegment <byte>(buf, 0, buf.Length), websocket_cts.Token)).EndOfMessage) { ; } SendSystemMessage("Content too large to load"); return(false); } catch { return(false); } RawMessageReceived?.Invoke(this, msg); IEnumerable <ChatMessage> chatmessages = Parse(JSON.FromString(msg)); ChatMessage racemessage = chatmessages.FirstOrDefault(x => x.Type == MessageType.Race); if (racemessage != null) { UpdateRaceData((RaceMessage)racemessage); } var errormsg = chatmessages.FirstOrDefault(x => x.Type == MessageType.Error)?.Message; if (errormsg != null && string.Join("", errormsg).Contains("Permission denied")) { ForceReload(); return(true); } else if (errormsg != null) { StateChanged?.Invoke(this, Race.State); UserListRefreshed?.Invoke(this, new EventArgs()); } MessageReceived?.Invoke(this, chatmessages); return(true); }
void RaiseUserListRefreshed(object sender, EventArgs e) { UserListRefreshed?.Invoke(this, null); }
private void UpdateRaceData(RaceMessage msg) { if (Race == null) { Race = msg.Race; RaceChanged?.Invoke(this, new EventArgs()); GoalChanged?.Invoke(this, new EventArgs()); UserListRefreshed?.Invoke(this, new EventArgs()); return; } switch (msg.Race?.State) { case RaceState.Starting: Model.CurrentState.Run.Offset = -msg.Race.StartDelay; Model.Start(); break; case RaceState.Cancelled: Model.Reset(); break; } if (RacetimeAPI.Instance.Authenticator.Identity == null) { return; } if ((Race.State == RaceState.Open || Race.State == RaceState.OpenInviteOnly) && Model.CurrentState.Run.Offset < TimeSpan.Zero && (msg.Race.StartDelay != Race.StartDelay)) { Model.CurrentState.Run.Offset = -msg.Race.StartDelay; } Race = msg.Race ?? Race; var newIdentity = msg.Race.Entrants?.FirstOrDefault(x => x.Name.ToLower() == RacetimeAPI.Instance.Authenticator.Identity.Name?.ToLower()); switch (newIdentity?.Status) { case UserStatus.Racing: Model.CurrentState.Run.Offset = DateTime.UtcNow - msg.Race.StartedAt; if (Model.CurrentState.CurrentPhase == TimerPhase.Ended) { Model.UndoSplit(); } if (Model.CurrentState.CurrentPhase == TimerPhase.Paused) { Model.Pause(); } if (Model.CurrentState.CurrentPhase == TimerPhase.NotRunning) { Model.Start(); } break; case UserStatus.Disqualified: Model.Reset(); break; case UserStatus.Finished: Model.Split(); break; case UserStatus.Forfeit: Model.Reset(); break; } RaceChanged?.Invoke(this, new EventArgs()); StateChanged?.Invoke(this, Race.State); UserListRefreshed?.Invoke(this, new EventArgs()); GoalChanged?.Invoke(this, new EventArgs()); }