private void ProcessQueue(IGameQueue newQueue) { // block all other threads calling this method semaphore.Wait(10 * 1000); // add new queue gameQueue.Add(newQueue); // Find Matches int index = 0; try { do { var waiting = gameQueue .Where(q => q.Player2 == null) .OrderBy(q => q.QueueDate) .ToArray(); if (waiting.Length < 1 || index > waiting.Length - 1) { break; } var first = waiting[index]; var others = waiting.Where(q => q.Id != first.Id).ToArray(); var match = others.FirstOrDefault(o => o.Player1 != first.Player1 && o.Language == first.Language && o.BoardId == first.BoardId); if (match == null) { index++; } else { logger.Debug($"Found game match. P1:{first.Player1} P2:{match.Player1} Q1:{first.Id} Q2:{match.Id}"); index = 0; // Send match found signal and remove both from queue gamesMatched.Add(new GameMatch { Queue01 = first, Queue02 = match }); RemoveQueue(first.Id); RemoveQueue(match.Id); } } while (true); } catch (Exception ex) { logger.Error("Error processing queue.", ex); throw; } finally { semaphore.Release(); } }
private async Task <IGame> StartGame(IGameQueue queue1, IGameQueue queue2 = null) { var player1 = queue1.Player1; var player2 = queue1.Player2; if (queue2 != null) // Queue Game Match { if (queue1.Player2 != null || queue2.Player2 != null) { throw new ApplicationException("A Matched game cannot have player 2 on both queues"); } player2 = queue2.Player1; } var game = await NewMultiPlayerGame(queue1.Language, queue1.BoardId, player1, player2); // Save game to DB await gameRepository.Add(game.ToDataModel()); gameCache.AddGame(game); logger.Info($"Game Started = P1:{player1} P2:{player2} Language:{queue1.Language} Board:{queue1.BoardId}", context: game.Id); return(game); }
static GameQueue() { LoginServer.Instance.UpdateManager.InitStaticImpl(typeof(GameQueue), typeof(GameQueueDefaultImpl), o => { mImpl = (IGameQueue)o; }); }