private void AcceptCallback(IAsyncResult ar) { LoginSocketState state = (LoginSocketState)ar.AsyncState; try { Socket client = state.Socket.EndAccept(ar); Thread.Sleep(1); if (state.Type == LoginSocketState.SocketType.Client) { _clientManagerReset.Set(); } else if (state.Type == LoginSocketState.SocketType.Search) { _searchManagerReset.Set(); } state.Socket = client; Logger.Info($"[{state.Type}] New Client: { ((IPEndPoint)state.Socket.RemoteEndPoint).Address}:{((IPEndPoint)state.Socket.RemoteEndPoint).Port}"); if (state.Type == LoginSocketState.SocketType.Client) { // ClientManager server sends data first byte[] buffer = LoginServerMessages.GenerateServerChallenge(ref state); SendToClient(ref state, buffer); if (state != null) { state.State++; } } else if (state.Type == LoginSocketState.SocketType.Search) { // SearchManager server waits for data first } } catch (NullReferenceException) { if (state != null) { state.Dispose(); } state = null; } catch (SocketException e) { Logger.Error(e, $"Error accepting client. SocketErrorCode: {e.SocketErrorCode}"); if (state != null) { state.Dispose(); } state = null; return; } WaitForData(ref state); }
private void KeepAliveCallback(object s) { LoginServer server = (LoginServer)s; try { if (_keepAliveTimer == null) { Dispose(); return; } LoginSocketState state = this; HeartbeatState++; Console.WriteLine("sending keep alive"); if (!server.SendToClient(ref state, LoginServerMessages.SendKeepAlive())) { Dispose(); return; } // every 2nd keep alive request, we send an additional heartbeat if (HeartbeatState % 2 == 0) { Console.WriteLine("sending heartbeat"); if (!server.SendToClient(ref state, LoginServerMessages.SendHeartbeat())) { Dispose(); return; } } } catch (Exception e) { logger.Error(e, "Error running keep alive"); Dispose(); } }
private void HandleSearchManager(ref LoginSocketState state, string query, Dictionary <string, string> keyValues) { if (state.State == 0) { if (query.Equals("nicks", StringComparison.InvariantCultureIgnoreCase)) { SendToClient(ref state, LoginServerMessages.SendNicks(ref state, keyValues)); } else if (query.Equals("check", StringComparison.InvariantCultureIgnoreCase)) { SendToClient(ref state, LoginServerMessages.SendCheck(ref state, keyValues)); } } else if (state.State == 1) { state.State++; } else if (state.State >= 2) { state.Dispose(); } }
private void HandleClientManager(ref LoginSocketState state, string query, Dictionary <string, string> keyValues) { if (state == null || String.IsNullOrWhiteSpace(query) || keyValues == null) { return; } if (state.State >= 4) { state.Dispose(); } else { switch (query) { case "login": SendToClient(ref state, LoginServerMessages.SendProof(ref state, keyValues)); Users[state.ProfileId] = state; state.StartKeepAlive(this); break; case "newuser": SendToClient(ref state, LoginServerMessages.NewUser(ref state, keyValues)); break; case "addbuddy": // \\addbuddy\\\\sesskey\\51437\\newprofileid\\1\\reason\\just be my friend var newFriendId = long.Parse(keyValues["newprofileid"]); if (Database.MainDBInstance.AddFriend(state.ProfileId, newFriendId)) { //var signature = (state.ProfileId.ToString() + newFriendId.ToString()).ToMD5(); // "\\bm\\%d\\f\\%d\\msg\\%s|signed|%s",GPI_BM_REQUEST,profileid,reason,signature); //SendToClient(ref state, $@"\bm\2\f\{newFriendId}\msg\{keyValues["reason"]}|signed|{signature}".ToAssciiBytes()); if (Users.TryGetValue(newFriendId, out LoginSocketState friendState)) { SendToClient(ref friendState, $@"\bm\100\f\{state.ProfileId}\msg\|s|{state.Status}{state.GetLSParameter()}|ss|{state.StatusString}\final\".ToAssciiBytes()); SendToClient(ref state, $@"\bm\100\f\{newFriendId}\msg\|s|{friendState.Status}{friendState.GetLSParameter()}|ss|{friendState.StatusString}\final\".ToAssciiBytes()); } else { SendToClient(ref state, $@"\bm\100\f\{newFriendId}\msg\|s|0|ss|Offline\final\".ToAssciiBytes()); } } break; case "delbuddy": // \delbuddy\\sesskey\51437\delprofileid\1 Database.MainDBInstance.RemoveFriend(state.ProfileId, long.Parse(keyValues["delprofileid"])); break; case "getprofile": SendToClient(ref state, LoginServerMessages.SendProfile(ref state, keyValues)); break; case "updatepro": //LoginServerMessages.UpdateProfile(ref state, keyValues); break; case "status": var remoteEndPoint = ((IPEndPoint)state.Socket.RemoteEndPoint); var profile = Database.MainDBInstance.GetProfileById(state.ProfileId); if (profile == null) { return; } var friends = profile.Friends ?? new List <long>(); SendToClient(ref state, $@"\bdy\{friends.Count + 1}\list\{string.Join(",",friends.Concat(new long[] { profile.Id }))}\final\".ToAssciiBytes()); // var loopbackIp = (uint)IPAddress.NetworkToHostOrder((int)IPAddress.Loopback.Address); // var loopbackIp = ReverseEndian32((uint)IPAddress.NetworkToHostOrder((int)IPAddress.Parse("192.168.159.128").Address)); // var port = ReverseEndian16(27900); state.Status = keyValues.GetOrDefault("status") ?? state.Status ?? "0"; state.StatusString = keyValues.GetOrDefault("statstring") ?? state.StatusString ?? "Offline"; state.LocString = keyValues.GetOrDefault("locstring") ?? state.LocString ?? "-1"; //SendToClient(ref state, $@"\bm\100\f\{profile.Id}\msg\|s|{1}|ss|DXP{"|ls|"}{-1}|ip|{loopbackIp}|p|{port}|qm|{0}\final\".ToAssciiBytes()); var statusResult = $@"\bm\100\f\{profile.Id}\msg\|s|{state.Status}{state.GetLSParameter()}|ss|{state.StatusString}\final\".ToAssciiBytes(); SendToClient(ref state, statusResult); for (int i = 0; i < friends.Count; i++) { var friendId = friends[i]; if (Users.TryGetValue(friendId, out LoginSocketState friendState)) { SendToClient(ref friendState, statusResult); //SendToClient(ref state, $@"\bm\100\f\{friendId}\msg\|s|{1}|ss|DXP|ls|-1\final\".ToAssciiBytes()); SendToClient(ref state, $@"\bm\100\f\{friendId}\msg\|s|{friendState.Status}{friendState.GetLSParameter()}|ss|{friendState.StatusString}\final\".ToAssciiBytes()); } else { SendToClient(ref state, $@"\bm\100\f\{friendId}\msg\|s|0|ss|Offline\final\".ToAssciiBytes()); } } // \status\1\sesskey\17562\statstring\DXP\locstring\-1 // userid\200000003\profileid\100000003\uniquenick\Bambochuk //sendBuddies() // SendToClient(ref state, $@"\bdy\1\list\100000003\final\".ToAssciiBytes()); //SendToClient(ref state, $@"\bdy\0\list\\final\".ToAssciiBytes()); // TODO: sendAddRequests(); //sendStatusUpdateToBuddies(this); // send self status // |s|%d|ss|%s%s%s|ip|%d|p|%d|qm|%d /* * c->status, * c->statusstr, * c->locstr[0] != 0 ? "|ls|" : "", * c->locstr, * reverse_endian32(c->ip), * reverse_endian16(c->port), * c->quietflags */ // SendToClient(ref state, $@"\bm\100\f\100000003\msg\|s|{2}|ss|DXP{"|ls|"}{-1}|ip|{(uint)IPAddress.NetworkToHostOrder((int)IPAddress.Loopback.Address)}|p|{ReverseEndian16(6500)}|qm|{0}\final\".ToAssciiBytes()); //SendToClient(ref state, $@"\bm\100\f\100000002\msg\|s|0|ss|Offline\final\".ToAssciiBytes()); //SendToClient(ref state, $@"\bm\100\f\100000001\msg\|s|{1}|ss|DXP{"|ls|"}{-1}|ip|{(uint)IPAddress.NetworkToHostOrder((int)remoteEndPoint.Address.Address)}|p|{ReverseEndian16(6500)}|qm|{0}\final\".ToAssciiBytes()); // send friend status break; case "logout": Users.TryRemove(state.ProfileId, out LoginSocketState removingState); LoginServerMessages.Logout(ref state, keyValues); break; case "registernick": SendToClient(ref state, DataFunctions.StringToBytes(string.Format(@"\rn\{0}\id\{1}\final\", keyValues["uniquenick"], keyValues["id"]))); break; case "ka": SendToClient(ref state, $@"\ka\\final\".ToAssciiBytes()); break; default: break; } } }