internal static void PacketReceived(AuthServer server, PacketStream stream) { // Header // [Size:4] // [ID:2] // [Checksum(?):1] short PacketId = stream.GetId(); if (!packet_db.ContainsKey(PacketId)) { ConsoleUtils.HexDump(stream.ToArray(), "Unknown Packet Received", PacketId, stream.GetSize()); return; } ConsoleUtils.HexDump( stream.ToArray(), "Packet Received", PacketId, stream.GetSize() ); packet_db[PacketId].func(server, ref stream, packet_db[PacketId].pos); stream.Dispose(); return; }
/// <summary> /// Sends a pulse to the LoginServer, to let it know this server is alive. /// </summary> private void m_PulseTimer_Elapsed(object sender, ElapsedEventArgs e) { PacketStream Packet = new PacketStream(0x66, 3); Packet.WriteByte(0x66); Packet.WriteUInt16(3); Packet.Flush(); m_LoginClient.Send(Packet.ToArray()); Packet.Dispose(); }
/// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> protected virtual void Dispose(bool disposing) { { if (disposing) { // Release managed resources if (PacketStream != null) { __bw.Close(); __br.Close(); PacketStream.Close(); PacketStream.Dispose(); PacketStream = null; } } // Release unmanaged resources } }
/// <summary> /// Connect to an OTEX server. /// </summary> /// <param name="endpoint">IP Endpoint (address and port) of the OTEX server.</param> /// <param name="password">Password required to connect to the server, if any. Leave as null for none.</param> /// <param name="metadata">Client-specific application data to send to the server.</param> /// <exception cref="ArgumentException" /> /// <exception cref="ArgumentNullException" /> /// <exception cref="ArgumentOutOfRangeException" /> /// <exception cref="ObjectDisposedException" /> /// <exception cref="SocketException" /> /// <exception cref="InvalidDataException" /> /// <exception cref="System.Runtime.Serialization.SerializationException" /> /// <exception cref="System.Security.SecurityException" /> /// <exception cref="IOException" /> /// <exception cref="InvalidOperationException" /> public void Connect(IPEndPoint endpoint, Password password = null, byte[] metadata = null) { if (isDisposed) { throw new ObjectDisposedException("OTEX.Client"); } if (!connected) { lock (connectedLock) { if (isDisposed) { throw new ObjectDisposedException("OTEX.Client"); } if (connected) { throw new InvalidOperationException("Client is already connected to a server. Call Disconnect() first."); } if (!connected) { //check endpoint if (endpoint == null) { throw new ArgumentNullException("endpoint"); } if (endpoint.Port < 1024 || Server.AnnouncePorts.Contains(endpoint.Port)) { throw new ArgumentOutOfRangeException("endpoint.Port", string.Format("Port must be between 1024-{0} or {1}-65535.", Server.AnnouncePorts.First - 1, Server.AnnouncePorts.Last + 1)); } if (endpoint.Address.Equals(IPAddress.Any) || endpoint.Address.Equals(IPAddress.Broadcast) || endpoint.Address.Equals(IPAddress.None) || endpoint.Address.Equals(IPAddress.IPv6Any) || endpoint.Address.Equals(IPAddress.IPv6None)) { throw new ArgumentOutOfRangeException("endpoint.Address", "Address cannot be Any, None or Broadcast."); } //check metadata if (metadata != null && metadata.Length > ClientMetadata.MaxSize) { throw new ArgumentOutOfRangeException("metadata", string.Format("metadata.Length may not be greater than {0}.", ClientMetadata.MaxSize)); } //session connection TcpClient tcpClient = null; PacketStream packetStream = null; Packet responsePacket = null; ConnectionResponse response = null; try { //establish tcp connection tcpClient = new TcpClient(AddressFamily.InterNetworkV6); tcpClient.Client.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false); tcpClient.Connect(endpoint); packetStream = new PacketStream(tcpClient); //send connection request packet packetStream.Write(ID, new ConnectionRequest(password, metadata)); //get response responsePacket = packetStream.Read(); if (responsePacket.SenderID.Equals(Guid.Empty)) { throw new InvalidDataException("responsePacket.SenderID was Guid.Empty"); } if (responsePacket.PayloadType != ConnectionResponse.PayloadType) { throw new InvalidDataException("unexpected response packet type"); } response = responsePacket.Payload.Deserialize <ConnectionResponse>(); if (response.Result != ConnectionResponse.ResponseCode.Approved) { throw new Exception(string.Format("connection rejected by server: {0}", response.Result)); } } catch (Exception) { if (packetStream != null) { packetStream.Dispose(); } if (tcpClient != null) { tcpClient.Close(); } throw; } //set connected state connected = true; clientSideDisconnection = false; serverPort = (ushort)endpoint.Port; serverAddress = endpoint.Address; serverFilePath = response.FilePath ?? ""; serverName = response.Name ?? ""; serverID = responsePacket.SenderID; awaitingOperationList = false; //fire events OnConnected?.Invoke(this); InvokeRemoteOperations(response.Operations); if (response.Metadata != null && OnMetadataUpdated != null) { foreach (var md in response.Metadata) { OnMetadataUpdated?.Invoke(this, md.Key, md.Value); } } //create management thread thread = new Thread(ControlThread); thread.Name = "OTEX Client ControlThread"; thread.IsBackground = false; thread.Start(new object[] { tcpClient, packetStream }); } } } }