More memory reading changes. We're getting there.
This commit is contained in:
parent
b8557fdb81
commit
6b381a214d
@ -799,7 +799,7 @@ namespace IW4MAdmin
|
||||
public override void Execute(Event E)
|
||||
{
|
||||
String[] Response = E.Owner.RCON.addRCON(E.Data.Trim());
|
||||
if (Response.Length > 0)
|
||||
if (Response != null && Response.Length > 0)
|
||||
E.Origin.Tell("Successfuly sent RCON command!");
|
||||
}
|
||||
}
|
||||
|
@ -17,12 +17,29 @@ namespace IW4MAdmin
|
||||
Directory.CreateDirectory(_Directory);
|
||||
|
||||
if (!File.Exists(fileName))
|
||||
{
|
||||
FileStream penis = File.Create(fileName);
|
||||
penis.Close();
|
||||
{
|
||||
try
|
||||
{
|
||||
FileStream penis = File.Create(fileName);
|
||||
penis.Close();
|
||||
}
|
||||
|
||||
catch
|
||||
{
|
||||
//Console.WriteLine("Unable to open log file for writing!");
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Handle = new StreamReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
|
||||
sze = Handle.BaseStream.Length;
|
||||
}
|
||||
|
||||
catch
|
||||
{
|
||||
//Console.WriteLine("Unable to open log file for writing!");
|
||||
}
|
||||
Handle = new StreamReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
|
||||
sze = Handle.BaseStream.Length;
|
||||
}
|
||||
|
||||
public file(String file, bool write)
|
||||
@ -41,8 +58,11 @@ namespace IW4MAdmin
|
||||
|
||||
public void Write(String line)
|
||||
{
|
||||
writeHandle.WriteLine(line);
|
||||
writeHandle.Flush();
|
||||
if (writeHandle != null)
|
||||
{
|
||||
writeHandle.WriteLine(line);
|
||||
writeHandle.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
public String[] getParameters(int num)
|
||||
|
@ -11,6 +11,7 @@ namespace IW4MAdmin
|
||||
static public double Version = 0.91;
|
||||
static public double latestVersion;
|
||||
static public bool usingMemory = true;
|
||||
static private Manager serverManager;
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
@ -36,13 +37,14 @@ namespace IW4MAdmin
|
||||
monitorThread.Start();
|
||||
}
|
||||
#endif
|
||||
IW4MAdmin.Manager IW4MAdmin = new IW4MAdmin.Manager();
|
||||
IW4MAdmin.Init();
|
||||
IW4MAdmin.Manager serverManager = new IW4MAdmin.Manager();
|
||||
serverManager.Init();
|
||||
|
||||
Console.WriteLine("IW4M Now Initialized! Visit http://127.0.0.1:1624 for server overview.");
|
||||
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();
|
||||
frontEnd.Init();
|
||||
//IW4MAdmin_Web.WebFront frontEnd = new IW4MAdmin_Web.WebFront(serverManager.getServers());
|
||||
//frontEnd.Init();
|
||||
}
|
||||
#if DEBUG
|
||||
static void setupConfig()
|
||||
@ -68,12 +70,17 @@ namespace IW4MAdmin
|
||||
}
|
||||
#endif
|
||||
|
||||
static String checkUpdate()
|
||||
static private String checkUpdate()
|
||||
{
|
||||
Connection Ver = new Connection("http://raidmax.org/IW4M/Admin/version.php");
|
||||
return Ver.Read();
|
||||
}
|
||||
|
||||
static public List<Server> getServers()
|
||||
{
|
||||
return serverManager.getServers();
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
static List<Server> checkConfig()
|
||||
{
|
||||
|
@ -14,15 +14,27 @@ namespace IW4MAdmin
|
||||
private List<Server> Servers;
|
||||
private SortedDictionary<int, Thread> ThreadList;
|
||||
private List<int> activePIDs;
|
||||
private Log mainLog;
|
||||
|
||||
public Manager()
|
||||
{
|
||||
ThreadList = new SortedDictionary<int, Thread>();
|
||||
file logFile = new file("IW4MAdmin_ApplicationLog.log");
|
||||
mainLog = new Log(logFile, Log.Level.All, 0);
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
activePIDs = getCurrentIW4MProcesses();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Servers = loadServers();
|
||||
|
||||
foreach (Server S in Servers)
|
||||
@ -31,12 +43,16 @@ namespace IW4MAdmin
|
||||
Thread IW4MServerThread = new Thread(IW4MServer.Monitor);
|
||||
ThreadList.Add(IW4MServer.pID(), IW4MServerThread);
|
||||
IW4MServerThread.Start();
|
||||
|
||||
//mainLog.Write("Now monitoring the server running on port " + IW4MServer.getPort(), Log.Level.All);
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
List<Server> defunctServers = new List<Server>();
|
||||
lock (Servers)
|
||||
{
|
||||
|
||||
foreach (Server S in Servers)
|
||||
{
|
||||
if (S == null)
|
||||
@ -50,22 +66,34 @@ namespace IW4MAdmin
|
||||
Defunct.Abort();
|
||||
ThreadList[S.pID()] = null;
|
||||
}
|
||||
mainLog.Write("Server with PID #" + S.pID() + " no longer appears to be running.", Log.Level.All);
|
||||
activePIDs.Remove(S.pID());
|
||||
defunctServers.Add(S);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Server S in defunctServers)
|
||||
Servers.Remove(S);
|
||||
defunctServers = null;
|
||||
|
||||
scanForNewServers();
|
||||
Utilities.Wait(5);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Server> getServers()
|
||||
{
|
||||
return Servers;
|
||||
}
|
||||
|
||||
private void scanForNewServers()
|
||||
{
|
||||
List<int> newProcesses = getCurrentIW4MProcesses();
|
||||
foreach (int pID in activePIDs)
|
||||
foreach (int pID in newProcesses)
|
||||
{
|
||||
bool newProcess = true;
|
||||
foreach (int I in newProcesses)
|
||||
foreach (int I in activePIDs)
|
||||
{
|
||||
if (I == pID)
|
||||
newProcess = false;
|
||||
@ -73,12 +101,16 @@ namespace IW4MAdmin
|
||||
|
||||
if (newProcess)
|
||||
{
|
||||
Server S = loadIndividualServer(pID);
|
||||
Servers.Add(S);
|
||||
Thread IW4MServerThread = new Thread(S.Monitor);
|
||||
ThreadList.Add(pID, IW4MServerThread);
|
||||
|
||||
IW4MServerThread.Start();
|
||||
if (!ThreadList.ContainsKey(pID))
|
||||
{
|
||||
Server S = loadIndividualServer(pID);
|
||||
Servers.Add(S);
|
||||
Thread IW4MServerThread = new Thread(S.Monitor);
|
||||
ThreadList.Add(pID, IW4MServerThread);
|
||||
mainLog.Write("New server dectected on port " + S.getPort(), Log.Level.All);
|
||||
IW4MServerThread.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,14 +120,19 @@ namespace IW4MAdmin
|
||||
{
|
||||
if (pID > 0)
|
||||
{
|
||||
Process P = Process.GetProcessById(pID);
|
||||
if (P.ProcessName.Length == 0)
|
||||
try
|
||||
{
|
||||
Process P = Process.GetProcessById(pID);
|
||||
return true;
|
||||
}
|
||||
|
||||
catch (System.ArgumentException)
|
||||
{
|
||||
return false;
|
||||
Console.WriteLine("Server with PID #" + pID + " doesn't seem to be running anymore");
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -141,12 +178,24 @@ namespace IW4MAdmin
|
||||
IntPtr Handle = OpenProcess(0x10, false, pID);
|
||||
if (Handle != null)
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
return 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 new Server(net_ip.current, Convert.ToInt32(net_port.current), "", (int)Handle, pID);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -18,9 +18,9 @@ namespace IW4MAdmin
|
||||
|
||||
public RCON(Server I)
|
||||
{
|
||||
sv_connection = new UdpClient();
|
||||
sv_connection.Client.SendTimeout = 1000;
|
||||
sv_connection.Client.ReceiveTimeout = 1000;
|
||||
//sv_connection = new UdpClient();
|
||||
// sv_connection.Client.SendTimeout = 1000;
|
||||
//sv_connection.Client.ReceiveTimeout = 1000;
|
||||
Instance = I;
|
||||
toSend = new Queue<RCON_Request>();
|
||||
}
|
||||
@ -112,7 +112,8 @@ namespace IW4MAdmin
|
||||
if (toSend.Count > 0)
|
||||
{
|
||||
RCON_Request Current = toSend.Peek();
|
||||
Current.Response = responseSendRCON(Current.Request);
|
||||
//Current.Response = responseSendRCON(Current.Request);
|
||||
Utilities.executeCommand(Instance.pID(), Current.Request);
|
||||
toSend.Dequeue();
|
||||
Utilities.Wait(0.567);
|
||||
}
|
||||
|
274
Admin/Server.cs
274
Admin/Server.cs
@ -19,7 +19,6 @@ namespace IW4MAdmin
|
||||
Handle = H;
|
||||
IP = address;
|
||||
Port = port;
|
||||
rcon_pass = password;
|
||||
clientnum = 0;
|
||||
RCON = new RCON(this);
|
||||
logFile = new file("admin_" + port + ".log", true);
|
||||
@ -528,6 +527,31 @@ 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);
|
||||
|
||||
}
|
||||
|
||||
private dvar getDvar(String DvarName)
|
||||
{
|
||||
return Utilities.getDvarValue(PID, DvarName);
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
|
||||
|
||||
@ -562,6 +586,9 @@ namespace IW4MAdmin
|
||||
Utilities.Wait(10);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if DEBUG
|
||||
//Thread to handle polling server for IP's
|
||||
Thread statusUpdate = new Thread(new ThreadStart(pollServer));
|
||||
@ -784,197 +811,38 @@ namespace IW4MAdmin
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//Vital RCON commands to establish log file and server name. May need to cleanup in the future
|
||||
#if USINGMEMORY
|
||||
private bool initializeBasics()
|
||||
{
|
||||
dvar map = Utilities.getDvar(0x2098DDC, Handle);
|
||||
|
||||
String mapOut;
|
||||
|
||||
mapname = map.current;
|
||||
|
||||
dvar sv_hostname = Utilities.getDvar(0x2098D98, Handle);
|
||||
hostname = sv_hostname.current;
|
||||
|
||||
dvar shortversion = Utilities.getDvar(0x1AD79D0, Handle);
|
||||
IW_Ver = shortversion.current;
|
||||
|
||||
dvar party_maxplayers = Utilities.getDvar(0x1080998, Handle);
|
||||
maxClients = Convert.ToInt32(party_maxplayers.current);
|
||||
|
||||
dvar g_gametype = Utilities.getDvar(0x1AD7934, Handle);
|
||||
Gametype = g_gametype.current;
|
||||
|
||||
// skipping website b/c dynamically allocated ( we will pick it up on maprotate )
|
||||
}
|
||||
#else
|
||||
private bool intializeBasics()
|
||||
{
|
||||
try
|
||||
{
|
||||
String[] infoResponse = RCON.addRCON("getstatus");
|
||||
|
||||
if (infoResponse == null || infoResponse.Length < 2)
|
||||
{
|
||||
Log.Write("Could not get server status!", Log.Level.All);
|
||||
hostname = "Offline"; // for the web front
|
||||
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;
|
||||
|
||||
infoResponse = infoResponse[1].Split('\\');
|
||||
Dictionary<String, String> infoResponseDict = new Dictionary<string, string>();
|
||||
// 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);
|
||||
|
||||
for (int i = 0; i < infoResponse.Length; i++)
|
||||
{
|
||||
if (i%2 == 0 || infoResponse[i] == String.Empty)
|
||||
continue;
|
||||
infoResponseDict.Add(infoResponse[i], infoResponse[i+1]);
|
||||
}
|
||||
if (Mod == String.Empty)
|
||||
logPath = Basepath + '\\' + "m2demo" + '\\' + logPath;
|
||||
else
|
||||
logPath = Basepath + '\\' + Mod + '\\' + logPath;
|
||||
|
||||
mapname = infoResponseDict["mapname"];
|
||||
try
|
||||
{
|
||||
mapname = maps.Find(m => m.Name.Equals(mapname)).Alias;
|
||||
}
|
||||
|
||||
catch(Exception)
|
||||
{
|
||||
Log.Write(mapname + " doesn't appear to be in the maps.cfg", Log.Level.Debug);
|
||||
}
|
||||
|
||||
hostname = Utilities.stripColors(infoResponseDict["sv_hostname"]);
|
||||
IW_Ver = infoResponseDict["shortversion"];
|
||||
maxClients = Convert.ToInt32(infoResponseDict["sv_maxclients"]);
|
||||
Gametype = infoResponseDict["g_gametype"];
|
||||
|
||||
try
|
||||
{
|
||||
Website = infoResponseDict["_website"];
|
||||
}
|
||||
|
||||
catch (Exception)
|
||||
{
|
||||
Website = "this server's website";
|
||||
Log.Write("Seems not to have website specified", Log.Level.Debug);
|
||||
}
|
||||
|
||||
String[] p = RCON.addRCON("fs_basepath");
|
||||
|
||||
if (p == null)
|
||||
{
|
||||
Log.Write("Could not obtain basepath!", Log.Level.All);
|
||||
return false;
|
||||
}
|
||||
|
||||
p = p[1].Split('"');
|
||||
Basepath = p[3].Substring(0, p[3].Length - 2).Trim();
|
||||
p = null;
|
||||
//END
|
||||
|
||||
//get fs_game
|
||||
p = RCON.addRCON("fs_game");
|
||||
|
||||
if (p == null)
|
||||
{
|
||||
Log.Write("Could not obtain mod path!", Log.Level.All);
|
||||
return false;
|
||||
}
|
||||
|
||||
p = p[1].Split('"');
|
||||
Mod = p[3].Substring(0, p[3].Length - 2).Trim().Replace('/', '\\');
|
||||
p = null;
|
||||
|
||||
//END
|
||||
|
||||
//get g_log
|
||||
p = RCON.addRCON("g_log");
|
||||
|
||||
if (p == null)
|
||||
{
|
||||
Log.Write("Could not obtain log path!", Log.Level.All);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (p.Length < 4)
|
||||
{
|
||||
Thread.Sleep(FLOOD_TIMEOUT);
|
||||
Log.Write("Server does not appear to have map loaded. Please map_rotate", Log.Level.All);
|
||||
return false;
|
||||
}
|
||||
|
||||
p = p[1].Split('"');
|
||||
string log = p[3].Substring(0, p[3].Length - 2).Trim();
|
||||
p = null;
|
||||
|
||||
//END
|
||||
|
||||
//get g_logsync
|
||||
p = RCON.addRCON("g_logsync");
|
||||
|
||||
if (p == null)
|
||||
{
|
||||
Log.Write("Could not obtain log sync status!", Log.Level.All);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
p = p[1].Split('"');
|
||||
int logsync = Convert.ToInt32(p[3].Substring(0, p[3].Length - 2).Trim());
|
||||
p = null;
|
||||
|
||||
if (logsync != 1)
|
||||
RCON.addRCON("g_logsync 1");
|
||||
//END
|
||||
|
||||
//get iw4m_onelog
|
||||
p = RCON.addRCON("iw4m_onelog");
|
||||
|
||||
if (p[0] == String.Empty || p[1].Length < 15)
|
||||
{
|
||||
Log.Write("Could not obtain iw4m_onelog value!", Log.Level.All);
|
||||
return false;
|
||||
}
|
||||
|
||||
p = p[1].Split('"');
|
||||
string onelog = p[3].Substring(0, p[3].Length - 2).Trim();
|
||||
p = null;
|
||||
//END
|
||||
|
||||
if (Mod == String.Empty || onelog == "1")
|
||||
logPath = Basepath + '\\' + "m2demo" + '\\' + log;
|
||||
else
|
||||
logPath = Basepath + '\\' + Mod + '\\' + log;
|
||||
|
||||
if (!File.Exists(logPath))
|
||||
{
|
||||
Log.Write("Gamelog does not exist!", Log.Level.All);
|
||||
return false;
|
||||
}
|
||||
|
||||
logFile = new file(logPath);
|
||||
Log.Write("Log file is " + logPath, Log.Level.Debug);
|
||||
|
||||
//get players ip's
|
||||
p = RCON.addRCON("status");
|
||||
if (p == null)
|
||||
{
|
||||
Log.Write("Unable to get initial player list!", Log.Level.Debug);
|
||||
if (!File.Exists(logPath))
|
||||
{
|
||||
Log.Write("Gamelog does not exist!", Log.Level.All);
|
||||
return false;
|
||||
}
|
||||
|
||||
lastPoll = DateTime.Now;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
/* 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();*/
|
||||
//logPath = "games_old.log";
|
||||
#endif
|
||||
Log.Write("Now monitoring " + this.getName(), Log.Level.All);
|
||||
return true;
|
||||
logFile = new file(logPath);
|
||||
Log.Write("Log file is " + logPath, Log.Level.Production);
|
||||
Log.Write("Now monitoring " + this.getName(), Log.Level.Production);
|
||||
return true;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
@ -982,21 +850,10 @@ namespace IW4MAdmin
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//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)
|
||||
Log.Write("Connect event triggered, but no client is detected!", Log.Level.Debug);
|
||||
addPlayer(E.Origin);
|
||||
return true;
|
||||
}*/
|
||||
#endif
|
||||
|
||||
if (E.Type == Event.GType.Connect)
|
||||
{
|
||||
return true;
|
||||
@ -1134,6 +991,8 @@ 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<String, String> infoResponseDict = new Dictionary<String, String>();
|
||||
String[] infoResponse = E.Data.Split('\\');
|
||||
@ -1215,14 +1074,7 @@ namespace IW4MAdmin
|
||||
public void Tell(String Message, Player Target)
|
||||
{
|
||||
if (Target.getClientNum() > -1)
|
||||
{
|
||||
#if DEBUG
|
||||
RCON.addRCON("tell " + Target.getClientNum() + " " + Message + "^7");
|
||||
|
||||
#else
|
||||
RCON.addRCON("tellraw " + Target.getClientNum() + " " + Message + "^7"); // I fixed tellraw :>
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public void Kick(String Message, Player Target)
|
||||
@ -1269,13 +1121,11 @@ namespace IW4MAdmin
|
||||
{
|
||||
clientDB.removeBan(Target.getID(), Target.getIP());
|
||||
|
||||
|
||||
for (int i = 0; i < IW4MAdmin.Program.Servers.Count; i++)
|
||||
IW4MAdmin.Program.Servers[i].Bans = IW4MAdmin.Program.Servers[i].clientDB.getBans();
|
||||
|
||||
Player P = clientDB.getPlayer(Target.getID(), -1);
|
||||
P.setLevel(Player.Permission.User);
|
||||
clientDB.updatePlayer(P);
|
||||
|
||||
Bans = clientDB.getBans();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1292,7 +1142,7 @@ namespace IW4MAdmin
|
||||
public void mapRotate(int delay)
|
||||
{
|
||||
Utilities.Wait(delay);
|
||||
RCON.addRCON("map_rotate");
|
||||
executeCommand("map_rotate");
|
||||
}
|
||||
|
||||
public void tempBan(String Message, Player Target)
|
||||
@ -1302,12 +1152,12 @@ namespace IW4MAdmin
|
||||
|
||||
public void mapRotate()
|
||||
{
|
||||
RCON.addRCON("map_rotate");
|
||||
mapRotate(0);
|
||||
}
|
||||
|
||||
public void Map(String map)
|
||||
public void Map(String mapName)
|
||||
{
|
||||
RCON.addRCON("map " + map);
|
||||
executeCommand("map " + mapName);
|
||||
}
|
||||
|
||||
public String Wisdom()
|
||||
@ -1531,6 +1381,8 @@ namespace IW4MAdmin
|
||||
private DateTime lastWebChat;
|
||||
private int Handle;
|
||||
private int PID;
|
||||
private String backupRotation;
|
||||
private int backupTimeLimit;
|
||||
|
||||
//Will probably move this later
|
||||
public Dictionary<String, Player> statusPlayers;
|
||||
|
@ -315,12 +315,72 @@ namespace IW4MAdmin
|
||||
return "a very long time";
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum ProcessAccessFlags : uint
|
||||
{
|
||||
Terminate = 0x00000001,
|
||||
CreateThread = 0x00000002,
|
||||
VMOperation = 0x00000008,
|
||||
VMRead = 0x00000010,
|
||||
VMWrite = 0x00000020,
|
||||
DupHandle = 0x00000040,
|
||||
SetInformation = 0x00000200,
|
||||
QueryInformation = 0x00000400,
|
||||
Synchronize = 0x00100000,
|
||||
All = 0x001F0FFF
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum AllocationType
|
||||
{
|
||||
Commit = 0x00001000,
|
||||
Reserve = 0x00002000,
|
||||
Decommit = 0x00004000,
|
||||
Release = 0x00008000,
|
||||
Reset = 0x00080000,
|
||||
TopDown = 0x00100000,
|
||||
WriteWatch = 0x00200000,
|
||||
Physical = 0x00400000,
|
||||
LargePages = 0x20000000
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum MemoryProtection
|
||||
{
|
||||
NoAccess = 0x0001,
|
||||
ReadOnly = 0x0002,
|
||||
ReadWrite = 0x0004,
|
||||
WriteCopy = 0x0008,
|
||||
Execute = 0x0010,
|
||||
ExecuteRead = 0x0020,
|
||||
ExecuteReadWrite = 0x0040,
|
||||
ExecuteWriteCopy = 0x0080,
|
||||
GuardModifierflag = 0x0100,
|
||||
NoCacheModifierflag = 0x0200,
|
||||
WriteCombineModifierflag = 0x0400
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
|
||||
public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, bool bInheritHandle, int dwProcessId);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern bool ReadProcessMemory(int hProcess, int lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
static extern bool TerminateThread(IntPtr hThread, uint dwExitCode);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, AllocationType flAllocationType, MemoryProtection flProtect);
|
||||
|
||||
[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)]
|
||||
static extern bool VirtualFree(IntPtr lpAddress, UIntPtr dwSize, AllocationType type);
|
||||
|
||||
public static dvar getDvar(int Location, int Handle)
|
||||
{
|
||||
int numberRead = 0;
|
||||
@ -363,6 +423,29 @@ namespace IW4MAdmin
|
||||
return dvar_actual;
|
||||
}
|
||||
|
||||
public static int getDvarCurrentAddress(int Location, int 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
|
||||
|
||||
dvar_t dvar_raw = Helpers.ReadStruct<dvar_t>(Buff); // get the dvar struct
|
||||
|
||||
int current = (int)dvar_raw.current;
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public static String getStringFromPointer(int Location, int Handle)
|
||||
{
|
||||
int numberRead = 0;
|
||||
@ -391,6 +474,124 @@ namespace IW4MAdmin
|
||||
return BitConverter.ToInt32(Buff, 0);
|
||||
}
|
||||
|
||||
public static Boolean getBoolFromPointer(int Location, int Handle)
|
||||
{
|
||||
int numberRead = 0;
|
||||
Byte[] Buff = new Byte[1];
|
||||
|
||||
ReadProcessMemory(Handle, Location, Buff, Buff.Length, ref numberRead);
|
||||
|
||||
return BitConverter.ToBoolean(Buff, 0);
|
||||
}
|
||||
|
||||
public static void executeCommand(int pID, String Command)
|
||||
{
|
||||
IntPtr ProcessHandle = OpenProcess(ProcessAccessFlags.All, false, pID);
|
||||
IntPtr memoryForCMDName = allocateAndWrite(Encoding.ASCII.GetBytes(Command + "\0"), ProcessHandle);
|
||||
uint threadID;
|
||||
|
||||
if (memoryForCMDName == IntPtr.Zero)
|
||||
return;
|
||||
|
||||
// set the dvar's current value pointer to our desired command
|
||||
setDvarCurrentPtr((IntPtr)0x2098D9C, memoryForCMDName, ProcessHandle);
|
||||
|
||||
// assembly instruction to execute the command we want stored in `surogate` dvar
|
||||
byte[] executeCMD = {
|
||||
0x55, 0x8B, 0xEC, 0x51, 0xC7, 0x45, 0xFC, // ---------------------------------------------
|
||||
0x9C, 0x8D, 0x09, 0x02, 0x8B, 0x45, 0xFC, // dvar_t** dvarWithCMD = (dvar_t**)(0x2098D9C);
|
||||
0x8B, 0x08, 0x8B, 0x51, 0x10, 0x52, 0x6A,
|
||||
0x00, 0x6A, 0x00, 0xFF, 0x15, 0x1C, 0x53, // Cmd_ExecuteSingleCommand(0, 0, (*dvarWithCMD)->current.string );
|
||||
0x11, 0x10, 0x83, 0xC4, 0x0C, 0x8B, 0xE5, // ---------------------------------------------
|
||||
0x5D, 0xC3
|
||||
};
|
||||
|
||||
// allocate the memory for the assembly command and write it
|
||||
IntPtr codeAllocation = allocateAndWrite(executeCMD, ProcessHandle);
|
||||
if (codeAllocation == IntPtr.Zero)
|
||||
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);
|
||||
|
||||
// cleanup
|
||||
if (!VirtualFree(codeAllocation, (UIntPtr)executeCMD.Length, AllocationType.Decommit))
|
||||
Thread.Sleep(1);
|
||||
if (!VirtualFree(memoryForCMDName, (UIntPtr)Command.Length + 1, AllocationType.Decommit))
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
|
||||
public static IntPtr allocateAndWrite(Byte[] Data, IntPtr ProcessHandle)
|
||||
{
|
||||
UIntPtr bytesWritten;
|
||||
IntPtr AllocatedMemory = VirtualAllocEx(ProcessHandle, IntPtr.Zero, (uint)Data.Length, AllocationType.Commit, MemoryProtection.ExecuteReadWrite);
|
||||
if (!WriteProcessMemory(ProcessHandle, AllocatedMemory, Data, (uint)Data.Length, out bytesWritten))
|
||||
{
|
||||
Console.WriteLine("UNABLE TO WRITE PROCESS MEMORY!");
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
if ((int)bytesWritten != Data.Length)
|
||||
return IntPtr.Zero;
|
||||
else
|
||||
return AllocatedMemory;
|
||||
}
|
||||
|
||||
public static bool setDvarCurrentPtr(IntPtr DvarAddress, IntPtr ValueAddress, IntPtr ProcessHandle)
|
||||
{
|
||||
int locationOfCurrentPtr = getIntFromPointer((int)DvarAddress, (int)ProcessHandle) + 0x10;
|
||||
Byte[] newTextPtr = BitConverter.GetBytes((int)ValueAddress);
|
||||
UIntPtr bytesWritten;
|
||||
if (!WriteProcessMemory(ProcessHandle, (IntPtr)locationOfCurrentPtr, newTextPtr, (uint)newTextPtr.Length, out bytesWritten))
|
||||
return false;
|
||||
if (newTextPtr.Length != (int)bytesWritten)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static dvar getDvarValue(int pID, String DVAR)
|
||||
{
|
||||
uint threadID = 0;
|
||||
|
||||
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");
|
||||
|
||||
setDvarCurrentPtr((IntPtr)0x2098D9C, memoryForDvarName, ProcessHandle);
|
||||
|
||||
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, //
|
||||
0x8B, 0x51, 0x10, 0x52, 0xFF, 0x15, // dvar_t *newDvar = Dvar_FindVar((*surogateDvar)->current.string);
|
||||
0x6C, 0x53, 0x11, 0x10, 0x83, 0xC4, //
|
||||
0x04, 0x89, 0x45, 0xF8, 0x83, 0x7D, // if (newDvar)
|
||||
0xF8, 0x00, 0x74, 0x0B, 0x8B, 0x45, //
|
||||
0xFC, 0x8B, 0x08, 0x8B, 0x55, 0xF8, // (*surogateDvar)->current.integer = (int)newDvar;
|
||||
0x89, 0x51, 0x10, 0x8B, 0xE5, 0x5D, // -----------------------------------------------
|
||||
0xC3
|
||||
};
|
||||
|
||||
IntPtr codeAllocation = allocateAndWrite(copyDvarValue, ProcessHandle);
|
||||
|
||||
if (codeAllocation == IntPtr.Zero)
|
||||
Console.WriteLine("UNABLE TO ALLOCATE MEMORY FOR CODE");
|
||||
|
||||
IntPtr ThreadHandle = CreateRemoteThread(ProcessHandle, IntPtr.Zero, 0, codeAllocation, IntPtr.Zero, 0, out threadID);
|
||||
|
||||
if (!VirtualFree(codeAllocation, UIntPtr.Zero, AllocationType.Release))
|
||||
Thread.Sleep(1);
|
||||
if (!VirtualFree(memoryForDvarName, UIntPtr.Zero, AllocationType.Release))
|
||||
Thread.Sleep(1);
|
||||
|
||||
int dvarLoc = getIntFromPointer(0x2098D9C, (int)ProcessHandle);
|
||||
//int ptrToOurDvar = getIntFromPointer(dvarLoc +, (int)ProcessHandle);
|
||||
return getDvar(dvarLoc + 0x10, (int)ProcessHandle);
|
||||
}
|
||||
|
||||
public static String timesConnected(int connection)
|
||||
{
|
||||
String Prefix = String.Empty;
|
||||
|
@ -8,7 +8,7 @@ using Kayak;
|
||||
using Kayak.Http;
|
||||
using System.Net;
|
||||
|
||||
|
||||
#if DEBUG
|
||||
namespace IW4MAdmin_Web
|
||||
{
|
||||
class Client
|
||||
@ -32,6 +32,8 @@ namespace IW4MAdmin_Web
|
||||
|
||||
class WebFront
|
||||
{
|
||||
private List<IW4MAdmin.Server> Servers;
|
||||
|
||||
public enum Page
|
||||
{
|
||||
main,
|
||||
@ -40,9 +42,9 @@ namespace IW4MAdmin_Web
|
||||
player
|
||||
}
|
||||
|
||||
public WebFront()
|
||||
public WebFront(List<IW4MAdmin.Server> curServers)
|
||||
{
|
||||
|
||||
Servers = curServers;
|
||||
}
|
||||
|
||||
public void Init()
|
||||
@ -87,19 +89,18 @@ namespace IW4MAdmin_Web
|
||||
switch (input)
|
||||
{
|
||||
case "SERVERS":
|
||||
var Servers = IW4MAdmin.Program.Servers;
|
||||
int cycleFix = 0;
|
||||
for (int i = 0; i < Servers.Count; i++)
|
||||
foreach (IW4MAdmin.Server S in IW4MAdmin.Program.getServers())
|
||||
{
|
||||
StringBuilder players = new StringBuilder();
|
||||
if (Servers[i].getClientNum() < 1)
|
||||
if (S.getClientNum() < 1)
|
||||
players.Append("<h2>No Players</h2>");
|
||||
else
|
||||
{
|
||||
int count = 0;
|
||||
double currentPlayers = Servers[i].statusPlayers.Count;
|
||||
double currentPlayers = S.statusPlayers.Count;
|
||||
|
||||
foreach (IW4MAdmin.Player P in Servers[i].getPlayers())
|
||||
foreach (IW4MAdmin.Player P in S.getPlayers())
|
||||
{
|
||||
if (P == null)
|
||||
continue;
|
||||
@ -119,7 +120,7 @@ namespace IW4MAdmin_Web
|
||||
}
|
||||
}
|
||||
|
||||
players.AppendFormat("<td><a href='/{0}/{1}/userip/?player'>{2}</a></td>", i, P.getDBID(), IW4MAdmin.Utilities.nameHTMLFormatted(P));
|
||||
players.AppendFormat("<td><a href='/{0}/{1}/userip/?player'>{2}</a></td>", S.pID(), P.getDBID(), IW4MAdmin.Utilities.nameHTMLFormatted(P));
|
||||
|
||||
if (count % 2 != 0)
|
||||
{
|
||||
@ -144,10 +145,10 @@ namespace IW4MAdmin_Web
|
||||
<table cellpadding='0' cellspacing='0' class='players'>
|
||||
{5}
|
||||
</table>",
|
||||
Servers[i].getName(), Servers[i].getMap(), Servers[i].getClientNum() + "/" + Servers[i].getMaxClients(), IW4MAdmin.Utilities.gametypeLocalized(Servers[i].getGametype()), i, players.ToString());
|
||||
buffer.AppendFormat("<div class='chatHistory' id='chatHistory_{0}'></div><script type='text/javascript'>$( document ).ready(function() {{ setInterval({1}loadChatMessages({0}, '#chatHistory_{0}'){1}, 2500); }});</script><div class='null' style='clear:both;'></div>", i, '\"');
|
||||
if (Servers[i].getClientNum() > 0)
|
||||
buffer.AppendFormat("<form class='chatOutFormat' action={1}javascript:chatRequest({0}, 'chatEntry_{0}'){1}><input class='chatFormat_text' type='text' placeholder='Enter a message...' id='chatEntry_{0}'/><input class='chatFormat_submit' type='submit'/></form>", i, '\"');
|
||||
S.getName(), S.getMap(), S.getClientNum() + "/" + S.getMaxClients(), IW4MAdmin.Utilities.gametypeLocalized(S.getGametype()), S.pID(), players.ToString());
|
||||
buffer.AppendFormat("<div class='chatHistory' id='chatHistory_{0}'></div><script type='text/javascript'>$( document ).ready(function() {{ setInterval({1}loadChatMessages({0}, '#chatHistory_{0}'){1}, 2500); }});</script><div class='null' style='clear:both;'></div>", S.pID(), '\"');
|
||||
if (S.getClientNum() > 0)
|
||||
buffer.AppendFormat("<form class='chatOutFormat' action={1}javascript:chatRequest({0}, 'chatEntry_{0}'){1}><input class='chatFormat_text' type='text' placeholder='Enter a message...' id='chatEntry_{0}'/><input class='chatFormat_submit' type='submit'/></form>", server.pID(), '\"');
|
||||
buffer.Append("<hr/>");
|
||||
}
|
||||
return buffer.ToString();
|
||||
@ -155,7 +156,7 @@ namespace IW4MAdmin_Web
|
||||
return "IW4M Administration";
|
||||
case "BANS":
|
||||
buffer.Append("<table cellspacing=0 class=bans>");
|
||||
int totalBans = IW4MAdmin.Program.Servers[0].Bans.Count;
|
||||
int totalBans = IW4MAdmin.Program.getServers()[0].Bans.Count;
|
||||
int range;
|
||||
int start = Pagination*30;
|
||||
cycleFix = 0;
|
||||
@ -170,7 +171,7 @@ namespace IW4MAdmin_Web
|
||||
List<IW4MAdmin.Ban> Bans = new List<IW4MAdmin.Ban>();
|
||||
|
||||
if (totalBans > 0)
|
||||
Bans = IW4MAdmin.Program.Servers[0].Bans.GetRange(start, range).OrderByDescending(x => x.getTime()).ToList();
|
||||
Bans = IW4MAdmin.Program.getServers()[0].Bans.GetRange(start, range).OrderByDescending(x => x.getTime()).ToList();
|
||||
else
|
||||
Bans.Add(new IW4MAdmin.Ban("No Bans", "0", "0", DateTime.Now, ""));
|
||||
|
||||
@ -185,8 +186,8 @@ namespace IW4MAdmin_Web
|
||||
if (Bans[i] == null)
|
||||
continue;
|
||||
|
||||
IW4MAdmin.Player P = IW4MAdmin.Program.Servers[0].clientDB.getPlayer(Bans[i].getID(), -1);
|
||||
IW4MAdmin.Player B = IW4MAdmin.Program.Servers[0].clientDB.getPlayer(Bans[i].getBanner(), -1);
|
||||
IW4MAdmin.Player P = IW4MAdmin.Program.getServers()[0].clientDB.getPlayer(Bans[i].getID(), -1);
|
||||
IW4MAdmin.Player B = IW4MAdmin.Program.getServers()[0].clientDB.getPlayer(Bans[i].getBanner(), -1);
|
||||
|
||||
if (P == null)
|
||||
P = new IW4MAdmin.Player("Unknown", "n/a", 0, 0, 0, "Unknown", 0, "");
|
||||
@ -212,8 +213,8 @@ namespace IW4MAdmin_Web
|
||||
}
|
||||
}
|
||||
buffer.Append("</table><hr/>");
|
||||
|
||||
buffer.Append(parsePagination(server, IW4MAdmin.Program.Servers[0].Bans.Count, 30, Pagination, "bans"));
|
||||
|
||||
buffer.Append(parsePagination(server, IW4MAdmin.Program.getServers()[0].Bans.Count, 30, Pagination, "bans"));
|
||||
return buffer.ToString();
|
||||
case "PAGE":
|
||||
buffer.Append("<div id=pages>");
|
||||
@ -662,3 +663,4 @@ namespace IW4MAdmin_Web
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user