public RecordViewModel(Record r) { Wins = r.Wins; Losses = r.Losses; Draws = r.Draws; TotalGames = r.GamesPlayed; ImageUrl = r.Game.ImageUrl; if(TotalGames == 0) WinPercent = 0; else WinPercent = 100 * Wins / TotalGames; RankedWins = r.RankedWins; RankedLosses = r.RankedLosses; RankedDraws = r.RankedDraws; RankedTotalGames = r.RankedGamesPlayed; if (RankedTotalGames == 0) RankedWinPercent = 0; else RankedWinPercent = 100 * RankedWins / RankedTotalGames; Name = r.Game.Name; }
public ActionResult UpdateMain(int id, GameUpdate update) { try { DateTime start = DateTime.Now; Table table = db.Tables.Find(id); Seat currentSeat = table.Seats.ElementAt(update.playerIndex); if (currentSeat.Player.Name != User.Identity.Name) return RedirectToAction("Index","Home"); PythonScriptEngine.InitScriptEngine(table.Alpha || table.SoloPlayTest); PythonScriptEngine.LoadModules(table.Version.ModuleName, table.Version.PythonScript, table.Alpha || table.SoloPlayTest,table.Version.GameVersionID); ScriptScope runScope = PythonScriptEngine.GetScope(table.Alpha || table.SoloPlayTest); runScope.ImportModule("cPickle"); string init_pickledState = Compression.DecompressStringState(table.GameState); DateTime modulesLoaded = DateTime.Now; // PYTHON UPDATE // Input state runScope.SetVariable("inputState", init_pickledState); runScope.SetVariable("update", update); // Input array of seats. Seat[] seatsArray = table.Seats.ToArray(); runScope.SetVariable("seats", seatsArray); DateTime variablesSet = DateTime.Now; List<bool> previousWaitingStates = seatsArray.Select(s => s.Waiting).ToList(); string errorString = PythonScriptEngine.RunCode(runScope, "gameState = cPickle.loads(inputState);gameState.update(update);gameState.set_waiting_status(seats);game_over = gameState.game_over;finalState = cPickle.dumps(gameState)", table.Alpha || table.SoloPlayTest); if (errorString != "") return Content(errorString); for(int i =0; i < seatsArray.Length; i++) { NotificationsHub.UpdateNotificationState(db, seatsArray[i], table, previousWaitingStates[i]); } string final_pickledState = runScope.GetVariable("finalState"); bool game_over = runScope.GetVariable("game_over"); if (game_over == true) { if (table.TableState != (int)TableState.Complete && table.Version.DevStage == "Release") { table.Game.CompletedGames++; // Log player wins/losses foreach (Seat s in table.Seats) { Player p = s.Player; if (p.Records == null) p.Records = new List<Record>(); // Find record if it exists. Otherwise create one. Record r = p.Records.FirstOrDefault(record => record.GameId == table.GameId); if (r == null) { r = new Record(); r.GameId = table.GameId; r.PlayerId = p.PlayerID; p.Records.Add(r); } if (table.Ranked == true) { r.RankedGamesPlayed++; if (s.Result == "Win") r.RankedWins++; if (s.Result == "Loss") r.RankedLosses++; if (s.Result == "Draw") r.RankedDraws++; } else { r.GamesPlayed++; if (s.Result == "Win") r.Wins++; if (s.Result == "Loss") r.Losses++; if (s.Result == "Draw") r.Draws++; } } // Game just ended. Collect stats. errorString = PythonScriptEngine.RunCode(runScope, "from encodings import hex_codec; import json; stats = json.dumps(gameState.stats())", table.Alpha || table.SoloPlayTest); if (errorString != "") return Content(errorString); String latestStats = runScope.GetVariable("stats"); if (table.Version.StatLog == "" || table.Version.StatLog == null) table.Version.StatLog = "[]"; table.Version.StatLog = table.Version.StatLog.Remove(table.Version.StatLog.Length - 1); if (table.Version.StatLog.Length > 1) table.Version.StatLog += ","; table.Version.StatLog += latestStats + "]"; // Notify players of game end. foreach (Seat s in seatsArray) { Notification existingNotification = db.Notifications.SingleOrDefault(n => n.PlayerID == s.PlayerId && n.TableID == id); if (existingNotification != null) { existingNotification.Suppressed = false; if(s.PlayerId==currentSeat.PlayerId) existingNotification.Read = true; else existingNotification.Read = false; SeatViewModel viewModel = new SeatViewModel(s); existingNotification.Message = "Game Over! "; if (s.Result == "Win") existingNotification.Message = "Victory! "; if(s.Result == "Loss") existingNotification.Message = "Defeat! "; if (s.Result == "Draw") existingNotification.Message = "Draw! "; existingNotification.Message += table.Game.Name + " game with " + viewModel.formattedOpponentNames + " has ended. (TableID:" + table.TableID + ") " + DateTime.Now; db.SaveChanges(); } } } table.TableState = (int)TableState.Complete; } table.GameState = Compression.CompressStringState(final_pickledState); DateTime scriptsExecuted = DateTime.Now; db.SaveChanges(); DateTime databaseSaved = DateTime.Now; // Send updated states to clients IConnectionManager connectionManager = AspNetHost.DependencyResolver.Resolve<IConnectionManager>(); dynamic clients = connectionManager.GetClients<GameList>(); for (int i = 0; i < table.Seats.Count; i++) { Seat s = table.Seats.ElementAt(i); if (table.SoloPlayTest == false || s.Waiting == true) { Tuple<string,string> viewInfo = GetPythonView(table, final_pickledState, i,false); if(viewInfo.Item2 != "") return Content(viewInfo.Item2); clients["GAME_"+s.Player.Name + id].main_updateGameState(viewInfo.Item1); } } DateTime end = DateTime.Now; TimeSpan totalTime = end.Subtract(start); TimeSpan moduleLoadTime = modulesLoaded.Subtract(start); TimeSpan variablesSetTime = variablesSet.Subtract(modulesLoaded); TimeSpan scriptsExecutedTime = scriptsExecuted.Subtract(variablesSet); TimeSpan databaseSavedTime = databaseSaved.Subtract(scriptsExecuted); TimeSpan updateTime = end.Subtract(databaseSaved); return View(); } catch (Exception e) { return Content(e.ToString()); } }