/// <summary> /// Parse message string to Packet class</summary> /// <param name="message">Packet string</param> /// <param name="conn">Client connection</param> /// </summary> private Packet ParseMessage(string Message, Connection conn) { string PacketHeader = Message.Split(Delimiter)[0]; Packet Packet = new Packet(PacketHeader); Message = Message.Substring(Message.IndexOf(Delimiter) + 1); //Only Packet Body //Parse type from incoming packet body values foreach (string Parameter in Message.Split(Delimiter)) { //TO-DO more type parsing int intN; bool boolN; if (int.TryParse(Parameter, out intN)) { Packet.AddInt32(intN); } else if (Boolean.TryParse(Parameter, out boolN)) { Packet.AddBoolean(boolN); } else { Packet.AddString(Parameter); } } //Always add connID to Packet to get client id on User Created DLL Packet.AddInt32(conn.connID); return(Packet); }
/// <summary> /// Handle Chat User Login /// <param name="username">Username given by Chat User</param> /// <param name="password">Password given by Chat User</param> /// <param name="connID">Connection ID provided by server</param> /// </summary> //Public method must return a result of type MethodResponse public MethodResponse Login(object username, object password, int connID) { //Create a new MethodResponse MethodResponse MethodResponse = new MethodResponse(); //Check if user exists from mysql //DataRow Row = MysqlConn.ReadDataRow("SELECT * FROM users where username = '******' AND password = '******'"); bool loginFailed = true; if (password.ToString() == "password") { loginFailed = false; } //if (Row != null) //{ //loginFailed = false; //} if (loginFailed) { //Create a new Packet LOGIN_RESPONSE and send Packet to the sender Packet LoginResponse = new Packet("LOGIN_RESPONSE"); //Add a boolean value to Packet. It means login failed LoginResponse.AddBoolean(false); //Add Packet to MethodResponse MethodResponse.AddPacket(LoginResponse); } else { Packet LoginResponse = new Packet("LOGIN_RESPONSE"); LoginResponse.AddBoolean(true);//It means successful login //Add a int value to Packet. It provides client the connection ID for future use LoginResponse.AddInt32(connID); //Announce to all clients a new user joined //Set sendToAll parameter to true (default false) if you want to send Packet to all clients Packet UserJoin = new Packet("USER_JOIN", true); //Add the name of the Chat User joined UserJoin.AddString(username.ToString()); //Add Packets to MethodResponse MethodResponse.AddPacket(LoginResponse); MethodResponse.AddPacket(UserJoin); Users.Add(new User(connID, username.ToString())); //Add the Chat User to a List //Write on server console from dll Logging.WriteLine("User: "******" has joined the chat", LogLevel.Information); } return(MethodResponse); //Return MethodResponse to Server }
private void Login(Session session, Packet packet) { IPlayer player; short clientVersion; short clientRevision; LoginHandlerMode loginMode; string playerName; string loginKey; try { clientVersion = packet.GetInt16(); clientRevision = packet.GetInt16(); loginMode = (LoginHandlerMode)packet.GetByte(); playerName = packet.GetString(); loginKey = packet.GetString(); } catch (Exception) { ReplyError(session, packet, Error.Unexpected); session.CloseSession(); return; } if (clientVersion <= Config.client_min_version && clientRevision < Config.client_min_revision) { ReplyError(session, packet, Error.ClientOldVersion); session.CloseSession(); return; } LoginResponseData loginResponseData; var loginResult = loginHandler.Login(loginMode, playerName, loginKey, out loginResponseData); if (loginResult != Error.Ok) { ReplyError(session, packet, loginResult); session.CloseSession(); return; } // If we are under admin only mode then kick out non admin if (Config.server_admin_only && loginResponseData.Player.Rights == PlayerRights.Basic) { ReplyError(session, packet, Error.UnderMaintenance); session.CloseSession(); return; } //Create the session id that will be used for the calls to the web server string sessionId; if (Config.server_admin_always && !Config.server_production) { sessionId = loginResponseData.Player.Id.ToString(CultureInfo.InvariantCulture); loginResponseData.Player.Rights = PlayerRights.Bureaucrat; } else { SHA1 sha = new SHA1CryptoServiceProvider(); byte[] hash = sha.ComputeHash(Encoding.UTF8.GetBytes(loginResponseData.Player.Id + Config.database_salt + DateTime.UtcNow.Ticks + Config.Random.Next())); sessionId = BitConverter.ToString(hash).Replace("-", String.Empty); } lock (loginLock) { bool newPlayer = !world.Players.TryGetValue(loginResponseData.Player.Id, out player); //If it's a new player then add him to our session if (newPlayer) { logger.Info(string.Format("Creating new player {0}({1}) IP: {2}", playerName, loginResponseData.Player.Id, session.RemoteIP)); player = playerFactory.CreatePlayer(loginResponseData.Player.Id, SystemClock.Now, SystemClock.Now, playerName, string.Empty, loginResponseData.Player.Rights, sessionId); if (!world.Players.TryAdd(player.PlayerId, player)) { session.CloseSession(); return; } } else { player.Name = playerName; } logger.Info(string.Format("Player login in {0}({1}) IP: {2}", player.Name, player.PlayerId, session.RemoteIP)); } locker.Lock(args => { var lockedPlayer = (IPlayer)args[0]; return(lockedPlayer.IsInTribe ? new ILockable[] { lockedPlayer.Tribesman.Tribe } : new ILockable[0]); }, new object[] { player }, player).Do(() => { // If someone is already connected as this player, kick them off potentially if (player.Session != null) { player.Session.CloseSession(); player.Session = null; // Kick people off who are spamming logins if (SystemClock.Now.Subtract(player.LastLogin).TotalMilliseconds < 1500) { session.CloseSession(); return; } } // Setup session references session.Player = player; player.HasTwoFactorAuthenticated = null; player.TwoFactorSecretKey = loginResponseData.Player.TwoFactorSecretKey; player.Session = session; player.SessionId = sessionId; player.Rights = loginResponseData.Player.Rights; player.LastLogin = SystemClock.Now; player.Banned = loginResponseData.Player.Banned; player.Achievements.Clear(); player.Achievements.AddRange(loginResponseData.Achievements); player.ThemePurchases.Clear(); player.ThemePurchases.AddRange(loginResponseData.ThemePurchases); dbManager.Save(player); // If player was banned then kick his ass out if (loginResponseData.Player.Banned) { ReplyError(session, packet, Error.Banned); session.CloseSession(); return; } var reply = new Packet(packet); reply.Option |= (ushort)Packet.Options.Compressed; reply.AddString(Config.welcome_motd); //Player Info reply.AddUInt32(player.PlayerId); reply.AddString(player.PlayerHash); reply.AddUInt32(player.TutorialStep); reply.AddBoolean(player.SoundMuted); reply.AddBoolean(player.Rights >= PlayerRights.Admin); reply.AddString(sessionId); reply.AddString(player.Name); reply.AddInt32(Config.newbie_protection); reply.AddInt32(loginResponseData.Player.Balance); reply.AddUInt32(UnixDateTime.DateTimeToUnix(player.Created.ToUniversalTime())); reply.AddInt32(player.Tribesman == null ? 0 : tribeManager.GetIncomingList(player.Tribesman.Tribe).Count()); reply.AddInt16((short)(player.Tribesman == null ? 0 : player.Tribesman.Tribe.AssignmentCount)); //Server time reply.AddUInt32(UnixDateTime.DateTimeToUnix(DateTime.UtcNow.ToUniversalTime())); //Server rate reply.AddString(Config.seconds_per_unit.ToString(CultureInfo.InvariantCulture)); // If it's a new player we send simply a 1 which means the client will need to send back a city name // Otherwise, we just send the whole login info if (player.GetCityCount() == 0) { reply.AddByte(1); } else { reply.AddByte(0); PacketHelper.AddLoginToPacket(session, themeManager, reply); SubscribeDefaultChannels(session, session.Player); } session.Write(reply); // Restart any city actions that may have been stopped due to inactivity foreach (var city in player.GetCityList() .Where(city => city.Worker.PassiveActions.Values.All(x => x.Type != ActionType.CityPassive))) { city.Worker.DoPassive(city, actionFactory.CreateCityPassiveAction(city.Id), false); } }); }