public Map GetMap(string map, int?mapInstanceIndex = null) { //Log.Debug($"Loading map {map}"); // Load the map from db, or the limbo map if it doesn't exist. if (!mapInfoByName.ContainsKey(map)) { var loadedMap = db.Get <MapInfo>("Content", "name", map) ?? db.Get <MapInfo>("Content", "name", "Limbo"); mapInfoByName[map] = loadedMap; string s = loadedMap?.ToString() ?? "NULL"; Log.Debug($"Loaded MapInfo for {{{map}}}"); } // A requested map may have been routed to limbo if it does not exist. MapInfo info = mapInfoByName[map]; string mapName = info.name; // First time? initialize instances collection of map if (!instances.ContainsKey(mapName)) { SpinUp(info); } List <Guid> instanceIds = instances[mapName]; if (mapInstanceIndex == null) { return(maps[instanceIds[0]]); } int ind = mapInstanceIndex.Value % instanceIds.Count; if (ind < 0) { ind *= -1; } var id = instanceIds[ind]; return(maps[id]); }
/// <summary> Connected database service </summary> /// <summary> Client -> Server RPC. Checks user and credentials to validate login, responds with <see cref="LoginResponse(RPCMessage)"/></summary> /// <param name="msg"> RPC Info. </param> public void Login(RPCMessage msg) { #if !UNITY string user = msg[0]; string hash = msg[1]; string version = msg.numArgs >= 3 ? msg[2] : "[[Version Not Set]]"; // Login flow. Credentials creds = null; LoginResult result = LoginResult.Failed_Unspecified; string reason = "none"; UserLoginInfo userInfo = null; #region Submethod CheckLogin() { // SubMethod: CheckLogin() if (version != versionCode) { Log.Debug($"{nameof(LoginService)}: Version mismatch {version}, expected {versionCode}"); reason = VERSION_MISMATCH; result = LoginResult.Failed_VersionMismatch; } else if (!usernameValidator(user)) { Log.Debug($"{nameof(LoginService)}: Bad username {user}"); reason = "Invalid Username"; result = LoginResult.Failed_BadUsername; } else if (GetLogin(msg.sender) != null) { Log.Debug($"{nameof(LoginService)}: Client {msg.sender.identity} already logged in"); reason = "Already Logged In"; result = LoginResult.Failed_ClientAlreadyLoggedIn; } else { userInfo = dbService.Get <UserLoginInfo>(nameof(userInfo.userName), user); if (userInfo == null) { Log.Debug($"{nameof(LoginService)}: User {user} not found, creating them now. "); Guid userId = Guid.NewGuid(); userInfo = CreateNewUser(msg); if (userInfo != null) { result = LoginResult.Success_Created; creds = new Credentials(user, hash, userInfo.guid); } else { result = LoginResult.Failed_CreationCooldown; reason = "Too many account creations"; } } else { // Check credentials against existing credentials. if (loginsByUserId.ContainsKey(userInfo.guid)) { reason = "Already logged in"; result = LoginResult.Failed_UserAlreadyLoggedIn; } else if (hash != userInfo.hash) { reason = "Bad credentials"; result = LoginResult.Failed_BadCredentials; } else { creds = new Credentials(user, hash, userInfo.guid); result = LoginResult.Success; } } } } // Submethod: CheckLogin() #endregion #region Submethod RecordLoginAttempt { // SubMethod: RecordLoginAttempt() LoginAttempt attempt = new LoginAttempt(); attempt.result = result; attempt.result_desc = result.ToString(); attempt.timestamp = DateTime.UtcNow; attempt.hash = hash; attempt.userName = user; attempt.ip = msg.sender.remoteIP; if (userInfo != null) { attempt.success = true; attempt.creation = result == LoginResult.Success_Created; attempt.guid = userInfo.guid; } else { attempt.success = attempt.creation = false; attempt.guid = Guid.Empty; } dbService.Save(attempt); } // Submethod: RecordLoginAttempt() #endregion #region Submethod Respond { // Submethod: Respond() if (creds == null) { msg.sender.Call(LoginResponse, "fail", reason); Log.Info($"Client {msg.sender.identity} Failed to login."); server.On(new LoginFailure_Server() { ip = msg.sender.remoteIP }); } else { var session = new Session(msg.sender, creds); loginsByClient[msg.sender] = session; loginsByUserId[creds.userId] = session; userInfo.lastLogin = DateTime.UtcNow; dbService.Save(userInfo); msg.sender.Call(LoginResponse, "succ", creds.userId); Log.Info($"Client {msg.sender.identity} logged in as user {creds.username} / {creds.userId}. "); server.On(new LoginSuccess_Server(msg.sender)); } } // Submethod: Respond() #endregion #endif }