diff --git a/Admin/Command.cs b/Admin/Command.cs index e8548348b..23b4a0f9e 100644 --- a/Admin/Command.cs +++ b/Admin/Command.cs @@ -75,10 +75,8 @@ namespace IW4MAdmin else E.Origin.Tell("This server already has an owner!"); } - } - class Warn : Command { public Warn(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } @@ -95,10 +93,8 @@ namespace IW4MAdmin E.Owner.Broadcast(Message); if (E.Target.Warnings >= 4) E.Target.Kick("You were kicked for too many warnings!"); - } - + } } - } class WarnClear : Command @@ -112,7 +108,6 @@ namespace IW4MAdmin String Message = String.Format("All warning cleared for {0}", E.Target.getName()); E.Owner.Broadcast(Message); } - } class Kick : Command @@ -122,13 +117,12 @@ namespace IW4MAdmin public override void Execute(Event E) { E.Target.LastOffense = Utilities.removeWords(E.Data, 1); - String Message = "^1Player Kicked: ^5" + E.Target.LastOffense + " ^1Admin: ^5" + E.Origin.getName(); + String Message = "^1Player Kicked: ^5" + E.Target.LastOffense + " ^1Admin: ^5" + E.Origin.getName(); if (E.Origin.getLevel() > E.Target.getLevel()) E.Target.Kick(Message); else E.Origin.Tell("You cannot kick " + E.Target.getName()); } - } class Say : Command @@ -139,7 +133,6 @@ namespace IW4MAdmin { E.Owner.Broadcast("^1" + E.Origin.getName() + " - ^6" + E.Data + "^7"); } - } class TempBan : Command @@ -155,7 +148,6 @@ namespace IW4MAdmin else E.Origin.Tell("You cannot temp ban " + E.Target.getName()); } - } class SBan : Command @@ -170,7 +162,7 @@ namespace IW4MAdmin if (E.Owner.Website == null) Message = "^1Player Banned: ^5" + E.Target.LastOffense; else - Message = "^1Player Banned: ^5" + E.Target.LastOffense + "^7 (appeal at nbsclan.org)"; + Message = "^1Player Banned: ^5" + E.Target.LastOffense + "^7 (appeal " + E.Owner.Website; if (E.Origin.getLevel() > E.Target.getLevel()) { E.Target.Ban(Message, E.Origin); @@ -179,7 +171,6 @@ namespace IW4MAdmin else E.Origin.Tell("You cannot ban " + E.Target.getName()); } - } class Unban : Command @@ -193,7 +184,6 @@ namespace IW4MAdmin else E.Origin.Tell("Unable to find a ban for that GUID"); } - } class WhoAmI : Command @@ -205,7 +195,6 @@ namespace IW4MAdmin String You = String.Format("{0} [^3#{1}^7] {2} [^3@{3}^7] [{4}^7] IP: {5}", E.Origin.getName(), E.Origin.getClientNum(), E.Origin.getID(), E.Origin.getDBID(), Utilities.levelToColor(E.Origin.getLevel()), E.Origin.getIP()); E.Origin.Tell(You); } - } class List : Command @@ -214,15 +203,17 @@ namespace IW4MAdmin public override void Execute(Event E) { - foreach (Player P in E.Owner.getPlayers()) + lock (E.Owner.getPlayers()) { - if (P == null) - continue; + foreach (Player P in E.Owner.getPlayers()) + { + if (P == null) + continue; - E.Origin.Tell(String.Format("[^3{0}^7]{3}[^3{1}^7] {2}", Utilities.levelToColor(P.getLevel()), P.getClientNum(), P.getName(), Utilities.getSpaces(Player.Permission.SeniorAdmin.ToString().Length - P.getLevel().ToString().Length))); + E.Origin.Tell(String.Format("[^3{0}^7]{3}[^3{1}^7] {2}", Utilities.levelToColor(P.getLevel()), P.getClientNum(), P.getName(), Utilities.getSpaces(Player.Permission.SeniorAdmin.ToString().Length - P.getLevel().ToString().Length))); + } } } - } class Help : Command @@ -271,7 +262,6 @@ namespace IW4MAdmin E.Origin.Tell("Type !help to get command usage example"); } } - } class FastRestart : Command @@ -295,7 +285,6 @@ namespace IW4MAdmin E.Owner.Broadcast("Performing map rotate in 5 seconds..."); E.Owner.mapRotate(5); } - } class SetLevel : Command @@ -324,7 +313,6 @@ namespace IW4MAdmin else E.Origin.Tell("Invalid group specified."); } - } class Usage : Command @@ -335,7 +323,6 @@ namespace IW4MAdmin { E.Origin.Tell("IW4M Admin is using " + Math.Round(((System.Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64 / 2048f) / 1200f), 1) + "MB"); } - } class Uptime : Command @@ -347,7 +334,6 @@ namespace IW4MAdmin TimeSpan uptime = DateTime.Now - System.Diagnostics.Process.GetCurrentProcess().StartTime; E.Origin.Tell(String.Format("IW4M Admin has been up for {0} days, {1} hours, and {2} minutes", uptime.Days, uptime.Hours, uptime.Minutes)); } - } class Admins : Command @@ -368,7 +354,6 @@ namespace IW4MAdmin } } } - } class Wisdom : Command @@ -379,7 +364,6 @@ namespace IW4MAdmin { E.Owner.Broadcast(E.Owner.Wisdom()); } - } @@ -405,7 +389,6 @@ namespace IW4MAdmin Utilities.Wait(3); E.Owner.Map(newMap); } - } class Find : Command diff --git a/Admin/File.cs b/Admin/File.cs index 43e04d031..4841cc524 100644 --- a/Admin/File.cs +++ b/Admin/File.cs @@ -26,7 +26,7 @@ namespace IW4MAdmin catch { - //Console.WriteLine("Unable to open log file for writing!"); + Console.WriteLine("Unable to open log file for writing!"); } } @@ -46,7 +46,7 @@ namespace IW4MAdmin { Name = file; writeHandle = new StreamWriter(new FileStream(Name, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)); - // writeHandle.AutoFlush = true; + // writeHandle.AutoFlush = true; sze = 0; } diff --git a/Admin/IW4M ADMIN.csproj b/Admin/IW4M ADMIN.csproj index 5ec7f6229..37ff7161c 100644 --- a/Admin/IW4M ADMIN.csproj +++ b/Admin/IW4M ADMIN.csproj @@ -54,13 +54,14 @@ prompt 0 true + On LocalIntranet - true + false IW4MAdmin.ico @@ -114,6 +115,9 @@ + + PreserveNewest + PreserveNewest diff --git a/Admin/Manager.cs b/Admin/Manager.cs index 663d9f6d7..4d282b8fe 100644 --- a/Admin/Manager.cs +++ b/Admin/Manager.cs @@ -20,7 +20,7 @@ namespace IW4MAdmin public Manager() { ThreadList = new SortedDictionary(); - file logFile = new file("IW4MAdmin_ApplicationLog.log"); + file logFile = new file("IW4MAdminManager.log", true); mainLog = new Log(logFile, Log.Level.All, 0); } @@ -31,7 +31,6 @@ namespace IW4MAdmin if (activePIDs.Count == 0) { mainLog.Write("No viable IW4M instances detected.", Log.Level.All); - mainLog.Write("Shutting Down...", Log.Level.All); Utilities.Wait(5); return; } @@ -199,12 +198,11 @@ namespace IW4MAdmin Utilities.Wait(5); - dvar net_ip = Utilities.getDvar(0x64A1DF8, (int)Handle); - dvar net_port = Utilities.getDvar(0x64A3004, (int)Handle); + dvar net_ip = Utilities.getDvarOld(0x64A1DF8, (int)Handle); + dvar net_port = Utilities.getDvarOld(0x64A3004, (int)Handle); return new Server(net_ip.current, Convert.ToInt32(net_port.current), "", (int)Handle, pID); } - return null; } return null; diff --git a/Admin/Server.cs b/Admin/Server.cs index 9fdad925d..a441e24d4 100644 --- a/Admin/Server.cs +++ b/Admin/Server.cs @@ -217,7 +217,6 @@ namespace IW4MAdmin NewPlayer.lastEvent = new Event(Event.GType.Say, null, NewPlayer, null, this); // this is messy but its throwing an error when they've started it too late else NewPlayer.lastEvent = P.lastEvent; - // lets check aliases if ((NewPlayer.Alias.getNames().Find(m => m.Equals(P.getName()))) == null || NewPlayer.getName() == null || NewPlayer.getName() == String.Empty) @@ -294,7 +293,7 @@ namespace IW4MAdmin } //finally lets check their clean status :> - checkClientStatus(NewPlayer); + //checkClientStatus(NewPlayer); lock (players) { @@ -529,27 +528,17 @@ namespace IW4MAdmin public void executeCommand(String CMD) { - if (CMD.ToLower() == "map_restart" || CMD.ToLower() == "map_rotate") - return; - - else if (CMD.ToLower().Substring(0, 4) == "map ") - { - backupRotation = getDvar("sv_mapRotation").current; - backupTimeLimit = Convert.ToInt32(getDvar("scr_" + Gametype + "_timelimit").current); - Utilities.executeCommand(PID, "sv_maprotation map " + CMD.ToLower().Substring(4, CMD.Length-4)); - Utilities.executeCommand(PID, "scr_" + Gametype + "_timelimit 0.001"); - Utilities.Wait(1); - Utilities.executeCommand(PID, "scr_" + Gametype + "_timelimit " + backupTimeLimit); - } - - else - Utilities.executeCommand(PID, CMD); - + Utilities.executeCommand(PID, CMD); } private dvar getDvar(String DvarName) { - return Utilities.getDvarValue(PID, DvarName); + return Utilities.getDvar(PID, DvarName); + } + + private void setDvar(String Dvar, String Value) + { + //Utilities.setDvar(PID, Dvar, Value); } [DllImport("kernel32.dll")] @@ -814,20 +803,30 @@ namespace IW4MAdmin { try { - // basic info dvars + // inject our dll + if (!Utilities.initalizeInterface(PID)) + { + Log.Write("Could not load IW4MAdmin interface!", IW4MAdmin.Log.Level.Debug); + return false; + } + // basic info dvars hostname = Utilities.stripColors(getDvar("sv_hostname").current); mapname = getDvar("mapname").current; IW_Ver = getDvar("shortversion").current; maxClients = Convert.ToInt32(getDvar("party_maxplayers").current); Gametype = getDvar("g_gametype").current; - // important log variables + // important log variables Basepath = getDvar("fs_basepath").current; Mod = getDvar("fs_game").current; logPath = getDvar("g_log").current; - //int logSync = Convert.ToInt32(getDvar("g_logSync").current); + int oneLog = Convert.ToInt32(getDvar("iw4m_onelog").current); - if (Mod == String.Empty) + // our settings + setDvar("sv_kickBanTime", "3600"); // 1 hour + setDvar("g_logSync", "1"); // yas + + if (Mod == String.Empty || oneLog == 1) logPath = Basepath + '\\' + "m2demo" + '\\' + logPath; else logPath = Basepath + '\\' + Mod + '\\' + logPath; diff --git a/Admin/Utilities.cs b/Admin/Utilities.cs index 3dc1d5f7b..92c1a4fc0 100644 --- a/Admin/Utilities.cs +++ b/Admin/Utilities.cs @@ -4,6 +4,7 @@ using System.Text; using System.Threading; using System.Text.RegularExpressions; using System.Runtime.InteropServices; +using System.IO; namespace IW4MAdmin { @@ -384,50 +385,61 @@ namespace IW4MAdmin [DllImport("kernel32.dll", SetLastError = true)] static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds); - public static dvar getDvar(int Location, int Handle) + [DllImport("kernel32.dll", SetLastError = true)] + static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName); + + [DllImport("kernel32.dll", SetLastError = true)] + static extern IntPtr GetModuleHandle(string lpModuleName); + + [DllImport("kernel32.dll", SetLastError = true)] + static extern int CloseHandle(IntPtr hObject); + + public static dvar getDvar(int Location, IntPtr Handle) { int numberRead = 0; Byte[] Buff = new Byte[72]; - Byte[] Ptr = new Byte[4]; - ReadProcessMemory(Handle, Location, Ptr, Ptr.Length, ref numberRead); // get location of dvar - - ReadProcessMemory(Handle, (int)BitConverter.ToUInt32(Ptr, 0), Buff, Buff.Length, ref numberRead); // read dvar memory + ReadProcessMemory((int)Handle, Location, Buff, Buff.Length, ref numberRead); // read dvar memory dvar_t dvar_raw = Helpers.ReadStruct(Buff); // get the dvar struct - dvar dvar_actual = new dvar(); // gotta convert to something readable - dvar_actual.name = getStringFromPointer((int)dvar_raw.name, Handle); - dvar_actual.description = getStringFromPointer((int)dvar_raw.description, Handle); + dvar_actual.name = getStringFromPointer((int)dvar_raw.name, (int)Handle); + dvar_actual.description = getStringFromPointer((int)dvar_raw.description, (int)Handle); if ((int)dvar_raw._default > short.MaxValue) - dvar_actual._default = getStringFromPointer((int)dvar_raw._default, Handle); + dvar_actual._default = getStringFromPointer((int)dvar_raw._default, (int)Handle); else dvar_actual._default = dvar_raw._default.ToString(); if ((int)dvar_raw.current > short.MaxValue) - dvar_actual.current = getStringFromPointer((int)dvar_raw.current, Handle); + dvar_actual.current = getStringFromPointer((int)dvar_raw.current, (int)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(); if ((int)dvar_raw.latched > short.MaxValue) - dvar_actual.latched = getStringFromPointer((int)dvar_raw.latched, Handle); + dvar_actual.latched = getStringFromPointer((int)dvar_raw.latched, (int)Handle); else dvar_actual.latched = dvar_raw.latched.ToString(); dvar_actual.type = dvar_raw.type; - dvar_actual.flags = getIntFromPointer((int)dvar_raw.flags, Handle); - dvar_actual.max = getIntFromPointer((int)dvar_raw.max, Handle); - dvar_actual.min = getIntFromPointer((int)dvar_raw.min, Handle); + dvar_actual.flags = getIntFromPointer((int)dvar_raw.flags, (int)Handle); + dvar_actual.max = getIntFromPointer((int)dvar_raw.max, (int)Handle); + dvar_actual.min = getIntFromPointer((int)dvar_raw.min, (int)Handle); // done! return dvar_actual; } + public static dvar getDvarOld(int Location, int Handle) + { + int loc = getIntFromPointer(Location, Handle); + return getDvar(loc, (IntPtr)Handle); + } + public static int getDvarCurrentAddress(int Location, int Handle) { int numberRead = 0; @@ -435,11 +447,9 @@ namespace IW4MAdmin Byte[] Ptr = new Byte[4]; ReadProcessMemory(Handle, Location, Ptr, Ptr.Length, ref numberRead); // get location of dvar - ReadProcessMemory(Handle, (int)BitConverter.ToUInt32(Ptr, 0), Buff, Buff.Length, ref numberRead); // read dvar memory dvar_t dvar_raw = Helpers.ReadStruct(Buff); // get the dvar struct - int current = (int)dvar_raw.current; return current; @@ -447,8 +457,8 @@ namespace IW4MAdmin public static void setDvar(int Location, int Handle, String Value) { - UIntPtr bytesWritten = UIntPtr.Zero; - WriteProcessMemory((IntPtr)Handle, (IntPtr)Location, Encoding.ASCII.GetBytes(Value), (uint)Value.Length, out bytesWritten); + //UIntPtr bytesWritten = UIntPtr.Zero; + //WriteProcessMemory((IntPtr)Handle, (IntPtr)Location, Encoding.ASCII.GetBytes(Value), (uint)Value.Length, out bytesWritten); } public static String getStringFromPointer(int Location, int Handle) @@ -491,7 +501,7 @@ namespace IW4MAdmin public static void executeCommand(int pID, String Command) { - IntPtr ProcessHandle = OpenProcess(ProcessAccessFlags.All, false, pID); + /*IntPtr ProcessHandle = OpenProcess(ProcessAccessFlags.All, false, pID); IntPtr memoryForCMDName = allocateAndWrite(Encoding.ASCII.GetBytes(Command + "\0"), ProcessHandle); uint threadID; @@ -521,13 +531,13 @@ namespace IW4MAdmin if (ThreadHandle == null || ThreadHandle == IntPtr.Zero) return; - WaitForSingleObject(ThreadHandle, 500000); + WaitForSingleObject(ThreadHandle, Int32.MaxValue); // gg if it doesn't finishe // cleanup if (!VirtualFreeEx(ProcessHandle, codeAllocation, 0, AllocationType.Release)) Console.WriteLine(Marshal.GetLastWin32Error()); if (!VirtualFreeEx(ProcessHandle, memoryForCMDName, 0, AllocationType.Release)) - Console.WriteLine(Marshal.GetLastWin32Error()); + Console.WriteLine(Marshal.GetLastWin32Error());*/ } @@ -559,19 +569,77 @@ namespace IW4MAdmin return true; } - public static dvar getDvarValue(int pID, String DVAR) + public static bool initalizeInterface(int pID) { - dvar requestedDvar = new dvar(); - uint threadID = 0; - IntPtr ProcessHandle = OpenProcess(ProcessAccessFlags.All, false, pID); + String Path = AppDomain.CurrentDomain.BaseDirectory + "lib\\AdminInterface.dll"; + + if (!File.Exists(Path)) + return false; + + UIntPtr bytesWritten; + uint threadID; + + IntPtr ProcessHandle = OpenProcess(ProcessAccessFlags.All, false, pID); + if (ProcessHandle == IntPtr.Zero) + return false; + + IntPtr lpLLAddress = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"); + + if (lpLLAddress == IntPtr.Zero) + return false; + + IntPtr pathAllocation = VirtualAllocEx(ProcessHandle, IntPtr.Zero, (uint)Path.Length + 1, AllocationType.Commit, MemoryProtection.ExecuteReadWrite); + + if (pathAllocation == IntPtr.Zero) + return false; + + byte[] pathBytes = Encoding.ASCII.GetBytes(Path); + + if (!WriteProcessMemory(ProcessHandle, pathAllocation, pathBytes, (uint)pathBytes.Length, out bytesWritten)) + return false; + + if (CreateRemoteThread(ProcessHandle, IntPtr.Zero, 0, lpLLAddress, pathAllocation, 0, out threadID) == IntPtr.Zero) + return false; + + CloseHandle(ProcessHandle); + + return true; + } + + public static void setDvar(int pID, String Name, String Value) + { + IntPtr ProcessHandle = OpenProcess(ProcessAccessFlags.All, false, pID); + IntPtr memoryForDvarName = allocateAndWrite(Encoding.ASCII.GetBytes(Name + " " + Value + "\0"), ProcessHandle); - IntPtr memoryForDvarName = allocateAndWrite(Encoding.ASCII.GetBytes(DVAR + "\0"), ProcessHandle); if (memoryForDvarName == IntPtr.Zero) + { Console.WriteLine("UNABLE TO ALLOCATE MEMORY FOR DVAR NAME"); + return; + } setDvarCurrentPtr((IntPtr)0x2098D9C, memoryForDvarName, ProcessHandle); - byte[] copyDvarValue = { + if (!VirtualFreeEx(ProcessHandle, memoryForDvarName, 0, AllocationType.Release)) + Console.WriteLine("Virtual Free Failed -- Error #" + Marshal.GetLastWin32Error()); + + CloseHandle(ProcessHandle); + } + + public static dvar getDvar(int pID, String DVAR) + { + dvar requestedDvar = new dvar(); + IntPtr ProcessHandle = OpenProcess(ProcessAccessFlags.All, false, pID); + IntPtr memoryForDvarName = allocateAndWrite(Encoding.ASCII.GetBytes(DVAR + "\0"), ProcessHandle); + + if (memoryForDvarName == IntPtr.Zero) + { + Console.WriteLine("UNABLE TO ALLOCATE MEMORY FOR DVAR NAME"); + return requestedDvar; + } + + setDvarCurrentPtr((IntPtr)0x2089E04, memoryForDvarName, ProcessHandle); // sv_debugRate +#if ASD + /* byte[] copyDvarValue = { 0x55, 0x8B, 0xEC, 0x83, 0xEC, 0x08, // ----------------------------------------------- 0xC7, 0x45, 0xFC, 0x9C, 0x8D, 0x09, // dvar_t** surogateDvar = (dvar_t**)(0x2098D9C); 0x02, 0x8B, 0x45, 0xFC, 0x8B, 0x08, // @@ -593,15 +661,25 @@ namespace IW4MAdmin if (ThreadHandle == null || ThreadHandle == IntPtr.Zero) return requestedDvar; - WaitForSingleObject(ThreadHandle, 500000); + WaitForSingleObject(ThreadHandle, Int32.MaxValue); // gg if thread doesn't finish if (!VirtualFreeEx(ProcessHandle, codeAllocation, 0, AllocationType.Release)) Console.WriteLine(Marshal.GetLastWin32Error()); if (!VirtualFreeEx(ProcessHandle, memoryForDvarName, 0, AllocationType.Release)) - Console.WriteLine(Marshal.GetLastWin32Error()); + Console.WriteLine(Marshal.GetLastWin32Error());*/ +#endif + Utilities.Wait(.3); + int dvarLoc = getIntFromPointer(0x2089E04, (int)ProcessHandle); // this is where the dvar is stored - int dvarLoc = getIntFromPointer(0x2098D9C, (int)ProcessHandle); - return getDvar(dvarLoc + 0x10, (int)ProcessHandle); + if (dvarLoc == 0) + return requestedDvar; + + dvarLoc = getIntFromPointer(dvarLoc + 0x10, (int)ProcessHandle); + + requestedDvar = getDvar(dvarLoc, ProcessHandle); + CloseHandle(ProcessHandle); + + return requestedDvar; } public static String timesConnected(int connection) diff --git a/Admin/WebFront.cs b/Admin/WebFront.cs index 38c6de7cd..2264d0151 100644 --- a/Admin/WebFront.cs +++ b/Admin/WebFront.cs @@ -95,6 +95,9 @@ namespace IW4MAdmin_Web int cycleFix = 0; for (int i = 0; i < Servers.Count(); i++) { + if (IW4MAdmin.Program.getServers()[i] == null) + continue; + StringBuilder players = new StringBuilder(); if (Servers[i].getClientNum() < 1) players.Append("

No Players

"); @@ -577,7 +580,7 @@ namespace IW4MAdmin_Web body = Macro.findMacros(header + main + footer, toSend, server); } - IW4MAdmin.Program.getServers()[server].Log.Write("Webfront processed request for " + request.Uri, IW4MAdmin.Log.Level.Debug); + //IW4MAdmin.Program.getServers()[server].Log.Write("Webfront processed request for " + request.Uri, IW4MAdmin.Log.Level.Debug); } var headers = new HttpResponseHead() diff --git a/Admin/lib/AdminInterface.dll b/Admin/lib/AdminInterface.dll new file mode 100644 index 000000000..b16bcd923 Binary files /dev/null and b/Admin/lib/AdminInterface.dll differ diff --git a/Admin/version.txt b/Admin/version.txt index 4102f2667..928202d55 100644 --- a/Admin/version.txt +++ b/Admin/version.txt @@ -2,6 +2,7 @@ CHANGELOG: -fixed issue with `history` timelime -fixed issue with mapname not being updated +-fixed rare crash related to !list -now reads memory for player info! ( experimental debug only ) VERSION: 0.9