Skip to content

Commit

Permalink
Major changes (v2.0)
Browse files Browse the repository at this point in the history
- Seperated classes
- Added support for loops
- Running the timecheck loop in a different thread
- Added support for saving sidechat to logfile
  • Loading branch information
dzoeteman committed Jun 16, 2013
1 parent 9843cc2 commit bf1cc4b
Show file tree
Hide file tree
Showing 9 changed files with 224 additions and 77 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -6,7 +6,7 @@ RCon client for automatic global messages in ArmA 2.
Requirements
============

This client was built on .NET Framework 4.0.
This client needs .NET Framework 4.0+.

Credits
=======
Expand Down
149 changes: 76 additions & 73 deletions ServerMessages/Program.cs
Expand Up @@ -6,128 +6,131 @@
using System.IO;
using System.Net;
using BattleNET;
using System.Runtime.InteropServices;

namespace ServerMessages
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " Reading messages...");
string messagesFile = File.ReadAllText(@"messages.cfg");
string[] messages = messagesFile.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " Starting Client...");

Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " Starting RCon, checking connection...");
checkConnection();
// Handler to listen for close window
handler = new ConsoleEventDelegate(ConsoleEventCallback);
SetConsoleCtrlHandler(handler, true);

int timeLoop = 0;
while(true)
{
if (timeLoop > 599)
{
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " Reading messages...");
messagesFile = File.ReadAllText(@"messages.cfg");
messages = messagesFile.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
timeLoop = 0;
}
// Creating necessary files if they don't exist yet
createFile("messages.cfg");
createFile("settings.cfg");
createFile("chat.log");

foreach (string x in messages)
{
string[] messageThis = x.Split('~');
if (DateTime.Now.ToString("HH:mm:ss") == messageThis[0]) sayGlobal(messageThis[1]);
}

timeLoop++;
System.Threading.Thread.Sleep(1000);
// If savechat is true, connect, otherwise try connection and disconnect
beConn.b.BattlEyeConnected += BattlEyeConnected;
beConn.b.BattlEyeDisconnected += BattlEyeDisconnected;
if (settings.saveChat == "true")
{
beConn.b.BattlEyeMessageReceived += writeChatLog;
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " Listening to chat...");
}
}
beConn.b.ReconnectOnPacketLoss = true;

private static void checkConnection()
{
BattlEyeLoginCredentials loginCredentials = new BattlEyeLoginCredentials();
loginCredentials.Host = IPAddress.Parse(Settings.hostRcon);
loginCredentials.Port = Convert.ToInt16(Settings.portRcon);
loginCredentials.Password = Settings.passRcon;
BattlEyeClient b = new BattlEyeClient(loginCredentials);
b.BattlEyeConnected += BattlEyeConnected;
b.BattlEyeDisconnected += BattlEyeDisconnected;
b.ReconnectOnPacketLoss = false;
beConn.b.Connect();

b.Connect();
b.Disconnect();
// Start timeChecker
timeChecker timecheckObj = new timeChecker();
Thread timecheckThread = new Thread(timecheckObj.Check);
timecheckThread.Start();
}

private static void BattlEyeConnected(BattlEyeConnectEventArgs args)
{
// This method decides what to do when getting connected to the BE server
if (args.ConnectionResult == BattlEyeConnectionResult.Success)
{
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " Succesful connection to BE server.");
}
if (args.ConnectionResult == BattlEyeConnectionResult.InvalidLogin)
{
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " Connection error: Invalid login! Press ENTER to exit");
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " Connection error: Invalid login details! Please check your password in settings.cfg. Press ENTER to exit");
Console.ReadLine();
Environment.Exit(0);
}
if (args.ConnectionResult == BattlEyeConnectionResult.ConnectionFailed)
{
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " Connection error: server unreachable! Checking connection in 5 seconds...");
System.Threading.Thread.Sleep(5000);
checkConnection();
Thread.Sleep(5000);
if(!beConn.b.Connected) beConn.b.Connect();
}
}

