public void StartUp(Guid matchGuid) { int counter = 0; MatchInvitation matchInvite = matchService.GetByGuid(matchGuid); var userId = Context.User.Identity.GetId().Value; var inputQueue = new BufferBlock <InputMessage>(); StrokeWarMatch match; lock (syncLock) { if (!matchesByMatchId.TryGetValue(matchGuid, out match)) { throw new HubException("Invalid match GUID"); } if (match.IsStarted) { return; } match.InputQueue = inputQueue; } int words = 0; int currentWord = 0; Task.Run(async() => { try { int players; IDictionaryFeed feed; if (matchInvite.CustomVocabId != 0) { feed = customDictionaryFeed((int)matchInvite.CustomVocabId); match.CustomVocabId = matchInvite.CustomVocabId; } else { feed = dictionaryFeed(matchInvite.DifficultyLevels); match.DiffLevels = matchInvite.DifficultyLevels; } var nextWord = feed.GetNextWord(); if (nextWord == null) { lock (syncLock) Clients.Clients(match.ConnectionIdsByUser.Values.Where(o => o != null).ToArray()).gameError("Vocab List is empty."); } WordCheck(nextWord.Word); TimeSpan newTotalTime = TotalTimeSpan(nextWord); lock (syncLock) { match.MatchHubDataCollector.StartWord(nextWord.Word); Clients.Clients(match.ConnectionIdsByUser.Values.Where(o => o != null).ToArray()).startWord(nextWord, newTotalTime.TotalMilliseconds); matchData.WordsSent++; players = match.ConnectionIdsByUser.Values.Where(o => o != null).ToArray().Length; } int completedEntries = 0; var roundTimeout = DateTime.Now.Add(newTotalTime); //ADD 6 SECONDS TO TIMER FOR GET READY COUNTDOWN roundTimeout += TimeSpan.FromSeconds(6); var connectionList = Clients.Clients(match.ConnectionIdsByUser.Values.Where(o => o != null).ToArray()); // LOCAL Functions (Start) ******************************************************************************************** // This function will be used to generate a new word from the dictionary, //process the word through the TotalTimeSpan function, reset the roundTimeOut, and send the new word to the active users. void NextFeed() { nextWord = feed.GetNextWord(); WordCheck(nextWord.Word); newTotalTime = TotalTimeSpan(nextWord); completedEntries = 0; roundTimeout = DateTime.Now.Add(newTotalTime); //ADD 3 SECONDS TO TIMER FOR GET STOPLIGHT TIME roundTimeout += TimeSpan.FromSeconds(3); lock (syncLock) { match.MatchHubDataCollector.StartWord(nextWord.Word); connectionList.startWord(nextWord, newTotalTime.TotalMilliseconds); matchData.WordsSent++; } } void WordCheck(string word) { lock (syncLock) { if (match.PlayedWords.Count > 15) { match.PlayedWords = new List <string>(); } if (!match.PlayedWords.Contains(word)) { match.PlayedWords.Add(word); counter = 0; } else { nextWord = feed.GetNextWord(); counter++; if (counter > 10) { match.PlayedWords = new List <string>(); WordCheck(nextWord.Word); counter = 0; } else { WordCheck(nextWord.Word); } } } } // This function calculates the total timespan allotted per word determined by the # of strokes. TimeSpan TotalTimeSpan(DictionaryWord word) { var strokeCount = word.StrokeData .Select(JObject.Parse) .Select(item => item.Value <JArray>("strokes")) .Select(arr => arr.Count) .Sum(); int milliseconds = 800; TimeSpan totalTime = TimeSpan.FromMilliseconds(strokeCount * (milliseconds)); Debug.Write(1 + " " + strokeCount + " "); Debug.Write(2 + " " + totalTime); return(totalTime); } // LOCAL Functions (End) ******************************************************************************************** while (true) { if (currentWord != words) { lock (syncLock) connectionList = Clients.Clients(match.ConnectionIdsByUser.Values.Where(o => o != null).ToArray()); currentWord++; } InputMessage message = null; try { var currentTime = (roundTimeout) - DateTime.Now; if ((currentTime) <= TimeSpan.FromSeconds(0)) { throw new TimeoutException(); } message = await inputQueue.ReceiveAsync(currentTime); } catch (InvalidOperationException) { return; } catch (TimeoutException) { words++; if (words >= matchInvite.TotalWords) { System.Threading.Thread.Sleep(100); lock (syncLock) { connectionList.endGame(match.ScoreByUser); Debug.WriteLine(match.ScoreByUser); words = 1; currentWord = 0; match.ScoreByUser.Clear(); } break; } NextFeed(); } lock (syncLock) { if (message != null) { SendMatchUpdate(match, message); if (message.EntryCompleted) { completedEntries++; } if (completedEntries == players) { words++; if (words >= matchInvite.TotalWords) { System.Threading.Thread.Sleep(100); connectionList.endGame(match.ScoreByUser); words = 1; currentWord = 0; match.ScoreByUser.Clear(); break; } NextFeed(); } } } } } finally { lock (syncLock) { if (match.InputQueue == inputQueue) { match.InputQueue = null; } } } }); }
public void JoinMatch(Guid matchGuidId) { string connectionId = Context.ConnectionId; int userId = Context.User.Identity.GetId().Value; MatchInvitation matchInvite = matchService.GetByGuid(matchGuidId); ////////// Only if opponent is USER ID#1, Game is OPEN MATCH. \\\\\\\\\\\\\\\ lock (syncLock) { if (matchInvite.Opponents[0] == 1) { if (!matchesByMatchId.ContainsKey(matchGuidId)) { StrokeWarMatch match = new StrokeWarMatch(); match.MatchHubDataCollector = matchHubDataCollector(); matchesByMatchId.Add(matchGuidId, match); matchesByConnection.Add(connectionId, match); match.MatchId = matchGuidId; match.MatchHubDataCollector.SetMatchId(matchGuidId); match.ConnectionIdsByUser.Add(userId, connectionId); SendPresence(match, "Open Match"); } else { StrokeWarMatch value; if (matchesByMatchId.TryGetValue(matchGuidId, out value)) { if (value.IsStarted) { Clients.Client(connectionId).inProgress(); } string existingConnection; if (value.ConnectionIdsByUser.TryGetValue(userId, out existingConnection)) { if (existingConnection != null) { matchesByConnection.Remove(existingConnection); Clients.Client(existingConnection).timeOut(); } } matchesByConnection.Add(connectionId, value); value.ConnectionIdsByUser[userId] = connectionId; SendPresence(value, "Open Match"); } } } /////////////////// NORMAL CODE FOR INVITE ONLY GAME \\\\\\\\\\\\\\\\\\\\\\\ else if (!matchesByMatchId.ContainsKey(matchGuidId)) { StrokeWarMatch match = new StrokeWarMatch(); match.MatchHubDataCollector = matchHubDataCollector(); matchesByMatchId.Add(matchGuidId, match); matchesByConnection.Add(connectionId, match); match.MatchId = matchGuidId; match.ConnectionIdsByUser.Add(userId, connectionId); if (userId == matchInvite.ChallengerId) { for (int i = 0; i < matchInvite.Opponents.Length; i++) { if (!match.ConnectionIdsByUser.ContainsKey(matchInvite.Opponents[i])) { match.ConnectionIdsByUser.Add(matchInvite.Opponents[i], null); } } SendPresence(match, "Challenger"); } else { match.ConnectionIdsByUser.Add(matchInvite.ChallengerId, null); for (int i = 0; i < matchInvite.Opponents.Length; i++) { if (userId != matchInvite.Opponents[i]) { match.ConnectionIdsByUser.Add(matchInvite.Opponents[i], null); } } SendPresence(match, "Opponent"); } match.MatchHubDataCollector.SetMatchId(matchGuidId); } else { StrokeWarMatch value; if (matchesByMatchId.TryGetValue(matchGuidId, out value)) { if (value.IsStarted) { Clients.Client(connectionId).inProgress(); } if (!value.ConnectionIdsByUser.ContainsKey(userId)) { throw new HubException("You were not invited to this match."); } string existingConnection; if (value.ConnectionIdsByUser.TryGetValue(userId, out existingConnection)) { if (existingConnection != null) { matchesByConnection.Remove(existingConnection); Clients.Client(existingConnection).timeOut(); } } matchesByConnection.Add(connectionId, value); value.ConnectionIdsByUser[userId] = connectionId; if (matchInvite.ChallengerId != userId) { SendPresence(value, "Opponent"); } else { SendPresence(value, "Challenger"); } } } } }