diff --git a/Admin/Main.cs b/Admin/Main.cs index 37f100f3c..0b36a7f4c 100644 --- a/Admin/Main.cs +++ b/Admin/Main.cs @@ -37,14 +37,22 @@ namespace IW4MAdmin monitorThread.Start(); } #endif - IW4MAdmin.Manager serverManager = new IW4MAdmin.Manager(); - serverManager.Init(); + serverManager = new IW4MAdmin.Manager(); + + Thread serverMGRThread = new Thread(serverManager.Init); + serverMGRThread.Start(); + + while(!serverManager.isReady()) + { + Utilities.Wait(1); + } if (serverManager.getServers() != null) Console.WriteLine("IW4M Now Initialized! Visit http://127.0.0.1:1624 for server overview."); - //IW4MAdmin_Web.WebFront frontEnd = new IW4MAdmin_Web.WebFront(serverManager.getServers()); - //frontEnd.Init(); + //this is blocking so if it goes down :( + IW4MAdmin_Web.WebFront frontEnd = new IW4MAdmin_Web.WebFront(); + frontEnd.Init(); } #if DEBUG static void setupConfig() @@ -76,9 +84,9 @@ namespace IW4MAdmin return Ver.Read(); } - static public List getServers() + static public Server[] getServers() { - return serverManager.getServers(); + return serverManager.getServers().ToArray(); } #if DEBUG diff --git a/Admin/Manager.cs b/Admin/Manager.cs index 136d6e460..663d9f6d7 100644 --- a/Admin/Manager.cs +++ b/Admin/Manager.cs @@ -15,6 +15,7 @@ namespace IW4MAdmin private SortedDictionary ThreadList; private List activePIDs; private Log mainLog; + private bool initialized = false; public Manager() { @@ -47,6 +48,8 @@ namespace IW4MAdmin //mainLog.Write("Now monitoring the server running on port " + IW4MServer.getPort(), Log.Level.All); } + initialized = true; + while (true) { List defunctServers = new List(); @@ -178,20 +181,24 @@ namespace IW4MAdmin IntPtr Handle = OpenProcess(0x10, false, pID); if (Handle != null) { - int timeWaiting = 0; + int timeWaiting = 0; + bool sv_running = false; - int sv_runningPtr = Utilities.getIntFromPointer(0x1AD7934, (int)Handle) + 0x10; // where the dvar_t struct is stored + the offset for current value + while(!sv_running) // server is still booting up { + int sv_runningPtr = Utilities.getIntFromPointer(0x1AD7934, (int)Handle) + 0x10; // where the dvar_t struct is stored + the offset for current value sv_running = Utilities.getBoolFromPointer(sv_runningPtr, (int)Handle); Utilities.Wait(1); timeWaiting++; - if (timeWaiting > 60) // don't want to get stuck waiting forever if the server is frozen + if (timeWaiting > 30) // don't want to get stuck waiting forever if the server is frozen return null; } + Utilities.Wait(5); + dvar net_ip = Utilities.getDvar(0x64A1DF8, (int)Handle); dvar net_port = Utilities.getDvar(0x64A3004, (int)Handle); @@ -202,5 +209,10 @@ namespace IW4MAdmin } return null; } + + public bool isReady() + { + return initialized; + } } } diff --git a/Admin/RCON.cs b/Admin/RCON.cs index b0acd754d..49ce78d7a 100644 --- a/Admin/RCON.cs +++ b/Admin/RCON.cs @@ -115,7 +115,8 @@ namespace IW4MAdmin //Current.Response = responseSendRCON(Current.Request); Utilities.executeCommand(Instance.pID(), Current.Request); toSend.Dequeue(); - Utilities.Wait(0.567); + //Utilities.Wait(0.567); + Utilities.Wait(.3); } else Utilities.Wait(0.01); diff --git a/Admin/Server.cs b/Admin/Server.cs index a2c82ad5e..1fc6aeab4 100644 --- a/Admin/Server.cs +++ b/Admin/Server.cs @@ -607,7 +607,6 @@ namespace IW4MAdmin DateTime playerCountStart = DateTime.Now; DateTime lastCount = DateTime.Now; - Utilities.Wait(1); #if DEBUG == false Broadcast("IW4M Admin is now ^2ONLINE"); #endif @@ -991,8 +990,6 @@ namespace IW4MAdmin if (E.Type == Event.GType.MapChange) { Log.Write("New map loaded - " + clientnum + " active players", Log.Level.Debug); - executeCommand("sv_mapRotation " + backupRotation); - executeCommand("scr_" + Gametype + "_timelimit " + backupTimeLimit); Dictionary infoResponseDict = new Dictionary(); String[] infoResponse = E.Data.Split('\\'); diff --git a/Admin/Utilities.cs b/Admin/Utilities.cs index 968662065..075729dd5 100644 --- a/Admin/Utilities.cs +++ b/Admin/Utilities.cs @@ -378,8 +378,11 @@ namespace IW4MAdmin [DllImport("kernel32.dll")] public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, out uint lpThreadId); + [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] + static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, AllocationType dwFreeType); + [DllImport("kernel32.dll", SetLastError = true)] - static extern bool VirtualFree(IntPtr lpAddress, UIntPtr dwSize, AllocationType type); + static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds); public static dvar getDvar(int Location, int Handle) { @@ -405,6 +408,8 @@ namespace IW4MAdmin if ((int)dvar_raw.current > short.MaxValue) dvar_actual.current = getStringFromPointer((int)dvar_raw.current, Handle); + else if ((int)dvar_raw.current <= 1025) + dvar_actual.current = ((int)dvar_raw.current % 1024).ToString(); else dvar_actual.current = dvar_raw.current.ToString(); @@ -512,14 +517,18 @@ namespace IW4MAdmin return; // create our thread that executes command :) - Console.WriteLine(codeAllocation.ToString("X8")); IntPtr ThreadHandle = CreateRemoteThread(ProcessHandle, IntPtr.Zero, 0, codeAllocation, IntPtr.Zero, 0, out threadID); + if (ThreadHandle == null || ThreadHandle == IntPtr.Zero) + return; + + WaitForSingleObject(ThreadHandle, 5000); // cleanup - if (!VirtualFree(codeAllocation, (UIntPtr)executeCMD.Length, AllocationType.Decommit)) - Thread.Sleep(1); - if (!VirtualFree(memoryForCMDName, (UIntPtr)Command.Length + 1, AllocationType.Decommit)) - Thread.Sleep(1); + if (!VirtualFreeEx(ProcessHandle, codeAllocation, 0, AllocationType.Release)) + Console.WriteLine(Marshal.GetLastWin32Error()); + if (!VirtualFreeEx(ProcessHandle, memoryForCMDName, 0, AllocationType.Release)) + Console.WriteLine(Marshal.GetLastWin32Error()); + } public static IntPtr allocateAndWrite(Byte[] Data, IntPtr ProcessHandle) @@ -552,8 +561,8 @@ namespace IW4MAdmin public static dvar getDvarValue(int pID, String DVAR) { + dvar requestedDvar = new dvar(); uint threadID = 0; - IntPtr ProcessHandle = OpenProcess(ProcessAccessFlags.All, false, pID); IntPtr memoryForDvarName = allocateAndWrite(Encoding.ASCII.GetBytes(DVAR + "\0"), ProcessHandle); @@ -581,14 +590,17 @@ namespace IW4MAdmin Console.WriteLine("UNABLE TO ALLOCATE MEMORY FOR CODE"); IntPtr ThreadHandle = CreateRemoteThread(ProcessHandle, IntPtr.Zero, 0, codeAllocation, IntPtr.Zero, 0, out threadID); + if (ThreadHandle == null || ThreadHandle == IntPtr.Zero) + return requestedDvar; - if (!VirtualFree(codeAllocation, UIntPtr.Zero, AllocationType.Release)) - Thread.Sleep(1); - if (!VirtualFree(memoryForDvarName, UIntPtr.Zero, AllocationType.Release)) - Thread.Sleep(1); + WaitForSingleObject(ThreadHandle, 5000); + + if (!VirtualFreeEx(ProcessHandle, codeAllocation, 0, AllocationType.Release)) + Console.WriteLine(Marshal.GetLastWin32Error()); + if (!VirtualFreeEx(ProcessHandle, memoryForDvarName, 0, AllocationType.Release)) + Console.WriteLine(Marshal.GetLastWin32Error()); int dvarLoc = getIntFromPointer(0x2098D9C, (int)ProcessHandle); - //int ptrToOurDvar = getIntFromPointer(dvarLoc +, (int)ProcessHandle); return getDvar(dvarLoc + 0x10, (int)ProcessHandle); } diff --git a/Admin/WebFront.cs b/Admin/WebFront.cs index 9d468f2b5..6db1643b1 100644 --- a/Admin/WebFront.cs +++ b/Admin/WebFront.cs @@ -1,4 +1,5 @@ -using System; +#define ENABLED_CRAP_CODE_THAT_NEEDS_TO_BE_REWRITTEN +using System; using System.Globalization; using System.Collections.Generic; using System.Linq; @@ -8,7 +9,8 @@ using Kayak; using Kayak.Http; using System.Net; -#if DEBUG + +#if ENABLED_CRAP_CODE_THAT_NEEDS_TO_BE_REWRITTEN namespace IW4MAdmin_Web { class Client @@ -32,7 +34,7 @@ namespace IW4MAdmin_Web class WebFront { - private List Servers; + private IW4MAdmin.Server[] Servers; public enum Page { @@ -42,9 +44,9 @@ namespace IW4MAdmin_Web player } - public WebFront(List curServers) + public WebFront() { - Servers = curServers; + Servers = IW4MAdmin.Program.getServers(); } public void Init() @@ -86,21 +88,22 @@ namespace IW4MAdmin_Web static public String parseMacros(String input, WebFront.Page Page, int server, int Pagination, bool logged, String Data) { StringBuilder buffer = new StringBuilder(); + IW4MAdmin.Server[] Servers= IW4MAdmin.Program.getServers(); switch (input) { case "SERVERS": int cycleFix = 0; - foreach (IW4MAdmin.Server S in IW4MAdmin.Program.getServers()) + for (int i = 0; i < Servers.Count(); i++) { StringBuilder players = new StringBuilder(); - if (S.getClientNum() < 1) + if (Servers[i].getClientNum() < 1) players.Append("

