Advertisement
Guest User

Untitled

a guest
Jun 24th, 2017
47
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VB.NET 13.76 KB | None | 0 0
  1. ''' <summary>
  2. ''' The individual client class that is monitored by the server.
  3. ''' </summary>
  4. ''' <remarks></remarks>
  5. Public Class [Client]
  6.     Implements IDisposable, IEqualityComparer
  7.  
  8.     'Variables
  9.     Private _client As TcpClient
  10.     Private _thread As New Threading.Thread(AddressOf Read) With {.IsBackground = True}
  11.     Private _disposed As Boolean = False
  12.  
  13.     'User Variables; these are all serializable.
  14.     Private _name As String = String.Empty
  15.     Private _password As String = String.Empty
  16.     Private _status As String = String.Empty
  17.     Private _display As String = String.Empty
  18.     Private _friends As New List(Of String)
  19.     Private _ip As String = String.Empty
  20.    
  21.     'Events
  22.     Public Event Message(ByRef sender As Client, ByRef obj As Object)
  23.     Public Event [Error](ByRef sender As Client, ByRef ex As Exception)
  24.     Public Event Disconnected(ByVal sender As Client)
  25.  
  26.     'Overridable Subs
  27.     ''' <summary>
  28.     ''' Called when the client has safely disconnected.
  29.     ''' </summary>
  30.     ''' <param name="ar">The IAsyncResult</param>
  31.     ''' <remarks></remarks>
  32.     Public Overridable Sub OnSafeDisconnect(ByVal ar As IAsyncResult)
  33.  
  34.         'If the event completed, the client has disconnected.
  35.         If ar.IsCompleted Then
  36.  
  37.             'Raise the Disconnected Event.
  38.             RaiseEvent Disconnected(Me)
  39.  
  40.             'Save myself
  41.             Me.Save()
  42.  
  43.             'Reset.
  44.             Me.Reset()
  45.  
  46.         End If
  47.  
  48.     End Sub
  49.    
  50.     'Properties
  51.     ''' <summary>
  52.     ''' Gets or sets the client's name.
  53.     ''' </summary>
  54.     ''' <value></value>
  55.     ''' <returns></returns>
  56.     ''' <remarks></remarks>
  57.     Public Property Name As String
  58.         Get
  59.             Return _name
  60.         End Get
  61.         Set(ByVal value As String)
  62.             _name = value
  63.         End Set
  64.     End Property
  65.  
  66.     ''' <summary>
  67.     ''' Gets or sets the client's password.
  68.     ''' </summary>
  69.     ''' <value></value>
  70.     ''' <returns></returns>
  71.     ''' <remarks></remarks>
  72.     Public Property Password As String
  73.         Get
  74.             Return _password
  75.         End Get
  76.         Set(ByVal value As String)
  77.             _password = value
  78.         End Set
  79.     End Property
  80.  
  81.     ''' <summary>
  82.     ''' Gets or sets the client's status.
  83.     ''' </summary>
  84.     ''' <value></value>
  85.     ''' <returns></returns>
  86.     ''' <remarks></remarks>
  87.     Public Property Status As String
  88.         Get
  89.             Return _status
  90.         End Get
  91.         Set(ByVal value As String)
  92.             _status = value
  93.             'ToDo: Client-side update/confirmation.
  94.         End Set
  95.     End Property
  96.  
  97.     ''' <summary>
  98.     ''' Gets or sets the client's display name.
  99.     ''' </summary>
  100.     ''' <value></value>
  101.     ''' <returns></returns>
  102.     ''' <remarks></remarks>
  103.     Public Property Display As String
  104.         Get
  105.             Return _display
  106.         End Get
  107.         Set(ByVal value As String)
  108.             _display = value
  109.             'ToDo: Client-side update/confirmation.
  110.         End Set
  111.     End Property
  112.  
  113.     ''' <summary>
  114.     ''' Gets the IP Address of the Client.
  115.     ''' </summary>
  116.     ''' <value></value>
  117.     ''' <returns></returns>
  118.     ''' <remarks></remarks>
  119.     Public ReadOnly Property IP As String
  120.         Get
  121.  
  122.             'If the IP Address hasn't been discovered, set it.
  123.             If _ip.Equals(String.Empty) Then Me.GetIP()
  124.  
  125.             'Return it.
  126.             Return _ip
  127.  
  128.         End Get
  129.     End Property
  130.  
  131.     ''' <summary>
  132.     ''' Gets whether the Client is disposed or not.
  133.     ''' </summary>
  134.     ''' <value></value>
  135.     ''' <returns></returns>
  136.     ''' <remarks></remarks>
  137.     Public ReadOnly Property Disposed As Boolean
  138.         Get
  139.             Return _disposed
  140.         End Get
  141.     End Property
  142.  
  143.     'Subs
  144.     ''' <summary>
  145.     ''' Creates a blank Client Class.
  146.     ''' </summary>
  147.     ''' <remarks></remarks>
  148.     Public Sub New()
  149.  
  150.     End Sub
  151.  
  152.     ''' <summary>
  153.     ''' Creates a new Client Class that handles the client information.
  154.     ''' </summary>
  155.     ''' <param name="IncomingClient">The TcpClient to handle.</param>
  156.     ''' <remarks></remarks>
  157.     Public Sub New(ByRef IncomingClient As TcpClient)
  158.  
  159.         'Get the Incoming Client.
  160.         _client = IncomingClient
  161.  
  162.         'Start the thread for reading.
  163.         _thread.Start()
  164.  
  165.         'Get the IP
  166.         Me.GetIP()
  167.  
  168.     End Sub
  169.  
  170.     ''' <summary>
  171.     ''' Listens for incoming messages to the stream.
  172.     ''' </summary>
  173.     ''' <remarks></remarks>
  174.     Private Sub Read()
  175.  
  176.         'It is in fact an infinite loop.
  177.         Do While Not _disposed
  178.  
  179.             'Create a try-catch block to trap any errors.
  180.             Try
  181.  
  182.                 'Create the deserializer
  183.                 Dim Reader As New Binary.BinaryFormatter
  184.  
  185.                 'Create our generic object.
  186.                 Dim Obj As New Object
  187.  
  188.                 'Now sit on the stream and deserialize whatever comes through.
  189.                 Obj = Reader.Deserialize(_client.GetStream)
  190.  
  191.                 'Raise the event to pass the message up.
  192.                 RaiseEvent Message(Me, Obj)
  193.  
  194.             Catch tex As Threading.ThreadAbortException
  195.  
  196.                 'IGNORE THREAD ABORT.
  197.                 Exit Do
  198.  
  199.             Catch ex As Exception
  200.  
  201.                 'Some sort of error; but the client has to disconnect now.
  202.                 RaiseEvent Error(Me, ex)
  203.  
  204.                 'Exit the loop
  205.                 Exit Do
  206.  
  207.             End Try
  208.  
  209.         Loop
  210.  
  211.  
  212.     End Sub
  213.  
  214.     ''' <summary>
  215.     ''' Writes an object to the stream.
  216.     ''' </summary>
  217.     ''' <param name="obj">The object to write to the stream.</param>
  218.     ''' <remarks></remarks>
  219.     Public Sub Write(ByRef obj As Object)
  220.  
  221.         'For errors.
  222.         Try
  223.  
  224.             'Create the writer.
  225.             Dim Writer As New Binary.BinaryFormatter
  226.  
  227.             'Now write it to the SyncLocked stream.
  228.             SyncLock _client.GetStream
  229.                 Writer.Serialize(_client.GetStream, obj)
  230.             End SyncLock
  231.  
  232.             'No errors, success.
  233.  
  234.         Catch ex As Exception
  235.  
  236.             'An error.
  237.             RaiseEvent Error(Me, ex)
  238.  
  239.         End Try
  240.  
  241.     End Sub
  242.    
  243.     ''' <summary>
  244.     ''' Disposes the Client and (tries) to release all utilized resources.
  245.     ''' </summary>
  246.     ''' <remarks></remarks>
  247.     Private Sub Dispose() Implements IDisposable.Dispose
  248.  
  249.         'If we aren't already disposed
  250.         If Not Disposed Then
  251.  
  252.             'Set our disposed variable to true.
  253.             _disposed = True
  254.  
  255.             'Kill the thread.
  256.             _thread.Abort()
  257.  
  258.             'Send a message to begin the disconnect.
  259.             Me.Write(New ArkDLL.Disconnect)
  260.  
  261.             'Begin the disconnection if we are not already disconnected
  262.             If _client.Connected Then _client.Client.BeginDisconnect(False, New AsyncCallback(AddressOf OnSafeDisconnect), Nothing)
  263.  
  264.         End If
  265.  
  266.     End Sub
  267.  
  268.     ''' <summary>
  269.     ''' Disposes the Client and (tries) to release all utilized resources.
  270.     ''' </summary>
  271.     ''' <param name="safe">If true, safely disconnect the client. If false, forcibly ends the connection.</param>
  272.     ''' <remarks></remarks>
  273.     Public Sub Dispose(ByVal safe As Boolean)
  274.  
  275.         'Make sure we're not disposed already.
  276.         If Disposed Then Return
  277.  
  278.         'If we want to safely dispose of the object,
  279.         'Call the generic Me.Dispose.
  280.         If safe Then Me.Dispose()
  281.  
  282.         'Otherwise, forcibly terminate shit.
  283.         _disposed = True
  284.  
  285.         'Kill the reader thread.
  286.         _thread.Abort()
  287.  
  288.         'Dispose the client, ignore the exception.
  289.         Try
  290.             If _client.Connected Then _client.Client.Close()
  291.         Catch ex As Exception
  292.         End Try
  293.  
  294.         'Save the user.
  295.         Me.Save()
  296.        
  297.         'Reset all variables
  298.         Me.Reset()
  299.         _client = Nothing
  300.         _thread = Nothing
  301.  
  302.         'Garbage Collect.
  303.         GC.Collect()
  304.  
  305.     End Sub
  306.  
  307.     ''' <summary>
  308.     ''' Resets the static variables.
  309.     ''' </summary>
  310.     ''' <remarks></remarks>
  311.     Private Sub Reset()
  312.  
  313.         _name = String.Empty
  314.         _display = String.Empty
  315.         _friends.Clear()
  316.         _ip = String.Empty
  317.         _password = String.Empty
  318.         _status = String.Empty
  319.  
  320.     End Sub
  321.  
  322.     ''' <summary>
  323.     ''' Attempts to discover the IP address of the client.
  324.     ''' </summary>
  325.     ''' <remarks></remarks>
  326.     Private Sub GetIP()
  327.         Try
  328.             Dim ipend As Net.IPEndPoint = CType(_client.Client.RemoteEndPoint, Net.IPEndPoint)
  329.             If Not ipend Is Nothing Then _ip = ipend.Address.ToString
  330.         Catch ex As System.ObjectDisposedException
  331.             _ip = String.Empty
  332.             RaiseEvent Error(Me, CType(ex, Exception))
  333.         Catch ex As SocketException
  334.             _ip = String.Empty
  335.             RaiseEvent Error(Me, CType(ex, Exception))
  336.         End Try
  337.     End Sub
  338.  
  339.     ''' <summary>
  340.     ''' Saves a Client to the system.
  341.     ''' </summary>
  342.     ''' <remarks></remarks>
  343.     Public Sub Save()
  344.  
  345.         'OK, format a path.
  346.         Dim path As String = IO.Path.Combine(Application.StartupPath, "users")
  347.         If Not Directory.Exists(path) Then Directory.CreateDirectory(path)
  348.  
  349.         'Now, to save. 1) Create FileStream.
  350.         Dim FS As New FileStream(String.Format("{0}\{1}.xml", path, Me.Name), FileMode.Create)
  351.  
  352.         'Create the formatter
  353.         Dim Saver As New Binary.BinaryFormatter
  354.  
  355.         'Save!
  356.         Saver.Serialize(FS, Me)
  357.  
  358.         'Close the stream.
  359.         FS.Close()
  360.  
  361.     End Sub
  362.  
  363.     ''' <summary>
  364.     ''' Loads a Client from the system files.
  365.     ''' </summary>
  366.     ''' <param name="username">The username to load.</param>
  367.     ''' <returns></returns>
  368.     ''' <remarks></remarks>
  369.     Public Function Load(ByVal username As String) As Client
  370.  
  371.         'Format the filepath.
  372.         Dim path As String = IO.Path.Combine(Application.StartupPath, "users")
  373.  
  374.         'Loop the files in the directory.
  375.         For Each File As String In IO.Directory.GetFiles(path)
  376.  
  377.             'Get the filename.
  378.             Dim Filename As String = IO.Path.GetFileNameWithoutExtension(File)
  379.  
  380.             'Compare
  381.             If Filename.Equals(username) Then
  382.  
  383.                 'Create a filestream.
  384.                 Dim FS As New FileStream(
  385.                     IO.Path.Combine(path, String.Format("{0}.xml", username)),
  386.                     FileMode.Open)
  387.  
  388.                 'Create a reader.
  389.                 Dim Reader As New Binary.BinaryFormatter
  390.  
  391.                 'Create the placeholder client.
  392.                 Dim Cli As New Client()
  393.  
  394.                 'Deserialize
  395.                 Cli = CType(Reader.Deserialize(FS), Client)
  396.  
  397.                 'Close the stream
  398.                 FS.Close()
  399.  
  400.                 'Return the client.
  401.                 Return Cli
  402.  
  403.             End If
  404.  
  405.         Next
  406.  
  407.         'Found nothing, give back a blank client.
  408.         Return New Client
  409.  
  410.     End Function
  411.  
  412.     ''' <summary>
  413.     ''' Determines whether the specified objects are equal.
  414.     ''' </summary>
  415.     ''' <returns>
  416.     ''' true if the specified objects are equal; otherwise, false.
  417.     ''' </returns>
  418.     ''' <param name="x">The first object to compare.</param>
  419.     ''' <param name="y">The second object to compare.</param>
  420.     ''' <exception cref="T:System.ArgumentException"><paramref name="x"/> and <paramref name="y"/> are of different types and neither one can handle comparisons with the other.</exception>
  421.     Public Shadows Function Equals(ByVal x As Object, ByVal y As Object) As Boolean Implements IEqualityComparer.Equals
  422.  
  423.         'Make sure they are both Client types.
  424.         If x.GetType Is GetType(Client) AndAlso y.GetType Is GetType(Client) Then
  425.  
  426.             'Convert them.
  427.             Dim c1 As Client = CType(x, Client)
  428.             Dim c2 As Client = CType(y, Client)
  429.  
  430.             'And now compare.
  431.             Return c1.Display.Equals(c2.Display) AndAlso c1.Name.Equals(c2.Display) AndAlso c1.Password.Equals(c2.Password) AndAlso c1.Status.Equals(c2.Status) AndAlso c1.IP.Equals(c2.IP)
  432.  
  433.         Else
  434.  
  435.             'They are not proper objects, throw an exception.
  436.             Throw New ArgumentException("In order to use the Equals function, both passed objects MUST be Clients!")
  437.  
  438.         End If
  439.  
  440.     End Function
  441.  
  442.     ''' <summary>
  443.     ''' Returns a hash code for the specified object.
  444.     ''' </summary>
  445.     ''' <returns>
  446.     ''' A hash code for the specified object.
  447.     ''' </returns>
  448.     ''' <param name="obj">The <see cref="T:System.Object"/> for which a hash code is to be returned.</param><exception cref="T:System.ArgumentNullException">The type of <paramref name="obj"/> is a reference type and <paramref name="obj"/> is null.</exception>
  449.     Public Overloads Function GetHashCode(ByVal obj As Object) As Integer Implements IEqualityComparer.GetHashCode
  450.         Throw New NotImplementedException()
  451.     End Function
  452.  
  453.     ''' <summary>
  454.     ''' Compares two Client classes to see if they are equal.
  455.     ''' </summary>
  456.     ''' <param name="one">The first client to compare.</param>
  457.     ''' <param name="two">The second. client to compare.</param>
  458.     ''' <returns></returns>
  459.     ''' <remarks></remarks>
  460.     Public Shared Operator =(ByVal one As Client, ByVal two As Client) As Boolean
  461.  
  462.         'Compare
  463.         Return one.Equals(one, two)
  464.  
  465.     End Operator
  466.  
  467.     ''' <summary>
  468.     ''' Compares two Client classes to see if they aren't equal.
  469.     ''' </summary>
  470.     ''' <param name="one">The first client to compare.</param>
  471.     ''' <param name="two">The second. client to compare.</param>
  472.     ''' <returns></returns>
  473.     ''' <remarks></remarks>
  474.     Public Shared Operator <>(ByVal one As Client, ByVal two As Client) As Boolean
  475.  
  476.         'Compare using the = method.
  477.         Return Not one.Equals(one, two)
  478.  
  479.     End Operator
  480.  
  481. End Class
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement