API. Even though my SecurityAPI is in C#, it is a .Net class library, which means you can use it with any .Net language really.I have no other plans of making VB.Net examples, so study this one carefully to get a feel for how to port C# code to VB.Net code. There might be small logic errors due to the porting process, but simple testing indicates it seems to work. I only spent enough time on this to port the code and get it working, I'm not comfortable with the VB.Net language, so my time here is really short. please don't ask me how you do things in VB.Net, I just Google'd everything.
Create a VB.Net Console project.
To add the "SilkroadSecurityApi.dll" as a reference:
1. Double click "My Project" (under the Solution Explorer on the right side of the screen)
2. Select "References" tab
3. Click Add
4. Choose "Browse"
5. Select the "SilkroadSecurityApi.dll" file and click OK
Now you can create a new code file and paste this in and edit it as needed.
Module1.vb
Code:
Imports SilkroadSecurityApi
Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Module Module1
Sub Main(ByVal args As String())
Dim recv_buffer As New TransferBuffer(4096, 0, 0)
Dim ping_timer As New Stopwatch()
Dim do_ping As Boolean = False
Dim stats_timer As New Stopwatch()
Dim last_stats_timer As New Stopwatch()
Dim do_stats As Boolean = False
Dim version As UInt32 = UInt32.Parse(args(1))
Dim locale As UInt32 = UInt32.Parse(args(0))
Dim hosts As New List(Of KeyValuePair(Of String, Int32))
Dim host_count As Int32 = Int32.Parse(args(2))
For x As Int32 = 0 To host_count - 1
hosts.Add(New KeyValuePair(Of String, Int32)(args(3 + x * 2), Int32.Parse(args(3 + x * 2 + 1))))
Next
Dim connection_closed_times As New List(Of DateTime)
Dim connect_errors As Int32 = 0
Dim receive_errors As Int32 = 0
Dim data_errors As Int32 = 0
Dim parse_errors As Int32 = 0
Dim send_errors As Int32 = 0
Dim misc_errors As Int32 = 0
Dim reconnect_time As Int32 = 5000
Dim stats_interval As Int32 = 1000
Dim stats_timeout As Int32 = 45000
Dim doExit As Boolean = False
While doExit <> True
Dim security As New SilkroadSecurityApi.Security ' This should actually be here rather than above in the C# example
Using s As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
Try ' Connect to the remote server
Dim host As KeyValuePair(Of String, Int32) = hosts(connect_errors Mod hosts.Count)
Console.WriteLine("Status: Now connecting to {0}:{1}", host.Key, host.Value)
s.Connect(host.Key, host.Value)
s.Blocking = False
s.NoDelay = True
Catch ex As Exception
connect_errors = connect_errors + 1
Console.WriteLine("Error: Could not connect to the server." + Environment.NewLine + Environment.NewLine + ex.Message)
If Console.KeyAvailable = True Then ' If the user wants to exit, let them.
Dim key As ConsoleKeyInfo = Console.ReadKey(True)
If key.Key = ConsoleKey.Escape Then
doExit = True
Exit While
End If
Console.WriteLine("This is error # {0}. Waiting {1} ms then trying again..." + Environment.NewLine, connect_errors, reconnect_time)
Thread.Sleep(reconnect_time)
Continue While
End If
End Try
last_stats_timer.Reset()
last_stats_timer.Start() ' Need to keep track of stats time state
' Main logic loop
While True
Try
If Console.KeyAvailable = True Then ' If the user wants to exit, let them.
Dim key As ConsoleKeyInfo = Console.ReadKey(True)
If key.Key = ConsoleKey.Escape Then
doExit = True
Exit While
End If
End If
Catch ex As Exception
misc_errors = misc_errors + 1
Console.WriteLine("Error: A misc error was encountered." + Environment.NewLine + Environment.NewLine + ex.Message)
Console.WriteLine("This is error # {0}. Waiting {1} ms then trying again..." + Environment.NewLine, misc_errors, reconnect_time)
Thread.Sleep(reconnect_time)
Exit While
End Try
' Receive network data
Try
' Receive logic, try to receive as much as possible, then pass to the security object
Dim err As SocketError
recv_buffer.Size = s.Receive(recv_buffer.Buffer, 0, recv_buffer.Buffer.Length, SocketFlags.None, err)
If err <> SocketError.Success Then
If err <> SocketError.WouldBlock Then
Throw New Exception(String.Format("Receive returned error code {0}.", err))
End If
Else
If recv_buffer.Size > 0 Then
Try
security.Recv(recv_buffer)
Catch ex As Exception
Console.WriteLine("Error: Could not process the data from the server." + Environment.NewLine + Environment.NewLine + ex.Message)
Console.WriteLine("This is error # {0}. Waiting {1} ms then trying again..." + Environment.NewLine, data_errors, reconnect_time)
Thread.Sleep(reconnect_time)
Exit While
End Try
Else
connection_closed_times.Add(DateTime.Now)
Console.WriteLine("Error: The connection has been closed.")
Console.WriteLine("This is disconnect # {0}. Waiting {1} ms then trying again..." + Environment.NewLine, connection_closed_times.Count, reconnect_time)
Thread.Sleep(reconnect_time)
Exit While
End If
End If
Catch ex As Exception
receive_errors = receive_errors + 1
Console.WriteLine("Error: Could not receive data from the server." + Environment.NewLine + Environment.NewLine + ex.Message)
Console.WriteLine("This is error # {0}. Waiting {1} ms then trying again..." + Environment.NewLine, receive_errors, reconnect_time)
Thread.Sleep(reconnect_time)
Exit While
End Try
' Process network data
Try
' Obtain all queued packets and add them to our own queue to process later.
Dim packets As List(Of Packet) = security.TransferIncoming()
If packets Is Nothing Then
Else
For Each packet As Packet In packets
' Debugging
Dim bytes As Byte() = packet.GetBytes()
Console.WriteLine("[S->C][0x{0:X4}][{1} bytes][Enc: {2}][Msv: {3}]", packet.Opcode, bytes.Length, packet.Encrypted, packet.Massive)
If packet.Opcode = &H5000 Then ' Handshake
' Ignore
ElseIf packet.Opcode = &H2001 Then ' Identify
Dim response As New Packet(&H6100, True, False) ' Version
response.WriteUInt8(locale)
response.WriteAscii("SR_Client")
response.WriteUInt32(version)
security.Send(response)
do_ping = True
ping_timer.Start()
ElseIf packet.Opcode = &H2005 Then ' server specific information
' Ignore
ElseIf packet.Opcode = &H6005 Then ' server specific information
' Ignore
ElseIf packet.Opcode = &HA100 Then ' Version response
Dim result As Byte = packet.ReadUInt8()
If result = 1 Then
If locale = 18 Then ' ISRO
Dim response As New Packet(&H6107, True, False) ' Request ping servers
security.Send(response)
Else
do_stats = True
stats_timer.Start()
Dim response As New Packet(&H6101, True) ' Request server list
security.Send(response)
End If
Else
result = packet.ReadUInt8()
If result = 2 Then ' Updates available
Dim ip As String = packet.ReadAscii()
Dim port As UShort = packet.ReadUInt16()
Dim new_version As UInt32 = packet.ReadUInt32()
Dim new_file As Byte = packet.ReadUInt8()
While new_file = 1
Dim file_id As UInt32 = packet.ReadUInt32()
Dim file_name As String = packet.ReadAscii()
Dim file_path As String = packet.ReadAscii()
Dim file_size As UInt32 = packet.ReadUInt32()
Dim file_pk2 As Byte = packet.ReadUInt8()
new_file = packet.ReadUInt8()
End While
version = new_version
Throw New Exception(String.Format("A new version is available."))
ElseIf result = 4 Then ' Server down
Throw New Exception(String.Format("The GatewayServer is closed."))
ElseIf result = 5 Then ' Version too old
version = version + 1 ' Try to correct it
Throw New Exception(String.Format("The version is too old."))
ElseIf result = 1 Then ' Version too new
version = version - 1 ' Try to correct it
Throw New Exception(String.Format("The version is too new."))
Else
' Not much we can do here, user has to fix version their self.
Throw New Exception(String.Format("Unhandled response {0}.", result))
End If
End If
ElseIf packet.Opcode = &HA107 Then ' Ping server response
Dim count As Byte = packet.ReadUInt8()
For x As Int32 = 0 To count - 1
Dim id As Byte = packet.ReadUInt8()
Dim host As String = packet.ReadAscii()
Dim port As UShort = packet.ReadUInt16()
Next
do_stats = True
stats_timer.Start()
Dim response As New Packet(&H6101, True) ' Request server list
security.Send(response)
ElseIf packet.Opcode = &HA101 Then ' Server list
Dim new_entry As Byte = packet.ReadUInt8()
While new_entry = 1
Dim id As Byte = packet.ReadUInt8()
Dim name As String = packet.ReadAscii()
new_entry = packet.ReadUInt8()
End While
new_entry = packet.ReadUInt8()
While new_entry = 1
Dim id As UShort = 0
Dim ratio As Single = 0
Dim name As String = ""
Dim country As Char = "?"
Dim state As Byte = 0
Dim cur As UShort = 0
Dim max As UShort = 0
Dim extra1 As Byte = 0
Dim extra2 As Byte = 0
id = packet.ReadUInt16()
If locale = 18 Then
name = packet.ReadAscii()
ElseIf locale = 12 Then
name = packet.ReadAscii(950)
ElseIf locale = 40 Then
name = packet.ReadAscii(1251)
ElseIf locale = 2 Then
name = packet.ReadAscii(949)
ElseIf locale = 4 Then
name = packet.ReadAscii(936)
ElseIf locale = 23 Then
name = packet.ReadAscii(936)
ElseIf locale = 38 Then
name = packet.ReadAscii()
Else
Throw New Exception(String.Format("This program does not support the locale {0} yet.", locale))
' name = packet.ReadAscii() ' Or comment out the line above and uncomment this one...
End If
If locale = 18 Then
country = name(0)
name = name.Remove(0, 1)
ratio = packet.ReadSingle()
Else
cur = packet.ReadUInt16()
max = packet.ReadUInt16()
End If
state = packet.ReadUInt8()
' Binds the server to the name server at the start of the packet.
If locale = 4 Or locale = 23 Then
extra1 = packet.ReadUInt8()
If extra1 = 1 Then
extra2 = packet.ReadUInt8()
End If
End If
new_entry = packet.ReadUInt8()
If locale = 18 Then
Dim status As String
If state = 1 Then
status = "Open"
Else
status = "Check"
End If
Dim country2 As String
If country = "0" Then
country2 = "Korea"
ElseIf country = "1" Then
country2 = "USA"
Else
country2 = "<Unknown>"
End If
Console.WriteLine("[{0}] [{4}] {1} ({2}% full) [{3}]", id, name, ratio * 100.0F, status, country2)
Else
Dim status As String
If state = 1 Then
status = "Open"
Else
status = "Check"
End If
' Default windows console with code page 1252 cannot display Unicode characters,
' so you will see ?'s. The string is correct though if you debug and check the name
Console.WriteLine("[{0}] {1} {2} / {3} [{4}]", id, name, cur, max, status)
End If
End While
last_stats_timer.Reset()
last_stats_timer.Start()
End If
Next
End If
Catch ex As Exception
Console.WriteLine("Error: Could not parse the data from the server." + Environment.NewLine + Environment.NewLine + ex.Message)
Console.WriteLine("This is error # {0}. Waiting {1} ms then trying again..." + Environment.NewLine, parse_errors, reconnect_time)
Thread.Sleep(reconnect_time)
Exit While
End Try
' Send network data
Try
' Check to see if we have any buffers to send
Dim buffers As List(Of KeyValuePair(Of TransferBuffer, Packet)) = security.TransferOutgoing()
If buffers Is Nothing Then
Else
For Each kvp As KeyValuePair(Of TransferBuffer, Packet) In buffers
Dim buffer As TransferBuffer = kvp.Key
Dim packet As Packet = kvp.Value
Dim err As SocketError = SocketError.Success
' Debugging
Dim bytes As Byte() = packet.GetBytes()
Console.WriteLine("[C->S][0x{0:X4}][{1} bytes][Enc: {2}][Msv: {3}]", packet.Opcode, bytes.Length, packet.Encrypted, packet.Massive)
' Since TCP is a stream protocol, we have to support partial sends. To do this, we
' will just loop until we send all the data or an exception is generated.
While buffer.Offset <> buffer.Size
Dim sent As Int32 = s.Send(buffer.Buffer, buffer.Offset, buffer.Size - buffer.Offset, SocketFlags.None, err)
If err <> SocketError.Success Then
If err <> SocketError.WouldBlock Then
Throw New Exception(String.Format("Send returned error code {0}.", err))
End If
End If
buffer.Offset += sent
Thread.Sleep(1)
End While
' If we should be pinging, we can reset the ping timer since data was sent.
If do_ping = True Then
ping_timer.Reset()
ping_timer.Start()
End If
Next
End If
Catch ex As Exception
send_errors = send_errors + 1
Console.WriteLine("Error: Could not send data from the server." + Environment.NewLine + Environment.NewLine + ex.Message)
Console.WriteLine("This is error # {0}. Waiting {1} ms then trying again..." + Environment.NewLine, send_errors, reconnect_time)
Thread.Sleep(reconnect_time)
Exit While
End Try
' Main state logic checks
Try
' Send the ping packet every 5s there is no other send.
If do_ping = True Then
If ping_timer.ElapsedMilliseconds >= 5000 Then
' We also set the time so we don't accidentally "multi-ping". That shouldn't
' happen in this program with a single thread, but it's an issue to look out for.
ping_timer.Reset()
ping_timer.Start()
Dim response As New Packet(&H2002) ' Ping packet
security.Send(response)
End If
End If
' Request stats each interval
If do_stats = True Then
If stats_timer.ElapsedMilliseconds >= stats_interval Then
stats_timer.Reset()
stats_timer.Start()
Dim response As New Packet(&H6101, True) ' Request server list
security.Send(response)
End If
End If
If last_stats_timer.ElapsedMilliseconds > stats_timeout Then
Throw New Exception(String.Format("No server list has been received in {0} ms.", last_stats_timer.ElapsedMilliseconds))
End If
Catch ex As Exception
misc_errors = misc_errors + 1
Console.WriteLine("Error: A misc error was encountered." + Environment.NewLine + Environment.NewLine + ex.Message)
Console.WriteLine("This is error # {0}. Waiting {1} ms then trying again..." + Environment.NewLine, misc_errors, reconnect_time)
Thread.Sleep(reconnect_time)
Exit While
End Try
End While
End Using
End While
Console.WriteLine("Status: The program is now exiting...")
End Sub
End Module
That's about it really, if you are familiar with VB.Net, then using the API shouldn't be too hard based on this example. The .Net class library system takes cares of most things for you. There might be easier/simpler/better ways to implement the code than I have shown, so keep that in mind. I'm not a VB.Net programmer, this is just an example for API usage!






