Newer
Older
Import / projects / Gameloft / bne_lib / tools / AutobotManager / src / ATcpClient.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Timers;


namespace AutobotManager
{
    public enum ATcpClientState
    {
        Idle,
        Getting_MessageSize,
        Getting_Message,
    };

    public class ATcpClient
    {

        #region Data
        private Form1 m_pParentForm;
        private ClientCaller m_oClientTcpCaller;
        private ATcpClientState m_eTcpClientState;
        private int m_iMessageCount;
        private String m_sMachineSummary;
        public String MachineShortID { get; set; }
        #endregion // Data

        public ATcpClient(Form1 a_pParentForm)
        {
            m_pParentForm = a_pParentForm;
            m_iMessageCount = 0;

            SetMachineSummary();
            CreateNewClientTCPProcess();
        }

        private void CreateNewClientTCPProcess()
        {
            m_eTcpClientState = ATcpClientState.Idle;
            System.Net.IPAddress[] oaIPAddresses = System.Net.Dns.GetHostAddresses(Properties.Settings.Default.AutobotServer);
            String sip4Address = "127.0.0.1";
            if (null != oaIPAddresses)
            {
                foreach (System.Net.IPAddress ipv4 in oaIPAddresses)
                {
                    if (ipv4.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                    {
                        sip4Address = ipv4.ToString();
                    }
                }
            }

            m_oClientTcpCaller = new ClientCaller(m_pParentForm, sip4Address, Properties.Settings.Default.AutobotServerPort);
            m_oClientTcpCaller.TcpOutReceived += new TcpDataReceivedHandler(this.TcpOutputStream);
            m_oClientTcpCaller.TcpErrorReceived += new TcpDataReceivedHandler(this.TcpErrorStream);
            m_oClientTcpCaller.HasDataEventCB += new HasDataHandler(this.HasData);
            m_oClientTcpCaller.Completed += new EventHandler(this.processCompletedOrCanceled);
            m_oClientTcpCaller.Cancelled += new EventHandler(this.processCompletedOrCanceled);
            m_oClientTcpCaller.Start();
        }

        public void SetMachineSummary()
        {
            String myIp = "";
            var host = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName());
            foreach (var ip in host.AddressList)
            {
                if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                {
                    myIp = ip.ToString();
                }
            }
            string sEnvCompName = System.Environment.GetEnvironmentVariable("COMPUTERNAME");
            m_sMachineSummary = sEnvCompName + ",";
            m_sMachineSummary = m_sMachineSummary + System.Environment.MachineName + ",";
            m_sMachineSummary = m_sMachineSummary + System.Net.Dns.GetHostName() + ",";
            m_sMachineSummary = m_sMachineSummary + "[" + myIp + "]";

            if (sEnvCompName.Length > 0)                        {   MachineShortID = sEnvCompName;                      }
            else if(System.Environment.MachineName.Length > 0)  {   MachineShortID = System.Environment.MachineName;    }
            else if(myIp.Length > 0)                            {   MachineShortID = myIp;                              }
            else if (System.Net.Dns.GetHostName().Length > 0)   {   MachineShortID = System.Net.Dns.GetHostName();      }
            else
            {
                MachineShortID = "praveen";
            }
        }

        public void UpdateServer()
        {
            if (null == m_oClientTcpCaller)
            {
                CreateNewClientTCPProcess();
            }
            else
            {
                string sMachine = "machine " + m_sMachineSummary;
                SendMessage(sMachine);

                string sData = "summary " + m_pParentForm.m_BotManager.GetSummary();
                SendMessage(sData);
            }
        }

        public void SendMessage(string a_Msg)
        {
            if (null != m_oClientTcpCaller && m_oClientTcpCaller.IsConnected())
            {
                //24 byte header
                string sMsgHeader = "Praveen_" + a_Msg.Length.ToString("D8") + "_" + m_iMessageCount.ToString("D7");
                m_oClientTcpCaller.SendData(sMsgHeader + a_Msg);
                ++m_iMessageCount;
            }
        }

        public void HasData(object sender, TcpDataReceivedEventArgs e)
        {
            if (null==m_oClientTcpCaller || m_oClientTcpCaller != sender)
            {
                return;
            }
            if (m_eTcpClientState == ATcpClientState.Idle)
            {
                if (m_oClientTcpCaller.ReadAmount(24))
                {
                    m_eTcpClientState = ATcpClientState.Getting_MessageSize;
                }
            }
        }

        private void ResetTcpConnection()
        {
            if (null!=m_oClientTcpCaller)
            {
                m_oClientTcpCaller.Cancel();
                m_oClientTcpCaller = null;
            }
            m_eTcpClientState = ATcpClientState.Idle;
        }

        public void TcpErrorStream(object sender, TcpDataReceivedEventArgs e)
        {
            if (null != m_oClientTcpCaller && m_oClientTcpCaller == sender)
            {
                ResetTcpConnection();
            }
        }

