public ActionResult Register(RegisterModel model)
        {
            if (ModelState.IsValid)
            {
                // Attempt to register the user
                try
                {
                    WebSecurity.CreateUserAndAccount(model.UserName, model.Password);

                    //Initialize userProfile
                    using (UsersContext db = new UsersContext())
                    {
                        UserProfile user = db.UserProfiles.FirstOrDefault(u => u.UserName.ToLower() == model.UserName.ToLower());
                        user.player = PlayerDataManager.initPlayerModel();
                        db.SaveChanges();
                    }

                    WebSecurity.Login(model.UserName, model.Password);
                    return RedirectToAction("Index", "Home");
                }
                catch (MembershipCreateUserException e)
                {
                    ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }
        public Game(string userName, UsersContext db)
        {
            this.user = db.UserProfiles.Include(up => up.player)
                    .Include(up => up.player.characters)
                    .Include(up => up.player.characters.Select(c => c.characterClasses))
                    .Include(up => up.player.characters.Select(c => c.stats))
                    .Include(up => up.player.objectives)
                    .Include(up => up.player.parties)
                    .Include(up => up.player.parties.Select(c => c.characters))
                    .Include(up => up.player.parties.Select(c => c.location))
                    .Include(up => up.player.parties.Select(c => c.location).Select(t => t.eventCollection))
                    .Include(up => up.player.parties.Select(c => c.location).Select(t => t.eventCollection).Select(e => e.events))
                    .Include(up => up.player.parties.Select(c => c.location).Select(t => t.eventCollection).Select(e => e.events.Select(k => k.eventData)))
                    .Include(up => up.player.parties.Select(c => c.location).Select(t => t.eventCollection).Select(e => e.events.Select(k => k.eventData.encounter)))
                    .Include(up => up.player.parties.Select(c => c.location).Select(t => t.eventCollection).Select(e => e.events.Select(k => k.eventData.encounter.enemies)))
                    .Include(up => up.player.currentCombat)
                    .Include(up => up.player.currentCombat.pcs)
                    .Include(up => up.player.currentCombat.npcs)
                    .Include(up => up.player.currentCombat.pcs.Select(c => c.stats))
                    .Include(up => up.player.currentCombat.pcs.Select(c => c.mods))
                    .Include(up => up.player.currentCombat.pcs.Select(c => c.mods.Select(d => d.conditions)))
                    .Include(up => up.player.currentCombat.npcs.Select(c => c.stats))
                    .Include(up => up.player.currentCombat.npcs.Select(c => c.mods))
                    .Include(up => up.player.currentCombat.npcs.Select(c => c.mods.Select(d => d.conditions)))
                    .Include(up => up.player.currentCombat.combatData)
                    .Include(up => up.player.currentCombat.combatData.cooldowns)
                    .FirstOrDefault(u => u.UserName.ToLower() == userName);
            this.player = user.player;
            this.userName = userName;
            this.db = db;
            this.messageQueue = new List<ClientMessage>();

            this.rng = new GameRNG();

            //Initialize player stuff if they have no value
            if (player.objectives == null)
            {
                player.objectives = new List<PlayerObjectiveModel>();
            }

            MapDataClasses.MapDataManager.setFunctions(() =>
            {
                List<string> characters = new List<string>();
                foreach (CharacterModel cm in this.player.characters)
                {
                    characters.Add(cm.name);
                }
                return characters;
            }, () =>
            {
                List<string> classes = PlayerDataManager.getClasses(player);
                return classes;
            }, (int start, int end) =>
            {
                return this.rng.getNumber(start, end);
            }, (string name) =>
                {
                    return DungeonUnlockedDirector.isDungeonUnlocked(name, player);
                }
            );

            currentMap = player.getActiveParty().location;
            if (currentMap == null)
            {
                currentMap = MapDataClasses.MapDataManager.createMap(this.player.rootMap);
                this.player.getActiveParty().location = currentMap;
                ObjectiveDirector.markCompletedObjectives(this.player);
            }
            else
            {
                MapDataClasses.MapDataManager.setupMapModel(currentMap);
                this.player.getActiveParty().location = currentMap;
                ObjectiveDirector.markCompletedObjectives(this.player);
            }

            foreach (CharacterModel cm in this.player.characters)
            {
                PlayerModels.StatCalculations.StatCalculator.updateCharacterStats(cm);
            }

            this.combatCountdown = rng.getNumber(MapDataClasses.MapDataManager.getMinCombatCount(player.rootMap), MapDataClasses.MapDataManager.getMaxCombatCount(player.rootMap));

            combatDirector = new CombatDataClasses.CombatDirector(this.player,
                currentMap.name,
                () =>
                {
                    return rng.getNumber(1, MapDataClasses.MapDataManager.getRandomEncounterCount(currentMap.name));
                },
                () =>
                {
                    return rng.calculateIntiative();
                },
                () =>
                {
                    setMap(MapDataClasses.MapDataManager.getHubMap(player.rootMap), true);
                    this.player.getActiveParty().location = currentMap;
                    this.combatCountdown = rng.getNumber(MapDataClasses.MapDataManager.getMinCombatCount(player.rootMap), MapDataClasses.MapDataManager.getMaxCombatCount(player.rootMap));
                    currentMap = MapDataClasses.MapDataManager.createMap(player.rootMap);
                    ObjectiveDirector.markCompletedObjectives(this.player);
                    player.rootX = currentMap.startX;
                    player.rootY = currentMap.startY;
                },
                () =>
                {
                    db.SaveChanges();
                },
                (CombatEndType combatEndType) =>
                {
                    if (player.currentCombat != null)
                    {
                        foreach (PartyModel pm in player.parties)
                        {
                            if (pm.uniq == player.activeParty)
                            {
                                foreach (PartyCharacterModel pcm in pm.characters)
                                {
                                    foreach (PlayerModels.CombatDataModels.CombatCharacterModel ccm in player.currentCombat.pcs)
                                    {
                                        if (pcm.characterUniq == ccm.characterUniq)
                                        {
                                            pcm.hp = ccm.stats.hp;
                                            pcm.mp = ccm.stats.mp;
                                        }
                                    }
                                }
                            }
                        }
                    }

                    player.currentCombat = null;

                    if (player.getActiveParty() != null)
                    {
                        MapDataClasses.MapEventModel currentEvent = player.getActiveParty().location.activeEvent;
                        if (currentEvent != null && currentEvent.eventData.type == MapDataClasses.EventClasses.EventDataType.Combat && combatEndType == CombatEndType.Victory)
                        {
                            if (currentEvent.eventData.nextEvent == null)
                            {
                                PlayerDataManager.processEvent(currentEvent, this.player, ref messageQueue);
                            }
                            else
                            {
                                messageQueue.Add(new ClientMessage() { type = ClientMessage.ClientMessageType.ExecuteEvent });
                                currentEvent.eventData = currentEvent.eventData.nextEvent;
                                player.getActiveParty().location.activeEvent = currentEvent;
                            }

                        }
                    }

                    db.SaveChanges();
                }
                );
        }
        public ActionResult ExternalLoginConfirmation(RegisterExternalLoginModel model, string returnUrl)
        {
            string provider = null;
            string providerUserId = null;

            if (User.Identity.IsAuthenticated || !OAuthWebSecurity.TryDeserializeProviderUserId(model.ExternalLoginData, out provider, out providerUserId))
            {
                return RedirectToAction("Manage");
            }

            if (ModelState.IsValid)
            {
                // Insert a new user into the database
                using (UsersContext db = new UsersContext())
                {
                    UserProfile user = db.UserProfiles.FirstOrDefault(u => u.UserName.ToLower() == model.UserName.ToLower());
                    // Check if user already exists
                    if (user == null)
                    {
                        // Insert name into the profile table
                        db.UserProfiles.Add(new UserProfile { UserName = model.UserName, player = PlayerDataManager.initPlayerModel() });
                        db.SaveChanges();

                        OAuthWebSecurity.CreateOrUpdateAccount(provider, providerUserId, model.UserName);
                        OAuthWebSecurity.Login(provider, providerUserId, createPersistentCookie: false);

                        return RedirectToLocal(returnUrl);
                    }
                    else
                    {
                        ModelState.AddModelError("UserName", "User name already exists. Please enter a different user name.");
                    }
                }
            }

            ViewBag.ProviderDisplayName = OAuthWebSecurity.GetOAuthClientData(provider).DisplayName;
            ViewBag.ReturnUrl = returnUrl;
            return View(model);
        }