private static void BattlEyeDisconnected(BattlEyeDisconnectEventArgs args)
{
if (args.DisconnectionType == BattlEyeDisconnectionType.ConnectionLost)
{
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " Connection lost: Packet exception! Checking connection in 5 seconds...");
System.Threading.Thread.Sleep(5000);
checkConnection();
}
// This method decides what to do when getting disconnected from the BE server
if (args.DisconnectionType == BattlEyeDisconnectionType.SocketException)
{
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " Connection lost: Socket exception! Checking connection in 5seconds...");
System.Threading.Thread.Sleep(5000);
checkConnection();
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " Connection lost: Socket exception! Reconnecting in 5 seconds...");
Thread.Sleep(5000);
if (!beConn.b.Connected)
beConn.b.Connect();
}
if (args.DisconnectionType == BattlEyeDisconnectionType.Manual)
{
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " Connection lost: Disconnected");
}
}

private static void sayGlobal(String saystr)
private static void writeChatLog(BattlEyeMessageEventArgs args)
{
BattlEyeLoginCredentials loginCredentials = new BattlEyeLoginCredentials();
loginCredentials.Host = IPAddress.Parse(Settings.hostRcon);
loginCredentials.Port = Convert.ToInt16(Settings.portRcon);
loginCredentials.Password = Settings.passRcon;
BattlEyeClient b = new BattlEyeClient(loginCredentials);
b.BattlEyeConnected += BattlEyeConnected;
b.BattlEyeDisconnected += BattlEyeDisconnected;
b.ReconnectOnPacketLoss = true;
// This method writes sidechat to the log file

b.Connect();
b.SendCommand("Say -1 " + saystr);
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " Said global: " + saystr);
b.Disconnect();
// First check whether chat msg was a side-chat msg
if (args.Message.Substring(0, Math.Min(args.Message.Length, 6)) == "(Side)")
{
// Check if linecount >= amount specified
if (File.ReadLines(@"chat.log").Count() >= Convert.ToInt16(settings.splitChatLogAt))
{
// If so, rename file and create new one
string fileNameWithTime = "chat_" + DateTime.Now.ToString("dd_MM_yyyy-HH_mm_ss") + ".log";
File.Move(@"chat.log", @fileNameWithTime);
createFile("chat.log");
}
// Write to logfile
TextWriter chatlog = new StreamWriter(@"chat.log", append: true);
chatlog.WriteLine(args.Message.Remove(0, 7));
chatlog.Close();
}

}

private static void createFile(String filename)
{
// This method creates files if they don't exist
if (!File.Exists(@filename))
{
using (FileStream fileCreate = File.Create(@filename))
{
fileCreate.Close();
}
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " Created file: " + filename);
}
}
}
public class Settings
{
public static string hostRcon = getSetting(1);
public static string portRcon = getSetting(2);
public static string passRcon = getSetting(3);

private static String getSetting(int x)
static bool ConsoleEventCallback(int eventType)
{
using (var sr = new StreamReader(@"settings.cfg"))
if (eventType == 2 || eventType == 0)
{
for (int i = 1; i < x; i++)
sr.ReadLine();
return sr.ReadLine().Remove(0, 5);
// Disconnect from server on close
if(beConn.b.Connected)
beConn.b.Disconnect();
}
return false;
}

// Close handler stuff
static ConsoleEventDelegate handler;
private delegate bool ConsoleEventDelegate(int eventType);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetConsoleCtrlHandler(ConsoleEventDelegate callback, bool add);
}
}
}
4 changes: 4 additions & 0 deletions ServerMessages/ServerMessages.csproj
Expand Up @@ -43,8 +43,12 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="beConn.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="publicMethods.cs" />
<Compile Include="settings.cs" />
<Compile Include="timeChecker.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BattleNET\BattleNET.csproj">
Expand Down
18 changes: 18 additions & 0 deletions ServerMessages/beConn.cs
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BattleNET;

