Bug fixes for server stability

This commit is contained in:
RaidMax 2015-08-17 15:38:42 -05:00
parent a0ccd3ffa8
commit d3e42541ea
11 changed files with 357 additions and 99 deletions

View File

@ -25,12 +25,13 @@
<UpdateRequired>false</UpdateRequired> <UpdateRequired>false</UpdateRequired>
<MapFileExtensions>false</MapFileExtensions> <MapFileExtensions>false</MapFileExtensions>
<InstallUrl>http://raidmax.org/IW4M/Admin/</InstallUrl> <InstallUrl>http://raidmax.org/IW4M/Admin/</InstallUrl>
<SupportUrl>http://raidmax.org/IW4MAdmin</SupportUrl>
<ProductName>IW4M Administration</ProductName> <ProductName>IW4M Administration</ProductName>
<PublisherName>RaidMax LLC</PublisherName> <PublisherName>RaidMax LLC</PublisherName>
<CreateWebPageOnPublish>true</CreateWebPageOnPublish> <CreateWebPageOnPublish>true</CreateWebPageOnPublish>
<WebPage>publish.htm</WebPage> <WebPage>publish.htm</WebPage>
<ApplicationRevision>7</ApplicationRevision> <ApplicationRevision>6</ApplicationRevision>
<ApplicationVersion>0.7.0.%2a</ApplicationVersion> <ApplicationVersion>0.9.1.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust> <UseApplicationTrust>false</UseApplicationTrust>
<PublishWizardCompleted>true</PublishWizardCompleted> <PublishWizardCompleted>true</PublishWizardCompleted>
<BootstrapperEnabled>true</BootstrapperEnabled> <BootstrapperEnabled>true</BootstrapperEnabled>
@ -72,12 +73,16 @@
<PropertyGroup> <PropertyGroup>
<StartupObject>IW4MAdmin.Program</StartupObject> <StartupObject>IW4MAdmin.Program</StartupObject>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup />
<NoWin32Manifest>true</NoWin32Manifest>
</PropertyGroup>
<PropertyGroup> <PropertyGroup>
<RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent> <RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
</PropertyGroup> </PropertyGroup>
<PropertyGroup>
<GenerateManifests>true</GenerateManifests>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>Properties\app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Kayak"> <Reference Include="Kayak">
<HintPath>..\packages\Kayak.0.7.2\lib\Kayak.dll</HintPath> <HintPath>..\packages\Kayak.0.7.2\lib\Kayak.dll</HintPath>
@ -123,21 +128,21 @@
<Compile Include="IW4_GameStructs.cs" /> <Compile Include="IW4_GameStructs.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="lib\AdminInterface.dll"> <None Include="lib\AdminInterface.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </None>
<Content Include="lib\Kayak.dll"> <None Include="lib\Kayak.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </None>
<Content Include="lib\Moserware.Skills.dll"> <None Include="lib\Moserware.Skills.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </None>
<Content Include="lib\SQLite.Interop.dll"> <None Include="lib\SQLite.Interop.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="lib\System.Data.SQLite.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </None>
<None Include="lib\System.Data.SQLite.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<Content Include="version.txt"> <Content Include="version.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
@ -171,13 +176,10 @@
<Content Include="config\rules.cfg"> <Content Include="config\rules.cfg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="config\servers.cfg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<None Include="app.config" /> <None Include="app.config" />
<None Include="IW4MAdmin.exe.config"> <Content Include="IW4MAdmin.exe.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </Content>
<None Include="m2demo\admin\commands.gsc"> <None Include="m2demo\admin\commands.gsc">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
@ -190,12 +192,18 @@
<None Include="m2demo\settings\main.gsc"> <None Include="m2demo\settings\main.gsc">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Include="Properties\app.manifest" />
<None Include="Properties\Settings.settings"> <None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator> <Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput> <LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.0">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5"> <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible> <Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName> <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
@ -204,16 +212,101 @@
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1"> <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible> <Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName> <ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Visual.C++.12.0.x86">
<Visible>False</Visible>
<ProductName>Visual C++ 2013 Runtime Libraries %28x86%29</ProductName>
<Install>true</Install> <Install>true</Install>
</BootstrapperPackage> </BootstrapperPackage>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="IW4MAdmin.ico" /> <Content Include="IW4MAdmin.ico" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PublishFile Include="config\maps.cfg">
<Visible>False</Visible>
<Group>
</Group>
<TargetPath>
</TargetPath>
<PublishState>DataFile</PublishState>
<IncludeHash>True</IncludeHash>
<FileType>File</FileType>
</PublishFile>
<PublishFile Include="config\messages.cfg">
<Visible>False</Visible>
<Group>
</Group>
<TargetPath>
</TargetPath>
<PublishState>DataFile</PublishState>
<IncludeHash>True</IncludeHash>
<FileType>File</FileType>
</PublishFile>
<PublishFile Include="config\rules.cfg">
<Visible>False</Visible>
<Group>
</Group>
<TargetPath>
</TargetPath>
<PublishState>DataFile</PublishState>
<IncludeHash>True</IncludeHash>
<FileType>File</FileType>
</PublishFile>
<PublishFile Include="IW4MAdmin.XmlSerializers">
<Visible>False</Visible>
<Group>
</Group>
<TargetPath>
</TargetPath>
<PublishState>Exclude</PublishState>
<IncludeHash>True</IncludeHash>
<FileType>Assembly</FileType>
</PublishFile>
<PublishFile Include="Kayak">
<Visible>False</Visible>
<Group>
</Group>
<TargetPath>
</TargetPath>
<PublishState>Exclude</PublishState>
<IncludeHash>True</IncludeHash>
<FileType>Assembly</FileType>
</PublishFile>
<PublishFile Include="Moserware.Skills">
<Visible>False</Visible>
<Group>
</Group>
<TargetPath>
</TargetPath>
<PublishState>Exclude</PublishState>
<IncludeHash>True</IncludeHash>
<FileType>Assembly</FileType>
</PublishFile>
<PublishFile Include="System.Data.SQLite">
<Visible>False</Visible>
<Group>
</Group>
<TargetPath>
</TargetPath>
<PublishState>Exclude</PublishState>
<IncludeHash>True</IncludeHash>
<FileType>Assembly</FileType>
</PublishFile>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup> <PropertyGroup>
<PostBuildEvent> <PostBuildEvent>cd "$(TargetDir)"
</PostBuildEvent> del *.dll
del *.config
del *.application
del *.pdb
del *.manifest
del *.rm
cd ..
cd ..
copy IW4MAdmin.exe.config $(TargetDir)\IW4MAdmin.exe.config</PostBuildEvent>
</PropertyGroup> </PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

