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 partial class Form1 : Form
{
#region Data
public String[] m_sCommandArgs;
public String[] m_sGamesList;
private bool m_bInternalUpdate;
private bool m_bBotFound;
private bool m_bInitialized;
public BotManager m_BotManager;
private System.Xml.XmlTextWriter m_Xmltw;
public ATcpClient m_TcpClient;
#endregion // Data
#region Form Events
public Form1()
{
m_bInitialized = false;
InitializeComponent();
m_bBotFound = false;
m_bInternalUpdate = true;
m_BotManager = new BotManager(this);
m_sGamesList = m_BotManager.GetGamesList();
if (m_sGamesList.Count() != 0)
{
cb_game.Items.AddRange(m_sGamesList);
cb_game.SelectedIndex = 0;
UpdateGameSelection();
}
m_BotManager.BindingRequiredItemsUi(dg_required_style);
m_TcpClient = new ATcpClient(this);
CreateNewXmlWriter();
launch_timer.Enabled = true;
launch_timer.Interval = (int)(n_launchDelay.Value * 1000);
cycle_timer.Enabled = true;
cycle_timer.Interval = (int)(n_Cycle_Bots_Freq.Value * 1000);
flush_timer.Enabled = true;
m_bInternalUpdate = false;
m_bInitialized = true;
}
private void Form1_Load(object sender, EventArgs e)
{
bool bAutoStartCycle = false;
bool bStartDeathTimer = false;
//Update from the command Line Parameters
if (null != m_sCommandArgs)
{
m_BotManager.UpdateFromCommandLine(m_sCommandArgs);
for (int i = 0; i < m_sCommandArgs.Length; i++)
{
if (0 == String.Compare(m_sCommandArgs[i], "--logfilter", true) && ((i + 1) < m_sCommandArgs.Length))
{
tb_log_filter.Text = m_sCommandArgs[i + 1];
}
else if (0 == String.Compare(m_sCommandArgs[i], "--launchdelay", true) && ((i + 1) < m_sCommandArgs.Length))
{
n_launchDelay.Value = Convert.ToDecimal(m_sCommandArgs[i + 1].ToUpper().Trim());
}
else if (0 == String.Compare(m_sCommandArgs[i], "--cycledelay", true) && ((i + 1) < m_sCommandArgs.Length))
{
n_Cycle_Bots_Freq.Value = Convert.ToDecimal(m_sCommandArgs[i + 1].ToUpper().Trim());
}
else if (0 == String.Compare(m_sCommandArgs[i], "--cyclecount", true) && ((i + 1) < m_sCommandArgs.Length))
{
int iCount = Convert.ToInt32(m_sCommandArgs[i + 1].ToUpper().Trim());
n_Cycle_Bots.Value = Convert.ToDecimal(iCount);
}
else if (0 == String.Compare(m_sCommandArgs[i], "--deathtimer", true) && ((i + 1) < m_sCommandArgs.Length))
{
int iCount = Convert.ToInt32(m_sCommandArgs[i + 1].ToUpper().Trim());
n_Death_Time.Value = Convert.ToDecimal(iCount);
bStartDeathTimer = true;
}
else if (0 == String.Compare(m_sCommandArgs[i], "--startcycle", true))
{
bAutoStartCycle = true;
}
else if (0 == String.Compare(m_sCommandArgs[i], "--botargs", true) && ((i + 1) < m_sCommandArgs.Length))
{
tb_args.Text = m_sCommandArgs[i + 1].ToUpper().Trim();
}
}
}
UpdateInternal();
checkBox_deathtimer.Checked = bStartDeathTimer;
checkBox_Cycle.Checked = bAutoStartCycle;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
checkBox_deathtimer.Checked = false;
checkBox_Cycle.Checked = false;
m_BotManager.KillAllBots();
if(m_BotManager.GetBotCount() > 0)
{
CloseDialog oClose = new CloseDialog(this);
if (oClose.ShowDialog() == DialogResult.Cancel)
{
e.Cancel = true;
return;
}
}
m_Xmltw.WriteEndElement();
m_Xmltw.Close();
}
#endregion
#region Helpers
// Append text of the given color.
void AppendText(RichTextBox box, Color color, string text)
{
int iTextLength = text.Length;
if (0 == iTextLength)
{
return;
}
int start = box.TextLength;
box.AppendText(text);
int end = box.TextLength;
box.Select(start, end - start);
box.SelectionColor = color;
int iExcess = end - 10000;
if (iExcess > 0)
{
box.Select(0, iExcess + 3);
box.SelectedText = "...";
}
box.Select(box.Text.Length - 1, 0);
box.ScrollToCaret();
}
void SetText(TextBox textbox, Label label, bool bValid, string sNewText)
{
if (!bValid)
{
textbox.Text = sNewText;
textbox.ForeColor = Color.Red;
label.ForeColor = Color.Red;
}
else if (sNewText != textbox.Text)
{
textbox.Text = sNewText;
textbox.ForeColor = Color.Blue;
label.ForeColor = Color.Blue;
}
else
{
textbox.ForeColor = Color.Black;
label.ForeColor = Color.Black;
}
}
bool IsFiltered(string s_Data, string s_filter)
{
String[] saResult = s_filter.Trim().ToUpper().Split(',');
if (null == saResult || 0 == saResult.Count())
{
return true;
}
s_Data = s_Data.ToUpper();
foreach (var stext in saResult)
{
if (s_Data.Contains(stext.Trim()))
{
return true;
}
}
return false;
}
public void MyLog(BotClass a_Bot, String a_sEntry, bool a_bError, bool a_bForceLog)
{
if(a_sEntry.Trim().Length > 0)
{
// Display on our Gui Console
bool bAllow = false;
if( (checkBox_display_out.Checked && !a_bError)
|| (checkBox_ErrorStream.Checked && a_bError)
|| ((checkBox_ErrorStream.Checked || checkBox_display_out.Checked) && a_bForceLog)
)
{
bAllow = IsFiltered(a_sEntry, tb_output_filter.Text) && IsSelectedBot(a_Bot.BotInctanceId);
if(bAllow)
{
String sDisplay = "\n[Bot_" + a_Bot.BotInctanceId.ToString() + "] " + a_sEntry;
Color oColor = (a_bError) ? Color.Red : Color.MidnightBlue;
AppendText(this.rt_Output, oColor, sDisplay);
}
}
// Write to Log
if (a_bForceLog || IsFiltered(a_sEntry, tb_log_filter.Text))
{
String sType = a_bError ? "Error" : "Log";
double fTimeElapsed = DateTime.Now.Subtract(a_Bot.StartTime).TotalSeconds;
fTimeElapsed = Math.Truncate(fTimeElapsed * 100) / 100;
string sTimeElapsed = string.Format("{0:N2}s", fTimeElapsed);
m_Xmltw.WriteStartElement("Bot_" + a_Bot.BotInctanceId.ToString());
m_Xmltw.WriteAttributeString("id", a_Bot.BotId.ToString());
m_Xmltw.WriteAttributeString("type", sType);
m_Xmltw.WriteAttributeString("timestamp", DateTime.Now.ToString());
m_Xmltw.WriteAttributeString("timeelapsed", sTimeElapsed);
m_Xmltw.WriteString(a_sEntry);
m_Xmltw.WriteEndElement();
}
}
}
#endregion
#region Functions
void UpdateInternal()
{
if (m_bInternalUpdate)
{
return;
}
m_bInternalUpdate = true;
String sAbsApp = "";
m_bBotFound = false;
try
{
sAbsApp = System.IO.Path.GetFullPath(tb_application.Text);
m_bBotFound = System.IO.File.Exists(sAbsApp);
if (!m_bBotFound)
{
String sAppPath = System.IO.Path.GetDirectoryName(Application.ExecutablePath) + "\\" + tb_application.Text;
sAbsApp = System.IO.Path.GetFullPath(sAppPath);
m_bBotFound = System.IO.File.Exists(sAbsApp);
}
}
catch
{
m_bBotFound = false;
}
bt_Launch.Enabled = m_bBotFound;
lbl_AppPath.Text = sAbsApp;
lbl_AppPath.ForeColor = (m_bBotFound) ? Color.Blue : Color.Red;
//Update BotStyleManager
m_BotManager.UpdateArguments(sAbsApp, tb_args.Text, Convert.ToInt32(n_Prefix.Value));
tb_finalArgs.Text = m_BotManager.GetPreviewArgs(cb_simulation.SelectedIndex);
m_bInternalUpdate = false;
}
bool IsSelectedBot(int a_iD)
{
foreach (DataGridViewRow row in dg_botList.SelectedRows)
{
BotClass oBot = row.DataBoundItem as BotClass;
if (oBot.BotInctanceId == a_iD)
{
return true;
}
}
return false;
}
void CreateNewXmlWriter()
{
String sDateTimeNow = DateTime.Now.ToString();
String sLogFileName = "BotLog_" + sDateTimeNow;
Regex oRegex = new Regex("[^0-9A-Za-z]");
sLogFileName = oRegex.Replace(sLogFileName, "_");
String sLogAppPath = System.IO.Path.GetDirectoryName(Application.ExecutablePath) + "\\" + sLogFileName + ".log.xml";
this.Text = "Autobot Manager - " + sLogAppPath;
m_Xmltw = new System.Xml.XmlTextWriter(sLogAppPath, Encoding.UTF8);
m_Xmltw.Formatting = System.Xml.Formatting.Indented;
m_Xmltw.Indentation = 2;
m_Xmltw.WriteStartDocument();
m_Xmltw.WriteStartElement("Bots");
m_Xmltw.WriteAttributeString("timestamp", sDateTimeNow);
}
#endregion
private void tb_application_TextChanged(object sender, EventArgs e)
{
UpdateInternal();
}
private void tb_args_TextChanged(object sender, EventArgs e)
{
UpdateInternal();
}
private void numeric_Count_ValueChanged(object sender, EventArgs e)
{
UpdateInternal();
}
private void cb_simulation_SelectedIndexChanged(object sender, EventArgs e)
{
UpdateInternal();
}
private void n_Prefix_ValueChanged(object sender, EventArgs e)
{
UpdateInternal();
}
private void bt_Simulate_Click(object sender, EventArgs e)
{
bool bStartImmediately = (m_BotManager.GetBotCount() == 0);
for (int i = 0; i < numeric_Count.Value; ++i)
{
int iSim = cb_simulation.SelectedIndex;
m_BotManager.CreateBotofType(iSim);
}
if (checkBox_Cycle.Checked == false && bStartImmediately)
{
StartNextBot();
launch_timer.Stop();
launch_timer.Start();
}
}
private void StartNextBot()
{
BotClass oBot = m_BotManager.StartNextBot();
if (null != oBot)
{
MyLog(oBot, "STARTING", false, true);
}
}
private void btSelect_Click(object sender, EventArgs e)
{
dg_botList.SelectAll();
}
private void btUnSelect_Click(object sender, EventArgs e)
{
dg_botList.ClearSelection();
}
private void bt_killBots_Click(object sender, EventArgs e)
{
BindingList<BotClass> lSelectedItems = new BindingList<BotClass>();
foreach (DataGridViewRow row in dg_botList.SelectedRows)
{
BotClass oBot = row.DataBoundItem as BotClass;
lSelectedItems.Add(oBot);
}
m_BotManager.KillBots(lSelectedItems, false);
}
public void Kill_All_Bots()
{
m_BotManager.KillAllBots();
}
private void bt_killAll_Click(object sender, EventArgs e)
{
Kill_All_Bots();
}
private void n_launchDelay_ValueChanged(object sender, EventArgs e)
{
launch_timer.Interval = (int)(n_launchDelay.Value * 1000);
}
private void cycle_timer_Tick(object sender, EventArgs e)
{
if (checkBox_Cycle.Checked == true)
{
QueueNextCyclicBot();
}
}
private void launch_timer_Tick(object sender, EventArgs e)
{
StartNextBot();
}
private void QueueNextCyclicBot()
{
//0. Early out
if(!m_bBotFound)
{
return;
}
//1. Kill a few bots
int iTotalRequired = m_BotManager.GetTotalRequiredCount();
int iTotalRunning = m_BotManager.GetStateTotalCount(BotState.BotState_Running);
int iCycleLevel = Convert.ToInt32(n_Cycle_Bots.Value);
int iMinRequiredBots = iTotalRequired - iCycleLevel;
int iTotalKillable = (iTotalRunning > iMinRequiredBots) ? (iTotalRunning - iMinRequiredBots) : 0;
int iTotalKilled = m_BotManager.KillRandomRunningBots(iTotalKillable);
//2. Create Random bots from the requirements
int iCreateThisFrame = iTotalRequired - (m_BotManager.GetBotCount() - iTotalKilled);
while (--iCreateThisFrame >= 0)
{
int iSim = m_BotManager.GetNextRandomSimToLaunch();
m_BotManager.CreateBotofType(iSim);
}
}
public void SetAutoCycle(bool a_bSet)
{
checkBox_Cycle.Checked = a_bSet;
}
private void checkBox_Cycle_CheckedChanged(object sender, EventArgs e)
{
UpdateInternal();
if (checkBox_Cycle.Checked)
{
gb_auto_cycle.Text = "[ Auto Cycle - RUNNING ]";
checkBox_Cycle.ForeColor = Color.Red;
if (0 == m_BotManager.GetBotCount())
{
QueueNextCyclicBot();
}
}
else
{
gb_auto_cycle.Text = "[ Auto Cycle - Paused ]";
checkBox_Cycle.ForeColor = Color.Blue;
}
}
private void autolaunch_dg_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
UpdateInternal();
}
private void n_Cycle_Bots_Count_ValueChanged(object sender, EventArgs e)
{
UpdateInternal();
}
private void n_Cycle_Bots_ValueChanged(object sender, EventArgs e)
{
UpdateInternal();
}
private void n_Cycle_Bots_Freq_ValueChanged(object sender, EventArgs e)
{
cycle_timer.Interval = (int)(n_Cycle_Bots_Freq.Value * 1000);
}
private void flush_timer_Tick(object sender, EventArgs e)
{
m_Xmltw.Flush();
}
private void btn_NewLog_Click(object sender, EventArgs e)
{
m_Xmltw.WriteEndElement();
m_Xmltw.Flush();
m_Xmltw.Close();
CreateNewXmlWriter();
}
private void dg_required_style_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
e.Control.KeyPress -= new KeyPressEventHandler(NumericColumn_KeyPress);
if (m_BotManager.IsNumericColumn(dg_required_style)) //Desired Column
{
TextBox tb = e.Control as TextBox;
if (tb != null)
{
tb.KeyPress += new KeyPressEventHandler(NumericColumn_KeyPress);
}
}
}
private void NumericColumn_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
{
e.Handled = true;
}
}
private void checkBox_display_out_CheckedChanged(object sender, EventArgs e)
{
}
private void death_timer_Tick(object sender, EventArgs e)
{
if(checkBox_deathtimer.Checked)
{
decimal fVal = Convert.ToDecimal(death_timer.Interval) / 1000;
n_Death_Time.Value = n_Death_Time.Value - fVal;
if(n_Death_Time.Value <= 0)
{
checkBox_deathtimer.Checked = false;
death_timer.Enabled = false;
death_timer.Stop();
checkBox_deathtimer.ForeColor = Color.Black;
n_Death_Time.ForeColor = Color.Black;
this.Close();
}
}
}
private void checkBox_deathtimer_CheckedChanged(object sender, EventArgs e)
{
if(checkBox_deathtimer.Checked)
{
death_timer.Enabled = true;
death_timer.Start();
checkBox_deathtimer.ForeColor = Color.Red;
n_Death_Time.ForeColor = Color.Red;
}
else
{
death_timer.Enabled = false;
death_timer.Stop();
checkBox_deathtimer.ForeColor = Color.Black;
n_Death_Time.ForeColor = Color.Black;
}
}
private void ui_refresh_timer_Tick(object sender, EventArgs e)
{
if (m_bInitialized)
{
m_BotManager.RefreshStatisticsUiBindings(dg_stats, dg_luabotstatus, dg_global_luaStatus, dg_metrics, dg_botList);
}
}
public void ReBindUi(bool a_bSet)
{
}
private void checkBox_BindUi_CheckedChanged(object sender, EventArgs e)
{
btSelect.Enabled = checkBox_BindUi.Checked;
btUnSelect.Enabled = checkBox_BindUi.Checked;
bt_killBots.Enabled = checkBox_BindUi.Checked;
if(checkBox_BindUi.Checked)
{
m_BotManager.BindingBotList(dg_botList);
}
else
{
dg_botList.DataSource = null;
}
}
private void tcp_refresh_timer_Tick(object sender, EventArgs e)
{
if (m_bInitialized)
{
m_TcpClient.UpdateServer();
}
}
public void Log_server_msg(String a_sMsg)
{
AppendText(rt_server_log, Color.Violet, DateTime.Now.ToString() + " : ");
AppendText(rt_server_log, Color.Blue, a_sMsg);
AppendText(rt_server_log, Color.Blue, "\n");
}
public void IncomingChatMsg(String a_sMsg)
{
AppendText(rt_server_chat, Color.Blue, a_sMsg + "\n");
}
private void btn_server_chat_Click(object sender, EventArgs e)
{
String sDateTime = DateTime.Now.ToString() + " : ";
AppendText(rt_server_chat, Color.Brown, sDateTime);
AppendText(rt_server_chat, Color.Black, rt_server_input.Text + "\n");
m_TcpClient.SendMessage("chat " + sDateTime + rt_server_input.Text);
rt_server_input.Text = "";
}
public void SetDeathTimer(int a_iSecs)
{
n_Death_Time.Value = a_iSecs;
}
public void SetBotSpawnTimer(int a_iSecs)
{
n_launchDelay.Value = a_iSecs;
}
public void ActivateDeathTimer(bool a_bSet)
{
checkBox_deathtimer.Checked = a_bSet;
}
public void RestartSimulation()
{
bool a_bPrevBinded = checkBox_BindUi.Checked;
dg_stats.DataSource = null;
dg_luabotstatus.DataSource = null;
dg_global_luaStatus.DataSource = null;
dg_metrics.DataSource = null;
dg_botList.DataSource = null;
dg_required_style.DataSource = null;
dg_botList.DataSource = null;
m_BotManager.Reset();
m_BotManager.RefreshStatisticsUiBindings(dg_stats, dg_luabotstatus, dg_global_luaStatus, dg_metrics, dg_botList);
m_BotManager.BindingRequiredItemsUi(dg_required_style);
if (a_bPrevBinded)
{
m_BotManager.BindingBotList(dg_botList);
}
}
private void btn_restart_Click(object sender, EventArgs e)
{
RestartSimulation();
}
private void cb_game_SelectedIndexChanged(object sender, EventArgs e)
{
UpdateGameSelection();
}
private void UpdateGameSelection()
{
m_BotManager.m_GameName = m_sGamesList[cb_game.SelectedIndex];
m_BotManager.UpdateGameStyles();
BotManager.GameSettingsDefinition settings = m_BotManager.GetGamesSettings();
if (settings != null)
{
tb_application.Text = settings.m_BotPath;
tb_args.Text = settings.m_BotArgs;
cb_simulation.Items.Clear();
cb_simulation.Items.AddRange(settings.m_BotStyles);
cb_simulation.SelectedIndex = 0;
}
}
}
}