public static async void Authenticate(int fromClient, Packet packet) { AuthCore core = (AuthCore)Server.the_core; int id = packet.ReadInt(); string user = packet.ReadString(); string password = packet.ReadString(); if (!Security.ReceivedIdMatchesClientId(id, fromClient)) { AuthHelpers.SendAuthFailed(fromClient); return; } int aid = await AuthHelpers.GetAidFromLoginPassword(fromClient, user, password); bool hasSession = await AuthHelpers.DoesAidHaveSession(aid); if (!hasSession) { AuthHelpers.SetSessionIDtoClient(fromClient, aid); core.Clients[fromClient].setAID(aid); AuthHelpers.CreateSessionInDatabase(fromClient, aid); CharacterSelectionEntry[] characters = await AuthHelpers.GetCharactersInAccount(aid); AuthHelpers.SendCharacterSelectionDataToClient(fromClient, characters); } else { core.Clients[fromClient].setAID(aid); AuthHelpers.SendAlreadyConnectedPacket(fromClient); AuthHelpers.SendDisconnectPacketToAlreadyConnectedClient(fromClient); } }
public static async Task <bool> AccountOwnsPlayer(int cid, int pid) { AuthCore core = (AuthCore)Server.the_core; List <MySqlParameter> _params = new List <MySqlParameter>() { MySQL_Param.Parameter("?id", pid), }; DataTable result = await Server.DB.QueryAsync("SELECT * FROM [[player]].player WHERE `id`=?id LIMIT 1", _params); if (result.Rows.Count == 0) { return(false); } Int32.TryParse(result.Rows[0]["aid"].ToString(), out int aid); Int32.TryParse(result.Rows[0]["id"].ToString(), out int _pid); if (aid <= 0 || _pid < 0) { return(false); } if (core.Clients[cid].aid != aid) { return(false); } return(true); }
public static async void EnterMap(int fromClient, Packet packet) { AuthCore core = (AuthCore)Server.the_core; int cid = packet.ReadInt(); int sid = packet.ReadInt(); int pid = packet.ReadInt(); if (!Security.Validate(cid, fromClient, sid)) { return; } bool ownsPlayer = await AuthHelpers.AccountOwnsPlayer(cid, pid); if (!ownsPlayer) { core.Clients[fromClient].tcp.Disconnect(); return; } DataTable result = await AuthHelpers.GetPlayerData(pid); await AuthHelpers.AssignPidToSession(result, cid); AuthHelpers.MakeClientConnectToGameServer(result, cid); }
public static async void SendDisconnectPacketToAlreadyConnectedClient(int client) { AuthCore core = (AuthCore)Server.the_core; bool isOnline = false; foreach (KeyValuePair <int, AuthClient> cc in core.Clients) { if (cc.Value.tcp != null && cc.Value != core.Clients[client]) { if (cc.Value.tcp.socket != null) { if (cc.Value.tcp.socket.Connected) { isOnline = true; // send a disconnect packet break; } } } } if (!isOnline) { List <MySqlParameter> delSess = new List <MySqlParameter>() { MySQL_Param.Parameter("?id", core.Clients[client].aid), }; await Server.DB.QueryAsync("DELETE FROM [[player]].sessions WHERE `aid`=?id LIMIT 1", delSess); } }
public static void MakeClientConnectToGameServer(DataTable result, int cid, int forcedMap = -1) { AuthCore core = (AuthCore)Server.the_core; Int32.TryParse(result.Rows[0]["map"].ToString(), out int map); Int32.TryParse(result.Rows[0]["id"].ToString(), out int pid); if (forcedMap > 0) { map = forcedMap; } foreach (GameServer server in Config.GameServers) { if (server.maps.Contains(map)) { using (Packet nPacket = new Packet((int)Packet.ServerPackets.goToServerAt)) { nPacket.Write(cid); nPacket.Write(core.Clients[cid].session_id); nPacket.Write(server.addr); nPacket.Write(server.port); AuthCore.SendTCPData(cid, nPacket); } Logger.Syslog($"Client #{cid} is entering map #{map} on the server labeled '{server.label}' with pid #{pid} with a session id of {((AuthCore)Server.the_core).Clients[cid].session_id}..."); break; } else { Logger.Syserr($"Client #{cid} attempted to enter a character of pid {pid} on a non existing map #{map} !!!"); core.Clients[cid].tcp.Disconnect(); return; } } }
public static void SendAlreadyConnectedPacket(int client) { using (Packet newPacket = new Packet((int)Packet.ServerPackets.alreadyConnected)) { newPacket.Write(client); AuthCore.SendTCPData(client, newPacket); } }
public static void SetSessionIDtoClient(int client, int aid) { AuthCore core = (AuthCore)Server.the_core; Random rnd1 = new Random(MathHelp.TimestampSeconds()); Random rnd2 = new Random(rnd1.Next(1, Int32.MaxValue) + aid); int nSessionId = rnd2.Next(1, Int32.MaxValue); core.Clients[client].setSessionId(nSessionId); }
public static void SendAuthFailed(int client) { using (Packet newPacket = new Packet((int)Packet.ServerPackets.authResult)) { newPacket.Write(client); newPacket.Write(false); AuthCore.SendTCPData(client, newPacket); } }
public static async void CreateSessionInDatabase(int client, int aid) { AuthCore core = (AuthCore)Server.the_core; List <MySqlParameter> sessParams = new List <MySqlParameter>() { MySQL_Param.Parameter("?session", core.Clients[client].session_id), MySQL_Param.Parameter("?pid", core.Clients[client].session_id), // as a temporary pid MySQL_Param.Parameter("?aid", aid) }; await Server.DB.QueryAsync("INSERT INTO [[player]].sessions (session,pid,aid) VALUES (?session,?pid,?aid)", sessParams); }
public new static void SendTCPData(int toClient, Packet packet) { try { packet.WriteLength(); AuthCore core = (AuthCore)Server.the_core; core.Clients[toClient].tcp.SendData(packet); } catch { Logger.Syserr($"Failed to send data to client #{toClient}"); } }
public static async Task <int> AssignPidToSession(DataTable rows, int cid) { AuthCore core = (AuthCore)Server.the_core; List <MySqlParameter> sParams = new List <MySqlParameter>() { MySQL_Param.Parameter("?session", core.Clients[cid].session_id), MySQL_Param.Parameter("?pid", rows.Rows[0]["id"].ToString()), MySQL_Param.Parameter("?aid", rows.Rows[0]["aid"].ToString()) }; await Server.DB.QueryAsync("UPDATE [[player]].sessions SET `pid`=?pid WHERE `session`=?session AND `aid`=?aid LIMIT 1", sParams); return(1); }
public static void SendCharacterSelectionDataToClient(int client, CharacterSelectionEntry[] characters) { AuthCore core = (AuthCore)Server.the_core; using (Packet nPacket = new Packet((int)Packet.ServerPackets.charSelection)) { nPacket.Write(client); nPacket.Write(core.Clients[client].session_id); for (int i = 0; i < Config.MaxCharactersInAccount; i++) { nPacket.Write(characters[i]); } AuthCore.SendTCPData(client, nPacket); } }
public static async void SendTargetGameServerForWarp(int fromClient, Packet packet) { AuthCore core = (AuthCore)Server.the_core; int cid = packet.ReadInt(); int sid = packet.ReadInt(); int pid = packet.ReadInt(); int map = packet.ReadInt(); if (!Security.ReceivedIdMatchesClientId(cid, fromClient)) { AuthHelpers.SendAuthFailed(fromClient); return; } List <MySqlParameter> _params = new List <MySqlParameter>() { MySQL_Param.Parameter("?session", sid), MySQL_Param.Parameter("?pid", pid), }; DataTable rows = await Server.DB.QueryAsync("SELECT COUNT(*) AS count FROM [[player]].sessions WHERE `session`=?session AND `pid`=?pid LIMIT 1", _params); if (Int32.Parse(rows.Rows[0]["count"].ToString()) > 0) { DataTable result = await AuthHelpers.GetPlayerData(pid); List <MySqlParameter> mapParams = new List <MySqlParameter>() { MySQL_Param.Parameter("?map", map), MySQL_Param.Parameter("?x", Config.SpawnPositionsForMaps[map].X), MySQL_Param.Parameter("?y", Config.SpawnPositionsForMaps[map].Y), MySQL_Param.Parameter("?z", Config.SpawnPositionsForMaps[map].Z), MySQL_Param.Parameter("?pid", pid), }; await Server.DB.QueryAsync("UPDATE [[player]].player SET `map`=?map, `x`=?x, `y`=?y, `z`=?z WHERE `id`=?pid LIMIT 1", mapParams); ((AuthCore)Server.the_core).Clients[cid].session_id = sid; AuthHelpers.MakeClientConnectToGameServer(result, cid, map); } else { Logger.Syserr($"Player #{pid} attempted to enter map #{map} but the session missmatched (sid of {sid})"); // todo : send a disconnect packet to the client } }
private static bool ValidatePacket(int cid, int fromClient, int session_id) { if (Config.Type == ServerTypes.Authentication) { AuthCore core = ((AuthCore)Server.the_core); if (cid != fromClient) { return(false); } if (core.Clients == null) { return(false); } if (core.Clients[fromClient] == null) { return(false); } if (core.Clients[fromClient].session_id != session_id) { return(false); } return(true); } if (cid != fromClient) { return(false); } if (Server.the_core.Clients == null) { return(false); } if (Server.the_core.Clients[fromClient] == null) { return(false); } if (Server.the_core.Clients[fromClient].session_id != session_id) { return(false); } return(true); }
public override void Connect(TcpClient _socket) { configureSocket(_socket); stream.BeginRead(receivedBuff, 0, buffer_size, ReceiveCallback, null); /* * * A new client has connected to the authentication server * This is NOT an authentication request, its just a heartbeat * If we hear back a valid PONG response then we "allow" the client to request authentication */ using (Packet newPacket = new Packet((int)Packet.ServerPackets.connectSucess)) { newPacket.Write("Ping?"); newPacket.Write(cid); AuthCore.SendTCPData(cid, newPacket); } try { Logger.Syslog($"Client #{client.cid} ({AuthCore.GetClientIP(cid)}) connected to the authentication server"); } catch { Logger.Syslog("A client connected to the authentication server but we couldn't retrieve it's ip address."); } }
public override void ReceiveCallback(IAsyncResult ar) { AuthCore core = (AuthCore)Server.the_core; try { int byteLength = stream.EndRead(ar); if (byteLength <= 0) { core.Clients[cid].tcp.Disconnect(); return; } resetSocket(byteLength); stream.BeginRead(receivedBuff, 0, buffer_size, ReceiveCallback, null); } catch { core.Clients[cid].tcp.Disconnect(); } }
public void OnAuthorization(AuthorizationFilterContext context) { try { var uin = AuthCore.GetUin(context.HttpContext.Request); if (String.IsNullOrEmpty(uin)) { bool isAjax = false; if (context.HttpContext.Request.Headers.ContainsKey("x-requested-with")) { isAjax = context.HttpContext.Request.Headers["x-requested-with"] == "XMLHttpRequest"; } if (!isAjax) { RedirectToActionResult content = new RedirectToActionResult("QrCode", "Login", null); context.Result = content; } else { context.Result = new JsonResult(new ApiResult() { Code = -2, Data = "登录过期,请重新登录" }); } } } catch (Exception ex) { RedirectToActionResult content = new RedirectToActionResult("QrCode", "Login", null); context.Result = content; LogHelper.Error("登录验证抛出异常", ex.Message); } }
public static void HandlePong(int fromClient, Packet packet) { int id = packet.ReadInt(); int pongLen = packet.ReadInt(); byte[] pong = packet.ReadBytes(pongLen); if (id == fromClient) { byte[] hashed = Security.Hash("PONG" + fromClient, Security.GetSalt()); if (Security.Verify(pong, hashed)) { using (Packet newPacket = new Packet((int)Packet.ServerPackets.requestAuth)) { newPacket.Write(fromClient); AuthCore.SendTCPData(fromClient, newPacket); } } else { Logger.Syserr($"Invalid client pong received, disconnecting client #{id}"); Server.the_core.Clients[id].tcp.Disconnect(); } } }
public new static string GetClientIP(int clientId) { AuthCore core = (AuthCore)Server.the_core; return(core.Clients[clientId].tcp.socket.Client.RemoteEndPoint.ToString()); }