View File

@ -21,6 +21,10 @@ namespace IW4MAdmin
Port = port; Port = port;
} }
public void Write(String line)
{
Write(line, Level.Debug);
}
public void Write(String line, Level lv) public void Write(String line, Level lv)
{ {

View File

@ -3,18 +3,22 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Runtime.InteropServices;
namespace IW4MAdmin namespace IW4MAdmin
{ {
class Program class Program
{ {
static public double Version = 0.91; static public double Version = 0.92;
static public double latestVersion; static public double latestVersion;
static public bool usingMemory = true; static public bool usingMemory = true;
static private Manager serverManager; static private Manager serverManager;
static void Main(string[] args) static void Main(string[] args)
{ {
handler = new ConsoleEventDelegate(OnProcessExit);
SetConsoleCtrlHandler(handler, true);
double.TryParse(checkUpdate(), out latestVersion); double.TryParse(checkUpdate(), out latestVersion);
Console.WriteLine("====================================================="); Console.WriteLine("=====================================================");
Console.WriteLine(" IW4M ADMIN"); Console.WriteLine(" IW4M ADMIN");
@ -48,7 +52,7 @@ namespace IW4MAdmin
} }
if (serverManager.getServers() != null) if (serverManager.getServers() != null)
Console.WriteLine("IW4M Now Initialized! Visit http://127.0.0.1:1624 for server overview."); Program.getManager().mainLog.Write("IW4M Now Initialized! Visit http://127.0.0.1:1624 for server overview.");
if (serverManager.getServers().Count > 0) if (serverManager.getServers().Count > 0)
{ {
@ -80,6 +84,38 @@ namespace IW4MAdmin
} }
#endif #endif
static ConsoleEventDelegate handler;
static private bool OnProcessExit(int e)
{
try
{
foreach (Server S in IW4MAdmin.Program.getServers())
{
if (S == null)
continue;
if (Utilities.shutdownInterface(S.pID(), IntPtr.Zero))
Program.getManager().mainLog.Write("Successfully removed IW4MAdmin from server with PID " + S.pID(), Log.Level.Debug);
else
Program.getManager().mainLog.Write("Could not remove IW4MAdmin from server with PID " + S.pID(), Log.Level.Debug);
}
Program.getManager().shutDown();
}
catch
{
return true;
}
return false;
}
private delegate bool ConsoleEventDelegate(int eventType);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetConsoleCtrlHandler(ConsoleEventDelegate callback, bool add);
static private String checkUpdate() static private String checkUpdate()
{ {
Connection Ver = new Connection("http://raidmax.org/IW4M/Admin/version.php"); Connection Ver = new Connection("http://raidmax.org/IW4M/Admin/version.php");
@ -91,6 +127,11 @@ namespace IW4MAdmin
return serverManager.getServers().ToArray(); return serverManager.getServers().ToArray();
} }
static public Manager getManager()
{
return serverManager;
}
#if DEBUG2 #if DEBUG2
static List<Server> checkConfig() static List<Server> checkConfig()
{ {

View File

@ -14,7 +14,7 @@ namespace IW4MAdmin
private List<Server> Servers; private List<Server> Servers;
private SortedDictionary<int, Thread> ThreadList; private SortedDictionary<int, Thread> ThreadList;
private List<int> activePIDs; private List<int> activePIDs;
private Log mainLog; public Log mainLog;
private bool initialized = false; private bool initialized = false;
public Manager() public Manager()
@ -80,6 +80,18 @@ namespace IW4MAdmin
} }
} }
public void shutDown()
{
foreach (Server S in Servers)
S.isRunning = false;
foreach (int PID in activePIDs)
{
ThreadList[PID].Abort();
mainLog.Write("Exited thread for PID " + PID);
}
}
public List<Server> getServers() public List<Server> getServers()
{ {
return Servers; return Servers;
@ -88,8 +100,15 @@ namespace IW4MAdmin
private void scanForNewServers() private void scanForNewServers()
{ {
List<int> newProcesses = getCurrentIW4MProcesses(); List<int> newProcesses = getCurrentIW4MProcesses();
if (activePIDs == null)
return;
foreach (int pID in newProcesses) foreach (int pID in newProcesses)
{ {
if (pID == 0)
continue;
bool newProcess = true; bool newProcess = true;
foreach (int I in activePIDs) foreach (int I in activePIDs)
{ {
@ -99,7 +118,6 @@ namespace IW4MAdmin
if (newProcess) if (newProcess)
{ {
if (!ThreadList.ContainsKey(pID)) if (!ThreadList.ContainsKey(pID))
{ {
Server S = loadIndividualServer(pID); Server S = loadIndividualServer(pID);

View File

@ -28,7 +28,8 @@ namespace IW4MAdmin
//We want to read the reponse //We want to read the reponse
public String[] responseSendRCON(String message) public String[] responseSendRCON(String message)
{ {
try return null;
/* try
{ {
String STR_REQUEST = String.Empty; String STR_REQUEST = String.Empty;
if (message != "getstatus") if (message != "getstatus")
@ -89,7 +90,7 @@ namespace IW4MAdmin
sv_connection.Close(); sv_connection.Close();
sv_connection = new UdpClient(); sv_connection = new UdpClient();
return null; return null;
} }*/
} }
public String[] addRCON(String Message) public String[] addRCON(String Message)
@ -113,7 +114,7 @@ namespace IW4MAdmin
{ {
RCON_Request Current = toSend.Peek(); RCON_Request Current = toSend.Peek();
//Current.Response = responseSendRCON(Current.Request); //Current.Response = responseSendRCON(Current.Request);
Utilities.executeCommand(Instance.pID(), Current.Request); Utilities.executeCommand(Instance.pID(), Current.Request, Instance.lastCommandPointer);
toSend.Dequeue(); toSend.Dequeue();
//Utilities.Wait(0.567); //Utilities.Wait(0.567);
Utilities.Wait(.3); Utilities.Wait(.3);

View File

@ -529,17 +529,17 @@ namespace IW4MAdmin
public void executeCommand(String CMD) public void executeCommand(String CMD)
{ {
Utilities.executeCommand(PID, CMD); lastCommandPointer = Utilities.executeCommand(PID, CMD, lastCommandPointer);
} }
private dvar getDvar(String DvarName) private dvar getDvar(String DvarName)
{ {
return Utilities.getDvar(PID, DvarName); return Utilities.getDvar(PID, DvarName, lastCommandPointer);
} }
private void setDvar(String Dvar, String Value) private void setDvar(String Dvar, String Value)
{ {
Utilities.executeCommand(PID, Dvar + " " + Value); lastDvarPointer = Utilities.executeCommand(PID, Dvar + " " + Value, lastDvarPointer);
} }
[DllImport("kernel32.dll")] [DllImport("kernel32.dll")]
@ -706,7 +706,7 @@ namespace IW4MAdmin
} }
oldLines = lines; oldLines = lines;
l_size = logFile.getSize(); l_size = logFile.getSize();
Thread.Sleep(250); Thread.Sleep(150);
} }
#if DEBUG == false #if DEBUG == false
catch (Exception E) catch (Exception E)
@ -721,7 +721,7 @@ namespace IW4MAdmin
RCONQueue.Abort(); RCONQueue.Abort();
eventQueue.Abort(); eventQueue.Abort();
} }
#if DEBUG #if DEBUG2
private void pollServer() private void pollServer()
{ {
int timesFailed = 0; int timesFailed = 0;
@ -814,7 +814,7 @@ namespace IW4MAdmin
if (maxClients == -1) if (maxClients == -1)
{ {
Log.Write("Could not get iw4m_onelog value", IW4MAdmin.Log.Level.Debug); Log.Write("Could not get max clients value", IW4MAdmin.Log.Level.Debug);
return false; return false;
} }
@ -844,12 +844,12 @@ namespace IW4MAdmin
if (!File.Exists(logPath)) if (!File.Exists(logPath))
{ {
Log.Write("Gamelog does not exist!", Log.Level.All); Log.Write("Gamelog `" + logPath + "` does not exist!", Log.Level.All);
return false; return false;
} }
logFile = new file(logPath); logFile = new file(logPath);
Log.Write("Log file is " + logPath, Log.Level.Production); Log.Write("Log file is " + logPath, Log.Level.Debug);
Log.Write("Now monitoring " + this.getName(), Log.Level.Production); Log.Write("Now monitoring " + this.getName(), Log.Level.Production);
return true; return true;
} }
@ -1221,11 +1221,6 @@ namespace IW4MAdmin
//END //END
public String getPassword()
{
return rcon_pass;
}
private void initMacros() private void initMacros()
{ {
Macros = new Dictionary<String, Object>(); Macros = new Dictionary<String, Object>();
@ -1379,12 +1374,12 @@ namespace IW4MAdmin
private String hostname; private String hostname;
private String mapname; private String mapname;
private int clientnum; private int clientnum;
private string rcon_pass;
private List<Player> players; private List<Player> players;
private List<Command> commands; private List<Command> commands;
private List<String> messages; private List<String> messages;
private int messageTime; private int messageTime;
private TimeSpan lastMessage; private TimeSpan lastMessage;
private DateTime lastPoll;
private int nextMessage; private int nextMessage;
private String IW_Ver; private String IW_Ver;
private int maxClients; private int maxClients;
@ -1393,14 +1388,14 @@ namespace IW4MAdmin
private DateTime lastWebChat; private DateTime lastWebChat;
private int Handle; private int Handle;
private int PID; private int PID;
private String backupRotation;
private int backupTimeLimit;
//Will probably move this later //Will probably move this later
public Dictionary<String, Player> statusPlayers; public Dictionary<String, Player> statusPlayers;
public bool isRunning; public bool isRunning;
private DateTime lastPoll; private IntPtr dllPointer;
public IntPtr lastCommandPointer;
public IntPtr lastDvarPointer;
//Log stuff //Log stuff
private String Basepath; private String Basepath;
private String Mod; private String Mod;

View File

@ -91,6 +91,8 @@ namespace IW4MAdmin
public static String stripColors(String str) public static String stripColors(String str)
{ {
if (str == null)
return "";
return Regex.Replace(str, @"\^[0-9]", ""); return Regex.Replace(str, @"\^[0-9]", "");
} }
@ -287,7 +289,7 @@ namespace IW4MAdmin
catch(Exception E) catch(Exception E)
{ {
/// need to handle eventually /// need to handle eventually
Console.WriteLine("Error handling player add -- " + E.Message); Program.getManager().mainLog.Write("Error handling player add -- " + E.Message);
continue; continue;
} }
} }
@ -403,6 +405,9 @@ namespace IW4MAdmin
[DllImport("kernel32.dll", SetLastError = true)] [DllImport("kernel32.dll", SetLastError = true)]
static extern int CloseHandle(IntPtr hObject); static extern int CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll")]
static extern bool GetExitCodeThread(IntPtr hThread, out uint lpExitCode);
[DllImport("ntdll.dll")] [DllImport("ntdll.dll")]
public static extern uint RtlCreateUserThread( public static extern uint RtlCreateUserThread(
[In] IntPtr Process, [In] IntPtr Process,
@ -538,7 +543,7 @@ namespace IW4MAdmin
return BitConverter.ToBoolean(Buff, 0); return BitConverter.ToBoolean(Buff, 0);
} }
public static void executeCommand(int pID, String Command) public static IntPtr executeCommand(int pID, String Command, IntPtr lastMemoryLocation)
{ {
/*IntPtr ProcessHandle = OpenProcess(ProcessAccessFlags.All, false, pID); /*IntPtr ProcessHandle = OpenProcess(ProcessAccessFlags.All, false, pID);
IntPtr memoryForCMDName = allocateAndWrite(Encoding.ASCII.GetBytes(Command + "\0"), ProcessHandle); IntPtr memoryForCMDName = allocateAndWrite(Encoding.ASCII.GetBytes(Command + "\0"), ProcessHandle);
@ -574,28 +579,34 @@ namespace IW4MAdmin
// cleanup // cleanup
if (!VirtualFreeEx(ProcessHandle, codeAllocation, 0, AllocationType.Release)) if (!VirtualFreeEx(ProcessHandle, codeAllocation, 0, AllocationType.Release))
Console.WriteLine(Marshal.GetLastWin32Error()); Program.getManager().mainLog.Write(Marshal.GetLastWin32Error());
if (!VirtualFreeEx(ProcessHandle, memoryForCMDName, 0, AllocationType.Release)) if (!VirtualFreeEx(ProcessHandle, memoryForCMDName, 0, AllocationType.Release))
Console.WriteLine(Marshal.GetLastWin32Error());*/ Program.getManager().mainLog.Write(Marshal.GetLastWin32Error());*/
IntPtr ProcessHandle = OpenProcess(ProcessAccessFlags.All, false, pID); IntPtr ProcessHandle = OpenProcess(ProcessAccessFlags.All, false, pID);
IntPtr memoryForDvarName = allocateAndWrite(Encoding.ASCII.GetBytes(Command + "\0"), ProcessHandle);
if (lastMemoryLocation != IntPtr.Zero)
{
if (!VirtualFreeEx(ProcessHandle, lastMemoryLocation, 0, AllocationType.Release))
{
Program.getManager().mainLog.Write("Virtual Free Failed -- Error #" + Marshal.GetLastWin32Error());
return IntPtr.Zero;
}
}
IntPtr memoryForDvarName = allocateAndWrite(Encoding.ASCII.GetBytes(Command + "\0"), ProcessHandle); // this gets disposed next call
if (memoryForDvarName == IntPtr.Zero) if (memoryForDvarName == IntPtr.Zero)
{ {
Console.WriteLine("UNABLE TO ALLOCATE MEMORY FOR DVAR NAME"); Program.getManager().mainLog.Write("UNABLE TO ALLOCATE MEMORY FOR DVAR NAME");
return; return IntPtr.Zero;
} }
setDvarCurrentPtr(0x2098D9C, memoryForDvarName, ProcessHandle); setDvarCurrentPtr(0x2098D9C, memoryForDvarName, ProcessHandle);
Utilities.Wait(.3);
if (!VirtualFreeEx(ProcessHandle, memoryForDvarName, 0, AllocationType.Release))
Console.WriteLine("Virtual Free Failed -- Error #" + Marshal.GetLastWin32Error());
CloseHandle(ProcessHandle); CloseHandle(ProcessHandle);
return memoryForDvarName;
} }
public static IntPtr allocateAndWrite(Byte[] Data, IntPtr ProcessHandle) public static IntPtr allocateAndWrite(Byte[] Data, IntPtr ProcessHandle)
@ -604,7 +615,7 @@ namespace IW4MAdmin
IntPtr AllocatedMemory = VirtualAllocEx(ProcessHandle, IntPtr.Zero, (uint)Data.Length, AllocationType.Commit, MemoryProtection.ExecuteReadWrite); IntPtr AllocatedMemory = VirtualAllocEx(ProcessHandle, IntPtr.Zero, (uint)Data.Length, AllocationType.Commit, MemoryProtection.ExecuteReadWrite);
if (!WriteProcessMemory(ProcessHandle, AllocatedMemory, Data, (uint)Data.Length, out bytesWritten)) if (!WriteProcessMemory(ProcessHandle, AllocatedMemory, Data, (uint)Data.Length, out bytesWritten))
{ {
Console.WriteLine("UNABLE TO WRITE PROCESS MEMORY!"); Program.getManager().mainLog.Write("Unable to write process memory!");
return IntPtr.Zero; return IntPtr.Zero;
} }
@ -626,26 +637,104 @@ namespace IW4MAdmin
return true; return true;
} }
public static bool initalizeInterface(int pID) public static bool shutdownInterface(int pID, IntPtr moduleHandle, params IntPtr[] cleanUp)
{
IntPtr threadID;
IntPtr ProcessHandle = OpenProcess(ProcessAccessFlags.All, false, pID);
#if DEBUG
Program.getManager().mainLog.Write("Process handle is: " + ProcessHandle);
Program.getManager().mainLog.Write("Module handle is " + moduleHandle);
#endif
if (ProcessHandle == IntPtr.Zero)
{
Program.getManager().mainLog.Write("Unable to open target process");
return false;
}
IntPtr baseAddress = IntPtr.Zero;
System.Diagnostics.Process P = System.Diagnostics.Process.GetProcessById(pID);
foreach (System.Diagnostics.ProcessModule M in P.Modules)
{
if (M.ModuleName == "AdminInterface.dll")
baseAddress = M.BaseAddress;
}
if (baseAddress == IntPtr.Zero)
{
Program.getManager().mainLog.Write("Base address was not found!");
return false;
}
IntPtr lpLLAddress = GetProcAddress(GetModuleHandle("kernel32.dll"), "FreeLibrary");
if (lpLLAddress == IntPtr.Zero)
{
Program.getManager().mainLog.Write("Could not obtain address of function address");
return false;
}
ClientId clientid = new ClientId();
threadID = new IntPtr();
RtlCreateUserThread(ProcessHandle, IntPtr.Zero, false, 0, (uint)0, IntPtr.Zero, lpLLAddress, baseAddress, out threadID, out clientid);
if (threadID == IntPtr.Zero)
{
Program.getManager().mainLog.Write("Could not create remote thread");
return false;
}
#if DEBUG
//Program.getManager().mainLog.Write("Thread Status is " + threadStatus);
Program.getManager().mainLog.Write("Thread ID is " + threadID);
#endif
uint responseCode = WaitForSingleObject(threadID, 3000);
if (responseCode != 0x00000000L)
{
Program.getManager().mainLog.Write("Thread did not finish in a timely manner!");
Program.getManager().mainLog.Write("Last error is: " + Marshal.GetLastWin32Error());
return false;
}
CloseHandle(ProcessHandle);
foreach (IntPtr Pointer in cleanUp)
{
if (Pointer != IntPtr.Zero)
{
if (!VirtualFreeEx(ProcessHandle, Pointer, 0, AllocationType.Release))
Program.getManager().mainLog.Write("Virtual Free Failed During Exit Cleanup -- Error #" + Marshal.GetLastWin32Error());
}
}
#if DEBUG
Program.getManager().mainLog.Write("shutdown finished -- last error : " + Marshal.GetLastWin32Error());
#endif
return true;
}
/////////////////////////////////////////////////////////////
public static Boolean initalizeInterface(int pID)
{ {
String Path = AppDomain.CurrentDomain.BaseDirectory + "lib\\AdminInterface.dll"; String Path = AppDomain.CurrentDomain.BaseDirectory + "lib\\AdminInterface.dll";
if (!File.Exists(Path)) if (!File.Exists(Path))
{ {
Console.WriteLine("AdminInterface DLL does not exist!"); Program.getManager().mainLog.Write("AdminInterface DLL does not exist!");
return false; return false;
} }
UIntPtr bytesWritten; UIntPtr bytesWritten;
IntPtr threadID; IntPtr threadID;
IntPtr ProcessHandle = OpenProcess(ProcessAccessFlags.All, false, pID); IntPtr ProcessHandle = OpenProcess(ProcessAccessFlags.All, false, pID);
#if DEBUG #if DEBUG
Console.WriteLine("Process handle is: " + ProcessHandle); Program.getManager().mainLog.Write("Process handle is: " + ProcessHandle);
#endif #endif
if (ProcessHandle == IntPtr.Zero) if (ProcessHandle == IntPtr.Zero)
{ {
Console.WriteLine("Unable to open target process"); Program.getManager().mainLog.Write("Unable to open target process");
return false; return false;
} }
@ -653,30 +742,30 @@ namespace IW4MAdmin
if (lpLLAddress == IntPtr.Zero) if (lpLLAddress == IntPtr.Zero)
{ {
Console.WriteLine("Could not obtain address of function address"); Program.getManager().mainLog.Write("Could not obtain address of function address");
return false; return false;
} }
#if DEBUG #if DEBUG
Console.WriteLine("LoadLibraryA location is 0x" + lpLLAddress.ToString("X8")); Program.getManager().mainLog.Write("LoadLibraryA location is 0x" + lpLLAddress.ToString("X8"));
#endif #endif
IntPtr pathAllocation = VirtualAllocEx(ProcessHandle, IntPtr.Zero, (uint)Path.Length + 1, AllocationType.Commit, MemoryProtection.ExecuteReadWrite); IntPtr pathAllocation = VirtualAllocEx(ProcessHandle, IntPtr.Zero, (uint)Path.Length + 1, AllocationType.Commit, MemoryProtection.ExecuteReadWrite);
if (pathAllocation == IntPtr.Zero) if (pathAllocation == IntPtr.Zero)
{ {
Console.WriteLine("Could not allocate memory for path location"); Program.getManager().mainLog.Write("Could not allocate memory for path location");
return false; return false;
} }
#if DEBUG #if DEBUG
Console.WriteLine("Allocated DLL path address is 0x" + pathAllocation.ToString("X8")); Program.getManager().mainLog.Write("Allocated DLL path address is 0x" + pathAllocation.ToString("X8"));
#endif #endif
byte[] pathBytes = Encoding.ASCII.GetBytes(Path); byte[] pathBytes = Encoding.ASCII.GetBytes(Path);
if (!WriteProcessMemory(ProcessHandle, pathAllocation, pathBytes, (uint)pathBytes.Length, out bytesWritten)) if (!WriteProcessMemory(ProcessHandle, pathAllocation, pathBytes, (uint)pathBytes.Length, out bytesWritten))
{ {
Console.WriteLine("Could not write process memory"); Program.getManager().mainLog.Write("Could not write process memory");
return false; return false;
} }
@ -686,46 +775,49 @@ namespace IW4MAdmin
if (threadID == IntPtr.Zero) if (threadID == IntPtr.Zero)
{ {
Console.WriteLine("Could not create remote thread"); Program.getManager().mainLog.Write("Could not create remote thread");
return false; return false;
} }
#if DEBUG #if DEBUG
//Console.WriteLine("Thread Status is " + threadStatus); //Program.getManager().mainLog.Write("Thread Status is " + threadStatus);
Console.WriteLine("Thread ID is " + threadID); Program.getManager().mainLog.Write("Thread ID is " + threadID);
#endif #endif
uint responseCode = WaitForSingleObject (threadID, 3000); uint responseCode = WaitForSingleObject(threadID, 5000);
if (responseCode != 0x00000000L) if (responseCode != 0x00000000L)
{ {
Console.WriteLine("Thread did not finish in a timely manner!"); Program.getManager().mainLog.Write("Thread did not finish in a timely manner!", Log.Level.Debug);
Console.WriteLine("Last error is: " + Marshal.GetLastWin32Error()); Program.getManager().mainLog.Write("Last error is: " + Marshal.GetLastWin32Error(), Log.Level.Debug);
return false; return false;
} }
if (!VirtualFreeEx(ProcessHandle, pathAllocation, 0, AllocationType.Decommit))
Console.WriteLine("Could not free memory allocated for DLL name");
CloseHandle(ProcessHandle); CloseHandle(ProcessHandle);
#if DEBUG #if DEBUG
Console.WriteLine("Initialization finished -- last error : " + Marshal.GetLastWin32Error()); Program.getManager().mainLog.Write("Initialization finished -- last error : " + Marshal.GetLastWin32Error());
#endif #endif
return true; return true;
} }
public static dvar getDvar(int pID, String DVAR) public static dvar getDvar(int pID, String DVAR, IntPtr lastMemoryLocation)
{ {
dvar requestedDvar = new dvar(); dvar requestedDvar = new dvar();
IntPtr ProcessHandle = OpenProcess(ProcessAccessFlags.All, false, pID); IntPtr ProcessHandle = OpenProcess(ProcessAccessFlags.All, false, pID);
if (lastMemoryLocation != IntPtr.Zero)
{
if (!VirtualFreeEx(ProcessHandle, lastMemoryLocation, 0, AllocationType.Release))
Program.getManager().mainLog.Write("Virtual free failed during cleanup-- Error #" + Marshal.GetLastWin32Error(), Log.Level.Debug);
}
IntPtr memoryForDvarName = allocateAndWrite(Encoding.ASCII.GetBytes(DVAR + "\0"), ProcessHandle); IntPtr memoryForDvarName = allocateAndWrite(Encoding.ASCII.GetBytes(DVAR + "\0"), ProcessHandle);
if (memoryForDvarName == IntPtr.Zero) if (memoryForDvarName == IntPtr.Zero)
{ {
Console.WriteLine("UNABLE TO ALLOCATE MEMORY FOR DVAR NAME"); Program.getManager().mainLog.Write("Unable to allocate memory for dvar name", Log.Level.Debug);
return requestedDvar; return requestedDvar;
} }
setDvarCurrentPtr(0x2089E04, memoryForDvarName, ProcessHandle); // sv_debugRate setDvarCurrentPtr(0x2089E04, memoryForDvarName, ProcessHandle); // sv_allowedclan1
#if ASD #if ASD
/* byte[] copyDvarValue = { /* byte[] copyDvarValue = {
0x55, 0x8B, 0xEC, 0x83, 0xEC, 0x08, // ----------------------------------------------- 0x55, 0x8B, 0xEC, 0x83, 0xEC, 0x08, // -----------------------------------------------
@ -743,7 +835,7 @@ namespace IW4MAdmin
IntPtr codeAllocation = allocateAndWrite(copyDvarValue, ProcessHandle); IntPtr codeAllocation = allocateAndWrite(copyDvarValue, ProcessHandle);
if (codeAllocation == IntPtr.Zero) if (codeAllocation == IntPtr.Zero)
Console.WriteLine("UNABLE TO ALLOCATE MEMORY FOR CODE"); Program.getManager().mainLog.Write("UNABLE TO ALLOCATE MEMORY FOR CODE");
IntPtr ThreadHandle = CreateRemoteThread(ProcessHandle, IntPtr.Zero, 0, codeAllocation, IntPtr.Zero, 0, out threadID); IntPtr ThreadHandle = CreateRemoteThread(ProcessHandle, IntPtr.Zero, 0, codeAllocation, IntPtr.Zero, 0, out threadID);
if (ThreadHandle == null || ThreadHandle == IntPtr.Zero) if (ThreadHandle == null || ThreadHandle == IntPtr.Zero)
@ -752,11 +844,11 @@ namespace IW4MAdmin
WaitForSingleObject(ThreadHandle, Int32.MaxValue); // gg if thread doesn't finish WaitForSingleObject(ThreadHandle, Int32.MaxValue); // gg if thread doesn't finish
if (!VirtualFreeEx(ProcessHandle, codeAllocation, 0, AllocationType.Release)) if (!VirtualFreeEx(ProcessHandle, codeAllocation, 0, AllocationType.Release))
Console.WriteLine(Marshal.GetLastWin32Error()); Program.getManager().mainLog.Write(Marshal.GetLastWin32Error());
if (!VirtualFreeEx(ProcessHandle, memoryForDvarName, 0, AllocationType.Release)) if (!VirtualFreeEx(ProcessHandle, memoryForDvarName, 0, AllocationType.Release))
Console.WriteLine(Marshal.GetLastWin32Error());*/ Program.getManager().mainLog.Write(Marshal.GetLastWin32Error());*/
#endif #endif
Utilities.Wait(.3); Thread.Sleep(120);
int dvarLoc = getIntFromPointer(0x2089E04, (int)ProcessHandle); // this is where the dvar is stored int dvarLoc = getIntFromPointer(0x2089E04, (int)ProcessHandle); // this is where the dvar is stored
if (dvarLoc == 0) if (dvarLoc == 0)

View File

@ -408,9 +408,10 @@ namespace IW4MAdmin_Web
{ {
public void OnException(IScheduler scheduler, Exception e) public void OnException(IScheduler scheduler, Exception e)
{ {
Console.WriteLine(e.InnerException.Message); //Program.getManager().mainLog.Write(e.InnerException.Message);
Console.Write(e.InnerException); //Console.Write(e.InnerException);
e.DebugStackTrace(); // e.DebugStackTrace();
IW4MAdmin.Program.getManager().mainLog.Write("Web front encountered an error!");
} }
public void OnStop(IScheduler scheduler) public void OnStop(IScheduler scheduler)
@ -426,7 +427,7 @@ namespace IW4MAdmin_Web
String type = "text/html"; String type = "text/html";
if (request.Uri.StartsWith("/")) if (request.Uri.StartsWith("/"))
{ {
//Console.WriteLine("[WEBFRONT] Processing Request for " + request.Uri); //Program.getManager().mainLog.Write("[WEBFRONT] Processing Request for " + request.Uri);
var body = String.Empty; var body = String.Empty;
if (request.Uri.StartsWith("/")) if (request.Uri.StartsWith("/"))
@ -476,6 +477,9 @@ namespace IW4MAdmin_Web
else if (request.QueryString == "playerhistory") else if (request.QueryString == "playerhistory")
{ {
//type = "text/plain"; //type = "text/plain";
if (IW4MAdmin.Program.getServers().Length < server)
return;
StringBuilder test = new StringBuilder(); StringBuilder test = new StringBuilder();
test.Append("<script type='text/javascript' src='//www.google.com/jsapi'></script><div id='chart_div'></div>"); test.Append("<script type='text/javascript' src='//www.google.com/jsapi'></script><div id='chart_div'></div>");
test.Append("<script> var players = ["); test.Append("<script> var players = [");
@ -515,6 +519,9 @@ namespace IW4MAdmin_Web
IP = req[2]; IP = req[2];
} }
if (IW4MAdmin.Program.getServers().Length < server)
return;
IW4MAdmin.Player P = IW4MAdmin.Program.getServers()[server].clientDB.getPlayer(IP); IW4MAdmin.Player P = IW4MAdmin.Program.getServers()[server].clientDB.getPlayer(IP);
if (P == null) if (P == null)
P = new IW4MAdmin.Player("Guest", "Guest", 0, 0); P = new IW4MAdmin.Player("Guest", "Guest", 0, 0);
@ -530,6 +537,9 @@ namespace IW4MAdmin_Web
// if (IW4MAdmin.Program.Servers[server].chatHistory.Count < 8) // if (IW4MAdmin.Program.Servers[server].chatHistory.Count < 8)
// IW4MAdmin.Program.Servers[server].chatHistory.Add(new IW4MAdmin.Chat(new IW4MAdmin.Player("TEST", "xuid", 0, 0), "TEST MESSAGE", DateTime.Now)); // IW4MAdmin.Program.Servers[server].chatHistory.Add(new IW4MAdmin.Chat(new IW4MAdmin.Player("TEST", "xuid", 0, 0), "TEST MESSAGE", DateTime.Now));
#endif #endif
if (IW4MAdmin.Program.getServers().Length < server)
return;
String IP, Text; String IP, Text;
if (req.Length > 3) if (req.Length > 3)
{ {

View File

@ -1,4 +1,8 @@
VERSION: 0.9.1 VERSION 0.9.2
CHANGELOG:
-fixed issues with crashing IW4 Servers
VERSION: 0.9.1
CHANGELOG: CHANGELOG:
-fixed issue with `history` timelime -fixed issue with `history` timelime
-fixed issue with mapname not being updated -fixed issue with mapname not being updated

View File

@ -1,7 +1,7 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013 # Visual Studio 2013
VisualStudioVersion = 12.0.31101.0 VisualStudioVersion = 12.0.40629.0
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IW4M ADMIN", "Admin\IW4M ADMIN.csproj", "{DD5DCDA2-51DB-4B1A-922F-5705546E6115}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IW4M ADMIN", "Admin\IW4M ADMIN.csproj", "{DD5DCDA2-51DB-4B1A-922F-5705546E6115}"
EndProject EndProject