        public void TcpOutputStream(object sender, TcpDataReceivedEventArgs e)
        {
            if (null == m_oClientTcpCaller || m_oClientTcpCaller != sender)
            {
                return;
            }
            if (m_eTcpClientState == ATcpClientState.Getting_MessageSize)
            {
                if (24 == e.Text.Length && e.Text.Substring(0, 8) == "Praveen_")
                {
                    int iSize = Convert.ToInt32(e.Text.Substring(8, 8));
                    if (m_oClientTcpCaller.ReadAmount(iSize))
                    {
                        m_eTcpClientState = ATcpClientState.Getting_Message;
                    }
                    else
                    {
                        ResetTcpConnection();
                    }
                }
                else
                {
                    ResetTcpConnection();
                }
            }
            else if (m_eTcpClientState == ATcpClientState.Getting_Message)
            {
                ProcessServerMessage(e.Text);
                m_eTcpClientState = ATcpClientState.Idle;
            }
        }

        public void processCompletedOrCanceled(object sender, EventArgs e)
        {
        }

        public void processFailed(object sender, System.Threading.ThreadExceptionEventArgs e)
        {
        }

        private void ProcessServerMessage(String a_sMsg)
        {
            m_pParentForm.Log_server_msg(a_sMsg);

            // we expect only 1 System Message per message from server and needs to be lowercase
            if(a_sMsg.StartsWith("system"))
            {
                string sCommand = a_sMsg.Substring(6);
                string sOutput = "sysresponse " + RunSystemCommand(sCommand);
                SendMessage(sOutput);
                return;
            }
            else if (a_sMsg.StartsWith("chat "))
            {
                string sCommand = a_sMsg.Substring(5);
                m_pParentForm.IncomingChatMsg(sCommand);
                return;
            }
            else if (a_sMsg.StartsWith("shutdown"))
            {
                m_pParentForm.Close();
                return;
            }

            String[] sList = a_sMsg.Split(',');
            foreach(var aCmd in sList)
            {
                string oCmd = aCmd.Trim();

                     if (oCmd.StartsWith("ping"))           {   SendMessage("pong");    }
                else if (oCmd.StartsWith("pong"))           {   /*ignore pong*/         }
                else if (oCmd.StartsWith("autocycle"))      {   m_pParentForm.SetAutoCycle(oCmd.EndsWith("on"));    }
                else if (oCmd.StartsWith("killallbots"))    {   m_pParentForm.Kill_All_Bots();                      }
                else if (oCmd.StartsWith("restartsim"))     {   m_pParentForm.RestartSimulation();                  }
                else if (oCmd.StartsWith("spawntimer")) 
                {
                    string[] sArray = oCmd.Split(' ');
                    if (sArray.Length == 2)
                    {
                        int iCount = 0;
                        if (Int32.TryParse(sArray[1], out iCount))
                        {
                            m_pParentForm.SetBotSpawnTimer(iCount);
                        }
                    }
                }
                else if (oCmd.StartsWith("botpair"))
                {
                    string[] sArray = oCmd.Split(' ');
                    if (sArray.Length == 3)
                    {
                        int iStyle = 0;
                        int iCount = 0;
                        if (Int32.TryParse(sArray[1], out iStyle) && Int32.TryParse(sArray[2], out iCount))
                        {
                            m_pParentForm.m_BotManager.SetBotPair(iStyle, iCount);
                        }
                    }
                }
                else if (oCmd.StartsWith("deathtimer"))
                {
                    string[] sArray = oCmd.Split(' ');
                    for(int i=1; i<sArray.Length; ++i)
                    {
                        int iCount = 0;
                        if (Int32.TryParse(sArray[i], out iCount))  {   m_pParentForm.SetDeathTimer(iCount);        }
                        else if (sArray[i].StartsWith("on"))        {   m_pParentForm.ActivateDeathTimer(true);     }
                        else if (sArray[i].StartsWith("off"))       {   m_pParentForm.ActivateDeathTimer(false);    }
                    }
                }
                else
                {
                    m_pParentForm.Log_server_msg("Error UnKnown Command:" + oCmd);
                }
            }
        }

        private string RunSystemCommand(String a_sCommand)
        {
            string sOutput = "";
            try
            {
                System.Diagnostics.Process process = new System.Diagnostics.Process();
                System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
                //startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
                startInfo.FileName = "cmd.exe";
                startInfo.Arguments = "/C " + a_sCommand;
                startInfo.RedirectStandardOutput = true;
                startInfo.UseShellExecute = false;
                process.StartInfo = startInfo;
                process.Start();
                process.WaitForExit();

                sOutput = process.StandardOutput.ReadToEnd();
            }
            catch (Exception e)
            {
                sOutput = sOutput + e.ToString();
            }
            return sOutput;
        }


    }
}