Silkroad Security API

06/07/2011 23:58 prot3ctor#1
i was trying to run the server_stats example but it just immediately closeed and i cant figure out why..
also i think i need ti configure the ip or port? where can i do this?

edit: I've found the error.. Index was Outside the bounds of the array line 33

the code:
Quote:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Runtime.InteropServices;
using SilkroadSecurityApi;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
try
{
Security security = new Security();
TransferBuffer recv_buffer = new TransferBuffer(4096, 0, 0);
List<Packet> packets = new List<Packet>();
Stopwatch ping_timer = new Stopwatch();
bool do_ping = false;
Stopwatch stats_timer = new Stopwatch();
bool do_stats = false;
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
uint version = UInt32.Parse(args[2]);
uint locale = UInt32.Parse(args[3]);

// Blocking connect to the server first, exception thrown on error
s.Connect(args[0], Int32.Parse(args[1]));

// Now make it non-blocking + disable nagle's algo
s.Blocking = false;
s.NoDelay = true;

while (!Console.KeyAvailable)
{
SocketError err;

// Receive logic, try to receive as much as possible, then pass to the security object
recv_buffer.Size = s.Receive(recv_buffer.Buffer, 0, recv_buffer.Buffer.Length, SocketFlags.None, out err);
if (err != SocketError.Success)
{
if (err != SocketError.WouldBlock)
{
Console.WriteLine("Error: Receive returned error code {0}.", err);
break;
}
}
else
{
if (recv_buffer.Size > 0)
{
security.Recv(recv_buffer);
}
else
{
Console.WriteLine("Status: The connection has been closed.");
break;
}
}

// Obtain all queued packets and add them to our own queue to process later.
List<Packet> tmp_packets = security.TransferIncoming();
if(tmp_packets != null)
{
packets.AddRange(tmp_packets);
}

if (packets.Count > 0)
{
foreach (Packet packet in packets)
{
byte[] packet_bytes = packet.GetBytes();

// Debug
Console.WriteLine("[S->C][{0:X4}][{1} bytes]{2}{3}{4}{5}{6}", packet.Opcode, packet_bytes.Length, packet.Encrypted ? "[Encrypted]" : "", packet.Massive ? "[Massive]" : "", Environment.NewLine, Utility.HexDump(packet_bytes), Environment.NewLine);

// Identify
if (packet.Opcode == 0x2001)
{
Packet response = new Packet(0x6100, true, false);
response.WriteUInt8(locale);
response.WriteAscii("SR_Client");
response.WriteUInt32(version);
security.Send(response);

do_ping = true;
ping_timer.Start();
}

// Version response
else if (packet.Opcode == 0xA100)
{
byte result = packet.ReadUInt8();
if (result == 1)
{
if (locale == 18)
{
Packet response = new Packet(0x6107, true, false);
security.Send(response);
}
else
{
do_stats = true;
stats_timer.Start();

Packet response = new Packet(0x6101, true);
security.Send(response);
}
}
else
{
result = packet.ReadUInt8();
if (result == 0x02) // Updates available
{
String ip = packet.ReadAscii();
ushort port = packet.ReadUInt16();
uint new_version = packet.ReadUInt32();

Console.WriteLine("New Version Avaliable -- [{0}][{1}:{2}]", new_version, ip, port);

byte new_file = packet.ReadUInt8();
while (new_file == 1)
{
uint file_id = packet.ReadUInt32();
String file_name = packet.ReadAscii();
String file_path = packet.ReadAscii();
uint file_size = packet.ReadUInt32();
byte file_pk2 = packet.ReadUInt8();
new_file = packet.ReadUInt8();

Console.WriteLine("[{0}][{1}][{2}] {3} bytes {4}", file_id, file_name, file_path, file_size, file_pk2 == 1 ? "(pk2)" : "");
}
}
else if (result == 0x04) // Server down
{
Console.WriteLine("The GatewayServer is closed.");
}
else if (result == 0x05) // Version too old
{
Console.WriteLine("The version is too old.");
}
else if (result == 0x01) // Version too new
{
Console.WriteLine("The version is too new.");
}
else
{
Console.WriteLine("Unknown response {0}.", result);
}
s.Disconnect(false);
}
}

// Location response
else if (packet.Opcode == 0xA107)
{
byte count = packet.ReadUInt8();
for (int x = 0; x < count; ++x)
{
byte id = packet.ReadUInt8();
string host = packet.ReadAscii();
ushort port = packet.ReadUInt16();

Console.WriteLine("[{0}] {1}:{2}", id, host, port);
}

Console.WriteLine("");

do_stats = true;
stats_timer.Start();

Packet response = new Packet(0x6101, true);
security.Send(response);
}

// Server stats
else if (packet.Opcode == 0xA101)
{
byte new_entry = packet.ReadUInt8();
while (new_entry == 1)
{
byte id = packet.ReadUInt8();
string name = packet.ReadAscii();
new_entry = packet.ReadUInt8();

Console.WriteLine("[{0}] {1}", id, name);
}

new_entry = packet.ReadUInt8();
while (new_entry == 1)
{
ushort id = 0;
float ratio = 0;
string name = null;
char country = '?';
byte state = 0;
ushort cur = 0;
ushort max = 0;
byte extra1 = 0;
byte extra2 = 0;

id = packet.ReadUInt16();

if (locale == 18)
{
name = packet.ReadAscii();
}
else if (locale == 40)
{
name = packet.ReadAscii(1251);
}
else if (locale == 2)
{
name = packet.ReadAscii(949);
}
else if (locale == 4)
{
name = packet.ReadAscii(936);
}
else if (locale == 23)
{
name = packet.ReadAscii(936);
}
else if (locale == 38)
{
name = packet.ReadAscii();
}

if (locale == 18)
{
country = name[0];
name = name.Remove(0, 1);
ratio = packet.ReadSingle();
}
else
{
cur = packet.ReadUInt16();
max = packet.ReadUInt16();
}

state = packet.ReadUInt8();

if (locale == 4 || locale == 23)
{
extra1 = packet.ReadUInt8();
if (extra1 == 1)
{
extra2 = packet.ReadUInt8();
}
}

new_entry = packet.ReadUInt8();

if (locale == 18)
{
Console.WriteLine("[{0}] [{4}] {1} ({2}% full) [{3}]", id, name, ratio * 100.0f, state == 1 ? "Open" : "Check", country == '0' ? "Korea" : "USA");
}
else
{
Console.WriteLine("[{0}] {1} {2} / {3} [{4}]", id, name, cur, max, state == 1 ? "Open" : "Check");
}
}

Console.WriteLine("");
}
}
packets.Clear();
}

// Check to see if we have any packets to send
List<KeyValuePair<TransferBuffer, Packet>> tmp_buffers = security.TransferOutgoing();
if (tmp_buffers != null)
{
foreach (var kvp in tmp_buffers)
{
TransferBuffer buffer = kvp.Key;
Packet packet = kvp.Value;

err = SocketError.Success;

// 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)
{
int sent = s.Send(buffer.Buffer, buffer.Offset, buffer.Size - buffer.Offset, SocketFlags.None, out err);
if (err != SocketError.Success)
{
if (err != SocketError.WouldBlock)
{
Console.WriteLine("Error: Send returned error code {0}.", err);
break;
}
}
buffer.Offset += sent;
Thread.Sleep(1);
}

// We need to check for an error to break out of the foreach loop
if (err != SocketError.Success)
{
break;
}

byte[] packet_bytes = packet.GetBytes();

// Debug (logical packet)
//Console.WriteLine("*** Logical ***");
Console.WriteLine("[C->S][{0:X4}][{1} bytes]{2}{3}{4}{5}{6}", packet.Opcode, packet_bytes.Length, packet.Encrypted ? "[Encrypted]" : "", packet.Massive ? "[Massive]" : "", Environment.NewLine, Utility.HexDump(packet_bytes), Environment.NewLine);

// Debug (physical packet)
//Console.WriteLine("*** Physical ***");
//Console.WriteLine("[C->S][{0} bytes]{1}{2}{3}", packet_bytes.Length, Environment.NewLine, Utility.HexDump(buffer.Buffer), Environment.NewLine);

// If we should be ping'ing, we can reset the ping timer
if (do_ping)
{
ping_timer.Reset();
ping_timer.Start();
}
}

// We need to check for an error to break out of the main loop
if (err != SocketError.Success)
{
break;
}
}

// Send the ping packet every 5s there is no other send
if (do_ping)
{
if (ping_timer.ElapsedMilliseconds > 5000)
{
ping_timer.Reset();
ping_timer.Start();

Packet response = new Packet(0x2002);
security.Send(response);
}
}

// Request stats each 15s
if (do_stats)
{
if (stats_timer.ElapsedMilliseconds > 15000)
{
stats_timer.Reset();
stats_timer.Start();

Packet response = new Packet(0x6101, true);
security.Send(response);
}
}

// Prevent 100% cpu use since this is a simple example
Thread.Sleep(1);
}

s.Shutdown(SocketShutdown.Both);
s.Close();
}
catch (System.Exception ex)
{
Console.WriteLine("Exception: {0}", ex);
}
}
}
}
06/08/2011 09:39 kevin_owner#2
Code:
// Blocking connect to the server first, exception thrown on error
s.Connect(args[0], Int32.Parse(args[1]));
I guess it's this part. the program needs to be runned in a command prompt with arguments. you can change these args to hardcoded ones. btw the code works fine for me so the code doesn't have a problem.
06/08/2011 14:05 lesderid#3
Quote:
Originally Posted by kevin_owner View Post
Code:
// Blocking connect to the server first, exception thrown on error
s.Connect(args[0], Int32.Parse(args[1]));
you can change these args to hardcoded ones.
Or you can add them to the debug start in VS.
06/08/2011 14:10 prot3ctor#4
so what do i need to do to get no errors?
06/08/2011 22:03 prot3ctor#5
help please
06/09/2011 00:53 pushedx#6
Quote:
Originally Posted by prot3ctor View Post
so what do i need to do to get no errors?
Examples of valid command lines are included in my code at the top. The order is simply: host port version locale

To set a command line inside Visual Studio, right click on the project, go to properties, click Debug, and type in the command line to the "Command line arguments" box.

If you don't want command line arguments, simply replace the "args" variables with your values. Everything is at the top, so you shouldn't have to do much work to change it.