/* Thor Server 2.0 Project - Codenamed "Stockholm" Copyright 2008 - 2009 Joe Hegarty This file is part of The Thor Server 2.0 Project - Codenamed "Stockholm". The Thor Server 2.0 Project - Codenamed "Stockholm" is free software: you can redistribute it and/or modify it under the terms of the Microsoft Public License The Thor Server Project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Microsoft Public License for more details. You should have received a copy of the Microsoft Public License along with The Thor Server Project. If not, see http://www.opensource.org/licenses/ms-pl.html */ using System; using System.Threading.Tasks; using System.Collections.Generic; using System.Linq; using StockholmLibrary.Net; using StockholmLibrary.Game; using StockholmLibrary.Util; using StockholmLibrary.Data; using StockholmLibrary.Game.Util; using StockholmLibrary.Game.Sessions; using StockholmLibrary.Game.Packets.Client; using StockholmLibrary.Game.Packets.Server; namespace StockholmLibrary.Game.Handlers.Generic { //------------------------------------ public class GenericUserHandler { //------------------------------------ private class LoginRequest { public string Username; public string Password; public Peer Peer; //********************************************** public LoginRequest() { } //********************************************** public LoginRequest(string username, string password, Peer peer) { Username = username; Password = password; Peer = peer; } } //********************************************** public GenericUserHandler() { Stockholm.Get().PacketManager.RegisterGenericHandler(EClientPacket.LOGIN, new PacketRoutingInfo.ProcessPacketDelegate(HandleLogin), false); Stockholm.Get().PacketManager.RegisterGenericHandler(EClientPacket.GENERATE_KEY, new PacketRoutingInfo.ProcessPacketDelegate(HandleGenerateKey), false); Stockholm.Get().PacketManager.RegisterGenericHandler(EClientPacket.APPROVENAME, new PacketRoutingInfo.ProcessPacketDelegate(HandleApproveName), false); Stockholm.Get().PacketManager.RegisterGenericHandler(EClientPacket.APPROVE_PASSWORD, new PacketRoutingInfo.ProcessPacketDelegate(HandleApprovePassword), false); Stockholm.Get().PacketManager.RegisterGenericHandler(EClientPacket.APPROVE_EMAIL, new PacketRoutingInfo.ProcessPacketDelegate(HandleApproveEmail), false); Stockholm.Get().PacketManager.RegisterGenericHandler(EClientPacket.AC, new PacketRoutingInfo.ProcessPacketDelegate(HandleAgeCheck), false); Stockholm.Get().PacketManager.RegisterGenericHandler(EClientPacket.REGISTER, new PacketRoutingInfo.ProcessPacketDelegate(HandleRegister), false); } //********************************************** private void HandleGenerateKey(ClientPacket packet) { packet.Peer.EnqueuePacket(new ClientAllowedSetsPacket()); packet.Peer.EnqueuePacket(new ClientFormattingPacket()); } //********************************************** private void HandleLogin(ClientPacket packet) { LoginPacket loginPacket = new LoginPacket(); loginPacket.Deserialise(packet); LoginRequest request = new LoginRequest(loginPacket.Username, loginPacket.Password, loginPacket.Peer); Task.Factory.StartNew(() => HandleLoginRequest(request)); } //********************************************** private void HandleLoginRequest(LoginRequest request) { StockholmDbDataContext db = Stockholm.Get().Database; var userQuery = from p in db.Users where p.Username == request.Username select p; if (userQuery.Count() == 1) { // User exists var user = userQuery.Single(); if (user.Password == request.Password) { // User details correct Session session = new Session(user.UserID, request.Peer); session.Peer = request.Peer; if (Stockholm.Get().GameManager.RoleManager.HasAccess(user.RoleID, "fuse_login")) { // User has the right to login, session is now active! Stockholm.Get().GameManager.SessionManager.AddSession(session); } else { // Bad permissions ErrorPacket packet = new ErrorPacket("login incorrect: Bad permissions"); request.Peer.EnqueuePacket(packet); } } else { // Bad password ErrorPacket packet = new ErrorPacket("login incorrect: Wrong password"); request.Peer.EnqueuePacket(packet); } } else { // Bad username ErrorPacket packet = new ErrorPacket("login incorrect: Wrong username"); request.Peer.EnqueuePacket(packet); } } private void HandleRegister(ClientPacket packet) { Task.Factory.StartNew(() => ProcessRegister(packet)); } private void ProcessRegister(ClientPacket packet) { UserPropertiesPacket registerPacket = new UserPropertiesPacket(); registerPacket.Deserialise(packet); // Store the custom user properties in a new User object User newUser = new User(); newUser.Username = registerPacket.Properties[EUserProperty.Username]; newUser.Password = registerPacket.Properties[EUserProperty.Password]; newUser.Email = registerPacket.Properties[EUserProperty.Email]; newUser.Dob = registerPacket.Properties[EUserProperty.DateOfBirth]; newUser.Figure = registerPacket.Properties[EUserProperty.Figure]; newUser.Sex = (registerPacket.Properties[EUserProperty.Sex] == "F") ? "F" : "M"; // Set the default properties for new users newUser.RoleID = GameConstants.USER_DEFAULT_ROLEID; newUser.Motto = GameConstants.USER_DEFAULT_MOTTO; newUser.Credits = GameConstants.USER_DEFAULT_CREDITS; newUser.Tickets = GameConstants.USER_DEFAULT_TICKETS; newUser.Film = GameConstants.USER_DEFAULT_FILM; newUser.PoolFigure = string.Empty; newUser.LastLogin = DateTime.Now; // Validate data, client already requested this through the registration process but never trust client input! DataValidator validator = Stockholm.Get().GameManager.DataValidator; if (validator.ValidateUsername(newUser.Username) && validator.ValidateUserPassword(newUser.Username, newUser.Password) && validator.ValidateUserFigure(newUser.Figure)) { if (!Stockholm.Get().GameManager.UserTools.UserExists(newUser.Username)) { StockholmDbDataContext db = Stockholm.Get().Database; db.Users.InsertOnSubmit(newUser); db.SubmitChanges(); // Log the user in LoginRequest request = new LoginRequest(newUser.Username, newUser.Password, registerPacket.Peer); HandleLoginRequest(request); } } } private void HandleApproveName(ClientPacket packet) { ApproveNamePacket approvePacket = new ApproveNamePacket(); approvePacket.Deserialise(packet); // No errors = 0 int errorCode = 0; // Check username length, characters etc if(!Stockholm.Get().GameManager.DataValidator.ValidateUsername(approvePacket.Name)) { errorCode = 2; } // Check if user exists if(errorCode == 0 && !approvePacket.IsPet && Stockholm.Get().GameManager.UserTools.UserExists(approvePacket.Name)) { errorCode = 4; } packet.Peer.EnqueuePacket(new NameApprovedPacket(errorCode)); } private void HandleApprovePassword(ClientPacket packet) { ApprovePasswordPacket approvePacket = new ApprovePasswordPacket(); approvePacket.Deserialise(packet); // Determine if this is a valid password for this user bool ok = Stockholm.Get().GameManager.DataValidator.ValidateUserPassword(approvePacket.Name, approvePacket.Password); packet.Peer.EnqueuePacket(new PasswordApprovedPacket(ok)); } private void HandleApproveEmail(ClientPacket packet) { ApproveEmailPacket approvePacket = new ApproveEmailPacket(); approvePacket.Deserialise(packet); // TODO: check email (do we really care?) packet.Peer.EnqueuePacket(new GenericApprovedPacket(null)); } private void HandleAgeCheck(ClientPacket packet) { AgeCheckPacket checkPacket = new AgeCheckPacket(); checkPacket.Deserialise(packet); // TODO: calculate age by DOB (do we really care?) packet.Peer.EnqueuePacket(new GenericApprovedPacket("1")); } } }