No Players

"); else { int count = 0; - double currentPlayers = S.statusPlayers.Count; - - foreach (IW4MAdmin.Player P in S.getPlayers()) + double currentPlayers = Servers[i].statusPlayers.Count; + + foreach (IW4MAdmin.Player P in Servers[i].getPlayers()) { if (P == null) continue; @@ -119,9 +122,9 @@ namespace IW4MAdmin_Web break; } } - - players.AppendFormat("{2}", S.pID(), P.getDBID(), IW4MAdmin.Utilities.nameHTMLFormatted(P)); - + + players.AppendFormat("{2}", Servers[i].pID(), P.getDBID(), IW4MAdmin.Utilities.nameHTMLFormatted(P)); + if (count % 2 != 0) { players.Append(""); @@ -144,11 +147,11 @@ namespace IW4MAdmin_Web {5} -
", - S.getName(), S.getMap(), S.getClientNum() + "/" + S.getMaxClients(), IW4MAdmin.Utilities.gametypeLocalized(S.getGametype()), S.pID(), players.ToString()); - buffer.AppendFormat("
", S.pID(), '\"'); - if (S.getClientNum() > 0) - buffer.AppendFormat("
", server.pID(), '\"'); + ", + Servers[i].getName(), Servers[i].getMap(), Servers[i].getClientNum() + "/" + Servers[i].getMaxClients(), IW4MAdmin.Utilities.gametypeLocalized(Servers[i].getGametype()), i, players.ToString()); + buffer.AppendFormat("
", i, '\"'); + if (Servers[i].getClientNum() > 0) + buffer.AppendFormat("
", i, '\"'); buffer.Append("
"); } return buffer.ToString(); @@ -214,13 +217,13 @@ namespace IW4MAdmin_Web } buffer.Append("
"); - buffer.Append(parsePagination(server, IW4MAdmin.Program.getServers()[0].Bans.Count, 30, Pagination, "bans")); + buffer.Append(parsePagination(server, Servers[0].Bans.Count, 30, Pagination, "bans")); return buffer.ToString(); case "PAGE": buffer.Append("
"); return buffer.ToString(); case "STATS": - int totalStats = IW4MAdmin.Program.Servers[server].statDB.totalStats(); + int totalStats = Servers[server].statDB.totalStats(); buffer.Append("

Starting at #{{TOP}}


"); buffer.Append(""); @@ -231,7 +234,7 @@ namespace IW4MAdmin_Web range = (totalStats - start); else range = 30; - List Stats = IW4MAdmin.Program.Servers[server].statDB.getMultipleStats(start, range).OrderByDescending(x => x.Skill).ToList(); + List Stats = Servers[server].statDB.getMultipleStats(start, range).OrderByDescending(x => x.Skill).ToList(); buffer.Append(""); cycleFix = 0; for (int i = 0; i < totalStats; i++) @@ -239,7 +242,7 @@ namespace IW4MAdmin_Web if (i >= Stats.Count -1 || Stats[i] == null ) continue; - IW4MAdmin.Player P = IW4MAdmin.Program.Servers[server].clientDB.getPlayer(Stats[i].statIndex); + IW4MAdmin.Player P = Servers[server].clientDB.getPlayer(Stats[i].statIndex); if (P == null) continue; @@ -268,18 +271,18 @@ namespace IW4MAdmin_Web List matchingPlayers = new List(); if (Data == null) - matchingPlayers.Add(IW4MAdmin.Program.Servers[server].clientDB.getPlayer(Pagination)); + matchingPlayers.Add(Servers[server].clientDB.getPlayer(Pagination)); else { - var alias = IW4MAdmin.Program.Servers[server].aliasDB.findPlayers(Data); + var alias = Servers[server].aliasDB.findPlayers(Data); foreach (var a in alias) { - var p = IW4MAdmin.Program.Servers[server].clientDB.getPlayer(a.getNumber()); + var p = Servers[server].clientDB.getPlayer(a.getNumber()); if (p != null) { List aliases = new List(); - IW4MAdmin.Program.Servers[server].getAliases(aliases, p); + Servers[server].getAliases(aliases, p); foreach (var pa in aliases) { @@ -303,7 +306,7 @@ namespace IW4MAdmin_Web buffer.Append(""); StringBuilder str = new StringBuilder(); List aliases = new List(); - IW4MAdmin.Program.Servers[server].getAliases(aliases, Player); + Servers[server].getAliases(aliases, Player); foreach (IW4MAdmin.Player a in aliases) { @@ -319,7 +322,7 @@ namespace IW4MAdmin_Web str.AppendFormat("{0}
", a.getName()); } - Player.stats = IW4MAdmin.Program.Servers[server].statDB.getStats(Player.getDBID()); + Player.stats = Servers[server].statDB.getStats(Player.getDBID()); String Rating = String.Empty; if (Player.stats == null) @@ -373,7 +376,7 @@ namespace IW4MAdmin_Web { String output = input; - bool logged = IW4MAdmin.Program.Servers[server].clientDB.getAdmins().Exists(player => player.getIP() == C.requestOrigin["Host"].Split(':')[0]); + bool logged = IW4MAdmin.Program.getServers()[server].clientDB.getAdmins().Exists(player => player.getIP() == C.requestOrigin["Host"].Split(':')[0]); switch (C.requestedPage) { @@ -469,11 +472,11 @@ namespace IW4MAdmin_Web test.Append("
"); test.Append("
NameKillsDeathsKDRRating