namespace ServerMessages
{
public static class beConn
{
public static BattlEyeClient b { get; set; }

static beConn()
{
b = new BattlEyeClient(settings.loginCredentials);
}
}
}
4 changes: 2 additions & 2 deletions ServerMessages/bin/Debug/messages.cfg
@@ -1,2 +1,2 @@
05:46:45~Example 1 msg
14:05:00~Example 2 msg
05:46:45~Example 1 msg~no-loop
14:05:00~Example 2 msg~loop-2
4 changes: 3 additions & 1 deletion ServerMessages/bin/Debug/settings.cfg
@@ -1,3 +1,5 @@
host=127.0.0.1
port=2302
pass=rconpassword
pass=rconpassword
savechat=true
split=50
19 changes: 19 additions & 0 deletions ServerMessages/publicMethods.cs
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ServerMessages
{
class publicMethods
{
public static void sayGlobal(String saystr)
{
// This method sends messages via BE to all players (globally)
if (!beConn.b.Connected)
beConn.b.Connect();
beConn.b.SendCommand("Say -1 " + saystr);
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " Said global: " + saystr);
}
}
}
40 changes: 40 additions & 0 deletions ServerMessages/settings.cs
@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using BattleNET;

namespace ServerMessages
{
class settings
{
// This class reads the settings.cfg and puts everything into variables for later use.
public static string hostRcon = getSetting(1, 5);
public static string portRcon = getSetting(2, 5);
public static string passRcon = getSetting(3, 5);
public static string saveChat = getSetting(4, 9);
public static string splitChatLogAt = getSetting(5, 6);

public static BattlEyeLoginCredentials loginCredentials = new BattlEyeLoginCredentials(host: IPAddress.Parse(hostRcon), port: Convert.ToInt16(portRcon), password: passRcon);

private static String getSetting(int x, int remChar)
{
using (var sr = new StreamReader(@"settings.cfg"))
{
if (File.ReadLines(@"settings.cfg").Count() < 5)
{
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " Your settings.cfg is incorrectly formatted. Press ENTER to exit.");
Console.ReadLine();
Environment.Exit(0);
}
for (int i = 1; i < x; i++)
sr.ReadLine();
string returnedLine = sr.ReadLine().Remove(0, remChar);
sr.Close();
return returnedLine;
}
}
}
}
61 changes: 61 additions & 0 deletions ServerMessages/timeChecker.cs
@@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;

namespace ServerMessages
{
class timeChecker
{
public void Check()
{
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " Reading messages...");
string messagesFile = File.ReadAllText(@"messages.cfg");
string[] messages = messagesFile.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

int timeLoop = 0;
while (true)
{
// If it has been +-10min since last read of messages file, read again
if (timeLoop > 599)
{
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " Reading messages...");
messagesFile = File.ReadAllText(@"messages.cfg");
messages = messagesFile.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
timeLoop = 0;
}

// For each message, check if time specified equals current time, if so say message globally.
foreach (string x in messages)
{
string[] messageThis = x.Split('~');
int typeLoop = 0;
if (messageThis[2] != "no-loop")
typeLoop = Convert.ToInt16(messageThis[2].Remove(0, 5));
DateTime checkDateTime = DateTime.ParseExact(messageThis[0], "HH:mm:ss", null);

if (typeLoop == 0)
{
if (checkDateTime.ToString("HH:mm:ss") == DateTime.Now.ToString("HH:mm:ss"))
publicMethods.sayGlobal(messageThis[1]);
}
else
{
DateTime originalDateTime = checkDateTime;
do
{
checkDateTime = checkDateTime.AddHours(typeLoop);
if (checkDateTime.ToString("HH:mm:ss") == DateTime.Now.ToString("HH:mm:ss"))
publicMethods.sayGlobal(messageThis[1]);
} while (checkDateTime.ToString("HH:mm:ss") != originalDateTime.ToString("HH:mm:ss"));
}
}

timeLoop++;
Thread.Sleep(1000);
}
}
}
}

0 comments on commit bf1cc4b

Please sign in to comment.