Valhalla Legends Archive

Programming => Battle.net Bot Development => Topic started by: Smarter on March 23, 2007, 07:38 AM

Title: Conversion Problem...
Post by: Smarter on March 23, 2007, 07:38 AM
I am attempting to convert a Parser/Buffer written by Joe in VB6 to C#, however I am having a few problems..:

VB6:

Private Sub wsBNET_DataArrival(ByVal bytesTotal As Long)
    wsBNET.GetData s, 8
    If CBool(InStr(1, s, vbCrLf)) Then
        Dim Splt() As String, i As Integer
        Splt = Split(s, vbCrLf)
        For i = LBound(Splt) To UBound(Splt)
            If Not CStr(Splt(i)) = "" Then Call ParseBNET(CStr(Splt(i)))
        Next i
    Else
        If Not CStr(s) = "" Then Call ParseBNET(CStr(s))
    End If
End Sub


My Attempt:

            while (sck.Connected)
            {
                byte[] packetData;
                string[] strData;
                try
                {
                    packetData = Recieve(8);
                    strData = Convert.ToString(packetData);
                    if (strData[0].Contains(Environment.NewLine))
                    {
                        foreach (string s in strData)
                        {
                            string[] dataSplit = s.Split(Environment.NewLine);
                            for (int i = 0; i < dataSplit.Length; i++)
                            {
                                main.ParseDATA(dataSplit[i]);
                            }
                        }
                    }
                    else
                    {
                        if (strData != null) { main.ParseDATA(strData); }
                    }
                }
                catch (SocketException)
                {
                }
            }


You'll notice that if (strData[0].Contains(Environment.NewLine)) is merely a substiture, seeing as you can only preform the Contains operation on a string, not a string array (that would be one of my conversion issues). What my main question would probably be is... is all of this nesscary just to Parse some TEXT?
Title: Re: Conversion Problem...
Post by: rabbit on March 23, 2007, 09:35 AM
Why are you using a string array?
Title: Re: Conversion Problem...
Post by: MyndFyre on March 23, 2007, 10:55 AM
It occurred to me earlier, when I saw this, that you don't really need to be using something so high-level.  If I could suggest an alternative:


        Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        s.Connect("useast.battle.net", 6112);
        s.Send(new byte[] { 3 });
        NetworkStream ns = new NetworkStream(s);
        StreamReader sr = new StreamReader(ns, Encoding.ASCII);

        ThreadStart ts = delegate
        {
            string st = null;
            while (st = sr.ReadLine() && s.Connected)
            {
                Console.WriteLine(st);
            }
        };
        Thread td = new Thread(ts);
        td.Start();
        StreamWriter sw = new StreamWriter(ns, Encoding.ASCII);
        sw.WriteLine("username");
        sw.WriteLine("password");

It should be pretty clear from that how to get a NetworkStream from your existing Socket object, and from that, a StreamReader and StreamWriter.  And, it does all the reading from the server in a background thread so that your UI isn't blocking from the pending I/O request.

:)
Title: Re: Conversion Problem...
Post by: Smarter on March 23, 2007, 12:05 PM
You have a slight error:

            while (st = sr.ReadLine() && s.Connected)

Should be:

while (s.Connected)
{
    st = sr.ReadLine();

otherwise you get a compile error, because operator && cannot be applied to string and bool.
Title: Re: Conversion Problem...
Post by: MyndFyre on March 23, 2007, 06:39 PM
Yeah, sorry, I confused StreamReader and IDataReader.  :)
Title: Re: Conversion Problem...
Post by: Smarter on March 24, 2007, 12:27 PM
Well, it's not working, my StreamReader pulls back "" then nothing else. Here's my coding:


using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Drawing;
using System.Runtime.InteropServices;
using System.IO;

namespace SmartRecon
{
    class Connection
    {
        private Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        private NetworkStream ns;
        private StreamReader sr;
        private StreamWriter sw;
        private frmMain main;
        private ThreadStart ts;
        private string user;

        public Connection(frmMain form)
        {
            main = form;
        }

        public void StartConnection(string Server, string Username, string Password)
        {
            user = Username;
            s.Connect(Server, 6112);
            ns = new NetworkStream(s);
            sr = new StreamReader(ns, Encoding.ASCII);
            sw = new StreamWriter(ns, Encoding.ASCII);
            ts = new ThreadStart(tStart);
            s.Send(new byte[] { 3 });
            Thread td = new Thread(ts);
            sw.WriteLine(Username);
            sw.WriteLine(Password);
            main.AddChat("Sending Username and Password...", Color.LightGreen);
            td.Start();
        }

