diff --git a/Admin/Heartbeat.cs b/Admin/Heartbeat.cs
index c4356087..3835d813 100644
--- a/Admin/Heartbeat.cs
+++ b/Admin/Heartbeat.cs
@@ -14,7 +14,7 @@ namespace IW4MAdmin
public void Send()
{
- String URI = String.Format("http://raidmax.org/IW4M/Admin/heartbeat.php?address={0}&name={1}&map={2}&players={3}&version={4}", Instance.getPort().ToString(), Instance.getName(), Instance.getMap(), Instance.statusPlayers.Count.ToString() + '/' + Instance.getMaxClients().ToString(), IW4MAdmin.Program.Version.ToString());
+ String URI = String.Format("http://raidmax.org/IW4M/Admin/heartbeat.php?address={0}&name={1}&map={2}&players={3}&version={4}", Instance.getPort().ToString(), Instance.getName(), Instance.getMap(), Instance.getClientNum() + '/' + Instance.getMaxClients().ToString(), IW4MAdmin.Program.Version.ToString());
Handle.Request(URI);
}
diff --git a/Admin/IW4M ADMIN.csproj b/Admin/IW4M ADMIN.csproj
index 07aee0cf..5ec7f622 100644
--- a/Admin/IW4M ADMIN.csproj
+++ b/Admin/IW4M ADMIN.csproj
@@ -102,6 +102,7 @@
+
diff --git a/Admin/IW4_GameStructs.cs b/Admin/IW4_GameStructs.cs
index b1e1c3ed..13046338 100644
--- a/Admin/IW4_GameStructs.cs
+++ b/Admin/IW4_GameStructs.cs
@@ -104,8 +104,6 @@ namespace IW4MAdmin
public int max;
}
-
-
class Helpers
{
public static String NET_AdrToString(netadr_t a)
@@ -122,5 +120,4 @@ namespace IW4MAdmin
return (T)Marshal.PtrToStructure(new IntPtr(b), typeof(T));
}
}
-
}
diff --git a/Admin/Main.cs b/Admin/Main.cs
index 042f8d7c..83035295 100644
--- a/Admin/Main.cs
+++ b/Admin/Main.cs
@@ -3,20 +3,13 @@ using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-using System.Net;
namespace IW4MAdmin
{
class Program
{
- static String IP;
- static int Port;
- static String RCON;
- static public double Version = 0.9;
+ static public double Version = 0.91;
static public double latestVersion;
- static public List Servers;
static public bool usingMemory = true;
static void Main(string[] args)
@@ -30,12 +23,9 @@ namespace IW4MAdmin
else
Console.WriteLine(" Version " + Version + " (unable to retrieve latest)");
Console.WriteLine("=====================================================");
-
- List viableServers = getServers();
-
+#if DEBUG
if (viableServers.Count < 1)
viableServers = checkConfig(); // fall back to config
-
Servers = viableServers;
foreach (Server IW4M in viableServers)
@@ -45,17 +35,16 @@ namespace IW4MAdmin
Thread monitorThread = new Thread(new ThreadStart(SV.Monitor));
monitorThread.Start();
}
+#endif
+ IW4MAdmin.Manager IW4MAdmin = new IW4MAdmin.Manager();
+ IW4MAdmin.Init();
- IW4MAdmin_Web.WebFront WebStuff = new IW4MAdmin_Web.WebFront();
-
- Thread webFrontThread = new Thread( new ThreadStart(WebStuff.Init));
- webFrontThread.Start();
-
- Utilities.Wait(3);
Console.WriteLine("IW4M Now Initialized! Visit http://127.0.0.1:1624 for server overview.");
-
- }
+ IW4MAdmin_Web.WebFront frontEnd = new IW4MAdmin_Web.WebFront();
+ frontEnd.Init();
+ }
+#if DEBUG
static void setupConfig()
{
bool validPort = false;
@@ -77,6 +66,7 @@ namespace IW4MAdmin
file Config = new file("config\\servers.cfg", true);
Console.WriteLine("Great! Let's go ahead and start 'er up.");
}
+#endif
static String checkUpdate()
{
@@ -84,6 +74,7 @@ namespace IW4MAdmin
return Ver.Read();
}
+#if DEBUG
static List checkConfig()
{
@@ -92,7 +83,6 @@ namespace IW4MAdmin
List Servers = new List();
Config.Close();
-
if (SV_CONF == null || SV_CONF.Length < 1 || SV_CONF[0] == String.Empty)
{
setupConfig(); // get our first time server
@@ -116,40 +106,8 @@ namespace IW4MAdmin
Servers.Add(new Server(server_line[0], newPort, server_line[2],0));
}
}
-
return Servers;
}
-
- [DllImport("kernel32.dll")]
- public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
-
- [DllImport("kernel32.dll")]
- public static extern bool ReadProcessMemory(int hProcess,
- int lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);
-
- static List getServers()
- {
- List Servers = new List();
- foreach ( Process P in Process.GetProcessesByName("iw4m"))
- {
- IntPtr Handle = OpenProcess(0x0010, false, P.Id);
- int numberRead = 0;
- Byte[] dediStuff = new Byte[1];
- ReadProcessMemory((int)Handle, 0x5DEC04, dediStuff, 1, ref numberRead);
-
- if (dediStuff[0] == 0)
- {
- Console.WriteLine("Viable IW4M Instance found with PID #" + P.Id);
-
- dvar net_ip = Utilities.getDvar(0x64A1DF8, (int)Handle);
- dvar net_port = Utilities.getDvar(0x64A3004, (int)Handle);
- dvar rcon_password = Utilities.getDvar(0x111FF634, (int)Handle);
-
- Servers.Add(new Server(Dns.GetHostAddresses(net_ip.current)[1].ToString(), Convert.ToInt32(net_port.current), rcon_password.current, (int)Handle));
- }
- }
- return Servers;
-
- }
+#endif
}
}
diff --git a/Admin/Manager.cs b/Admin/Manager.cs
new file mode 100644
index 00000000..b1d28081
--- /dev/null
+++ b/Admin/Manager.cs
@@ -0,0 +1,157 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Net;
+using System.Threading;
+
+namespace IW4MAdmin
+{
+ class Manager
+ {
+ private List Servers;
+ private SortedDictionary ThreadList;
+ private List activePIDs;
+
+ public Manager()
+ {
+ ThreadList = new SortedDictionary();
+ }
+
+ public void Init()
+ {
+ activePIDs = getCurrentIW4MProcesses();
+ Servers = loadServers();
+
+ foreach (Server S in Servers)
+ {
+ Server IW4MServer = S;
+ Thread IW4MServerThread = new Thread(IW4MServer.Monitor);
+ ThreadList.Add(IW4MServer.pID(), IW4MServerThread);
+ IW4MServerThread.Start();
+ }
+
+ while (true)
+ {
+ lock (Servers)
+ {
+ foreach (Server S in Servers)
+ {
+ if (S == null)
+ continue;
+
+ if (!isIW4MStillRunning(S.pID()))
+ {
+ Thread Defunct = ThreadList[S.pID()];
+ if (Defunct != null)
+ {
+ Defunct.Abort();
+ ThreadList[S.pID()] = null;
+ }
+ activePIDs.Remove(S.pID());
+ }
+ }
+ }
+ scanForNewServers();
+ Utilities.Wait(5);
+ }
+ }
+
+ private void scanForNewServers()
+ {
+ List newProcesses = getCurrentIW4MProcesses();
+ foreach (int pID in activePIDs)
+ {
+ bool newProcess = true;
+ foreach (int I in newProcesses)
+ {
+ if (I == pID)
+ newProcess = false;
+ }
+
+ if (newProcess)
+ {
+ Server S = loadIndividualServer(pID);
+ Servers.Add(S);
+ Thread IW4MServerThread = new Thread(S.Monitor);
+ ThreadList.Add(pID, IW4MServerThread);
+
+ IW4MServerThread.Start();
+ }
+ }
+
+ }
+
+ private bool isIW4MStillRunning(int pID)
+ {
+ if (pID > 0)
+ {
+ Process P = Process.GetProcessById(pID);
+ if (P.ProcessName.Length == 0)
+ {
+ return false;
+ Console.WriteLine("Server with PID #" + pID + " doesn't seem to be running anymore");
+ }
+ return true;
+ }
+ return false;
+ }
+
+ [DllImport("kernel32.dll")]
+ public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
+
+ [DllImport("kernel32.dll")]
+ public static extern bool ReadProcessMemory(int hProcess, int lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);
+
+ private List getCurrentIW4MProcesses()
+ {
+ List PIDs = new List();
+ foreach (Process P in Process.GetProcessesByName("iw4m"))
+ {
+ IntPtr Handle = OpenProcess(0x10, false, P.Id);
+ Byte[] isClient = new Byte[1];
+ int numberRead = 0;
+ ReadProcessMemory((int)Handle, 0x5DEC04, isClient, 1, ref numberRead);
+
+ if (isClient[0] == 0)
+ PIDs.Add(P.Id);
+ }
+
+ return PIDs;
+ }
+
+ private List loadServers()
+ {
+ List activeServers = new List();
+ foreach (int pID in activePIDs)
+ {
+ Server S = loadIndividualServer(pID);
+ if (S != null)
+ activeServers.Add(S);
+ }
+ return activeServers;
+ }
+
+ private Server loadIndividualServer(int pID)
+ {
+ if (pID > 0)
+ {
+ IntPtr Handle = OpenProcess(0x10, false, pID);
+ if (Handle != null)
+ {
+ dvar net_ip = Utilities.getDvar(0x64A1DF8, (int)Handle);
+ dvar net_port = Utilities.getDvar(0x64A3004, (int)Handle);
+ // unfortunately this needs to be updated for every iw4m build :/
+ dvar rcon_password = Utilities.getDvar(0x1120CC3C, (int)Handle);
+
+ return new Server(Dns.GetHostAddresses(net_ip.current)[1].ToString(), Convert.ToInt32(net_port.current), rcon_password.current, (int)Handle, pID);
+ }
+
+ return null;
+ }
+ return null;
+ }
+ }
+}
diff --git a/Admin/Server.cs b/Admin/Server.cs
index 047f953e..d14cf329 100644
--- a/Admin/Server.cs
+++ b/Admin/Server.cs
@@ -1,11 +1,9 @@
-//#define USINGMEMORY
-using System;
+using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
-using System.Threading; //SLEEP
+using System.Threading;
using System.IO;
-using System.Diagnostics;
using System.Runtime.InteropServices;
@@ -15,8 +13,9 @@ namespace IW4MAdmin
{
const int FLOOD_TIMEOUT = 300;
- public Server(string address, int port, string password, int H)
+ public Server(string address, int port, string password, int H, int PID)
{
+ this.PID = PID;
Handle = H;
IP = address;
Port = port;
@@ -114,6 +113,11 @@ namespace IW4MAdmin
return Bans;
}
+ public int pID()
+ {
+ return this.PID;
+ }
+
public void getAliases(List returnPlayers, Player Origin)
{
if (Origin == null)
@@ -558,7 +562,7 @@ namespace IW4MAdmin
Utilities.Wait(10);
return;
}
-#if DEBUG == false
+#if DEBUG
//Thread to handle polling server for IP's
Thread statusUpdate = new Thread(new ThreadStart(pollServer));
statusUpdate.Start();
@@ -583,8 +587,6 @@ namespace IW4MAdmin
while (isRunning)
{
-
-
#if DEBUG == false
try
#endif
@@ -622,7 +624,7 @@ namespace IW4MAdmin
}
}
-#if DEBUG
+#if DEBUG == false
if ((DateTime.Now - lastPoll).Milliseconds > 750)
{
int numberRead = 0;
@@ -634,6 +636,8 @@ namespace IW4MAdmin
ReadProcessMemory((int)Handle, 0x31D9390 + (buff.Length)*(i), buff, buff.Length, ref numberRead); // svs_clients start + current client
client_s eachClient = (client_s)Helpers.ReadStruct(buff);
+ if (eachClient.isBot == 1)
+ continue;
if (eachClient.state == 0)
removePlayer(i);
@@ -707,7 +711,7 @@ namespace IW4MAdmin
RCONQueue.Abort();
eventQueue.Abort();
}
-
+#if DEBUG
private void pollServer()
{
int timesFailed = 0;
@@ -779,6 +783,7 @@ namespace IW4MAdmin
Utilities.Wait(15);
}
}
+#endif
//Vital RCON commands to establish log file and server name. May need to cleanup in the future
#if USINGMEMORY
@@ -941,9 +946,7 @@ namespace IW4MAdmin
logPath = Basepath + '\\' + "m2demo" + '\\' + log;
else
logPath = Basepath + '\\' + Mod + '\\' + log;
-#if DEBUG
- // logPath = "C:\\Users\\Michael\\Desktop\\test.txt";
-#endif
+
if (!File.Exists(logPath))
{
Log.Write("Gamelog does not exist!", Log.Level.All);
@@ -964,7 +967,7 @@ namespace IW4MAdmin
lastPoll = DateTime.Now;
#if DEBUG
- /* System.Net.FtpWebRequest tmp = (System.Net.FtpWebRequest)System.Net.FtpWebRequest.Create("ftp://raidmax.org/logs/games_old.log");
+ /* System.Net.FtpWebRequest tmp = (System.Net.FtpWebRequest)System.Net.FtpWebRequest.Create("");
tmp.Credentials = new System.Net.NetworkCredential("*", "*");
System.IO.Stream ftpStream = tmp.GetResponse().GetResponseStream();
String ftpLog = new StreamReader(ftpStream).ReadToEnd();*/
@@ -983,6 +986,8 @@ namespace IW4MAdmin
//Process any server event
public bool processEvent(Event E)
{
+
+#if DEBUG
/*if (E.Type == Event.GType.Connect) // this is anow handled by memory :)
{
if (E.Origin == null)
@@ -990,6 +995,7 @@ namespace IW4MAdmin
addPlayer(E.Origin);
return true;
}*/
+#endif
if (E.Type == Event.GType.Connect)
{
@@ -1353,7 +1359,6 @@ namespace IW4MAdmin
//END
- //THIS IS BAD BECAUSE WE DON"T WANT EVERYONE TO HAVE ACCESS :/
public String getPassword()
{
return rcon_pass;
@@ -1365,8 +1370,7 @@ namespace IW4MAdmin
Macros.Add("WISDOM", Wisdom());
Macros.Add("TOTALPLAYERS", clientDB.totalPlayers());
Macros.Add("TOTALKILLS", totalKills);
- Macros.Add("VERSION", IW4MAdmin.Program.Version);
-
+ Macros.Add("VERSION", IW4MAdmin.Program.Version);
}
private void initMaps()
@@ -1507,7 +1511,6 @@ namespace IW4MAdmin
public List chatHistory;
public Queue playerHistory;
-
//Info
private String IP;
private int Port;
@@ -1527,13 +1530,12 @@ namespace IW4MAdmin
private Moserware.TrueSkill Skills;
private DateTime lastWebChat;
private int Handle;
-
+ private int PID;
//Will probably move this later
public Dictionary statusPlayers;
public bool isRunning;
private DateTime lastPoll;
-
//Log stuff
private String Basepath;
diff --git a/Admin/WebFront.cs b/Admin/WebFront.cs
index 70bc4fee..990856f4 100644
--- a/Admin/WebFront.cs
+++ b/Admin/WebFront.cs
@@ -350,7 +350,12 @@ namespace IW4MAdmin_Web
forumID = forumID - 76561197960265728;
}
- buffer.AppendFormat("{0} | {1} | {2} | {3} | {4} | {5} | {6} ago | {8} | ", Player.getName(), str, IPs, Rating, IW4MAdmin.Utilities.nameHTMLFormatted(Player.getLevel()), Player.getConnections(), Player.getLastConnection(), forumID, Player.getName(), "/0/" + Player.getDBID() + "/userip/?player");
+ String Screenshot = String.Empty;
+
+ if (logged)
+ Screenshot = String.Format("", forumID, Player.getName());
+
+ buffer.AppendFormat("{0}{10} | {1} | {2} | {3} | {4} | {5} | {6} ago | {8} | ", Player.getName(), str, IPs, Rating, IW4MAdmin.Utilities.nameHTMLFormatted(Player.getLevel()), Player.getConnections(), Player.getLastConnection(), forumID, Player.getName(), "/0/" + Player.getDBID() + "/userip/?player", Screenshot);
buffer.Append("");
}
diff --git a/Admin/webfront/header.html b/Admin/webfront/header.html
index f69df801..182f5853 100644
--- a/Admin/webfront/header.html
+++ b/Admin/webfront/header.html
@@ -11,7 +11,7 @@
-
+