public void UpdateState(PlayerState playerState, SignalRChat.ChatHub hub)
        {
            lock (_lock)
            {
                this.PlayerStates[playerState.Id].UpdateClicks(playerState); //Interlocking so is Threadsafe 
                this.PlayerStates[playerState.Id].SentLatestFlag = true;
                //update sent flag duh!

                if (this.IsDownloadReady()) //uses Interlocking to check playerstate dependecy flag 
                {
                    //GameGroup gg = GameGroups[playerState.GroupId];

                    //ChatHub.DebugOut("GameGroups id : " + gg.id);

                    //Clients.Group(playerState.GroupId).UpdateGame(gg); //sends group back to players in group
                    hub.Clients.Group(playerState.GroupId).UpdateGame(this);

                    this.ResetSents();
                }
            }

        }
 internal void UpdateClicks(PlayerState playerState)
 {
     Interlocked.Exchange(ref this.Clicks, playerState.Clicks);
 }
 ///for load test harness - convert add game group from GroupList info
 private void addGameGroupAndUsers(string groupID)
 {
     GameGroup newGameGroup = new GameGroup(groupID);
     bool failedAdd = false;
     foreach (UserDetail user in GroupList.FirstOrDefault(o => o.id == groupID).users)
     {
         PlayerState playerState = new PlayerState();
         playerState.Id = user.ConnectionId;
         if (!newGameGroup.PlayerStates.TryAdd(user.ConnectionId, playerState)) { failedAdd = true; } //LOW threadsafe Risk, only one client inititates creation of group
     }
     //What if not added initially, requires while loop?
     if (!GameGroups.TryAdd(groupID, newGameGroup)) { failedAdd = true; } //MEDIUM threadsafe Risk
     if (failedAdd)
     {
         //TODO: Add ClientError() callback
         DebugOut("Failed to Add Player to Group or Group to List");
     }
     else
     {
         DebugOut("Added Following Group " + newGameGroup.id + " !!!!!! ");
     }
 }
 //Uploads from Client, finds and updates current client, then sends update to group if has latest info
 public void UploadData(PlayerState playerState)
 {
     try
     {
         GameGroups[playerState.GroupId].UpdateState(playerState, this);
     }
     catch (Exception e)
     {
         DebugOut("UploadData() error, message: " + e.Message);
     }
 }
        public void EndGame(PlayerState playerState)
        {

            //Need to update the end time only
            GameGroups[playerState.GroupId].PlayerStates[playerState.Id] = playerState;

            // check group has finished
            DebugOut("------- Loop -------");
            bool areAllFinished = true;
            foreach (PlayerState ps in GameGroups[playerState.GroupId].PlayerStates.Values)
            {
                if (ps.GetFinishTimeMS() <= 0 && !ps.playerLeftGame)
                {
                    areAllFinished = false;
                }
                DebugOut("finsihTime : " + ps.FinishTimeMS);
            }

            if (areAllFinished)
            {
                var sortedList = GameGroups[playerState.GroupId].PlayerStates.OrderBy(kp => kp.Value.FinishTimeMS).ToList();
                Clients.Group(playerState.GroupId).clientEndGame(sortedList);
            }

        }
        private void InitGame(string groupID) 
        {
            GameGroup newGroup = new GameGroup(groupID);
            bool failedAdd = false;
            foreach (UserDetail user in GroupList.FirstOrDefault(o => o.id == groupID).users) {
                PlayerState playerState = new PlayerState();
                playerState.Id = user.ConnectionId;
                if (!newGroup.PlayerStates.TryAdd(user.ConnectionId, playerState)) { failedAdd = true; } //LOW threadsafe Risk, only one client inititates creation of group
            }

            //What if not added initially, requires while loop?
            if(!GameGroups.TryAdd(groupID, newGroup)){ failedAdd = true; } //MEDIUM threadsafe Risk
            
            if(failedAdd){
                //Clients.Group(groupID).clientError("Couldn't Add Player", "Failed to Add a player(s) to the game"); //failed to add player to group or group list
                DebugOut("failed to add player to group or group list");
            }
            else{
                Clients.Group(groupID).showGameScreen();
                this.StartCountDown(GameGroups[groupID]);
            }

        }