        public void sText(string text)
        {
            sw.WriteLine(text);
            main.AddChat("<" + user + "> " + text, Color.LightBlue);
        }

        public void tStart()
        {
            string st = null;
            while (s.Connected)
            {
                st = sr.ReadLine();
                string[] stSplt = st.Split(' ');
                #region Parser
                switch (stSplt[1])
                {
                    case "NAME":
                        main.AddChat("Successfully logged on as: " + stSplt[2], Color.Green);
                        break;
                    case "CHANNEL":
                        main.AddChat("Joined Channel: ", Color.Yellow);
                        // do something else here.. " & GetString(sData) & ".")
                        // lblChannel.Caption = GetString(sData)
                        // lvChannel.ListItems.Clear
                        break;
                    case "USER":
                        //main.AddChat("User " + stSplt[2] + " has joined the channel, using " + stSplt[4] + ".", Color.DarkGreen);
                        main.AddUser(stSplt[2]);
                        //Call lvChannel.ListItems.Add(, , Splt(2))
                        break;
                    case "INFO":
                        main.AddChat(stSplt[2], Color.SteelBlue);
                        break;
                    case "ERROR":
                        main.AddChat(stSplt[2], Color.DarkRed);
                        break;
                    case "TALK":
                        main.AddChat("<" + stSplt[2] + "> " + stSplt[4], Color.White);
                        break;
                    case "JOIN":
                        string game = stSplt[4].Replace("[", ""); stSplt[4].Replace("]", "");
                        main.AddChat(stSplt[2] + " has joined the channel using " + game + ".", Color.DarkGreen);
                        main.AddUser(stSplt[2]);
                        break;
                    case "LEAVE":
                        main.AddChat(stSplt[2] + " has left the channel.", Color.Yellow);
                        main.RemUser(stSplt[2]);
                        break;
                }
                #endregion
            }
        }
    }
}


I get my error at:

                st = sr.ReadLine();
                string[] stSplt = st.Split(' ');
                #region Parser
                switch (stSplt[1]) -------


It says my index is out of bounds, which doesn't make sense, as I had already sent the data, and i'm connected, so what am I doing wrong here >.<...
Title: Re: Conversion Problem...
Post by: Hdx on March 24, 2007, 12:30 PM
It should be stSplit[0] not [1]
The first thing you are getting is "Username:" If i recall correctly. Which dosen't have a space in it, hence Index out fo bounds.
~Hdx
Title: Re: Conversion Problem...
Post by: MyndFyre on March 24, 2007, 02:21 PM
We found out the problem.  Apparently you need to call Flush() on StreamWriter after you write with it.

Here's the complete code to what I wrote this morning:


using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Net;
using System.Threading;

namespace BncsCHAT
{
    class Program
    {
        private static Socket s_sck;
        private static NetworkStream s_ns;
        private static StreamReader s_sr;
        private static StreamWriter s_sw;

        static void Main(string[] args)
        {
            Console.WriteLine("Connect to which server?");
            string server = Console.ReadLine();
            IPHostEntry iphe = Dns.Resolve(server);
            s_sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            s_sck.Connect(iphe.AddressList[0], 6112);
            Console.WriteLine("Connected!");

            s_sck.Send(new byte[] { 3 });
            s_ns = new NetworkStream(s_sck);
            s_sr = new StreamReader(s_ns, Encoding.ASCII);
            s_sw = new StreamWriter(s_ns, Encoding.ASCII);

            Thread td = new Thread(ListenerThread);
            td.Start();

            string input = string.Empty;
            while (StringComparer.InvariantCultureIgnoreCase.Compare(input, "/quit") != 0)
            {
                input = Console.ReadLine();
                s_sw.WriteLine(input);
                s_sw.Flush();
            }

            Console.WriteLine("Disconnecting...");
            s_sck.Disconnect(false);
            Console.ReadLine();
        }

        private static void ListenerThread()
        {
            while (s_sck.Connected)
            {
                string fromServer = s_sr.ReadLine();
                DateTime dt = DateTime.Now;
                Console.WriteLine("[{0:d2}:{1:d2}:{2:d2}] {3}", dt.Hour, dt.Minute, dt.Second, fromServer);
            }
        }
    }
}
Title: Re: Conversion Problem...
Post by: Smarter on March 24, 2007, 03:10 PM
Once finished I think i'll post my entire code on here in the C# section, it's a nice place for C# programmers to start.