mirror of
https://github.com/MathiasLui/CSGO-Projects.git
synced 2025-05-06 13:51:18 +00:00
More cleanup of CsgoHelper
Mainly let CodeMaid reorganize the file
This commit is contained in:
parent
a05d9785bd
commit
08caef7aaa
1 changed files with 179 additions and 159 deletions
|
@ -7,55 +7,22 @@ using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Management;
|
using System.Management;
|
||||||
using Pfim;
|
using Pfim;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
|
||||||
namespace SteamShared
|
namespace SteamShared
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A class that aids in getting information about CS:GO.
|
||||||
|
/// </summary>
|
||||||
public class CsgoHelper
|
public class CsgoHelper
|
||||||
{
|
{
|
||||||
public string? CsgoPath { get; set; }
|
|
||||||
|
|
||||||
public static readonly float DuckModifier = 0.34f;
|
|
||||||
|
|
||||||
public static readonly float WalkModifier = 0.52f;
|
|
||||||
|
|
||||||
public static readonly int GameID = 730;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the prefixes allowed for maps when using <see cref="GetMaps"/>.
|
/// Empty constructor.
|
||||||
|
/// Make sure the other constructor is called before using the object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
|
||||||
/// If adjusted, <see cref="GetMaps"/> should also be adjusted to set the type.
|
|
||||||
/// </remarks>
|
|
||||||
private readonly string[] validMapPrefixes = new[]
|
|
||||||
{
|
|
||||||
"de",
|
|
||||||
"cs",
|
|
||||||
"dz",
|
|
||||||
"ar"
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the files relative to the CS:GO install path that are checked when <see cref="Validate(string)">validating</see>.
|
|
||||||
/// </summary>
|
|
||||||
private readonly string[] filesToValidate = new[]
|
|
||||||
{
|
|
||||||
"csgo\\scripts\\items\\items_game.txt" // Item info (weapon stats etc.)
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the directories relative to the CS:GO install path that are checked when <see cref="Validate(string)">validating</see>.
|
|
||||||
/// </summary>
|
|
||||||
private readonly string[] directoriesToValidate = new[]
|
|
||||||
{
|
|
||||||
"csgo\\resource\\overviews" // Map overviews
|
|
||||||
};
|
|
||||||
|
|
||||||
public CsgoHelper()
|
public CsgoHelper()
|
||||||
{
|
{
|
||||||
// Nothing to do, don't use this ctor, aside from before the program initialises.
|
// Nothing to do, don't use this ctor, aside from before the program initialises.
|
||||||
|
@ -70,37 +37,18 @@ namespace SteamShared
|
||||||
this.CsgoPath = csgoPath;
|
this.CsgoPath = csgoPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The absolute path to the CS:GO root directory.
|
||||||
|
/// </summary>
|
||||||
|
public string? CsgoPath { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Validates files and directories for CS:GO installed in the <see cref="CsgoPath">path</see>.
|
/// Validates files and directories for CS:GO installed in the <see cref="CsgoPath">path</see>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>whether the files and directories exist.</returns>
|
/// <returns>whether the files and directories exist.</returns>
|
||||||
public bool Validate()
|
public bool Validate()
|
||||||
{
|
{
|
||||||
return this.Validate(this.CsgoPath!);
|
return this.Validate(this.CsgoPath);
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a handle to the currently running CS:GO instance.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>a tuple containing the process handle, as well as the arguments it was started with, either can be null.</returns>
|
|
||||||
public (Process?,string?) GetRunningCsgo()
|
|
||||||
{
|
|
||||||
// This is used as the normal process handle
|
|
||||||
Process? csgoProcess = Process.GetProcessesByName("csgo").FirstOrDefault(p => Globals.ComparePaths(p.MainModule?.FileName!, this.CsgoPath!));
|
|
||||||
|
|
||||||
// And this is used for grabbing the command line arguments the process was started with
|
|
||||||
string? cmdLine = string.Empty;
|
|
||||||
|
|
||||||
var mgmtClass = new ManagementClass("Win32_Process");
|
|
||||||
foreach (ManagementObject o in mgmtClass.GetInstances())
|
|
||||||
{
|
|
||||||
if (o["Name"].Equals("csgo.exe"))
|
|
||||||
{
|
|
||||||
cmdLine = o["CommandLine"].ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (csgoProcess, cmdLine);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -112,8 +60,11 @@ namespace SteamShared
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="csgoPath">The path to the CS:GO install directory, in which the executable resides.</param>
|
/// <param name="csgoPath">The path to the CS:GO install directory, in which the executable resides.</param>
|
||||||
/// <returns>whether the files and directories exist.</returns>
|
/// <returns>whether the files and directories exist.</returns>
|
||||||
public bool Validate(string csgoPath)
|
public bool Validate(string? csgoPath)
|
||||||
{
|
{
|
||||||
|
if (csgoPath is null)
|
||||||
|
return false;
|
||||||
|
|
||||||
foreach (string file in this.filesToValidate)
|
foreach (string file in this.filesToValidate)
|
||||||
{
|
{
|
||||||
if (!File.Exists(Path.Combine(csgoPath, file)))
|
if (!File.Exists(Path.Combine(csgoPath, file)))
|
||||||
|
@ -129,6 +80,30 @@ namespace SteamShared
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a handle to the currently running CS:GO instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>a tuple containing the process handle, as well as the arguments it was started with, either can be null.</returns>
|
||||||
|
public (Process? processHandle, string? startArguments) GetRunningCsgo()
|
||||||
|
{
|
||||||
|
// This is used as the normal process handle
|
||||||
|
Process? csgoProcess = Process.GetProcessesByName("csgo").FirstOrDefault(p => Globals.ComparePaths(p.MainModule?.FileName!, this.CsgoPath!));
|
||||||
|
|
||||||
|
// And this is used for grabbing the command line arguments the process was started with
|
||||||
|
string? cmdLine = string.Empty;
|
||||||
|
|
||||||
|
var mgmtClass = new ManagementClass("Win32_Process");
|
||||||
|
foreach (ManagementObject o in mgmtClass.GetInstances())
|
||||||
|
{
|
||||||
|
if (o["Name"].Equals("csgo.exe"))
|
||||||
|
{
|
||||||
|
cmdLine = o["CommandLine"].ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (csgoProcess, cmdLine);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets all maps and tries to fill all the information it can find about it.
|
/// Gets all maps and tries to fill all the information it can find about it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -391,6 +366,97 @@ namespace SteamShared
|
||||||
return weapons;
|
return weapons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads entity list from uncompressed BSP file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bspFilePath">The absolute path to the BSP file.</param>
|
||||||
|
/// <returns>the entity list, null if actual length differed from length specified in file, or a general error occurred.</returns>
|
||||||
|
public string? ReadEntityListFromBsp(string bspFilePath)
|
||||||
|
{
|
||||||
|
using (var bspFile = File.OpenRead(bspFilePath))
|
||||||
|
{
|
||||||
|
using (var reader = new BinaryReader(bspFile))
|
||||||
|
{
|
||||||
|
reader.BaseStream.Position = 8; // Skip magic bytes and file version
|
||||||
|
int offset = reader.ReadInt32(); // Lump data offset from beginning of file
|
||||||
|
int length = reader.ReadInt32(); // Length of lump data
|
||||||
|
|
||||||
|
reader.BaseStream.Position = offset;
|
||||||
|
char[] chars = new char[length];
|
||||||
|
int charsRead = reader.Read(chars, 0, length);
|
||||||
|
|
||||||
|
if (charsRead == length)
|
||||||
|
{
|
||||||
|
// Everything was read
|
||||||
|
return new string(chars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads packed files from a BSP and checks for NAV and AIN files.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bspFilePath">The absolute path to the BSP file.</param>
|
||||||
|
/// <returns>a tuple containing whether NAV or AIN files were found, as well as the parsed NAV mesh.</returns>
|
||||||
|
public (bool navFilesFound, bool ainFilesFound, NavMesh? navMesh) ReadIfPackedNavFilesInBsp(string bspFilePath)
|
||||||
|
{
|
||||||
|
bool navFound = false;
|
||||||
|
bool ainFound = false;
|
||||||
|
byte[]? readZipBytes = null;
|
||||||
|
|
||||||
|
using (var bspFile = File.OpenRead(bspFilePath))
|
||||||
|
{
|
||||||
|
using (var reader = new BinaryReader(bspFile))
|
||||||
|
{
|
||||||
|
// Skip stuff before (lumps + (pakfile index * lump array item length))
|
||||||
|
reader.BaseStream.Position = 8 + (40 * 16);
|
||||||
|
|
||||||
|
// Get lump pos and size
|
||||||
|
int offset = reader.ReadInt32();
|
||||||
|
int length = reader.ReadInt32();
|
||||||
|
|
||||||
|
// Read zip file
|
||||||
|
reader.BaseStream.Position = offset;
|
||||||
|
readZipBytes = reader.ReadBytes(length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readZipBytes == null)
|
||||||
|
return (false, false, null);
|
||||||
|
|
||||||
|
using var stream = new MemoryStream(readZipBytes);
|
||||||
|
|
||||||
|
// Packed files are contained in a ZIP file within the BSP file
|
||||||
|
using var zip = new ZipArchive(stream, ZipArchiveMode.Read);
|
||||||
|
|
||||||
|
NavMesh? nav = null;
|
||||||
|
foreach (var entry in zip.Entries)
|
||||||
|
{
|
||||||
|
if (entry.FullName.ToLower().EndsWith(".nav"))
|
||||||
|
{
|
||||||
|
// Found a packed NAV file
|
||||||
|
navFound = true;
|
||||||
|
nav = NavFile.Parse(entry.Open());
|
||||||
|
}
|
||||||
|
if (entry.FullName.ToLower().EndsWith(".ain"))
|
||||||
|
// Found a packed AIN file
|
||||||
|
ainFound = true;
|
||||||
|
|
||||||
|
if (navFound && ainFound)
|
||||||
|
{
|
||||||
|
// If both are already found, return prematurely,
|
||||||
|
// as we don't care how many there are
|
||||||
|
return (navFound, ainFound, nav);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We get here, if either no NAV or no AIN file has been found
|
||||||
|
// If navFound is null, nav will be null as well
|
||||||
|
return (navFound, ainFound, nav);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets whether a given weapon can be fired (Hint: You can't shoot knives, at least not in the usual sense).
|
/// Gets whether a given weapon can be fired (Hint: You can't shoot knives, at least not in the usual sense).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -404,7 +470,7 @@ namespace SteamShared
|
||||||
if (prefabTrace != null)
|
if (prefabTrace != null)
|
||||||
{
|
{
|
||||||
// Stuff involving prefab trace here
|
// Stuff involving prefab trace here
|
||||||
if(prefabTrace.FirstOrDefault(pr => pr == "primary" || pr == "secondary") != null)
|
if (prefabTrace.FirstOrDefault(pr => pr == "primary" || pr == "secondary") != null)
|
||||||
// Allow any weapon in the primary or secondary slot
|
// Allow any weapon in the primary or secondary slot
|
||||||
isWhitelisted = true;
|
isWhitelisted = true;
|
||||||
}
|
}
|
||||||
|
@ -470,7 +536,7 @@ namespace SteamShared
|
||||||
// =========================== ATTRIBUTES =========================== //
|
// =========================== ATTRIBUTES =========================== //
|
||||||
|
|
||||||
// Base damage
|
// Base damage
|
||||||
if (weapon.BaseDamage == -1)
|
if (weapon.BaseDamage == -1)
|
||||||
{
|
{
|
||||||
string damage = attributes["damage"]?.Value!;
|
string damage = attributes["damage"]?.Value!;
|
||||||
if (damage != null)
|
if (damage != null)
|
||||||
|
@ -608,7 +674,7 @@ namespace SteamShared
|
||||||
{
|
{
|
||||||
string fileName = Path.GetFileName(mapPath.ToLower());
|
string fileName = Path.GetFileName(mapPath.ToLower());
|
||||||
|
|
||||||
foreach(string prefix in this.validMapPrefixes)
|
foreach (string prefix in this.validMapPrefixes)
|
||||||
{
|
{
|
||||||
if (fileName.StartsWith(prefix.ToLower()))
|
if (fileName.StartsWith(prefix.ToLower()))
|
||||||
return true;
|
return true;
|
||||||
|
@ -617,97 +683,6 @@ namespace SteamShared
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Reads entity list from uncompressed BSP file.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="bspFilePath">The absolute path to the BSP file.</param>
|
|
||||||
/// <returns>the entity list, null if actual length differed from length specified in file, or a general error occurred.</returns>
|
|
||||||
public string? ReadEntityListFromBsp(string bspFilePath)
|
|
||||||
{
|
|
||||||
using(var bspFile = File.OpenRead(bspFilePath))
|
|
||||||
{
|
|
||||||
using(var reader = new BinaryReader(bspFile))
|
|
||||||
{
|
|
||||||
reader.BaseStream.Position = 8; // Skip magic bytes and file version
|
|
||||||
int offset = reader.ReadInt32(); // Lump data offset from beginning of file
|
|
||||||
int length = reader.ReadInt32(); // Length of lump data
|
|
||||||
|
|
||||||
reader.BaseStream.Position = offset;
|
|
||||||
char[] chars = new char[length];
|
|
||||||
int charsRead = reader.Read(chars, 0, length);
|
|
||||||
|
|
||||||
if(charsRead == length)
|
|
||||||
{
|
|
||||||
// Everything was read
|
|
||||||
return new string(chars);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Reads packed files from a BSP and checks for NAV and AIN files.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="bspFilePath">The absolute path to the BSP file.</param>
|
|
||||||
/// <returns>a tuple containing whether NAV or AIN files were found, as well as the parsed NAV mesh.</returns>
|
|
||||||
public (bool NavFilesFound, bool AinFilesFound, NavMesh? NavMesh) ReadIfPackedNavFilesInBsp(string bspFilePath)
|
|
||||||
{
|
|
||||||
bool navFound = false;
|
|
||||||
bool ainFound = false;
|
|
||||||
byte[]? readZipBytes = null;
|
|
||||||
|
|
||||||
using (var bspFile = File.OpenRead(bspFilePath))
|
|
||||||
{
|
|
||||||
using (var reader = new BinaryReader(bspFile))
|
|
||||||
{
|
|
||||||
// Skip stuff before (lumps + (pakfile index * lump array item length))
|
|
||||||
reader.BaseStream.Position = 8 + (40 * 16);
|
|
||||||
|
|
||||||
// Get lump pos and size
|
|
||||||
int offset = reader.ReadInt32();
|
|
||||||
int length = reader.ReadInt32();
|
|
||||||
|
|
||||||
// Read zip file
|
|
||||||
reader.BaseStream.Position = offset;
|
|
||||||
readZipBytes = reader.ReadBytes(length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (readZipBytes == null)
|
|
||||||
return (false, false, null);
|
|
||||||
|
|
||||||
using var stream = new MemoryStream(readZipBytes);
|
|
||||||
|
|
||||||
// Packed files are contained in a ZIP file within the BSP file
|
|
||||||
using var zip = new ZipArchive(stream, ZipArchiveMode.Read);
|
|
||||||
|
|
||||||
NavMesh? nav = null;
|
|
||||||
foreach (var entry in zip.Entries)
|
|
||||||
{
|
|
||||||
if (entry.FullName.ToLower().EndsWith(".nav"))
|
|
||||||
{
|
|
||||||
// Found a packed NAV file
|
|
||||||
navFound = true;
|
|
||||||
nav = NavFile.Parse(entry.Open());
|
|
||||||
}
|
|
||||||
if (entry.FullName.ToLower().EndsWith(".ain"))
|
|
||||||
// Found a packed AIN file
|
|
||||||
ainFound = true;
|
|
||||||
|
|
||||||
if (navFound && ainFound)
|
|
||||||
{
|
|
||||||
// If both are already found, return prematurely,
|
|
||||||
// as we don't care how many there are
|
|
||||||
return (navFound, ainFound, nav);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We get here, if either no NAV or no AIN file has been found
|
|
||||||
// If navFound is null, nav will be null as well
|
|
||||||
return (navFound, ainFound, nav);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks whether a lump is unused (all zeroes).
|
/// Checks whether a lump is unused (all zeroes).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -715,7 +690,7 @@ namespace SteamShared
|
||||||
/// <returns>a bool indicating if the lump is unused.</returns>
|
/// <returns>a bool indicating if the lump is unused.</returns>
|
||||||
private bool isLumpUnused(byte[] lump)
|
private bool isLumpUnused(byte[] lump)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < lump.Length; i++)
|
for (int i = 0; i < lump.Length; i++)
|
||||||
{
|
{
|
||||||
if (lump[i] != 0)
|
if (lump[i] != 0)
|
||||||
return false;
|
return false;
|
||||||
|
@ -723,5 +698,50 @@ namespace SteamShared
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The multiplier for player movement speed while ducking.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly float DuckModifier = 0.34f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The multiplier for player movement speed while shifting.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly float WalkModifier = 0.52f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Steam game ID of CS:GO.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly int GameID = 730;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the prefixes allowed for maps when using <see cref="GetMaps"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// If adjusted, <see cref="GetMaps"/> should also be adjusted to set the type.
|
||||||
|
/// </remarks>
|
||||||
|
private readonly string[] validMapPrefixes = new[]
|
||||||
|
{
|
||||||
|
"de",
|
||||||
|
"cs",
|
||||||
|
"dz",
|
||||||
|
"ar"
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the files relative to the CS:GO install path that are checked when <see cref="Validate(string)">validating</see>.
|
||||||
|
/// </summary>
|
||||||
|
private readonly string[] filesToValidate = new[]
|
||||||
|
{
|
||||||
|
"csgo\\scripts\\items\\items_game.txt" // Item info (weapon stats etc.)
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the directories relative to the CS:GO install path that are checked when <see cref="Validate(string)">validating</see>.
|
||||||
|
/// </summary>
|
||||||
|
private readonly string[] directoriesToValidate = new[]
|
||||||
|
{
|
||||||
|
"csgo\\resource\\overviews" // Map overviews
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue