private void ListenForClients() { Console.WriteLine("Server Up... Listening at port " + port); tcpListener.Start(); while (true) { try { TcpClient tcpClient = tcpListener.AcceptTcpClient(); IPEndPoint ipEndPoint = tcpClient.Client.RemoteEndPoint as IPEndPoint; IPAddress ip = ipEndPoint.Address; foreach (IPBan ban in World.IPBans) { if (ban.IP.ToString() == ipEndPoint.Address.ToString()) { tcpClient.Close(); throw new KickOutException("Warning! Attempt to conect from banned IP! " + ban.IP.ToString()); } } Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientCommunication)); Client client = new Client(tcpClient, encoder, clientThread); Clients.Add(client); clientThread.Start(client); } catch (KickOutException e) { Console.WriteLine(e.Message); } catch { Console.WriteLine("Warning!!! Exception in ListenForClients!!!"); } } }
//This is actually giant switch private string handleRequest(RequestType type, List<string> parameters, Client client, out AnswerType answerType) { if (client.Player == null) { return handleUnloggedRequest(type, parameters, client, out answerType); } else { return handleLoggedInRequest(type, parameters, client, out answerType); } }
private string handleUnloggedRequest(RequestType type, List<string> parameters, Client client, out AnswerType answerType) { IPEndPoint ipEndPoint = client.TcpClient.Client.RemoteEndPoint as IPEndPoint; switch (type) { case RequestType.Welcome: Version clientVersion = new Version(int.Parse(parameters[1]), int.Parse(parameters[2]), int.Parse(parameters[3]), int.Parse(parameters[4])); bool isSupported = (clientVersion.Major == supportedVersion.Major && clientVersion.Minor == supportedVersion.Minor && clientVersion.Build == supportedVersion.Build); answerType = AnswerType.Welcome; return string.Format("{0}~{1}~{2}~", isSupported, name, Message); case RequestType.Update: answerType = AnswerType.Update; return string.Format("{0}~", clientFileBuffer.Length); case RequestType.Registration: byte[] buffer = new byte[512]; int length = client.TcpClient.GetStream().Read(buffer, 0, 512); byte[] passwordBuffer = new byte[length]; Array.Copy(buffer, passwordBuffer, length); passwordBuffer = client.Encryptor.XorThis(passwordBuffer); if (parameters[0].Length > 24 || parameters[1].Length > 16 || parameters[2].Length > 1024) { throw new KickOutException("Invalid Registration Input"); } Registration newRegistration = new Registration(parameters[0], parameters[1], parameters[2], passwordBuffer, ipEndPoint.Address); answerType = AnswerType.Registration; if (World.Registrations.Count >= 10) { return string.Format("{0}~", 6); } int errorCode = 0; foreach (Registration registration in World.Registrations) { if (registration.IP.ToString() == newRegistration.IP.ToString()) { errorCode = 3; break; } if (registration.Login == newRegistration.Login) { errorCode = 1; break; } if (registration.Name == newRegistration.Name) { errorCode = 2; break; } } if (errorCode == 0) { foreach (Player player in World.Players) { if (player.Login == newRegistration.Login) { errorCode = 4; break; } if (player.Name == newRegistration.Name) { errorCode = 5; break; } } if (errorCode == 0) { World.Registrations.Add(newRegistration); } } return string.Format("{0}~", errorCode); case RequestType.Login: answerType = AnswerType.Login; buffer = new byte[512]; length = client.TcpClient.GetStream().Read(buffer, 0, 512); passwordBuffer = new byte[length]; Array.Copy(buffer, passwordBuffer, length); passwordBuffer = client.Encryptor.XorThis(passwordBuffer); foreach (Player player in World.Players) { if (player.Login == parameters[0]) { bool passwordMatch = passwordBuffer.Length == player.Password.Length; for (int i = 0; i < player.Password.Length; i++) { if (passwordBuffer[i] != player.Password[i]) { passwordMatch = false; break; } } if (passwordMatch) { client.Player = player; return "0~"; } } } if (client.BadLoginAttempts >= 2) { banThis(ipEndPoint.Address, 5, 0, "Bad Logins"); throw new KickOutException("Banned IP, too many bad login attemts"); } else { client.BadLoginAttempts++; return "1~"; } } throw new KickOutException("Invalid Request from unauthorized Client"); }
private string handleLoggedInRequest(RequestType type, List<string> parameters, Client client, out AnswerType answerType) { IPEndPoint ipEndPoint = client.TcpClient.Client.RemoteEndPoint as IPEndPoint; switch (type) { case RequestType.ChangeLogin: answerType = AnswerType.ChangeLogin; if (parameters[0].Length > 24) { throw new KickOutException("Invalid Change Login Request"); } foreach (Registration registration in World.Registrations) { if (registration.Login == parameters[0]) { return "1~"; } } foreach (Player player in World.Players) { if (player.Login == parameters[0]) { return "2~"; } } client.Player.Login = parameters[0]; return "0~"; case RequestType.ChangeName: answerType = AnswerType.ChangeName; if (parameters[0].Length > 16) { throw new KickOutException("Invalid Change Name Request"); } foreach (Registration registration in World.Registrations) { if (registration.Name == parameters[0]) { return "1~"; } } foreach (Player player in World.Players) { if (player.Name == parameters[0]) { return "2~"; } } client.Player.Name = parameters[0]; return "0~"; case RequestType.ChangePassword: answerType = AnswerType.ChangePassword; byte[] buffer = new byte[512]; int length = client.TcpClient.GetStream().Read(buffer, 0, 512); byte[] passwordBuffer = new byte[length]; Array.Copy(buffer, passwordBuffer, length); passwordBuffer = client.Encryptor.XorThis(passwordBuffer); client.Player.Password = passwordBuffer; return string.Empty; case RequestType.EnterGame: int villagesCount = (from v in World.Villages where v.Owner == client.Player select v).Count(); if (villagesCount > 0) { answerType = AnswerType.Village; return string.Empty; //TODO: return first village } answerType = AnswerType.Map; return WorldController.GetNotifications(client.Player) + WorldController.GetMap(client.Player); } throw new KickOutException("Invalid Request from authorized Client"); }