/// <summary> /// Callback for when a connection had disconnected /// </summary> protected void ClientDisconnected(SBClient client) { // Remove client, and call OnUpdate Event try { // Release this stream's AsyncEventArgs to the object pool Release(client.Stream); // Remove client from online list if (Clients.TryRemove(client.ConnectionID, out client) && !client.Disposed) { client.Dispose(); } } catch (Exception e) { LogWriter.Log.Write(LogLevel.Error, "[SB]: An Error occured at : {0}", e.ToString()); } }
/// <summary> /// Takes a message sent through the Stream and sends back a respose /// </summary> /// <param name="message"></param> public static void ParseRequest(SBClient client, string message) { string[] data = message.Split(new char[] { '\x00' }, StringSplitOptions.RemoveEmptyEntries); string gamename = data[1].ToLowerInvariant(); string validate = data[2].Substring(0, 8); string filter = FixFilter(data[2].Substring(8)); string[] fields = data[3].Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries); // Send the encrypted serverlist to the client byte[] unencryptedServerList = PackServerList(client, filter, fields); string sendingBuffer = Encoding.UTF8.GetString(Enctypex.Encode( Encoding.UTF8.GetBytes("hW6m9a"), // Battlfield 2 Handoff Key Encoding.UTF8.GetBytes(validate), unencryptedServerList, unencryptedServerList.LongLength) ); client.Send(sendingBuffer); }
/// <summary> /// Accepts a TcpClient, and begin the serverlist fetching process for the client. /// This method is executed when the user updates his server browser ingame /// </summary> protected override void ProcessAccept(TCPStream Stream) { // Get our connection id long ConID = Interlocked.Increment(ref ConnectionCounter); SBClient client; // End the operation and display the received data on // the console. try { // Convert the TcpClient to a MasterClient client = new SBClient(Stream, ConID); Clients.TryAdd(client.ConnectionID, client); // Start receiving data Stream.BeginReceive(); } catch (ObjectDisposedException) // Ignore { // Remove client Clients.TryRemove(ConID, out client); } catch (IOException) // Connection closed before a TcpClientStream could be made { // Remove client Clients.TryRemove(ConID, out client); } catch (Exception e) { // Remove client Clients.TryRemove(ConID, out client); // Report error LogWriter.Log.Write(LogLevel.Error, "[SB] : An Error occured at : {0}", e.ToString()); //ExceptionHandler.GenerateExceptionLog(e); } }
/// <summary> /// Packs and prepares the response to a Server List request from the clients game. /// </summary> /// <param name="filter"></param> /// <param name="fields"></param> /// <returns></returns> private static byte[] PackServerList(SBClient client, string filter, string[] fields) { IPEndPoint remoteEndPoint = ((IPEndPoint)client.RemoteEndPoint); byte fieldsCount = (byte)fields.Length; byte[] ipBytes = remoteEndPoint.Address.GetAddressBytes(); byte[] value2 = BitConverter.GetBytes((ushort)6500); if (BitConverter.IsLittleEndian) { Array.Reverse(value2, 0, value2.Length); } List <byte> data = new List <byte>(); data.AddRange(ipBytes); data.AddRange(value2); data.Add(fieldsCount); data.Add(0); foreach (var field in fields) { data.AddRange(Encoding.UTF8.GetBytes(field)); data.AddRange(new byte[] { 0, 0 }); } // TODO: after implementing QueryReport, please touch this function again, this changes were done just to compile the server throw new NotImplementedException("SB after QR2"); // Execute query right here in memory /*IQueryable<GameServer> servers = QueryReport.Servers.ToList().Select(x => x.Value).Where(x => x.IsValidated).AsQueryable(); * if (!String.IsNullOrWhiteSpace(filter)) * { * try * { * // Apply Filter * servers = servers.Where(filter); * } * catch (Exception e) * { * LogWriter.Log.WriteException(e); * //Program.ErrorLog.Write("ERROR: [PackServerList] " + e.Message); * // Program.ErrorLog.Write(" - Filter Used: " + filter); * } * } * * * // Add Servers * foreach (GameServer server in servers) * { * // Get port bytes * byte[] portBytes = BitConverter.GetBytes((ushort)server.QueryPort); * if (BitConverter.IsLittleEndian) * Array.Reverse(portBytes, 0, portBytes.Length); * * data.Add(81); // it could be 85 as well, unsure of the difference, but 81 seems more common... * data.AddRange(server.AddressInfo.Address.GetAddressBytes()); * data.AddRange(portBytes); * data.Add(255); * * for (int i = 0; i < fields.Length; i++) * { * data.AddRange(Encoding.UTF8.GetBytes(GetField(server, fields[i]))); * if (i < fields.Length - 1) * data.AddRange(new byte[] { 0, 255 }); // Field Seperator * } * * data.Add(0); * } * * data.AddRange(new byte[] { 0, 255, 255, 255, 255 }); * return data.ToArray();*/ }