mirror of
https://github.com/roflmuffin/CounterStrikeSharp.git
synced 2025-12-07 08:26:34 -08:00
Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f9630b92d | ||
|
|
02bf2483d3 | ||
|
|
cb181b6a49 | ||
|
|
cc21dca5a0 | ||
|
|
5721d060ea | ||
|
|
220521d571 | ||
|
|
5698b511e9 | ||
|
|
48c9d195ff | ||
|
|
603827d331 | ||
|
|
e557d54c32 | ||
|
|
48d3ade5cf | ||
|
|
77b05e912e | ||
|
|
1354b4972d | ||
|
|
8b5eb7e38d | ||
|
|
2dd62c44d3 | ||
|
|
f811338ce4 | ||
|
|
194c340ae7 | ||
|
|
6b0912d3cd | ||
|
|
2d3aa09aa4 | ||
|
|
911084e71e | ||
|
|
5b99206568 | ||
|
|
4bfdf28beb | ||
|
|
9bcd0f7e92 | ||
|
|
11c6486ec5 | ||
|
|
ee69560a66 | ||
|
|
d37e5e194a | ||
|
|
c4740d1cc9 | ||
|
|
7e92f178fd | ||
|
|
107ca08132 | ||
|
|
8cda8d9a50 | ||
|
|
3d59a05de8 | ||
|
|
77b7040d6c | ||
|
|
75de9732ef | ||
|
|
7c7f52a219 | ||
|
|
cd593fb238 | ||
|
|
c5cc65be48 | ||
|
|
59928bbcc5 |
@@ -63,6 +63,10 @@ public class HelloWorldPlugin : BasePlugin
|
||||
|
||||
public override string ModuleVersion => "0.0.1";
|
||||
|
||||
public override string ModuleAuthor => "roflmuffin";
|
||||
|
||||
public override string ModuleDescription => "Simple hello world plugin";
|
||||
|
||||
public override void Load(bool hotReload)
|
||||
{
|
||||
Logger.LogInformation("Plugin loaded successfully!");
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"PublicChatTrigger": [ "!" ],
|
||||
"SilentChatTrigger": [ "/" ],
|
||||
"FollowCS2ServerGuidelines": true
|
||||
"FollowCS2ServerGuidelines": true,
|
||||
"PluginHotReloadEnabled": true
|
||||
}
|
||||
@@ -68,19 +68,20 @@ Now build your project using your ide or the `dotnet build` command. You should
|
||||
|
||||
### Installing your Plugin
|
||||
|
||||
Locate the `plugins` folder in your CS2 dedicated server (`/game/csgo/addons/counterstrikesharp/plugins`) and create a new folder with the exact same name as your output .dll file. In this example it would be `HelloWorldPlugin.dll`, so I will make a new folder called `HelloWorldPlugin`. Inside of this folder, copy and paste all of the `.dll` files _except_ the `CounterStrikeSharp.API.dll` file. Once completed, the folder should look as follows:
|
||||
Locate the `plugins` folder in your CS2 dedicated server (`/game/csgo/addons/counterstrikesharp/plugins`) and create a new folder with the exact same name as your output .dll file. In this example it would be `HelloWorldPlugin.dll`, so I will make a new folder called `HelloWorldPlugin`. Inside of this folder, copy and paste the: `HelloWorldPlugin.deps.json`, `HelloWorldPlugin.dll`, and `HelloWorldPlugin.pdb` files. Once completed, the folder should look as follows:
|
||||
|
||||
```shell
|
||||
.
|
||||
└── SamplePlugin
|
||||
├── McMaster.NETCore.Plugins.dll
|
||||
├── Microsoft.DotNet.PlatformAbstractions.dll
|
||||
├── Microsoft.Extensions.DependencyModel.dll
|
||||
├── SamplePlugin.deps.json
|
||||
├── SamplePlugin.dll
|
||||
└── SamplePlugin.pdb
|
||||
└── HelloWorldPlugin
|
||||
├── HelloWorldPlugin.deps.json
|
||||
├── HelloWorldPlugin.dll
|
||||
└── HelloWorldPlugin.pdb
|
||||
```
|
||||
|
||||
:::caution
|
||||
If you have installed external nuget packages for your plugin, you may need to include their respective `.dll`s. For example, if you utilize the `Stateless` C# library, include `stateless.dll` in your `HelloWorld` plugin directory.
|
||||
:::
|
||||
|
||||
:::note
|
||||
Note that some of these dependencies may change depending on the version of CounterStrikeSharp being used.
|
||||
:::
|
||||
|
||||
@@ -25,6 +25,10 @@ public class HelloWorldPlugin : BasePlugin
|
||||
|
||||
public override string ModuleVersion => "0.0.1";
|
||||
|
||||
public override string ModuleAuthor => "roflmuffin";
|
||||
|
||||
public override string ModuleDescription => "Simple hello world plugin";
|
||||
|
||||
public override void Load(bool hotReload)
|
||||
{
|
||||
Logger.LogInformation("Plugin loaded successfully!");
|
||||
|
||||
@@ -23,4 +23,8 @@ receive a ban.
|
||||
|
||||
:::note
|
||||
Disable this option at your own risk.
|
||||
:::
|
||||
:::
|
||||
|
||||
## PluginHotReloadEnabled
|
||||
|
||||
When enabled, plugins are automatically reloaded when their .dll file is updated.
|
||||
|
||||
12
examples/HelloWorld/HelloWorld.csproj
Normal file
12
examples/HelloWorld/HelloWorld.csproj
Normal file
@@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\managed\CounterStrikeSharp.API\CounterStrikeSharp.API.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
24
examples/HelloWorld/HelloWorldPlugin.cs
Normal file
24
examples/HelloWorld/HelloWorldPlugin.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace HelloWorld;
|
||||
|
||||
[MinimumApiVersion(80)]
|
||||
public class HelloWorldPlugin : BasePlugin
|
||||
{
|
||||
public override string ModuleName => "Example: Hello World";
|
||||
public override string ModuleVersion => "1.0.0";
|
||||
public override string ModuleAuthor => "CounterStrikeSharp & Contributors";
|
||||
public override string ModuleDescription => "A simple plugin that says hello world!";
|
||||
|
||||
public override void Load(bool hotReload)
|
||||
{
|
||||
Logger.LogInformation("Hello World! We are loading!");
|
||||
}
|
||||
|
||||
public override void Unload(bool hotReload)
|
||||
{
|
||||
Logger.LogInformation("Hello World! We are unloading!");
|
||||
}
|
||||
}
|
||||
2
examples/HelloWorld/README.md
Normal file
2
examples/HelloWorld/README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# Hello World
|
||||
This is a minimal "Hello World" example that executes code on load & unload.
|
||||
@@ -73,7 +73,7 @@ namespace WarcraftPlugin
|
||||
var victim = @event.Userid;
|
||||
var headshot = @event.Headshot;
|
||||
|
||||
if (attacker.IsValid && victim.IsValid && (attacker.EntityIndex.Value.Value != victim.EntityIndex.Value.Value) && !attacker.IsBot)
|
||||
if (attacker.IsValid && victim.IsValid && (attacker != victim) && !attacker.IsBot)
|
||||
{
|
||||
var weaponName = attacker.PlayerPawn.Value.WeaponServices.ActiveWeapon.Value.DesignerName;
|
||||
|
||||
|
||||
4
examples/WithCommands/README.md
Normal file
4
examples/WithCommands/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# With Commands
|
||||
This is an example that shows how to register chat & console commands.
|
||||
|
||||
All commands that are prefixed with "css_" will automatically be registered as a chat command without the prefix. i.e. `css_ping` can be called with `!ping` or `/ping`.
|
||||
12
examples/WithCommands/WithCommands.csproj
Normal file
12
examples/WithCommands/WithCommands.csproj
Normal file
@@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\managed\CounterStrikeSharp.API\CounterStrikeSharp.API.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
63
examples/WithCommands/WithCommandsPlugin.cs
Normal file
63
examples/WithCommands/WithCommandsPlugin.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
using CounterStrikeSharp.API.Core.Attributes.Registration;
|
||||
using CounterStrikeSharp.API.Modules.Admin;
|
||||
using CounterStrikeSharp.API.Modules.Commands;
|
||||
|
||||
namespace WithCommands;
|
||||
|
||||
[MinimumApiVersion(80)]
|
||||
public class WithCommandsPlugin : BasePlugin
|
||||
{
|
||||
public override string ModuleName => "Example: With Commands";
|
||||
public override string ModuleVersion => "1.0.0";
|
||||
public override string ModuleAuthor => "CounterStrikeSharp & Contributors";
|
||||
public override string ModuleDescription => "A simple plugin that registers some commands";
|
||||
|
||||
public override void Load(bool hotReload)
|
||||
{
|
||||
// All commands that are prefixed with "css_" will automatically be registered as a chat command without the prefix.
|
||||
// i.e. `css_ping` can be called with `!ping` or `/ping`.
|
||||
// Commands can be registered using the instance `AddCommand` method.
|
||||
AddCommand("css_ping", "Responds to the caller with \"pong\"", (player, commandInfo) =>
|
||||
{
|
||||
// The player is null, then the command has been called by the server console.
|
||||
if (player == null)
|
||||
{
|
||||
commandInfo.ReplyToCommand("pong server");
|
||||
return;
|
||||
}
|
||||
|
||||
commandInfo.ReplyToCommand("pong");
|
||||
});
|
||||
}
|
||||
|
||||
// Commands can also be registered using the `Command` attribute.
|
||||
[ConsoleCommand("css_hello", "Responds to the caller with \"pong\"")]
|
||||
// The `CommandHelper` attribute can be used to provide additional information about the command.
|
||||
[CommandHelper(minArgs: 1, usage: "[name]", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
|
||||
[RequiresPermissions("@css/cvar")]
|
||||
public void OnHelloCommand(CCSPlayerController? player, CommandInfo commandInfo)
|
||||
{
|
||||
// The first argument is the command name, in this case "css_hello".
|
||||
commandInfo.GetArg(0); // css_hello
|
||||
|
||||
// The second argument is the first argument passed to the command, in this case "name".
|
||||
// The `minArgs` helper parameter is used to ensure that the second argument is present.
|
||||
var name = commandInfo.GetArg(1);
|
||||
|
||||
commandInfo.ReplyToCommand($"Hello {name}");
|
||||
}
|
||||
|
||||
// Permissions can be added to commands using the `RequiresPermissions` attribute.
|
||||
// See the admin documentation for more information on permissions.
|
||||
[RequiresPermissions("@css/kick")]
|
||||
[CommandHelper(minArgs: 1, usage: "[id]", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
|
||||
public void OnSpecialCommand(CCSPlayerController? player, CommandInfo commandInfo)
|
||||
{
|
||||
var id = commandInfo.GetArg(1);
|
||||
|
||||
Server.ExecuteCommand($"kick {id}");
|
||||
}
|
||||
}
|
||||
2
examples/WithConfig/README.md
Normal file
2
examples/WithConfig/README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# WithConfig
|
||||
This example shows how you can implement the `IPluginConfig` interface to allow for semi-automatic config parsing & loading.
|
||||
12
examples/WithConfig/WithConfig.csproj
Normal file
12
examples/WithConfig/WithConfig.csproj
Normal file
@@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\managed\CounterStrikeSharp.API\CounterStrikeSharp.API.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
38
examples/WithConfig/WithConfigPlugin.cs
Normal file
38
examples/WithConfig/WithConfigPlugin.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
|
||||
namespace WithConfig;
|
||||
|
||||
public class SampleConfig : BasePluginConfig
|
||||
{
|
||||
[JsonPropertyName("ChatPrefix")] public string ChatPrefix { get; set; } = "My Cool Plugin";
|
||||
|
||||
[JsonPropertyName("ChatInterval")] public float ChatInterval { get; set; } = 60;
|
||||
}
|
||||
|
||||
[MinimumApiVersion(80)]
|
||||
public class WithConfigPlugin : BasePlugin, IPluginConfig<SampleConfig>
|
||||
{
|
||||
public override string ModuleName => "Example: With Config";
|
||||
public override string ModuleVersion => "1.0.0";
|
||||
|
||||
public SampleConfig Config { get; set; }
|
||||
|
||||
public void OnConfigParsed(SampleConfig config)
|
||||
{
|
||||
// Do manual verification of the config and override any invalid values
|
||||
if (config.ChatInterval > 60)
|
||||
{
|
||||
config.ChatInterval = 60;
|
||||
}
|
||||
|
||||
if (config.ChatPrefix.Length > 25)
|
||||
{
|
||||
throw new Exception($"Invalid value has been set to config value 'ChatPrefix': {config.ChatPrefix}");
|
||||
}
|
||||
|
||||
// Once we've validated the config, we can set it to the instance
|
||||
Config = config;
|
||||
}
|
||||
}
|
||||
2
examples/WithDatabaseDapper/README.md
Normal file
2
examples/WithDatabaseDapper/README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# With Database (Dapper)
|
||||
Simple SQLite database example using Dapper library to track kills.
|
||||
16
examples/WithDatabaseDapper/WithDatabaseDapper.csproj
Normal file
16
examples/WithDatabaseDapper/WithDatabaseDapper.csproj
Normal file
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\managed\CounterStrikeSharp.API\CounterStrikeSharp.API.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Dapper" Version="2.1.24" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="7.0.14" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
89
examples/WithDatabaseDapper/WithDatabaseDapperPlugin.cs
Normal file
89
examples/WithDatabaseDapper/WithDatabaseDapperPlugin.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
using CounterStrikeSharp.API.Core.Attributes.Registration;
|
||||
using CounterStrikeSharp.API.Modules.Commands;
|
||||
using Dapper;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace WithDatabaseDapper;
|
||||
|
||||
[MinimumApiVersion(80)]
|
||||
public class WithDatabaseDapperPlugin : BasePlugin
|
||||
{
|
||||
public override string ModuleName => "Example: With Database (Dapper)";
|
||||
public override string ModuleVersion => "1.0.0";
|
||||
public override string ModuleAuthor => "CounterStrikeSharp & Contributors";
|
||||
public override string ModuleDescription => "A plugin that reads and writes from the database.";
|
||||
|
||||
private SqliteConnection _connection = null!;
|
||||
|
||||
public override void Load(bool hotReload)
|
||||
{
|
||||
Logger.LogInformation("Loading database from {Path}", Path.Join(ModuleDirectory, "database.db"));
|
||||
_connection = new SqliteConnection($"Data Source={Path.Join(ModuleDirectory, "database.db")}");
|
||||
_connection.Open();
|
||||
|
||||
// Create the table if it doesn't exist
|
||||
// Run in a separate thread to avoid blocking the main thread
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await _connection.ExecuteAsync(@"
|
||||
CREATE TABLE IF NOT EXISTS `players` (
|
||||
`steamid` UNSIGNED BIG INT NOT NULL,
|
||||
`kills` INT NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`steamid`));");
|
||||
});
|
||||
}
|
||||
|
||||
[GameEventHandler]
|
||||
public HookResult OnPlayerKilled(EventPlayerDeath @event, GameEventInfo info)
|
||||
{
|
||||
// Don't count suicides.
|
||||
if (@event.Attacker == @event.Userid) return HookResult.Continue;
|
||||
|
||||
// Capture the steamid of the player as `@event` will not be available outside of this function.
|
||||
var steamId = @event.Attacker.AuthorizedSteamID?.SteamId64;
|
||||
|
||||
if (steamId == null) return HookResult.Continue;
|
||||
|
||||
// Run in a separate thread to avoid blocking the main thread
|
||||
Task.Run(async () =>
|
||||
{
|
||||
// insert or update the player's kills
|
||||
await _connection.ExecuteAsync(@"
|
||||
INSERT INTO `players` (`steamid`, `kills`) VALUES (@SteamId, 1)
|
||||
ON CONFLICT(`steamid`) DO UPDATE SET `kills` = `kills` + 1;",
|
||||
new
|
||||
{
|
||||
SteamId = steamId
|
||||
});
|
||||
});
|
||||
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
[ConsoleCommand("css_kills", "Get count of kills for a player")]
|
||||
public void OnKillsCommand(CCSPlayerController? player, CommandInfo commandInfo)
|
||||
{
|
||||
if (player == null) return;
|
||||
|
||||
// Capture the SteamID of the player as `@event` will not be available outside of this function.
|
||||
var steamId = player.AuthorizedSteamID.SteamId64;
|
||||
|
||||
// Run in a separate thread to avoid blocking the main thread
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var result = await _connection.QueryFirstOrDefaultAsync(@"SELECT `kills` FROM `players` WHERE `steamid` = @SteamId;",
|
||||
new
|
||||
{
|
||||
SteamId = steamId
|
||||
});
|
||||
|
||||
// Print the result to the player's chat. Note that this needs to be run on the game thread.
|
||||
// So we use `Server.NextFrame` to run it on the next game tick.
|
||||
Server.NextFrame(() => { player.PrintToChat($"Kills: {result?.kills ?? 0}"); });
|
||||
});
|
||||
}
|
||||
}
|
||||
2
examples/WithDependencyInjection/README.md
Normal file
2
examples/WithDependencyInjection/README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# With Dependency Injection
|
||||
This example shows how can you implement the `IPluginServiceCollection` interface to register your services in a provided DI container.
|
||||
@@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\managed\CounterStrikeSharp.API\CounterStrikeSharp.API.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,50 @@
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace WithDependencyInjection;
|
||||
|
||||
[MinimumApiVersion(80)]
|
||||
public class WithDependencyInjectionPlugin : BasePlugin
|
||||
{
|
||||
public override string ModuleName => "Example: Dependency Injection";
|
||||
public override string ModuleVersion => "1.0.0";
|
||||
public override string ModuleAuthor => "CounterStrikeSharp & Contributors";
|
||||
public override string ModuleDescription => "An example plugin that uses dependency injection.";
|
||||
|
||||
private readonly TestInjectedClass _testInjectedClass;
|
||||
|
||||
public WithDependencyInjectionPlugin(TestInjectedClass testInjectedClass)
|
||||
{
|
||||
_testInjectedClass = testInjectedClass;
|
||||
}
|
||||
|
||||
public override void Load(bool hotReload)
|
||||
{
|
||||
_testInjectedClass.SayHello();
|
||||
}
|
||||
}
|
||||
|
||||
public class WithDependencyInjectionPluginServiceCollection : IPluginServiceCollection<WithDependencyInjectionPlugin>
|
||||
{
|
||||
public void ConfigureServices(IServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.AddSingleton<TestInjectedClass>();
|
||||
}
|
||||
}
|
||||
|
||||
public class TestInjectedClass
|
||||
{
|
||||
private readonly ILogger<TestInjectedClass> _logger;
|
||||
|
||||
public TestInjectedClass(ILogger<TestInjectedClass> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void SayHello()
|
||||
{
|
||||
_logger.LogInformation("Hello World from Test Injected Class");
|
||||
}
|
||||
}
|
||||
2
examples/WithGameEventHandlers/README.md
Normal file
2
examples/WithGameEventHandlers/README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# With Game Event Handlers
|
||||
This is example shows how you can subscribe to legacy Source 1 game events.
|
||||
12
examples/WithGameEventHandlers/WithGameEventHandlers.csproj
Normal file
12
examples/WithGameEventHandlers/WithGameEventHandlers.csproj
Normal file
@@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\managed\CounterStrikeSharp.API\CounterStrikeSharp.API.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,54 @@
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
using CounterStrikeSharp.API.Core.Attributes.Registration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace WithGameEventHandlers;
|
||||
|
||||
[MinimumApiVersion(80)]
|
||||
public class WithGameEventHandlersPlugin : BasePlugin
|
||||
{
|
||||
public override string ModuleName => "Example: With Game Event Handlers";
|
||||
public override string ModuleVersion => "1.0.0";
|
||||
public override string ModuleAuthor => "CounterStrikeSharp & Contributors";
|
||||
public override string ModuleDescription => "A simple plugin that subscribes to game events";
|
||||
|
||||
public override void Load(bool hotReload)
|
||||
{
|
||||
// Subscriptions can be added via the instance method
|
||||
RegisterEventHandler<EventPlayerDeath>((@event, info) =>
|
||||
{
|
||||
// You can use `info.DontBroadcast` to set the dont broadcast flag on the event (in pre handlers)
|
||||
// This will prevent the event from being broadcast to other clients.
|
||||
// In this example we prevent kill-feed messages from being broadcast if it was not a headshot.
|
||||
if (!@event.Headshot)
|
||||
{
|
||||
@event.Attacker.PrintToChat($"Skipping player_death broadcast");
|
||||
info.DontBroadcast = true;
|
||||
}
|
||||
|
||||
return HookResult.Continue;
|
||||
}, HookMode.Pre);
|
||||
}
|
||||
|
||||
// Subscriptions can be added via an attribute
|
||||
[GameEventHandler]
|
||||
public HookResult OnPlayerBlind(EventPlayerBlind @event, GameEventInfo info)
|
||||
{
|
||||
Logger.LogInformation("Player was just blinded for {Duration}", @event.BlindDuration);
|
||||
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
// The event name is inferred from the event type you pass to the first argument.
|
||||
// e.g. EventRoundStart becomes "round_start"
|
||||
// Note: You can use the `HookMode` enum to specify the hook mode
|
||||
// If you do not specify a hook mode, it will default to `HookMode.Post`
|
||||
[GameEventHandler(HookMode.Pre)]
|
||||
public HookResult OnEventRoundStartPre(EventRoundStart @event, GameEventInfo info)
|
||||
{
|
||||
Logger.LogInformation("Round has started with Timelimit: {Timelimit}", @event.Timelimit);
|
||||
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
@@ -30,5 +30,19 @@ namespace CounterStrikeSharp.API
|
||||
{
|
||||
Handle = pointer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new instance of the specified type using the pointer from the passed in object.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Useful for creating a new instance of a class that inherits from NativeObject.
|
||||
/// e.g. <code>var weaponServices = playerWeaponServices.As<CCSPlayer_WeaponServices>();</code>
|
||||
/// </remarks>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public T As<T>() where T : NativeObject
|
||||
{
|
||||
return (T)Activator.CreateInstance(typeof(T), this.Handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,6 +157,30 @@ namespace CounterStrikeSharp.API.Core
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetClientConvarValue(int clientindex, string convarname){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(clientindex);
|
||||
ScriptContext.GlobalScriptContext.Push(convarname);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0xAE4B1B79);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (string)ScriptContext.GlobalScriptContext.GetResult(typeof(string));
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetFakeClientConvarValue(int clientindex, string convarname, string convarvalue){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(clientindex);
|
||||
ScriptContext.GlobalScriptContext.Push(convarname);
|
||||
ScriptContext.GlobalScriptContext.Push(convarvalue);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x4C61E8BB);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
}
|
||||
}
|
||||
|
||||
public static T DynamicHookGetReturn<T>(IntPtr hook, int datatype){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
@@ -534,6 +558,49 @@ namespace CounterStrikeSharp.API.Core
|
||||
}
|
||||
}
|
||||
|
||||
public static uint GetRefFromEntityPointer(IntPtr entitypointer){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(entitypointer);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0xAF13DA94);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (uint)ScriptContext.GlobalScriptContext.GetResult(typeof(uint));
|
||||
}
|
||||
}
|
||||
|
||||
public static IntPtr GetEntityPointerFromRef(uint entityref){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(entityref);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0xDBC17174);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (IntPtr)ScriptContext.GlobalScriptContext.GetResult(typeof(IntPtr));
|
||||
}
|
||||
}
|
||||
|
||||
public static IntPtr GetConcreteEntityListPointer(){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x5756DB36);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (IntPtr)ScriptContext.GlobalScriptContext.GetResult(typeof(IntPtr));
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsRefValidEntity(uint entityref){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(entityref);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x6E38A1FC);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (bool)ScriptContext.GlobalScriptContext.GetResult(typeof(bool));
|
||||
}
|
||||
}
|
||||
|
||||
public static void PrintToConsole(int index, string message){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
@@ -555,6 +622,28 @@ namespace CounterStrikeSharp.API.Core
|
||||
}
|
||||
}
|
||||
|
||||
public static ulong GetPlayerAuthorizedSteamid(int slot){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(slot);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0xD1F30B3B);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (ulong)ScriptContext.GlobalScriptContext.GetResult(typeof(ulong));
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetPlayerIpAddress(int slot){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(slot);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x46A45CB0);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (string)ScriptContext.GlobalScriptContext.GetResult(typeof(string));
|
||||
}
|
||||
}
|
||||
|
||||
public static void HookEvent(string name, InputArgument callback, bool ispost){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
@@ -967,6 +1056,17 @@ namespace CounterStrikeSharp.API.Core
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetSchemaClassSize(string classname){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(classname);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x9CE4FC56);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (int)ScriptContext.GlobalScriptContext.GetResult(typeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
public static IntPtr GetEconItemSystem(){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
@@ -977,6 +1077,16 @@ namespace CounterStrikeSharp.API.Core
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsServerPaused(){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0xB216AAAC);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (bool)ScriptContext.GlobalScriptContext.GetResult(typeof(bool));
|
||||
}
|
||||
}
|
||||
|
||||
public static IntPtr CreateTimer(float interval, InputArgument callback, int flags){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
|
||||
@@ -43,6 +43,9 @@ namespace CounterStrikeSharp.API.Core
|
||||
|
||||
[JsonPropertyName("FollowCS2ServerGuidelines")]
|
||||
public bool FollowCS2ServerGuidelines { get; set; } = true;
|
||||
|
||||
[JsonPropertyName("PluginHotReloadEnabled")]
|
||||
public bool PluginHotReloadEnabled { get; set; } = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -80,6 +83,11 @@ namespace CounterStrikeSharp.API.Core
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public static bool FollowCS2ServerGuidelines => _coreConfig.FollowCS2ServerGuidelines;
|
||||
|
||||
/// <summary>
|
||||
/// When enabled, plugins are automatically reloaded when their .dll file is updated.
|
||||
/// </summary>
|
||||
public static bool PluginHotReloadEnabled => _coreConfig.PluginHotReloadEnabled;
|
||||
}
|
||||
|
||||
public partial class CoreConfig : IStartupService
|
||||
|
||||
@@ -23,6 +23,10 @@ namespace CounterStrikeSharp.API.Core
|
||||
{
|
||||
T Config { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Called when the `ConfigManager` has parsed the configuration file for this plugin
|
||||
/// </summary>
|
||||
/// <param name="config">Parsed config instance</param>
|
||||
public void OnConfigParsed(T config);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +125,18 @@ namespace CounterStrikeSharp.API.Core
|
||||
{
|
||||
return new InputArgument(value);
|
||||
}
|
||||
|
||||
[SecurityCritical]
|
||||
public static implicit operator InputArgument(NativeObject value)
|
||||
{
|
||||
return new InputArgument(value.Handle);
|
||||
}
|
||||
|
||||
[SecurityCritical]
|
||||
public static implicit operator InputArgument(NativeEntity value)
|
||||
{
|
||||
return new InputArgument(value.Handle);
|
||||
}
|
||||
|
||||
[SecurityCritical]
|
||||
public static unsafe implicit operator InputArgument(void* value)
|
||||
|
||||
@@ -126,5 +126,26 @@ namespace CounterStrikeSharp.API.Core
|
||||
/// <param name="hostname">New hostname of the server</param>
|
||||
[ListenerName("OnHostNameChanged")]
|
||||
public delegate void OnHostNameChanged(string hostname);
|
||||
|
||||
/// <summary>
|
||||
/// Called before the server enters fatal shutdown.
|
||||
/// </summary>
|
||||
[ListenerName("OnPreFatalShutdown")]
|
||||
public delegate void OnServerPreFatalShutdown();
|
||||
|
||||
/// <summary>
|
||||
/// Called when the server is in a loading stage.
|
||||
/// </summary>
|
||||
/// <param name="frameTime"></param>
|
||||
[ListenerName("OnUpdateWhenNotInGame")]
|
||||
public delegate void OnUpdateWhenNotInGame(float frameTime);
|
||||
|
||||
/// <summary>
|
||||
/// Called before the world updates.
|
||||
/// This seems to be called even when the server is hibernating.
|
||||
/// </summary>
|
||||
/// <param name="simulating"><see langword="true"/> if simulating, <see langword="false"/> otherwise</param>
|
||||
[ListenerName("OnServerPreWorldUpdate")]
|
||||
public delegate void OnServerPreWorldUpdate(bool simulating);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
using System;
|
||||
|
||||
using CounterStrikeSharp.API.Modules.Cvars;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
using CounterStrikeSharp.API.Modules.Entities.Constants;
|
||||
using CounterStrikeSharp.API.Modules.Memory;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
@@ -11,8 +14,7 @@ public partial class CCSPlayerController
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EntityIndex == null) return null;
|
||||
return NativeAPI.GetUseridFromIndex((int)this.EntityIndex.Value.Value);
|
||||
return NativeAPI.GetUseridFromIndex((int)this.Index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +40,7 @@ public partial class CCSPlayerController
|
||||
|
||||
public void PrintToConsole(string message)
|
||||
{
|
||||
NativeAPI.PrintToConsole((int)EntityIndex.Value.Value, $"{message}\n\0");
|
||||
NativeAPI.PrintToConsole((int)Index, $"{message}\n\0");
|
||||
}
|
||||
|
||||
public void PrintToChat(string message)
|
||||
@@ -50,13 +52,15 @@ public partial class CCSPlayerController
|
||||
{
|
||||
VirtualFunctions.ClientPrint(this.Handle, HudDestination.Center, message, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
public void PrintToCenterHtml(string message) => PrintToCenterHtml(message, 5);
|
||||
|
||||
public void PrintToCenterHtml(string message)
|
||||
public void PrintToCenterHtml(string message, int duration)
|
||||
{
|
||||
var @event = new EventShowSurvivalRespawnStatus(true)
|
||||
{
|
||||
LocToken = message,
|
||||
Duration = 5,
|
||||
Duration = duration,
|
||||
Userid = this
|
||||
};
|
||||
@event.FireEventToClient(this);
|
||||
@@ -140,8 +144,94 @@ public partial class CCSPlayerController
|
||||
team);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a ConVar value for given player
|
||||
/// </summary>
|
||||
/// <param name="conVar">Name of the convar to retrieve</param>
|
||||
/// <returns>ConVar string value</returns>
|
||||
public string GetConVarValue(string conVar)
|
||||
{
|
||||
return NativeAPI.GetClientConvarValue(this.Slot, conVar);
|
||||
}
|
||||
|
||||
public string GetConVarValue(ConVar? conVar)
|
||||
{
|
||||
if (conVar == null)
|
||||
{
|
||||
throw new Exception("Invalid convar passed to 'GetConVarValue'");
|
||||
}
|
||||
|
||||
return GetConVarValue(conVar.Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a ConVar value on a fake client (bot).
|
||||
/// </summary>
|
||||
/// <param name="conVar">Console variable name</param>
|
||||
/// <param name="value">String value to set</param>
|
||||
/// <exception cref="InvalidOperationException">Player is not a bot</exception>
|
||||
public void SetFakeClientConVar(string conVar, string value)
|
||||
{
|
||||
if (!IsBot)
|
||||
{
|
||||
throw new InvalidOperationException("'SetFakeClientConVar' can only be called for fake clients (bots)");
|
||||
}
|
||||
|
||||
NativeAPI.SetFakeClientConvarValue(this.Slot, conVar, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc cref="SetFakeClientConVar(string,string)"/>
|
||||
/// </summary>
|
||||
/// <exception cref="ArgumentException"><paramref name="conVar"/> is <see langword="null"/></exception>
|
||||
/// <inheritdoc cref="SetFakeClientConVar(string,string)" select="exception"/>
|
||||
public void SetFakeClientConVar(ConVar conVar, string value)
|
||||
{
|
||||
if (conVar == null)
|
||||
{
|
||||
throw new ArgumentException("Invalid convar passed to 'SetFakeClientConVar'");
|
||||
}
|
||||
|
||||
SetFakeClientConVar(conVar.Name, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the active pawns button state. Will work even if the player is dead or observing.
|
||||
/// </summary>
|
||||
public PlayerButtons Buttons => (PlayerButtons)Pawn.Value.MovementServices!.Buttons.ButtonStates[0];
|
||||
|
||||
public void ExecuteClientCommand(string command) => NativeAPI.IssueClientCommand(Slot, command);
|
||||
|
||||
public int Slot => (int)Index - 1;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the authorized SteamID of this user which has been validated with the SteamAPI.
|
||||
/// </summary>
|
||||
public SteamID? AuthorizedSteamID
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!this.IsValid) return null;
|
||||
var authorizedSteamId = NativeAPI.GetPlayerAuthorizedSteamid(this.Slot);
|
||||
if ((long)authorizedSteamId == -1) return null;
|
||||
|
||||
return (SteamID)authorizedSteamId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the IP address (and possibly port) of this player.
|
||||
/// <remarks>Returns 127.0.0.1 if the player is a bot.</remarks>
|
||||
/// </summary>
|
||||
public string? IpAddress
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!this.IsValid) return null;
|
||||
var ipAddress = NativeAPI.GetPlayerIpAddress(this.Slot);
|
||||
if (string.IsNullOrWhiteSpace(ipAddress)) return null;
|
||||
|
||||
return ipAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,23 +12,36 @@ namespace CounterStrikeSharp.API.Core;
|
||||
|
||||
public partial class CEntityInstance : IEquatable<CEntityInstance>
|
||||
{
|
||||
public bool IsValid => Handle != IntPtr.Zero;
|
||||
public CEntityInstance(IntPtr pointer) : base(pointer)
|
||||
{
|
||||
}
|
||||
|
||||
public CEntityIndex? EntityIndex => IsValid ? Entity?.EntityHandle.Index : null;
|
||||
public CEntityInstance(uint rawHandle) : base(rawHandle)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks that the entity handle is valid and the handle points to a valid entity
|
||||
/// </summary>
|
||||
public bool IsValid => EntityHandle.IsValid && Handle != IntPtr.Zero;
|
||||
|
||||
[Obsolete("Use Index instead", true)]
|
||||
public CEntityIndex? EntityIndex => new CEntityIndex(EntityHandle.Index);
|
||||
|
||||
public uint Index => EntityHandle.Index;
|
||||
|
||||
public string DesignerName => IsValid ? Entity?.DesignerName : null;
|
||||
|
||||
public void Remove() => VirtualFunctions.UTIL_Remove(this.Handle);
|
||||
|
||||
|
||||
|
||||
public bool Equals(CEntityInstance? other)
|
||||
{
|
||||
return this.Handle == other?.Handle;
|
||||
return this.EntityHandle.Equals(other?.EntityHandle);
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return ReferenceEquals(this, obj) || obj is CEntityInstance other && Equals(other);
|
||||
return obj is CEntityInstance other && Equals(other);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
@@ -50,5 +63,5 @@ public partial class CEntityInstance : IEquatable<CEntityInstance>
|
||||
public partial class CEntityIdentity
|
||||
{
|
||||
public unsafe CEntityInstance EntityInstance => new(Unsafe.Read<IntPtr>((void*)Handle));
|
||||
public unsafe CHandle<CEntityInstance> EntityHandle => new(Handle + 0x10);
|
||||
public unsafe CHandle<CEntityInstance> EntityHandle => new(this.Handle + 0x10);
|
||||
}
|
||||
@@ -9420,10 +9420,8 @@ public partial class CEntityIdentity : NativeObject
|
||||
|
||||
}
|
||||
|
||||
public partial class CEntityInstance : NativeObject
|
||||
public partial class CEntityInstance : NativeEntity
|
||||
{
|
||||
public CEntityInstance (IntPtr pointer) : base(pointer) {}
|
||||
|
||||
// m_iszPrivateVScripts
|
||||
public string PrivateVScripts
|
||||
{
|
||||
|
||||
@@ -64,23 +64,26 @@ namespace CounterStrikeSharp.API.Core.Plugin
|
||||
config.IsUnloadable = true;
|
||||
});
|
||||
|
||||
_fileWatcher = new FileSystemWatcher
|
||||
if (CoreConfig.PluginHotReloadEnabled)
|
||||
{
|
||||
Path = Path.GetDirectoryName(path)
|
||||
};
|
||||
|
||||
_fileWatcher.Deleted += async (s, e) =>
|
||||
{
|
||||
if (e.FullPath == path)
|
||||
_fileWatcher = new FileSystemWatcher
|
||||
{
|
||||
_logger.LogInformation("Plugin {Name} has been deleted, unloading...", Plugin.ModuleName);
|
||||
Unload(true);
|
||||
}
|
||||
};
|
||||
Path = Path.GetDirectoryName(path)
|
||||
};
|
||||
|
||||
_fileWatcher.Filter = "*.dll";
|
||||
_fileWatcher.EnableRaisingEvents = true;
|
||||
Loader.Reloaded += async (s, e) => await OnReloadedAsync(s, e);
|
||||
_fileWatcher.Deleted += async (s, e) =>
|
||||
{
|
||||
if (e.FullPath == path)
|
||||
{
|
||||
_logger.LogInformation("Plugin {Name} has been deleted, unloading...", Plugin.ModuleName);
|
||||
Unload(true);
|
||||
}
|
||||
};
|
||||
|
||||
_fileWatcher.Filter = "*.dll";
|
||||
_fileWatcher.EnableRaisingEvents = true;
|
||||
Loader.Reloaded += async (s, e) => await OnReloadedAsync(s, e);
|
||||
}
|
||||
}
|
||||
|
||||
private Task OnReloadedAsync(object sender, PluginReloadedEventArgs eventargs)
|
||||
|
||||
@@ -205,6 +205,16 @@ namespace CounterStrikeSharp.API.Core
|
||||
|
||||
return;
|
||||
}
|
||||
else if (arg is NativeObject nativeObject)
|
||||
{
|
||||
Push(context, (InputArgument)nativeObject);
|
||||
return;
|
||||
}
|
||||
else if (arg is NativeEntity nativeValue)
|
||||
{
|
||||
Push(context, (InputArgument)nativeValue);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Marshal.SizeOf(arg.GetType()) <= 8)
|
||||
{
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
|
||||
// The server console should have access to all commands, regardless of groups.
|
||||
if (player == null) return true;
|
||||
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) { return false; }
|
||||
var playerData = GetPlayerAdminData((SteamID)player.SteamID);
|
||||
var playerData = GetPlayerAdminData((SteamID)player.AuthorizedSteamID);
|
||||
return playerData?.Groups.IsSupersetOf(groups) ?? false;
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
|
||||
{
|
||||
if (player == null) return;
|
||||
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) { return; }
|
||||
AddPlayerToGroup((SteamID)player.SteamID, groups);
|
||||
AddPlayerToGroup((SteamID)player.AuthorizedSteamID, groups);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -161,7 +161,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
|
||||
{
|
||||
if (player == null) return;
|
||||
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) { return; }
|
||||
RemovePlayerFromGroup((SteamID)player.SteamID, true, groups);
|
||||
RemovePlayerFromGroup((SteamID)player.AuthorizedSteamID, true, groups);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -102,7 +102,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
|
||||
// The server console should have access to all commands, regardless of permissions.
|
||||
if (player == null) return true;
|
||||
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) { return false; }
|
||||
var playerData = GetPlayerAdminData((SteamID)player.SteamID);
|
||||
var playerData = GetPlayerAdminData(player.AuthorizedSteamID);
|
||||
return playerData?.Flags.IsSupersetOf(flags) ?? false;
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
|
||||
// The server console should have access to all commands, regardless of permissions.
|
||||
if (player == null) return true;
|
||||
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) { return false; }
|
||||
var playerData = GetPlayerAdminData((SteamID)player.SteamID);
|
||||
var playerData = GetPlayerAdminData((SteamID)player.AuthorizedSteamID);
|
||||
return playerData?.CommandOverrides.ContainsKey(command) ?? false;
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
|
||||
// The server console should have access to all commands, regardless of permissions.
|
||||
if (player == null) return true;
|
||||
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) { return false; }
|
||||
var playerData = GetPlayerAdminData((SteamID)player.SteamID);
|
||||
var playerData = GetPlayerAdminData((SteamID)player.AuthorizedSteamID);
|
||||
return playerData?.CommandOverrides.GetValueOrDefault(command) ?? false;
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
|
||||
// The server console should have access to all commands, regardless of permissions.
|
||||
if (player == null) return;
|
||||
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) { return; }
|
||||
SetPlayerCommandOverride((SteamID)player.SteamID, command, state);
|
||||
SetPlayerCommandOverride((SteamID)player.AuthorizedSteamID, command, state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -235,7 +235,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
|
||||
{
|
||||
if (player == null) return;
|
||||
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) return;
|
||||
AddPlayerPermissions((SteamID)player.SteamID, flags);
|
||||
AddPlayerPermissions((SteamID)player.AuthorizedSteamID, flags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -278,7 +278,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
|
||||
if (player == null) return;
|
||||
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) return;
|
||||
|
||||
RemovePlayerPermissions((SteamID)player.SteamID, flags);
|
||||
RemovePlayerPermissions((SteamID)player.AuthorizedSteamID, flags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -306,7 +306,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
|
||||
if (player == null) return;
|
||||
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) return;
|
||||
|
||||
ClearPlayerPermissions((SteamID)player.SteamID);
|
||||
ClearPlayerPermissions((SteamID)player.AuthorizedSteamID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -335,7 +335,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
|
||||
if (player == null) return;
|
||||
if (!player.IsValid || player.Connected != PlayerConnectedState.PlayerConnected || player.IsBot) return;
|
||||
|
||||
SetPlayerImmunity((SteamID)player.SteamID, value);
|
||||
SetPlayerImmunity((SteamID)player.AuthorizedSteamID, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -366,10 +366,10 @@ namespace CounterStrikeSharp.API.Modules.Admin
|
||||
if (target == null) return false;
|
||||
if (!target.IsValid || target.Connected != PlayerConnectedState.PlayerConnected) return false;
|
||||
|
||||
var callerData = GetPlayerAdminData((SteamID)caller.SteamID);
|
||||
var callerData = GetPlayerAdminData((SteamID)caller.AuthorizedSteamID);
|
||||
if (callerData == null) return false;
|
||||
|
||||
var targetData = GetPlayerAdminData((SteamID)target.SteamID);
|
||||
var targetData = GetPlayerAdminData((SteamID)target.AuthorizedSteamID);
|
||||
if (targetData == null) return true;
|
||||
|
||||
return callerData.Immunity >= targetData.Immunity;
|
||||
|
||||
@@ -31,7 +31,8 @@ namespace CounterStrikeSharp.API.Modules.Admin
|
||||
{
|
||||
// If we have a command in the "command_overrides" section in "configs/admins.json",
|
||||
// we skip the checks below and just return the defined value.
|
||||
var adminData = AdminManager.GetPlayerAdminData((SteamID)caller.SteamID);
|
||||
if (caller?.AuthorizedSteamID == null) return false;
|
||||
var adminData = AdminManager.GetPlayerAdminData(caller.AuthorizedSteamID);
|
||||
if (adminData == null) return false;
|
||||
if (adminData.CommandOverrides.ContainsKey(Command))
|
||||
{
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace CounterStrikeSharp.API.Modules.Admin
|
||||
var groupPermissions = Permissions.Where(perm => perm.StartsWith(PermissionCharacters.GroupPermissionChar));
|
||||
var userPermissions = Permissions.Where(perm => perm.StartsWith(PermissionCharacters.UserPermissionChar));
|
||||
|
||||
var adminData = AdminManager.GetPlayerAdminData((SteamID)caller.SteamID);
|
||||
var adminData = AdminManager.GetPlayerAdminData(caller.AuthorizedSteamID);
|
||||
if (adminData == null) return false;
|
||||
return (groupPermissions.Intersect(adminData.Groups).Count() + userPermissions.Intersect(adminData.Flags).Count()) > 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
namespace CounterStrikeSharp.API.Modules.Entities.Constants;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the instance types for a Steam account.
|
||||
/// </summary>
|
||||
public enum SteamAccountInstance
|
||||
{
|
||||
/// <summary>
|
||||
/// Invalid instance.
|
||||
/// </summary>
|
||||
Invalid = -1,
|
||||
|
||||
/// <summary>
|
||||
/// All instances.
|
||||
/// </summary>
|
||||
All = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Desktop instance.
|
||||
/// </summary>
|
||||
Desktop = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Console instance.
|
||||
/// </summary>
|
||||
Console = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Web instance.
|
||||
/// </summary>
|
||||
Web = 4
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace CounterStrikeSharp.API.Modules.Entities.Constants;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the types of Steam accounts.
|
||||
/// </summary>
|
||||
public enum SteamAccountType
|
||||
{
|
||||
/// <summary>
|
||||
/// Invalid account type.
|
||||
/// </summary>
|
||||
[EnumMember(Value = "I")]
|
||||
Invalid = 0,
|
||||
/// <summary>
|
||||
/// Individual account type.
|
||||
/// </summary>
|
||||
[EnumMember(Value = "U")]
|
||||
Individual,
|
||||
/// <summary>
|
||||
/// MultiSeat account type.
|
||||
/// </summary>
|
||||
[EnumMember(Value = "M")]
|
||||
MultiSeat,
|
||||
/// <summary>
|
||||
/// Game Server account type.
|
||||
/// </summary>
|
||||
[EnumMember(Value = "G")]
|
||||
GameServer,
|
||||
/// <summary>
|
||||
/// Anonymous Game Server account type.
|
||||
/// </summary>
|
||||
[EnumMember(Value = "A")]
|
||||
AnonGameServer,
|
||||
/// <summary>
|
||||
/// Pending account type.
|
||||
/// </summary>
|
||||
[EnumMember(Value = "P")]
|
||||
Pending,
|
||||
/// <summary>
|
||||
/// Content Server account type.
|
||||
/// </summary>
|
||||
[EnumMember(Value = "C")]
|
||||
ContentServer,
|
||||
/// <summary>
|
||||
/// Clan account type.
|
||||
/// </summary>
|
||||
[EnumMember(Value = "g")]
|
||||
Clan,
|
||||
/// <summary>
|
||||
/// Chat account type.
|
||||
/// </summary>
|
||||
[EnumMember(Value = "T")]
|
||||
Chat,
|
||||
/// <summary>
|
||||
/// Console user account type.
|
||||
/// </summary>
|
||||
[EnumMember(Value = "c")]
|
||||
ConsoleUser,
|
||||
/// <summary>
|
||||
/// P2P Super Seeder account type.
|
||||
/// </summary>
|
||||
[EnumMember(Value = " ")]
|
||||
P2PSuperSeeder,
|
||||
/// <summary>
|
||||
/// Anonymous user account type.
|
||||
/// </summary>
|
||||
[EnumMember(Value = "a")]
|
||||
AnonUser,
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
namespace CounterStrikeSharp.API.Modules.Entities.Constants;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the universe of a Steam account.
|
||||
/// </summary>
|
||||
public enum SteamAccountUniverse
|
||||
{
|
||||
/// <summary>
|
||||
/// Individual / unspecified universe.
|
||||
/// </summary>
|
||||
Unspecified = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Public universe.
|
||||
/// </summary>
|
||||
Public = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Beta universe.
|
||||
/// </summary>
|
||||
Beta = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Internal universe.
|
||||
/// </summary>
|
||||
Internal = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Development universe.
|
||||
/// </summary>
|
||||
Dev = 4,
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using CounterStrikeSharp.API.Modules.Memory;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
|
||||
namespace CounterStrikeSharp.API.Modules.Entities;
|
||||
|
||||
public static class EntitySystem
|
||||
{
|
||||
private static Lazy<IntPtr> ConcreteEntityListPointer = new(NativeAPI.GetConcreteEntityListPointer);
|
||||
|
||||
private const int MaxEntities = 32768;
|
||||
private const int MaxEntitiesPerChunk = 512;
|
||||
private const int MaxChunks = MaxEntities / MaxEntitiesPerChunk;
|
||||
private const int SizeOfEntityIdentity = 0x78;
|
||||
private const int HandleOffset = 0x10;
|
||||
private const uint InvalidEHandleIndex = 0xFFFFFFFF;
|
||||
|
||||
static unsafe Span<IntPtr> IdentityChunks => new((void*)ConcreteEntityListPointer.Value, MaxChunks);
|
||||
public static IntPtr FirstActiveEntity => Marshal.ReadIntPtr(ConcreteEntityListPointer.Value, MaxEntitiesPerChunk);
|
||||
|
||||
public static IntPtr? GetEntityByHandle(uint raw)
|
||||
{
|
||||
return GetEntityByHandle(new CHandle<CEntityInstance>(raw));
|
||||
}
|
||||
|
||||
public static IntPtr? GetEntityByHandle<T>(CHandle<T> handle) where T : NativeEntity
|
||||
{
|
||||
if (!handle.IsValid)
|
||||
return null;
|
||||
|
||||
IntPtr pChunkToUse = IdentityChunks[(int)(handle.Index / MaxEntitiesPerChunk)];
|
||||
if (pChunkToUse == IntPtr.Zero)
|
||||
return null;
|
||||
|
||||
IntPtr pIdentityPtr = IntPtr.Add(pChunkToUse, SizeOfEntityIdentity * (int)(handle.Index % MaxEntitiesPerChunk));
|
||||
|
||||
if (pIdentityPtr == IntPtr.Zero)
|
||||
return null;
|
||||
|
||||
var foundHandle = new CEntityHandle(pIdentityPtr + HandleOffset);
|
||||
|
||||
if (foundHandle.Raw != handle.Raw)
|
||||
return null;
|
||||
|
||||
return Marshal.ReadIntPtr(pIdentityPtr);
|
||||
}
|
||||
|
||||
public static IntPtr? GetEntityByIndex(uint index)
|
||||
{
|
||||
if ((int)index <= -1 || index >= MaxEntities - 1) return null;
|
||||
|
||||
IntPtr pChunkToUse = IdentityChunks[(int)(index / MaxEntitiesPerChunk)];
|
||||
if (pChunkToUse == IntPtr.Zero)
|
||||
return null;
|
||||
|
||||
IntPtr pIdentityPtr = IntPtr.Add(pChunkToUse, SizeOfEntityIdentity * (int)(index % MaxEntitiesPerChunk));
|
||||
|
||||
if (pIdentityPtr == IntPtr.Zero)
|
||||
return null;
|
||||
|
||||
var foundHandle = new CEntityHandle(pIdentityPtr + HandleOffset);
|
||||
|
||||
if (foundHandle.Index != index)
|
||||
return null;
|
||||
|
||||
return Marshal.ReadIntPtr(pIdentityPtr);
|
||||
}
|
||||
|
||||
public static uint GetRawHandleFromEntityPointer(IntPtr pointer)
|
||||
{
|
||||
if (pointer == IntPtr.Zero)
|
||||
return InvalidEHandleIndex;
|
||||
|
||||
return Schema.GetPointer<CEntityIdentity?>(pointer, "CEntityInstance", "m_pEntity")?.EntityHandle.Raw ??
|
||||
InvalidEHandleIndex;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using CounterStrikeSharp.API.Modules.Entities.Constants;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
|
||||
namespace CounterStrikeSharp.API.Modules.Entities
|
||||
{
|
||||
@@ -12,6 +13,7 @@ namespace CounterStrikeSharp.API.Modules.Entities
|
||||
|
||||
public static explicit operator SteamID(ulong u) => new(u);
|
||||
public static explicit operator SteamID(string s) => new(s);
|
||||
|
||||
ulong ParseId(string id)
|
||||
{
|
||||
var parts = id.Split(':');
|
||||
@@ -34,7 +36,7 @@ namespace CounterStrikeSharp.API.Modules.Entities
|
||||
|
||||
public string SteamId3
|
||||
{
|
||||
get => $"[U:1:{SteamId64 - Base}]";
|
||||
get => $"[{EnumUtils.GetEnumMemberAttributeValue(AccountType)}:{(int)AccountUniverse}:{SteamId64 - Base}]";
|
||||
set => SteamId64 = ParseId3(value);
|
||||
}
|
||||
|
||||
@@ -44,20 +46,54 @@ namespace CounterStrikeSharp.API.Modules.Entities
|
||||
set => SteamId64 = (ulong)value + Base;
|
||||
}
|
||||
|
||||
public int AccountId => (int)((SteamId64 >> 0) & 0xFFFFFFFF);
|
||||
|
||||
public SteamAccountInstance AccountInstance =>
|
||||
(SteamAccountInstance)((SteamId64 >> 32) & 0xFFFFF);
|
||||
|
||||
public SteamAccountType AccountType =>
|
||||
(SteamAccountType)((SteamId64 >> 52) & 0xF);
|
||||
|
||||
public SteamAccountUniverse AccountUniverse =>
|
||||
(SteamAccountUniverse)((SteamId64 >> 56) & 0xF);
|
||||
|
||||
public bool IsValid()
|
||||
{
|
||||
if (AccountUniverse == SteamAccountUniverse.Unspecified
|
||||
|| AccountType == SteamAccountType.Invalid
|
||||
|| AccountInstance == SteamAccountInstance.Invalid)
|
||||
return false;
|
||||
if (AccountType == SteamAccountType.Individual
|
||||
&& (AccountId == 0 || AccountInstance != SteamAccountInstance.Desktop))
|
||||
return false;
|
||||
if (AccountType == SteamAccountType.Clan
|
||||
&& (AccountId == 0 || AccountInstance != SteamAccountInstance.All))
|
||||
return false;
|
||||
if (AccountType == SteamAccountType.GameServer && AccountId == 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string ToString() => $"[SteamID {SteamId64}, {SteamId2}, {SteamId3}]";
|
||||
|
||||
public Uri ToCommunityUrl()
|
||||
{
|
||||
string url = string.Empty;
|
||||
if (AccountType == SteamAccountType.Individual)
|
||||
url = "https://steamcommunity.com/profiles/" + SteamId64;
|
||||
if (AccountType == SteamAccountType.Clan)
|
||||
url = "https://steamcommunity.com/gid/" + SteamId64;
|
||||
return new Uri(url);
|
||||
}
|
||||
|
||||
public bool Equals(SteamID? other)
|
||||
{
|
||||
if (ReferenceEquals(null, other)) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
return SteamId64 == other.SteamId64;
|
||||
return other != null && SteamId64 == other.SteamId64;
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != this.GetType()) return false;
|
||||
if (obj?.GetType() != this.GetType()) return false;
|
||||
return Equals((SteamID)obj);
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace CounterStrikeSharp.API.Modules.Events
|
||||
break;
|
||||
case var _ when value is CCSPlayerController player:
|
||||
// When I was testing this, the code seems to expect a slot, even though it is called index
|
||||
SetEntityIndex(name, (int)player.EntityIndex.Value.Value - 1);
|
||||
SetEntityIndex(name, (int)player.Index - 1);
|
||||
break;
|
||||
case var _ when value is string s:
|
||||
SetString(name, s);
|
||||
@@ -124,6 +124,6 @@ namespace CounterStrikeSharp.API.Modules.Events
|
||||
|
||||
public void FireEvent(bool dontBroadcast) => NativeAPI.FireEvent(Handle, dontBroadcast);
|
||||
|
||||
public void FireEventToClient(CCSPlayerController player) => NativeAPI.FireEventToClient(Handle, (int)player.EntityIndex.Value.Value);
|
||||
public void FireEventToClient(CCSPlayerController player) => NativeAPI.FireEventToClient(Handle, (int)player.Index);
|
||||
}
|
||||
}
|
||||
@@ -28,11 +28,35 @@ public abstract class BaseMemoryFunction : NativeObject
|
||||
return function;
|
||||
}
|
||||
|
||||
private static IntPtr CreateValveFunctionBySignature(string signature, string binarypath, DataType returnType,
|
||||
DataType[] argumentTypes)
|
||||
{
|
||||
if (!_createdFunctions.TryGetValue(signature, out var function))
|
||||
{
|
||||
try
|
||||
{
|
||||
function = NativeAPI.CreateVirtualFunctionBySignature(IntPtr.Zero, binarypath, signature,
|
||||
argumentTypes.Length, (int)returnType, argumentTypes.Cast<object>().ToArray());
|
||||
_createdFunctions[signature] = function;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return function;
|
||||
}
|
||||
|
||||
public BaseMemoryFunction(string signature, DataType returnType, DataType[] parameters) : base(
|
||||
CreateValveFunctionBySignature(signature, returnType, parameters))
|
||||
{
|
||||
}
|
||||
|
||||
public BaseMemoryFunction(string signature, string binarypath, DataType returnType, DataType[] parameters) : base(
|
||||
CreateValveFunctionBySignature(signature, binarypath, returnType, parameters))
|
||||
{
|
||||
}
|
||||
|
||||
public void Hook(Func<DynamicHook, HookResult> handler, HookMode mode)
|
||||
{
|
||||
NativeAPI.HookFunction(Handle, handler, mode == HookMode.Post);
|
||||
|
||||
@@ -8,6 +8,10 @@ public class MemoryFunctionVoid : BaseMemoryFunction
|
||||
{
|
||||
}
|
||||
|
||||
public MemoryFunctionVoid(string signature, string binarypath) : base(signature, binarypath, DataType.DATA_TYPE_VOID, Array.Empty<DataType>())
|
||||
{
|
||||
}
|
||||
|
||||
public void Invoke()
|
||||
{
|
||||
InvokeInternalVoid();
|
||||
@@ -21,6 +25,11 @@ public class MemoryFunctionVoid<T1> : BaseMemoryFunction
|
||||
{
|
||||
}
|
||||
|
||||
public MemoryFunctionVoid(string signature, string binarypath) : base(signature, binarypath, DataType.DATA_TYPE_VOID,
|
||||
new[] { typeof(T1).ToValidDataType() })
|
||||
{
|
||||
}
|
||||
|
||||
public void Invoke(T1 arg1)
|
||||
{
|
||||
InvokeInternalVoid(arg1);
|
||||
@@ -34,6 +43,11 @@ public class MemoryFunctionVoid<T1, T2> : BaseMemoryFunction
|
||||
{
|
||||
}
|
||||
|
||||
public MemoryFunctionVoid(string signature, string binarypath) : base(signature, binarypath, DataType.DATA_TYPE_VOID,
|
||||
new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType() })
|
||||
{
|
||||
}
|
||||
|
||||
public void Invoke(T1 arg1, T2 arg2)
|
||||
{
|
||||
InvokeInternalVoid(arg1, arg2);
|
||||
@@ -47,6 +61,11 @@ public class MemoryFunctionVoid<T1, T2, T3> : BaseMemoryFunction
|
||||
{
|
||||
}
|
||||
|
||||
public MemoryFunctionVoid(string signature, string binarypath) : base(signature, binarypath, DataType.DATA_TYPE_VOID,
|
||||
new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType() })
|
||||
{
|
||||
}
|
||||
|
||||
public void Invoke(T1 arg1, T2 arg2, T3 arg3)
|
||||
{
|
||||
InvokeInternalVoid(arg1, arg2, arg3);
|
||||
@@ -64,6 +83,15 @@ public class MemoryFunctionVoid<T1, T2, T3, T4> : BaseMemoryFunction
|
||||
{
|
||||
}
|
||||
|
||||
public MemoryFunctionVoid(string signature, string binarypath) : base(signature, binarypath, DataType.DATA_TYPE_VOID,
|
||||
new[]
|
||||
{
|
||||
typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(),
|
||||
typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType()
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4)
|
||||
{
|
||||
InvokeInternalVoid(arg1, arg2, arg3, arg4);
|
||||
@@ -82,6 +110,16 @@ public class MemoryFunctionVoid<T1, T2, T3, T4, T5> : BaseMemoryFunction
|
||||
{
|
||||
}
|
||||
|
||||
public MemoryFunctionVoid(string signature, string binarypath) : base(signature, binarypath, DataType.DATA_TYPE_VOID,
|
||||
new[]
|
||||
{
|
||||
typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(),
|
||||
typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(),
|
||||
typeof(T5).ToValidDataType()
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
|
||||
{
|
||||
InvokeInternalVoid(arg1, arg2, arg3, arg4, arg5);
|
||||
@@ -100,6 +138,16 @@ public class MemoryFunctionVoid<T1, T2, T3, T4, T5, T6> : BaseMemoryFunction
|
||||
{
|
||||
}
|
||||
|
||||
public MemoryFunctionVoid(string signature, string binarypath) : base(signature, binarypath, DataType.DATA_TYPE_VOID,
|
||||
new[]
|
||||
{
|
||||
typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(),
|
||||
typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(),
|
||||
typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType()
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6)
|
||||
{
|
||||
InvokeInternalVoid(arg1, arg2, arg3, arg4, arg5, arg6);
|
||||
@@ -119,6 +167,17 @@ public class MemoryFunctionVoid<T1, T2, T3, T4, T5, T6, T7> : BaseMemoryFunction
|
||||
{
|
||||
}
|
||||
|
||||
public MemoryFunctionVoid(string signature, string binarypath) : base(signature, binarypath, DataType.DATA_TYPE_VOID,
|
||||
new[]
|
||||
{
|
||||
typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(),
|
||||
typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(),
|
||||
typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(),
|
||||
typeof(T7).ToValidDataType()
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7)
|
||||
{
|
||||
InvokeInternalVoid(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
||||
@@ -138,6 +197,17 @@ public class MemoryFunctionVoid<T1, T2, T3, T4, T5, T6, T7, T8> : BaseMemoryFunc
|
||||
{
|
||||
}
|
||||
|
||||
public MemoryFunctionVoid(string signature, string binarypath) : base(signature, binarypath, DataType.DATA_TYPE_VOID,
|
||||
new[]
|
||||
{
|
||||
typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(),
|
||||
typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(),
|
||||
typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(),
|
||||
typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType()
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8)
|
||||
{
|
||||
InvokeInternalVoid(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
||||
@@ -158,6 +228,18 @@ public class MemoryFunctionVoid<T1, T2, T3, T4, T5, T6, T7, T8, T9> : BaseMemory
|
||||
{
|
||||
}
|
||||
|
||||
public MemoryFunctionVoid(string signature, string binarypath) : base(signature, binarypath, DataType.DATA_TYPE_VOID,
|
||||
new[]
|
||||
{
|
||||
typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(),
|
||||
typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(),
|
||||
typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(),
|
||||
typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(),
|
||||
typeof(T9).ToValidDataType()
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9)
|
||||
{
|
||||
InvokeInternalVoid(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
|
||||
@@ -178,6 +260,18 @@ public class MemoryFunctionVoid<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : BaseM
|
||||
{
|
||||
}
|
||||
|
||||
public MemoryFunctionVoid(string signature, string binarypath) : base(signature, binarypath, DataType.DATA_TYPE_VOID,
|
||||
new[]
|
||||
{
|
||||
typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(),
|
||||
typeof(T3).ToValidDataType(), typeof(T4).ToValidDataType(),
|
||||
typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(),
|
||||
typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(),
|
||||
typeof(T9).ToValidDataType(), typeof(T10).ToValidDataType()
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
public void Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10)
|
||||
{
|
||||
InvokeInternalVoid(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
|
||||
|
||||
@@ -9,6 +9,11 @@ public class MemoryFunctionWithReturn<TResult> : BaseMemoryFunction
|
||||
{
|
||||
}
|
||||
|
||||
public MemoryFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath, typeof(TResult).ToValidDataType(),
|
||||
Array.Empty<DataType>())
|
||||
{
|
||||
}
|
||||
|
||||
public TResult Invoke()
|
||||
{
|
||||
return InvokeInternal<TResult>();
|
||||
@@ -22,6 +27,11 @@ public class MemoryFunctionWithReturn<T1, TResult> : BaseMemoryFunction
|
||||
{
|
||||
}
|
||||
|
||||
public MemoryFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath, typeof(TResult).ToValidDataType(),
|
||||
new[] { typeof(T1).ToValidDataType() })
|
||||
{
|
||||
}
|
||||
|
||||
public TResult Invoke(T1 arg1)
|
||||
{
|
||||
return InvokeInternal<TResult>(arg1);
|
||||
@@ -35,6 +45,11 @@ public class MemoryFunctionWithReturn<T1, T2, TResult> : BaseMemoryFunction
|
||||
{
|
||||
}
|
||||
|
||||
public MemoryFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath, typeof(TResult).ToValidDataType(),
|
||||
new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType() })
|
||||
{
|
||||
}
|
||||
|
||||
public TResult Invoke(T1 arg1, T2 arg2)
|
||||
{
|
||||
return InvokeInternal<TResult>(arg1, arg2);
|
||||
@@ -48,6 +63,11 @@ public class MemoryFunctionWithReturn<T1, T2, T3, TResult> : BaseMemoryFunction
|
||||
{
|
||||
}
|
||||
|
||||
public MemoryFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath, typeof(TResult).ToValidDataType(),
|
||||
new[] { typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType() })
|
||||
{
|
||||
}
|
||||
|
||||
public TResult Invoke(T1 arg1, T2 arg2, T3 arg3)
|
||||
{
|
||||
return InvokeInternal<TResult>(arg1, arg2, arg3);
|
||||
@@ -65,6 +85,15 @@ public class MemoryFunctionWithReturn<T1, T2, T3, T4, TResult> : BaseMemoryFunct
|
||||
{
|
||||
}
|
||||
|
||||
public MemoryFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath, typeof(TResult).ToValidDataType(),
|
||||
new[]
|
||||
{
|
||||
typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(),
|
||||
typeof(T4).ToValidDataType()
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4)
|
||||
{
|
||||
return InvokeInternal<TResult>(arg1, arg2, arg3, arg4);
|
||||
@@ -82,6 +111,15 @@ public class MemoryFunctionWithReturn<T1, T2, T3, T4, T5, TResult> : BaseMemoryF
|
||||
{
|
||||
}
|
||||
|
||||
public MemoryFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath, typeof(TResult).ToValidDataType(),
|
||||
new[]
|
||||
{
|
||||
typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(),
|
||||
typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType()
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
|
||||
{
|
||||
return InvokeInternal<TResult>(arg1, arg2, arg3, arg4, arg5);
|
||||
@@ -99,6 +137,15 @@ public class MemoryFunctionWithReturn<T1, T2, T3, T4, T5, T6, TResult> : BaseMem
|
||||
{
|
||||
}
|
||||
|
||||
public MemoryFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath, typeof(TResult).ToValidDataType(),
|
||||
new[]
|
||||
{
|
||||
typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(),
|
||||
typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType()
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6)
|
||||
{
|
||||
return InvokeInternal<TResult>(arg1, arg2, arg3, arg4, arg5, arg6);
|
||||
@@ -117,6 +164,16 @@ public class MemoryFunctionWithReturn<T1, T2, T3, T4, T5, T6, T7, TResult> : Bas
|
||||
{
|
||||
}
|
||||
|
||||
public MemoryFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath, typeof(TResult).ToValidDataType(),
|
||||
new[]
|
||||
{
|
||||
typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(),
|
||||
typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(),
|
||||
typeof(T7).ToValidDataType()
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7)
|
||||
{
|
||||
return InvokeInternal<TResult>(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
||||
@@ -135,6 +192,16 @@ public class MemoryFunctionWithReturn<T1, T2, T3, T4, T5, T6, T7, T8, TResult> :
|
||||
{
|
||||
}
|
||||
|
||||
public MemoryFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath, typeof(TResult).ToValidDataType(),
|
||||
new[]
|
||||
{
|
||||
typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(),
|
||||
typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(),
|
||||
typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType()
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8)
|
||||
{
|
||||
return InvokeInternal<TResult>(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
||||
@@ -153,6 +220,16 @@ public class MemoryFunctionWithReturn<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResul
|
||||
{
|
||||
}
|
||||
|
||||
public MemoryFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath, typeof(TResult).ToValidDataType(),
|
||||
new[]
|
||||
{
|
||||
typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(),
|
||||
typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(),
|
||||
typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), typeof(T9).ToValidDataType()
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9)
|
||||
{
|
||||
return InvokeInternal<TResult>(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
|
||||
@@ -172,6 +249,17 @@ public class MemoryFunctionWithReturn<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T
|
||||
{
|
||||
}
|
||||
|
||||
public MemoryFunctionWithReturn(string signature, string binarypath) : base(signature, binarypath, typeof(TResult).ToValidDataType(),
|
||||
new[]
|
||||
{
|
||||
typeof(T1).ToValidDataType(), typeof(T2).ToValidDataType(), typeof(T3).ToValidDataType(),
|
||||
typeof(T4).ToValidDataType(), typeof(T5).ToValidDataType(), typeof(T6).ToValidDataType(),
|
||||
typeof(T7).ToValidDataType(), typeof(T8).ToValidDataType(), typeof(T9).ToValidDataType(),
|
||||
typeof(T10).ToValidDataType()
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10)
|
||||
{
|
||||
return InvokeInternal<TResult>(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
|
||||
namespace CounterStrikeSharp.API.Modules.Memory;
|
||||
@@ -49,6 +50,8 @@ public class Schema
|
||||
"m_nActiveCoinRank",
|
||||
"m_nMusicID",
|
||||
};
|
||||
|
||||
public static int GetClassSize(string className) => NativeAPI.GetSchemaClassSize(className);
|
||||
|
||||
public static short GetSchemaOffset(string className, string propertyName)
|
||||
{
|
||||
@@ -92,9 +95,9 @@ public class Schema
|
||||
return ref Unsafe.AsRef<T>((void*)(pointer + GetSchemaOffset(className, memberName)));
|
||||
}
|
||||
|
||||
public static unsafe T GetPointer<T>(IntPtr pointer)
|
||||
public static T GetPointer<T>(IntPtr pointer)
|
||||
{
|
||||
var pointerTo = Unsafe.Read<IntPtr>((void*)pointer);
|
||||
var pointerTo = Marshal.ReadIntPtr(pointer);
|
||||
if (pointerTo == IntPtr.Zero)
|
||||
{
|
||||
return default;
|
||||
@@ -103,9 +106,9 @@ public class Schema
|
||||
return (T)Activator.CreateInstance(typeof(T), pointerTo);
|
||||
}
|
||||
|
||||
public static unsafe T GetPointer<T>(IntPtr pointer, string className, string memberName)
|
||||
public static T GetPointer<T>(IntPtr pointer, string className, string memberName)
|
||||
{
|
||||
var pointerTo = Unsafe.Read<IntPtr>((void*)(pointer + GetSchemaOffset(className, memberName)));
|
||||
var pointerTo = Marshal.ReadIntPtr(pointer + GetSchemaOffset(className, memberName));
|
||||
if (pointerTo == IntPtr.Zero)
|
||||
{
|
||||
return default;
|
||||
|
||||
@@ -45,6 +45,26 @@ public partial class VirtualFunction
|
||||
return function;
|
||||
}
|
||||
|
||||
private static IntPtr CreateVirtualFunctionBySignature(string signature, string binarypath, IEnumerable<DataType> argumentTypes,
|
||||
DataType returnType,
|
||||
object[] arguments)
|
||||
{
|
||||
if (!_createdFunctions.TryGetValue(signature, out var function))
|
||||
{
|
||||
try
|
||||
{
|
||||
function = NativeAPI.CreateVirtualFunctionBySignature(IntPtr.Zero, binarypath, signature,
|
||||
argumentTypes.Count(), (int)returnType, arguments);
|
||||
_createdFunctions[signature] = function;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return function;
|
||||
}
|
||||
|
||||
#region Funcs
|
||||
public static Func<TResult> Create<TResult>(string signature)
|
||||
{
|
||||
@@ -306,7 +326,270 @@ public partial class VirtualFunction
|
||||
NativeAPI.ExecuteVirtualFunction<TResult>(virtualFunctionPointer,
|
||||
new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 });
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region FuncsBinary
|
||||
public static Func<TResult> Create<TResult>(string signature, string binarypath)
|
||||
{
|
||||
var arguments = Enumerable.Empty<DataType>().ToArray();
|
||||
|
||||
if (typeof(TResult).ToDataType() == null)
|
||||
{
|
||||
throw new Exception($"Invalid argument type(s) supplied to Virtual Function");
|
||||
}
|
||||
|
||||
var virtualFunctionPointer = CreateVirtualFunctionBySignature(signature, binarypath, arguments,
|
||||
(DataType)typeof(TResult).ToDataType()!, arguments.Cast<object>().ToArray());
|
||||
|
||||
return () => NativeAPI.ExecuteVirtualFunction<TResult>(virtualFunctionPointer, new object[] { });
|
||||
}
|
||||
|
||||
public static Func<TArg1, TResult> Create<TArg1, TResult>(string signature, string binarypath)
|
||||
{
|
||||
var arguments = new[]
|
||||
{
|
||||
typeof(TArg1).ToDataType()
|
||||
};
|
||||
|
||||
if (arguments.Any(x => x == null))
|
||||
{
|
||||
throw new Exception($"Invalid argument type(s) supplied to Virtual Function");
|
||||
}
|
||||
|
||||
var virtualFunctionPointer = CreateVirtualFunctionBySignature(signature, binarypath, arguments.Cast<DataType>(),
|
||||
(DataType)typeof(TResult).ToDataType()!, arguments.Cast<object>().ToArray());
|
||||
|
||||
return (arg1) => NativeAPI.ExecuteVirtualFunction<TResult>(virtualFunctionPointer, new object[] { arg1 });
|
||||
}
|
||||
|
||||
public static Func<TArg1, TArg2, TResult> Create<TArg1, TArg2, TResult>(string signature, string binarypath)
|
||||
{
|
||||
var arguments = new[]
|
||||
{
|
||||
typeof(TArg1).ToDataType(),
|
||||
typeof(TArg2).ToDataType()
|
||||
};
|
||||
|
||||
if (arguments.Any(x => x == null))
|
||||
{
|
||||
throw new Exception($"Invalid argument type(s) supplied to Virtual Function");
|
||||
}
|
||||
|
||||
var virtualFunctionPointer = CreateVirtualFunctionBySignature(signature, binarypath, arguments.Cast<DataType>(),
|
||||
(DataType)typeof(TResult).ToDataType()!, arguments.Cast<object>().ToArray());
|
||||
|
||||
return (arg1, arg2) =>
|
||||
NativeAPI.ExecuteVirtualFunction<TResult>(virtualFunctionPointer, new object[] { arg1, arg2 });
|
||||
}
|
||||
|
||||
public static Func<TArg1, TArg2, TArg3, TResult> Create<TArg1, TArg2, TArg3, TResult>(string signature, string binarypath)
|
||||
{
|
||||
var arguments = new[]
|
||||
{
|
||||
typeof(TArg1).ToDataType(),
|
||||
typeof(TArg2).ToDataType(),
|
||||
typeof(TArg3).ToDataType()
|
||||
};
|
||||
|
||||
if (arguments.Any(x => x == null))
|
||||
{
|
||||
throw new Exception($"Invalid argument type(s) supplied to Virtual Function");
|
||||
}
|
||||
|
||||
var virtualFunctionPointer = CreateVirtualFunctionBySignature(signature, binarypath, arguments.Cast<DataType>(),
|
||||
(DataType)typeof(TResult).ToDataType()!, arguments.Cast<object>().ToArray());
|
||||
|
||||
return (arg1, arg2, arg3) =>
|
||||
NativeAPI.ExecuteVirtualFunction<TResult>(virtualFunctionPointer, new object[] { arg1, arg2, arg3 });
|
||||
}
|
||||
|
||||
public static Func<TArg1, TArg2, TArg3, TArg4, TResult> Create<TArg1, TArg2, TArg3, TArg4, TResult>(
|
||||
string signature, string binarypath)
|
||||
{
|
||||
var arguments = new[]
|
||||
{
|
||||
typeof(TArg1).ToDataType(),
|
||||
typeof(TArg2).ToDataType(),
|
||||
typeof(TArg3).ToDataType(),
|
||||
typeof(TArg4).ToDataType()
|
||||
};
|
||||
|
||||
if (arguments.Any(x => x == null))
|
||||
{
|
||||
throw new Exception($"Invalid argument type(s) supplied to Virtual Function");
|
||||
}
|
||||
|
||||
var virtualFunctionPointer = CreateVirtualFunctionBySignature(signature, binarypath, arguments.Cast<DataType>(),
|
||||
(DataType)typeof(TResult).ToDataType()!, arguments.Cast<object>().ToArray());
|
||||
|
||||
return (arg1, arg2, arg3, arg4) =>
|
||||
NativeAPI.ExecuteVirtualFunction<TResult>(virtualFunctionPointer, new object[] { arg1, arg2, arg3, arg4 });
|
||||
}
|
||||
|
||||
public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TResult> Create<TArg1, TArg2, TArg3, TArg4, TArg5, TResult>(
|
||||
string signature, string binarypath)
|
||||
{
|
||||
var arguments = new[]
|
||||
{
|
||||
typeof(TArg1).ToDataType(),
|
||||
typeof(TArg2).ToDataType(),
|
||||
typeof(TArg3).ToDataType(),
|
||||
typeof(TArg4).ToDataType(),
|
||||
typeof(TArg5).ToDataType()
|
||||
};
|
||||
|
||||
if (arguments.Any(x => x == null))
|
||||
{
|
||||
throw new Exception($"Invalid argument type(s) supplied to Virtual Function");
|
||||
}
|
||||
|
||||
var virtualFunctionPointer = CreateVirtualFunctionBySignature(signature, binarypath, arguments.Cast<DataType>(),
|
||||
(DataType)typeof(TResult).ToDataType()!, arguments.Cast<object>().ToArray());
|
||||
|
||||
return (arg1, arg2, arg3, arg4, arg5) =>
|
||||
NativeAPI.ExecuteVirtualFunction<TResult>(virtualFunctionPointer,
|
||||
new object[] { arg1, arg2, arg3, arg4, arg5 });
|
||||
}
|
||||
|
||||
public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TResult> Create<TArg1, TArg2, TArg3, TArg4, TArg5,
|
||||
TArg6, TResult>(string signature, string binarypath)
|
||||
{
|
||||
var arguments = new[]
|
||||
{
|
||||
typeof(TArg1).ToDataType(),
|
||||
typeof(TArg2).ToDataType(),
|
||||
typeof(TArg3).ToDataType(),
|
||||
typeof(TArg4).ToDataType(),
|
||||
typeof(TArg5).ToDataType(),
|
||||
typeof(TArg6).ToDataType()
|
||||
};
|
||||
|
||||
if (arguments.Any(x => x == null))
|
||||
{
|
||||
throw new Exception($"Invalid argument type(s) supplied to Virtual Function");
|
||||
}
|
||||
|
||||
var virtualFunctionPointer = CreateVirtualFunctionBySignature(signature, binarypath, arguments.Cast<DataType>(),
|
||||
(DataType)typeof(TResult).ToDataType()!, arguments.Cast<object>().ToArray());
|
||||
|
||||
return (arg1, arg2, arg3, arg4, arg5, arg6) => NativeAPI.ExecuteVirtualFunction<TResult>(virtualFunctionPointer,
|
||||
new object[] { arg1, arg2, arg3, arg4, arg5, arg6 });
|
||||
}
|
||||
|
||||
public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TResult> Create<TArg1, TArg2, TArg3, TArg4,
|
||||
TArg5, TArg6, TArg7, TResult>(string signature, string binarypath)
|
||||
{
|
||||
var arguments = new[]
|
||||
{
|
||||
typeof(TArg1).ToDataType(),
|
||||
typeof(TArg2).ToDataType(),
|
||||
typeof(TArg3).ToDataType(),
|
||||
typeof(TArg4).ToDataType(),
|
||||
typeof(TArg5).ToDataType(),
|
||||
typeof(TArg6).ToDataType(),
|
||||
typeof(TArg7).ToDataType()
|
||||
};
|
||||
|
||||
if (arguments.Any(x => x == null))
|
||||
{
|
||||
throw new Exception($"Invalid argument type(s) supplied to Virtual Function");
|
||||
}
|
||||
|
||||
var virtualFunctionPointer = CreateVirtualFunctionBySignature(signature, binarypath, arguments.Cast<DataType>(),
|
||||
(DataType)typeof(TResult).ToDataType()!, arguments.Cast<object>().ToArray());
|
||||
|
||||
return (arg1, arg2, arg3, arg4, arg5, arg6, arg7) =>
|
||||
NativeAPI.ExecuteVirtualFunction<TResult>(virtualFunctionPointer,
|
||||
new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 });
|
||||
}
|
||||
|
||||
public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TResult> Create<TArg1, TArg2, TArg3,
|
||||
TArg4, TArg5, TArg6, TArg7, TArg8, TResult>(string signature, string binarypath)
|
||||
{
|
||||
var arguments = new[]
|
||||
{
|
||||
typeof(TArg1).ToDataType(),
|
||||
typeof(TArg2).ToDataType(),
|
||||
typeof(TArg3).ToDataType(),
|
||||
typeof(TArg4).ToDataType(),
|
||||
typeof(TArg5).ToDataType(),
|
||||
typeof(TArg6).ToDataType(),
|
||||
typeof(TArg7).ToDataType(),
|
||||
typeof(TArg8).ToDataType()
|
||||
};
|
||||
|
||||
if (arguments.Any(x => x == null))
|
||||
{
|
||||
throw new Exception($"Invalid argument type(s) supplied to Virtual Function");
|
||||
}
|
||||
|
||||
var virtualFunctionPointer = CreateVirtualFunctionBySignature(signature, binarypath, arguments.Cast<DataType>(),
|
||||
(DataType)typeof(TResult).ToDataType()!, arguments.Cast<object>().ToArray());
|
||||
|
||||
return (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) =>
|
||||
NativeAPI.ExecuteVirtualFunction<TResult>(virtualFunctionPointer,
|
||||
new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 });
|
||||
}
|
||||
|
||||
public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TResult> Create<TArg1, TArg2,
|
||||
TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TResult>(string signature, string binarypath)
|
||||
{
|
||||
var arguments = new[]
|
||||
{
|
||||
typeof(TArg1).ToDataType(),
|
||||
typeof(TArg2).ToDataType(),
|
||||
typeof(TArg3).ToDataType(),
|
||||
typeof(TArg4).ToDataType(),
|
||||
typeof(TArg5).ToDataType(),
|
||||
typeof(TArg6).ToDataType(),
|
||||
typeof(TArg7).ToDataType(),
|
||||
typeof(TArg8).ToDataType(),
|
||||
typeof(TArg9).ToDataType()
|
||||
};
|
||||
|
||||
if (arguments.Any(x => x == null))
|
||||
{
|
||||
throw new Exception($"Invalid argument type(s) supplied to Virtual Function");
|
||||
}
|
||||
|
||||
var virtualFunctionPointer = CreateVirtualFunctionBySignature(signature, binarypath, arguments.Cast<DataType>(),
|
||||
(DataType)typeof(TResult).ToDataType()!, arguments.Cast<object>().ToArray());
|
||||
|
||||
return (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) =>
|
||||
NativeAPI.ExecuteVirtualFunction<TResult>(virtualFunctionPointer,
|
||||
new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 });
|
||||
}
|
||||
|
||||
public static Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TResult> Create<TArg1,
|
||||
TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TResult>(string signature, string binarypath)
|
||||
{
|
||||
var arguments = new[]
|
||||
{
|
||||
typeof(TArg1).ToDataType(),
|
||||
typeof(TArg2).ToDataType(),
|
||||
typeof(TArg3).ToDataType(),
|
||||
typeof(TArg4).ToDataType(),
|
||||
typeof(TArg5).ToDataType(),
|
||||
typeof(TArg6).ToDataType(),
|
||||
typeof(TArg7).ToDataType(),
|
||||
typeof(TArg8).ToDataType(),
|
||||
typeof(TArg9).ToDataType(),
|
||||
typeof(TArg10).ToDataType()
|
||||
};
|
||||
|
||||
if (arguments.Any(x => x == null))
|
||||
{
|
||||
throw new Exception($"Invalid argument type(s) supplied to Virtual Function");
|
||||
}
|
||||
|
||||
var virtualFunctionPointer = CreateVirtualFunctionBySignature(signature, binarypath, arguments.Cast<DataType>(),
|
||||
(DataType)typeof(TResult).ToDataType()!, arguments.Cast<object>().ToArray());
|
||||
|
||||
return (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) =>
|
||||
NativeAPI.ExecuteVirtualFunction<TResult>(virtualFunctionPointer,
|
||||
new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 });
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Void Actions
|
||||
@@ -587,4 +870,281 @@ public partial class VirtualFunction
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Void Actions Binary
|
||||
public static Action CreateVoid(string signature, string binarypath)
|
||||
{
|
||||
var arguments = Enumerable.Empty<DataType>().ToArray();
|
||||
|
||||
var virtualFunctionPointer = CreateVirtualFunctionBySignature(signature, binarypath, arguments,
|
||||
DataType.DATA_TYPE_VOID, arguments.Cast<object>().ToArray());
|
||||
|
||||
return () => { NativeAPI.ExecuteVirtualFunction<object>(virtualFunctionPointer, new object[] { }); };
|
||||
}
|
||||
|
||||
public static Action<TArg1> CreateVoid<TArg1>(string signature, string binarypath)
|
||||
{
|
||||
var arguments = new[]
|
||||
{
|
||||
typeof(TArg1).ToDataType()
|
||||
};
|
||||
|
||||
if (arguments.Any(x => x == null))
|
||||
{
|
||||
throw new Exception($"Invalid argument type(s) supplied to Virtual Function");
|
||||
}
|
||||
|
||||
var virtualFunctionPointer = CreateVirtualFunctionBySignature(signature, binarypath, arguments.Cast<DataType>(),
|
||||
DataType.DATA_TYPE_VOID, arguments.Cast<object>().ToArray());
|
||||
|
||||
return (arg1) => { NativeAPI.ExecuteVirtualFunction<object>(virtualFunctionPointer, new object[] { arg1 }); };
|
||||
}
|
||||
|
||||
public static Action<TArg1, TArg2> CreateVoid<TArg1, TArg2>(string signature, string binarypath)
|
||||
{
|
||||
var arguments = new[]
|
||||
{
|
||||
typeof(TArg1).ToDataType(),
|
||||
typeof(TArg2).ToDataType()
|
||||
};
|
||||
|
||||
if (arguments.Any(x => x == null))
|
||||
{
|
||||
throw new Exception($"Invalid argument type(s) supplied to Virtual Function");
|
||||
}
|
||||
|
||||
var virtualFunctionPointer = CreateVirtualFunctionBySignature(signature, binarypath, arguments.Cast<DataType>(),
|
||||
DataType.DATA_TYPE_VOID, arguments.Cast<object>().ToArray());
|
||||
|
||||
return (arg1, arg2) =>
|
||||
{
|
||||
NativeAPI.ExecuteVirtualFunction<object>(virtualFunctionPointer, new object[] { arg1, arg2 });
|
||||
};
|
||||
}
|
||||
|
||||
public static Action<TArg1, TArg2, TArg3> CreateVoid<TArg1, TArg2, TArg3>(string signature, string binarypath)
|
||||
{
|
||||
var arguments = new[]
|
||||
{
|
||||
typeof(TArg1).ToDataType(),
|
||||
typeof(TArg2).ToDataType(),
|
||||
typeof(TArg3).ToDataType()
|
||||
};
|
||||
|
||||
if (arguments.Any(x => x == null))
|
||||
{
|
||||
throw new Exception($"Invalid argument type(s) supplied to Virtual Function");
|
||||
}
|
||||
|
||||
var virtualFunctionPointer = CreateVirtualFunctionBySignature(signature, binarypath, arguments.Cast<DataType>(),
|
||||
DataType.DATA_TYPE_VOID, arguments.Cast<object>().ToArray());
|
||||
|
||||
return (arg1, arg2, arg3) =>
|
||||
{
|
||||
NativeAPI.ExecuteVirtualFunction<object>(virtualFunctionPointer, new object[] { arg1, arg2, arg3 });
|
||||
};
|
||||
}
|
||||
|
||||
public static Action<TArg1, TArg2, TArg3, TArg4> CreateVoid<TArg1, TArg2, TArg3, TArg4>(string signature, string binarypath)
|
||||
{
|
||||
var arguments = new[]
|
||||
{
|
||||
typeof(TArg1).ToDataType(),
|
||||
typeof(TArg2).ToDataType(),
|
||||
typeof(TArg3).ToDataType(),
|
||||
typeof(TArg4).ToDataType()
|
||||
};
|
||||
|
||||
if (arguments.Any(x => x == null))
|
||||
{
|
||||
throw new Exception($"Invalid argument type(s) supplied to Virtual Function");
|
||||
}
|
||||
|
||||
var virtualFunctionPointer = CreateVirtualFunctionBySignature(signature, binarypath, arguments.Cast<DataType>(),
|
||||
DataType.DATA_TYPE_VOID, arguments.Cast<object>().ToArray());
|
||||
|
||||
return (arg1, arg2, arg3, arg4) =>
|
||||
{
|
||||
NativeAPI.ExecuteVirtualFunction<object>(virtualFunctionPointer,
|
||||
new object[] { arg1, arg2, arg3, arg4 });
|
||||
};
|
||||
}
|
||||
|
||||
public static Action<TArg1, TArg2, TArg3, TArg4, TArg5> CreateVoid<TArg1, TArg2, TArg3, TArg4, TArg5>(
|
||||
string signature, string binarypath)
|
||||
{
|
||||
var arguments = new[]
|
||||
{
|
||||
typeof(TArg1).ToDataType(),
|
||||
typeof(TArg2).ToDataType(),
|
||||
typeof(TArg3).ToDataType(),
|
||||
typeof(TArg4).ToDataType(),
|
||||
typeof(TArg5).ToDataType()
|
||||
};
|
||||
|
||||
if (arguments.Any(x => x == null))
|
||||
{
|
||||
throw new Exception($"Invalid argument type(s) supplied to Virtual Function");
|
||||
}
|
||||
|
||||
var virtualFunctionPointer = CreateVirtualFunctionBySignature(signature, binarypath, arguments.Cast<DataType>(),
|
||||
DataType.DATA_TYPE_VOID, arguments.Cast<object>().ToArray());
|
||||
|
||||
return (arg1, arg2, arg3, arg4, arg5) =>
|
||||
{
|
||||
NativeAPI.ExecuteVirtualFunction<object>(virtualFunctionPointer,
|
||||
new object[] { arg1, arg2, arg3, arg4, arg5 });
|
||||
};
|
||||
}
|
||||
|
||||
public static Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6> CreateVoid<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(
|
||||
string signature, string binarypath)
|
||||
{
|
||||
var arguments = new[]
|
||||
{
|
||||
typeof(TArg1).ToDataType(),
|
||||
typeof(TArg2).ToDataType(),
|
||||
typeof(TArg3).ToDataType(),
|
||||
typeof(TArg4).ToDataType(),
|
||||
typeof(TArg5).ToDataType(),
|
||||
typeof(TArg6).ToDataType()
|
||||
};
|
||||
|
||||
if (arguments.Any(x => x == null))
|
||||
{
|
||||
throw new Exception($"Invalid argument type(s) supplied to Virtual Function");
|
||||
}
|
||||
|
||||
var virtualFunctionPointer = CreateVirtualFunctionBySignature(signature, binarypath, arguments.Cast<DataType>(),
|
||||
DataType.DATA_TYPE_VOID, arguments.Cast<object>().ToArray());
|
||||
|
||||
return (arg1, arg2, arg3, arg4, arg5, arg6) =>
|
||||
{
|
||||
NativeAPI.ExecuteVirtualFunction<object>(virtualFunctionPointer,
|
||||
new object[] { arg1, arg2, arg3, arg4, arg5, arg6 });
|
||||
};
|
||||
}
|
||||
|
||||
public static Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7> CreateVoid<TArg1, TArg2, TArg3, TArg4, TArg5,
|
||||
TArg6, TArg7>(string signature, string binarypath)
|
||||
{
|
||||
var arguments = new[]
|
||||
{
|
||||
typeof(TArg1).ToDataType(),
|
||||
typeof(TArg2).ToDataType(),
|
||||
typeof(TArg3).ToDataType(),
|
||||
typeof(TArg4).ToDataType(),
|
||||
typeof(TArg5).ToDataType(),
|
||||
typeof(TArg6).ToDataType(),
|
||||
typeof(TArg7).ToDataType()
|
||||
};
|
||||
|
||||
if (arguments.Any(x => x == null))
|
||||
{
|
||||
throw new Exception($"Invalid argument type(s) supplied to Virtual Function");
|
||||
}
|
||||
|
||||
var virtualFunctionPointer = CreateVirtualFunctionBySignature(signature, binarypath, arguments.Cast<DataType>(),
|
||||
DataType.DATA_TYPE_VOID, arguments.Cast<object>().ToArray());
|
||||
|
||||
return (arg1, arg2, arg3, arg4, arg5, arg6, arg7) =>
|
||||
{
|
||||
NativeAPI.ExecuteVirtualFunction<object>(virtualFunctionPointer,
|
||||
new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 });
|
||||
};
|
||||
}
|
||||
|
||||
public static Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8> CreateVoid<TArg1, TArg2, TArg3, TArg4,
|
||||
TArg5, TArg6, TArg7, TArg8>(string signature, string binarypath)
|
||||
{
|
||||
var arguments = new[]
|
||||
{
|
||||
typeof(TArg1).ToDataType(),
|
||||
typeof(TArg2).ToDataType(),
|
||||
typeof(TArg3).ToDataType(),
|
||||
typeof(TArg4).ToDataType(),
|
||||
typeof(TArg5).ToDataType(),
|
||||
typeof(TArg6).ToDataType(),
|
||||
typeof(TArg7).ToDataType(),
|
||||
typeof(TArg8).ToDataType()
|
||||
};
|
||||
|
||||
if (arguments.Any(x => x == null))
|
||||
{
|
||||
throw new Exception($"Invalid argument type(s) supplied to Virtual Function");
|
||||
}
|
||||
|
||||
var virtualFunctionPointer = CreateVirtualFunctionBySignature(signature, binarypath, arguments.Cast<DataType>(),
|
||||
DataType.DATA_TYPE_VOID, arguments.Cast<object>().ToArray());
|
||||
|
||||
return (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) =>
|
||||
{
|
||||
NativeAPI.ExecuteVirtualFunction<object>(virtualFunctionPointer,
|
||||
new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 });
|
||||
};
|
||||
}
|
||||
|
||||
public static Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9> CreateVoid<TArg1, TArg2, TArg3,
|
||||
TArg4, TArg5, TArg6, TArg7, TArg8, TArg9>(string signature, string binarypath)
|
||||
{
|
||||
var arguments = new[]
|
||||
{
|
||||
typeof(TArg1).ToDataType(),
|
||||
typeof(TArg2).ToDataType(),
|
||||
typeof(TArg3).ToDataType(),
|
||||
typeof(TArg4).ToDataType(),
|
||||
typeof(TArg5).ToDataType(),
|
||||
typeof(TArg6).ToDataType(),
|
||||
typeof(TArg7).ToDataType(),
|
||||
typeof(TArg8).ToDataType(),
|
||||
typeof(TArg9).ToDataType()
|
||||
};
|
||||
|
||||
if (arguments.Any(x => x == null))
|
||||
{
|
||||
throw new Exception($"Invalid argument type(s) supplied to Virtual Function");
|
||||
}
|
||||
|
||||
var virtualFunctionPointer = CreateVirtualFunctionBySignature(signature, binarypath, arguments.Cast<DataType>(),
|
||||
DataType.DATA_TYPE_VOID, arguments.Cast<object>().ToArray());
|
||||
|
||||
return (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) =>
|
||||
{
|
||||
NativeAPI.ExecuteVirtualFunction<object>(virtualFunctionPointer,
|
||||
new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 });
|
||||
};
|
||||
}
|
||||
|
||||
public static Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10> CreateVoid<TArg1, TArg2,
|
||||
TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10>(string signature, string binarypath)
|
||||
{
|
||||
var arguments = new[]
|
||||
{
|
||||
typeof(TArg1).ToDataType(),
|
||||
typeof(TArg2).ToDataType(),
|
||||
typeof(TArg3).ToDataType(),
|
||||
typeof(TArg4).ToDataType(),
|
||||
typeof(TArg5).ToDataType(),
|
||||
typeof(TArg6).ToDataType(),
|
||||
typeof(TArg7).ToDataType(),
|
||||
typeof(TArg8).ToDataType(),
|
||||
typeof(TArg9).ToDataType(),
|
||||
typeof(TArg10).ToDataType()
|
||||
};
|
||||
|
||||
if (arguments.Any(x => x == null))
|
||||
{
|
||||
throw new Exception($"Invalid argument type(s) supplied to Virtual Function");
|
||||
}
|
||||
|
||||
var virtualFunctionPointer = CreateVirtualFunctionBySignature(signature, binarypath, arguments.Cast<DataType>(),
|
||||
DataType.DATA_TYPE_VOID, arguments.Cast<object>().ToArray());
|
||||
|
||||
return (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) =>
|
||||
{
|
||||
NativeAPI.ExecuteVirtualFunction<object>(virtualFunctionPointer,
|
||||
new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 });
|
||||
};
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
* This file is part of CounterStrikeSharp.
|
||||
* CounterStrikeSharp is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CounterStrikeSharp is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
|
||||
*/
|
||||
|
||||
namespace CounterStrikeSharp.API.Modules.Memory;
|
||||
|
||||
public partial class VirtualFunctionVoid
|
||||
{
|
||||
private Action Function;
|
||||
|
||||
public VirtualFunctionVoid(string signature)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid(signature);
|
||||
}
|
||||
|
||||
public VirtualFunctionVoid(string signature, string binarypath)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid(signature, binarypath);
|
||||
}
|
||||
|
||||
public void Invoke()
|
||||
{
|
||||
this.Function();
|
||||
}
|
||||
}
|
||||
|
||||
public partial class VirtualFunctionVoid<TArg1>
|
||||
{
|
||||
private Action<TArg1> Function;
|
||||
|
||||
public VirtualFunctionVoid(string signature)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1>(signature);
|
||||
}
|
||||
|
||||
public VirtualFunctionVoid(string signature, string binarypath)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1>(signature, binarypath);
|
||||
}
|
||||
|
||||
public VirtualFunctionVoid(IntPtr objectPtr, int offset)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1>(objectPtr, offset);
|
||||
}
|
||||
|
||||
public void Invoke(TArg1 arg1)
|
||||
{
|
||||
this.Function(arg1);
|
||||
}
|
||||
}
|
||||
|
||||
public partial class VirtualFunctionVoid<TArg1, TArg2>
|
||||
{
|
||||
private Action<TArg1, TArg2> Function;
|
||||
|
||||
public VirtualFunctionVoid(string signature)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2>(signature);
|
||||
}
|
||||
|
||||
public VirtualFunctionVoid(string signature, string binarypath)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2>(signature, binarypath);
|
||||
}
|
||||
|
||||
public VirtualFunctionVoid(IntPtr objectPtr, int offset)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2>(objectPtr, offset);
|
||||
}
|
||||
|
||||
public void Invoke(TArg1 arg1, TArg2 arg2)
|
||||
{
|
||||
this.Function(arg1, arg2);
|
||||
}
|
||||
}
|
||||
|
||||
public partial class VirtualFunctionVoid<TArg1, TArg2, TArg3>
|
||||
{
|
||||
private Action<TArg1, TArg2, TArg3> Function;
|
||||
|
||||
public VirtualFunctionVoid(string signature)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3>(signature);
|
||||
}
|
||||
|
||||
public VirtualFunctionVoid(string signature, string binarypath)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3>(signature, binarypath);
|
||||
}
|
||||
|
||||
public VirtualFunctionVoid(IntPtr objectPtr, int offset)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3>(objectPtr, offset);
|
||||
}
|
||||
|
||||
public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3)
|
||||
{
|
||||
this.Function(arg1, arg2, arg3);
|
||||
}
|
||||
}
|
||||
|
||||
public partial class VirtualFunctionVoid<TArg1, TArg2, TArg3, TArg4>
|
||||
{
|
||||
private Action<TArg1, TArg2, TArg3, TArg4> Function;
|
||||
|
||||
public VirtualFunctionVoid(string signature)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3, TArg4>(signature);
|
||||
}
|
||||
|
||||
public VirtualFunctionVoid(string signature, string binarypath)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3, TArg4>(signature, binarypath);
|
||||
}
|
||||
|
||||
public VirtualFunctionVoid(IntPtr objectPtr, int offset)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3, TArg4>(objectPtr, offset);
|
||||
}
|
||||
|
||||
public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4)
|
||||
{
|
||||
this.Function(arg1, arg2, arg3, arg4);
|
||||
}
|
||||
}
|
||||
|
||||
public partial class VirtualFunctionVoid<TArg1, TArg2, TArg3, TArg4, TArg5>
|
||||
{
|
||||
private Action<TArg1, TArg2, TArg3, TArg4, TArg5> Function;
|
||||
|
||||
public VirtualFunctionVoid(string signature)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3, TArg4, TArg5>(signature);
|
||||
}
|
||||
|
||||
public VirtualFunctionVoid(string signature, string binarypath)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3, TArg4, TArg5>(signature, binarypath);
|
||||
}
|
||||
|
||||
public VirtualFunctionVoid(IntPtr objectPtr, int offset)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3, TArg4, TArg5>(objectPtr, offset);
|
||||
}
|
||||
|
||||
public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5)
|
||||
{
|
||||
this.Function(arg1, arg2, arg3, arg4, arg5);
|
||||
}
|
||||
}
|
||||
|
||||
public partial class VirtualFunctionVoid<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>
|
||||
{
|
||||
private Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6> Function;
|
||||
|
||||
public VirtualFunctionVoid(string signature)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(signature);
|
||||
}
|
||||
|
||||
public VirtualFunctionVoid(string signature, string binarypath)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(signature, binarypath);
|
||||
}
|
||||
|
||||
public VirtualFunctionVoid(IntPtr objectPtr, int offset)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(objectPtr, offset);
|
||||
}
|
||||
|
||||
public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6)
|
||||
{
|
||||
this.Function(arg1, arg2, arg3, arg4, arg5, arg6);
|
||||
}
|
||||
}
|
||||
|
||||
public partial class VirtualFunctionVoid<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7>
|
||||
{
|
||||
private Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7> Function;
|
||||
|
||||
public VirtualFunctionVoid(string signature)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7>(signature);
|
||||
}
|
||||
|
||||
public VirtualFunctionVoid(string signature, string binarypath)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7>(signature, binarypath);
|
||||
}
|
||||
|
||||
public VirtualFunctionVoid(IntPtr objectPtr, int offset)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7>(objectPtr, offset);
|
||||
}
|
||||
|
||||
public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7)
|
||||
{
|
||||
this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
||||
}
|
||||
}
|
||||
|
||||
public partial class VirtualFunctionVoid<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8>
|
||||
{
|
||||
private Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8> Function;
|
||||
|
||||
public VirtualFunctionVoid(string signature)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8>(signature);
|
||||
}
|
||||
|
||||
public VirtualFunctionVoid(string signature, string binarypath)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8>(signature, binarypath);
|
||||
}
|
||||
|
||||
public VirtualFunctionVoid(IntPtr objectPtr, int offset)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8>(objectPtr, offset);
|
||||
}
|
||||
|
||||
public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8)
|
||||
{
|
||||
this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
||||
}
|
||||
}
|
||||
|
||||
public partial class VirtualFunctionVoid<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9>
|
||||
{
|
||||
private Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9> Function;
|
||||
|
||||
public VirtualFunctionVoid(string signature)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9>(signature);
|
||||
}
|
||||
|
||||
public VirtualFunctionVoid(string signature, string binarypath)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9>(signature, binarypath);
|
||||
}
|
||||
|
||||
public VirtualFunctionVoid(IntPtr objectPtr, int offset)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9>(objectPtr, offset);
|
||||
}
|
||||
|
||||
public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9)
|
||||
{
|
||||
this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
|
||||
}
|
||||
}
|
||||
|
||||
public partial class VirtualFunctionVoid<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10>
|
||||
{
|
||||
private Action<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10> Function;
|
||||
|
||||
public VirtualFunctionVoid(string signature)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10>(signature);
|
||||
}
|
||||
|
||||
public VirtualFunctionVoid(string signature, string binarypath)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10>(signature, binarypath);
|
||||
}
|
||||
|
||||
public VirtualFunctionVoid(IntPtr objectPtr, int offset)
|
||||
{
|
||||
this.Function = VirtualFunction.CreateVoid<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10>(objectPtr, offset);
|
||||
}
|
||||
|
||||
public void Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10)
|
||||
{
|
||||
this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* This file is part of CounterStrikeSharp.
|
||||
* CounterStrikeSharp is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CounterStrikeSharp is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
|
||||
*/
|
||||
|
||||
namespace CounterStrikeSharp.API.Modules.Memory;
|
||||
|
||||
public partial class VirtualFunctionWithReturn<TResult>
|
||||
{
|
||||
private Func<TResult> Function;
|
||||
|
||||
public VirtualFunctionWithReturn(string signature)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TResult>(signature);
|
||||
}
|
||||
|
||||
public VirtualFunctionWithReturn(string signature, string binarypath)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TResult>(signature, binarypath);
|
||||
}
|
||||
|
||||
public VirtualFunctionWithReturn(IntPtr objectPtr, int offset)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TResult>(objectPtr, offset);
|
||||
}
|
||||
|
||||
public TResult Invoke()
|
||||
{
|
||||
return this.Function();
|
||||
}
|
||||
}
|
||||
|
||||
public partial class VirtualFunctionWithReturn<TArg1, TResult>
|
||||
{
|
||||
private Func<TArg1, TResult> Function;
|
||||
|
||||
public VirtualFunctionWithReturn(string signature)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TResult>(signature);
|
||||
}
|
||||
|
||||
public VirtualFunctionWithReturn(string signature, string binarypath)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TResult>(signature, binarypath);
|
||||
}
|
||||
|
||||
public VirtualFunctionWithReturn(IntPtr objectPtr, int offset)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TResult>(objectPtr, offset);
|
||||
}
|
||||
|
||||
public TResult Invoke(TArg1 arg1)
|
||||
{
|
||||
return this.Function(arg1);
|
||||
}
|
||||
}
|
||||
|
||||
public partial class VirtualFunctionWithReturn<TArg1, TArg2, TResult>
|
||||
{
|
||||
private Func<TArg1, TArg2, TResult> Function;
|
||||
|
||||
public VirtualFunctionWithReturn(string signature)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TResult>(signature);
|
||||
}
|
||||
|
||||
public VirtualFunctionWithReturn(string signature, string binarypath)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TResult>(signature, binarypath);
|
||||
}
|
||||
|
||||
public VirtualFunctionWithReturn(IntPtr objectPtr, int offset)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TResult>(objectPtr, offset);
|
||||
}
|
||||
|
||||
public TResult Invoke(TArg1 arg1, TArg2 arg2)
|
||||
{
|
||||
return this.Function(arg1, arg2);
|
||||
}
|
||||
}
|
||||
|
||||
public partial class VirtualFunctionWithReturn<TArg1, TArg2, TArg3, TResult>
|
||||
{
|
||||
private Func<TArg1, TArg2, TArg3, TResult> Function;
|
||||
|
||||
public VirtualFunctionWithReturn(string signature)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TResult>(signature);
|
||||
}
|
||||
|
||||
public VirtualFunctionWithReturn(string signature, string binarypath)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TResult>(signature, binarypath);
|
||||
}
|
||||
|
||||
public VirtualFunctionWithReturn(IntPtr objectPtr, int offset)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TResult>(objectPtr, offset);
|
||||
}
|
||||
|
||||
public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3)
|
||||
{
|
||||
return this.Function(arg1, arg2, arg3);
|
||||
}
|
||||
}
|
||||
|
||||
public partial class VirtualFunctionWithReturn<TArg1, TArg2, TArg3, TArg4, TResult>
|
||||
{
|
||||
private Func<TArg1, TArg2, TArg3, TArg4, TResult> Function;
|
||||
|
||||
public VirtualFunctionWithReturn(string signature)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TArg4, TResult>(signature);
|
||||
}
|
||||
|
||||
public VirtualFunctionWithReturn(string signature, string binarypath)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TArg4, TResult>(signature, binarypath);
|
||||
}
|
||||
|
||||
public VirtualFunctionWithReturn(IntPtr objectPtr, int offset)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TArg4, TResult>(objectPtr, offset);
|
||||
}
|
||||
|
||||
public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4)
|
||||
{
|
||||
return this.Function(arg1, arg2, arg3, arg4);
|
||||
}
|
||||
}
|
||||
|
||||
public partial class VirtualFunctionWithReturn<TArg1, TArg2, TArg3, TArg4, TArg5, TResult>
|
||||
{
|
||||
private Func<TArg1, TArg2, TArg3, TArg4, TArg5, TResult> Function;
|
||||
|
||||
public VirtualFunctionWithReturn(string signature)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TArg4, TArg5, TResult>(signature);
|
||||
}
|
||||
|
||||
public VirtualFunctionWithReturn(string signature, string binarypath)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TArg4, TArg5, TResult>(signature, binarypath);
|
||||
}
|
||||
|
||||
public VirtualFunctionWithReturn(IntPtr objectPtr, int offset)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TArg4, TArg5, TResult>(objectPtr, offset);
|
||||
}
|
||||
|
||||
public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5)
|
||||
{
|
||||
return this.Function(arg1, arg2, arg3, arg4, arg5);
|
||||
}
|
||||
}
|
||||
|
||||
public partial class VirtualFunctionWithReturn<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TResult>
|
||||
{
|
||||
private Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TResult> Function;
|
||||
|
||||
public VirtualFunctionWithReturn(string signature)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TResult>(signature);
|
||||
}
|
||||
|
||||
public VirtualFunctionWithReturn(string signature, string binarypath)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TResult>(signature, binarypath);
|
||||
}
|
||||
|
||||
public VirtualFunctionWithReturn(IntPtr objectPtr, int offset)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TResult>(objectPtr, offset);
|
||||
}
|
||||
|
||||
public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6)
|
||||
{
|
||||
return this.Function(arg1, arg2, arg3, arg4, arg5, arg6);
|
||||
}
|
||||
}
|
||||
|
||||
public partial class VirtualFunctionWithReturn<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TResult>
|
||||
{
|
||||
private Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TResult> Function;
|
||||
|
||||
public VirtualFunctionWithReturn(string signature)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TResult>(signature);
|
||||
}
|
||||
|
||||
public VirtualFunctionWithReturn(string signature, string binarypath)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TResult>(signature, binarypath);
|
||||
}
|
||||
|
||||
public VirtualFunctionWithReturn(IntPtr objectPtr, int offset)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TResult>(objectPtr, offset);
|
||||
}
|
||||
|
||||
public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7)
|
||||
{
|
||||
return this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
||||
}
|
||||
}
|
||||
|
||||
public partial class VirtualFunctionWithReturn<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TResult>
|
||||
{
|
||||
private Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TResult> Function;
|
||||
|
||||
public VirtualFunctionWithReturn(string signature)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TResult>(signature);
|
||||
}
|
||||
|
||||
public VirtualFunctionWithReturn(string signature, string binarypath)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TResult>(signature, binarypath);
|
||||
}
|
||||
|
||||
public VirtualFunctionWithReturn(IntPtr objectPtr, int offset)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TResult>(objectPtr, offset);
|
||||
}
|
||||
|
||||
public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8)
|
||||
{
|
||||
return this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
||||
}
|
||||
}
|
||||
|
||||
public partial class VirtualFunctionWithReturn<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TResult>
|
||||
{
|
||||
private Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TResult> Function;
|
||||
|
||||
public VirtualFunctionWithReturn(string signature)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TResult>(signature);
|
||||
}
|
||||
|
||||
public VirtualFunctionWithReturn(string signature, string binarypath)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TResult>(signature, binarypath);
|
||||
}
|
||||
|
||||
public VirtualFunctionWithReturn(IntPtr objectPtr, int offset)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TResult>(objectPtr, offset);
|
||||
}
|
||||
|
||||
public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9)
|
||||
{
|
||||
return this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
|
||||
}
|
||||
}
|
||||
|
||||
public partial class VirtualFunctionWithReturn<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TResult>
|
||||
{
|
||||
private Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TResult> Function;
|
||||
|
||||
public VirtualFunctionWithReturn(string signature)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TResult>(signature);
|
||||
}
|
||||
|
||||
public VirtualFunctionWithReturn(string signature, string binarypath)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TResult>(signature, binarypath);
|
||||
}
|
||||
|
||||
public VirtualFunctionWithReturn(IntPtr objectPtr, int offset)
|
||||
{
|
||||
this.Function = VirtualFunction.Create<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TResult>(objectPtr, offset);
|
||||
}
|
||||
|
||||
public TResult Invoke(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10)
|
||||
{
|
||||
return this.Function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
|
||||
namespace CounterStrikeSharp.API.Modules.Utils;
|
||||
|
||||
@@ -9,22 +11,80 @@ public readonly record struct CEntityIndex(uint Value)
|
||||
public override string ToString() => $"Entity Index {Value}";
|
||||
}
|
||||
|
||||
public class CHandle<T> : NativeObject
|
||||
public class CHandle<T> : IEquatable<CHandle<T>> where T : NativeEntity
|
||||
{
|
||||
public CHandle(IntPtr pointer) : base(pointer)
|
||||
private uint _raw;
|
||||
private IntPtr? _pointer;
|
||||
|
||||
public uint Raw
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_pointer != null)
|
||||
{
|
||||
return (uint)Marshal.ReadInt32(_pointer.Value);
|
||||
}
|
||||
|
||||
return _raw;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_pointer != null)
|
||||
{
|
||||
Marshal.WriteInt32(_pointer.Value, (int)value);
|
||||
return;
|
||||
}
|
||||
|
||||
_raw = value;
|
||||
}
|
||||
}
|
||||
|
||||
public T Value => (T)Activator.CreateInstance(typeof(T), NativeAPI.GetEntityPointerFromHandle(Handle));
|
||||
public CHandle(uint raw)
|
||||
{
|
||||
Raw = raw;
|
||||
}
|
||||
|
||||
public unsafe ref ulong Raw => ref Unsafe.AsRef<ulong>((void*)Handle);
|
||||
public CHandle(IntPtr raw)
|
||||
{
|
||||
_pointer = raw;
|
||||
}
|
||||
|
||||
public override string ToString() => IsValid ? $"Index = {Index.Value}, Serial = {SerialNum}" : "<invalid>";
|
||||
public T? Value => (T)Activator.CreateInstance(typeof(T), EntitySystem.GetEntityByHandle(this));
|
||||
|
||||
public bool IsValid => Index.Value != (Utilities.MaxEdicts - 1);
|
||||
public override string ToString() => IsValid ? $"Index = {Index}, Serial = {SerialNum}" : "<invalid>";
|
||||
|
||||
public CEntityIndex Index => new((uint)(Raw & (Utilities.MaxEdicts - 1)));
|
||||
public uint SerialNum => (uint)(Raw >> Utilities.MaxEdictBits);
|
||||
public bool IsValid => Index != (Utilities.MaxEdicts - 1);
|
||||
|
||||
public uint Index => (uint)(Raw & (Utilities.MaxEdicts - 1));
|
||||
public uint SerialNum => Raw >> Utilities.MaxEdictBits;
|
||||
|
||||
public static implicit operator uint(CHandle<T> handle) => handle.Raw;
|
||||
|
||||
public bool Equals(CHandle<T>? other)
|
||||
{
|
||||
return other != null && Raw == other.Raw;
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return Equals(obj as CHandle<T>);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (int)Raw;
|
||||
}
|
||||
}
|
||||
|
||||
public class CEntityHandle : CHandle<CEntityInstance>
|
||||
{
|
||||
public CEntityHandle(uint raw) : base(raw)
|
||||
{
|
||||
}
|
||||
|
||||
public CEntityHandle(IntPtr raw) : base (raw)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class PointerTo<T> : NativeObject where T : NativeObject
|
||||
|
||||
21
managed/CounterStrikeSharp.API/NativeEntity.cs
Normal file
21
managed/CounterStrikeSharp.API/NativeEntity.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
|
||||
namespace CounterStrikeSharp.API;
|
||||
|
||||
public abstract class NativeEntity : NativeObject
|
||||
{
|
||||
public new IntPtr Handle => EntitySystem.GetEntityByHandle(EntityHandle) ?? IntPtr.Zero;
|
||||
public CEntityHandle EntityHandle { get; }
|
||||
|
||||
public NativeEntity(IntPtr pointer) : base(pointer)
|
||||
{
|
||||
EntityHandle = new(EntitySystem.GetRawHandleFromEntityPointer(pointer));
|
||||
}
|
||||
|
||||
public NativeEntity(uint rawHandle) : base(EntitySystem.GetEntityByHandle(rawHandle) ?? IntPtr.Zero)
|
||||
{
|
||||
EntityHandle = new(rawHandle);
|
||||
}
|
||||
}
|
||||
@@ -35,14 +35,14 @@ namespace CounterStrikeSharp.API
|
||||
Reload = (1 << 13),
|
||||
Alt1 = (1 << 14),
|
||||
Alt2 = (1 << 15),
|
||||
Speed = (1 << 16), /**< Player is holding the speed key */
|
||||
Walk = (1 << 17), /**< Player holding walk key */
|
||||
Zoom = (1 << 18), /**< Zoom key for HUD zoom */
|
||||
Weapon1 = (1 << 19), /**< weapon defines these bits */
|
||||
Weapon2 = (1 << 20), /**< weapon defines these bits */
|
||||
Speed = (1 << 16), /** Player is holding the speed key */
|
||||
Walk = (1 << 17), /** Player holding walk key */
|
||||
Zoom = (1 << 18), /** Zoom key for HUD zoom */
|
||||
Weapon1 = (1 << 19), /** weapon defines these bits */
|
||||
Weapon2 = (1 << 20), /** weapon defines these bits */
|
||||
Bullrush = (1 << 21),
|
||||
Grenade1 = (1 << 22), /**< grenade 1 */
|
||||
Grenade2 = (1 << 23), /**< grenade 2 */
|
||||
Grenade1 = (1 << 22), /** grenade 1 */
|
||||
Grenade2 = (1 << 23), /** grenade 2 */
|
||||
Attack3 = (1 << 24)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,15 +22,17 @@ using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using CounterStrikeSharp.API.Modules.Commands.Targeting;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
|
||||
namespace CounterStrikeSharp.API
|
||||
{
|
||||
public static class Utilities
|
||||
{
|
||||
// https://github.com/dotabuff/manta/blob/master/entity.go#L186-L190
|
||||
public const int MaxEdictBits = 14;
|
||||
public const int MaxEdictBits = 15;
|
||||
public const int MaxEdicts = 1 << MaxEdictBits;
|
||||
public const int NumEHandleSerialNumberBits = 17;
|
||||
public const uint InvalidEHandleIndex = 0xFFFFFFFF;
|
||||
|
||||
public static IEnumerable<T> FlagsToList<T>(this T flags) where T : Enum
|
||||
{
|
||||
@@ -65,7 +67,7 @@ namespace CounterStrikeSharp.API
|
||||
|
||||
public static CCSPlayerController? GetPlayerFromSteamId(ulong steamId)
|
||||
{
|
||||
return Utilities.GetPlayers().FirstOrDefault(player => player.SteamID == steamId);
|
||||
return Utilities.GetPlayers().FirstOrDefault(player => player.AuthorizedSteamID == (SteamID)steamId);
|
||||
}
|
||||
|
||||
public static TargetResult ProcessTargetString(string pattern, CCSPlayerController player)
|
||||
@@ -75,7 +77,7 @@ namespace CounterStrikeSharp.API
|
||||
|
||||
public static IEnumerable<T> FindAllEntitiesByDesignerName<T>(string designerName) where T : CEntityInstance
|
||||
{
|
||||
var pEntity = new CEntityIdentity(NativeAPI.GetFirstActiveEntity());
|
||||
var pEntity = new CEntityIdentity(EntitySystem.FirstActiveEntity);
|
||||
for (; pEntity != null && pEntity.Handle != IntPtr.Zero; pEntity = pEntity.Next)
|
||||
{
|
||||
if (!pEntity.DesignerName.Contains(designerName)) continue;
|
||||
@@ -83,6 +85,15 @@ namespace CounterStrikeSharp.API
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<CEntityInstance> GetAllEntities()
|
||||
{
|
||||
var pEntity = new CEntityIdentity(EntitySystem.FirstActiveEntity);
|
||||
for (; pEntity != null && pEntity.Handle != IntPtr.Zero; pEntity = pEntity.Next)
|
||||
{
|
||||
yield return new PointerTo<CEntityInstance>(pEntity.Handle).Value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of <see cref="CCSPlayerController"/> that are valid and have a valid <see cref="CCSPlayerController.UserId"/> >= 0
|
||||
/// </summary>
|
||||
|
||||
@@ -12,6 +12,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WarcraftPlugin", "..\exampl
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{7DF99C35-881D-4FF2-B1C9-246BD3DECB9A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WithConfig", "..\examples\WithConfig\WithConfig.csproj", "{2846604A-5B9F-4D80-9476-657C09CFDD5C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloWorld", "..\examples\HelloWorld\HelloWorld.csproj", "{DDA4F93A-7D4A-4698-8C2A-5DAE7FBCDC72}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WithDependencyInjection", "..\examples\WithDependencyInjection\WithDependencyInjection.csproj", "{E497E40C-A7B4-41A7-A1C6-2EC6698FF3BF}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WithCommands", "..\examples\WithCommands\WithCommands.csproj", "{EA2F596E-2236-4999-B476-B1FDA287674A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WithGameEventHandlers", "..\examples\WithGameEventHandlers\WithGameEventHandlers.csproj", "{3032F3FA-E20A-4581-9A08-2FB5FF1524F4}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WithDatabaseDapper", "..\examples\WithDatabaseDapper\WithDatabaseDapper.csproj", "{A641D8D7-35F1-48AB-AABA-EDFB6B7FC49B}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -38,9 +50,39 @@ Global
|
||||
{DAE388A8-94A4-4C24-9450-E34677EEA2CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DAE388A8-94A4-4C24-9450-E34677EEA2CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DAE388A8-94A4-4C24-9450-E34677EEA2CF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2846604A-5B9F-4D80-9476-657C09CFDD5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2846604A-5B9F-4D80-9476-657C09CFDD5C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2846604A-5B9F-4D80-9476-657C09CFDD5C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2846604A-5B9F-4D80-9476-657C09CFDD5C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DDA4F93A-7D4A-4698-8C2A-5DAE7FBCDC72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DDA4F93A-7D4A-4698-8C2A-5DAE7FBCDC72}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DDA4F93A-7D4A-4698-8C2A-5DAE7FBCDC72}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DDA4F93A-7D4A-4698-8C2A-5DAE7FBCDC72}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E497E40C-A7B4-41A7-A1C6-2EC6698FF3BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E497E40C-A7B4-41A7-A1C6-2EC6698FF3BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E497E40C-A7B4-41A7-A1C6-2EC6698FF3BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E497E40C-A7B4-41A7-A1C6-2EC6698FF3BF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EA2F596E-2236-4999-B476-B1FDA287674A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EA2F596E-2236-4999-B476-B1FDA287674A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EA2F596E-2236-4999-B476-B1FDA287674A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EA2F596E-2236-4999-B476-B1FDA287674A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3032F3FA-E20A-4581-9A08-2FB5FF1524F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3032F3FA-E20A-4581-9A08-2FB5FF1524F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3032F3FA-E20A-4581-9A08-2FB5FF1524F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3032F3FA-E20A-4581-9A08-2FB5FF1524F4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A641D8D7-35F1-48AB-AABA-EDFB6B7FC49B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A641D8D7-35F1-48AB-AABA-EDFB6B7FC49B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A641D8D7-35F1-48AB-AABA-EDFB6B7FC49B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A641D8D7-35F1-48AB-AABA-EDFB6B7FC49B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{57E64289-5D69-4AA1-BEF0-D0D96A55EE8F} = {7DF99C35-881D-4FF2-B1C9-246BD3DECB9A}
|
||||
{DAE388A8-94A4-4C24-9450-E34677EEA2CF} = {7DF99C35-881D-4FF2-B1C9-246BD3DECB9A}
|
||||
{2846604A-5B9F-4D80-9476-657C09CFDD5C} = {7DF99C35-881D-4FF2-B1C9-246BD3DECB9A}
|
||||
{DDA4F93A-7D4A-4698-8C2A-5DAE7FBCDC72} = {7DF99C35-881D-4FF2-B1C9-246BD3DECB9A}
|
||||
{E497E40C-A7B4-41A7-A1C6-2EC6698FF3BF} = {7DF99C35-881D-4FF2-B1C9-246BD3DECB9A}
|
||||
{EA2F596E-2236-4999-B476-B1FDA287674A} = {7DF99C35-881D-4FF2-B1C9-246BD3DECB9A}
|
||||
{3032F3FA-E20A-4581-9A08-2FB5FF1524F4} = {7DF99C35-881D-4FF2-B1C9-246BD3DECB9A}
|
||||
{A641D8D7-35F1-48AB-AABA-EDFB6B7FC49B} = {7DF99C35-881D-4FF2-B1C9-246BD3DECB9A}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace TestPlugin
|
||||
[JsonPropertyName("LogPrefix")] public string LogPrefix { get; set; } = "CSSharp";
|
||||
}
|
||||
|
||||
[MinimumApiVersion(33)]
|
||||
[MinimumApiVersion(80)]
|
||||
public class SamplePlugin : BasePlugin, IPluginConfig<SampleConfig>
|
||||
{
|
||||
public override string ModuleName => "Sample Plugin";
|
||||
@@ -137,7 +137,7 @@ namespace TestPlugin
|
||||
VirtualFunctions.UTIL_RemoveFunc.Hook(hook =>
|
||||
{
|
||||
var entityInstance = hook.GetParam<CEntityInstance>(0);
|
||||
Logger.LogInformation("Removed entity {EntityIndex}", entityInstance.EntityIndex.Value.Value);
|
||||
Logger.LogInformation("Removed entity {EntityIndex}", entityInstance.Index);
|
||||
|
||||
return HookResult.Continue;
|
||||
}, HookMode.Post);
|
||||
@@ -217,7 +217,7 @@ namespace TestPlugin
|
||||
if (!@event.Userid.PlayerPawn.IsValid) return 0;
|
||||
|
||||
Logger.LogInformation("Player spawned with entity index: {EntityIndex} & User ID: {UserId}",
|
||||
@event.Userid.EntityIndex, @event.Userid.UserId);
|
||||
@event.Userid.Index, @event.Userid.UserId);
|
||||
|
||||
return HookResult.Continue;
|
||||
});
|
||||
@@ -229,27 +229,21 @@ namespace TestPlugin
|
||||
var activeWeapon = @event.Userid.PlayerPawn.Value.WeaponServices?.ActiveWeapon.Value;
|
||||
var weapons = @event.Userid.PlayerPawn.Value.WeaponServices?.MyWeapons;
|
||||
|
||||
Server.NextFrame(() =>
|
||||
{
|
||||
var weaponServices = player.PlayerPawn.Value.WeaponServices.As<CCSPlayer_WeaponServices>();
|
||||
player.PrintToChat(weaponServices.ActiveWeapon.Value?.DesignerName);
|
||||
});
|
||||
|
||||
// Set player to random colour
|
||||
player.PlayerPawn.Value.Render = Color.FromArgb(Random.Shared.Next(0, 255),
|
||||
Random.Shared.Next(0, 255), Random.Shared.Next(0, 255));
|
||||
|
||||
Server.NextFrame(() =>
|
||||
{
|
||||
player.PrintToCenter(string.Join("\n", weapons.Select(x => x.Value.DesignerName)));
|
||||
});
|
||||
|
||||
activeWeapon.ReserveAmmo[0] = 250;
|
||||
activeWeapon.Clip1 = 250;
|
||||
|
||||
Logger.LogInformation("Pawn Position: {AbsOrigin}-{Rotation}", pawn.AbsOrigin, pawn.AbsRotation);
|
||||
|
||||
char randomColourChar = (char)new Random().Next(0, 16);
|
||||
Server.PrintToChatAll($"Random String with Random Colour: {randomColourChar}{new Random().Next()}");
|
||||
|
||||
pawn.Health += 5;
|
||||
|
||||
Logger.LogInformation("Bullet Impact: {X},{Y},{Z}", @event.X, @event.Y, @event.Z);
|
||||
|
||||
return HookResult.Continue;
|
||||
});
|
||||
RegisterEventHandler<EventRoundStart>((@event, info) =>
|
||||
@@ -304,7 +298,7 @@ namespace TestPlugin
|
||||
switch (designerName)
|
||||
{
|
||||
case "smokegrenade_projectile":
|
||||
var projectile = new CSmokeGrenadeProjectile(entity.Handle);
|
||||
var projectile = entity.As<CSmokeGrenadeProjectile>();
|
||||
|
||||
Server.NextFrame(() =>
|
||||
{
|
||||
@@ -316,7 +310,7 @@ namespace TestPlugin
|
||||
});
|
||||
return;
|
||||
case "flashbang_projectile":
|
||||
var flashbang = new CBaseCSGrenadeProjectile(entity.Handle);
|
||||
var flashbang = entity.As<CBaseCSGrenadeProjectile>();
|
||||
|
||||
Server.NextFrame(() => { flashbang.Remove(); });
|
||||
return;
|
||||
@@ -470,6 +464,20 @@ namespace TestPlugin
|
||||
}
|
||||
}
|
||||
|
||||
[ConsoleCommand("css_entities", "List entities")]
|
||||
public void OnCommandEntities(CCSPlayerController? player, CommandInfo command)
|
||||
{
|
||||
foreach (var entity in Utilities.GetAllEntities())
|
||||
{
|
||||
command.ReplyToCommand($"{entity.Index}:{entity.DesignerName}");
|
||||
}
|
||||
|
||||
foreach (var entity in Utilities.FindAllEntitiesByDesignerName<CBaseEntity>("cs_"))
|
||||
{
|
||||
command.ReplyToCommand($"{entity.Index}:{entity.DesignerName}");
|
||||
}
|
||||
}
|
||||
|
||||
[ConsoleCommand("css_colors", "List Chat Colors")]
|
||||
public void OnCommandColors(CCSPlayerController? player, CommandInfo command)
|
||||
{
|
||||
@@ -481,6 +489,15 @@ namespace TestPlugin
|
||||
command.ReplyToCommand($" {(char)i}Color 0x{i:x}");
|
||||
}
|
||||
}
|
||||
|
||||
[ConsoleCommand("css_sound", "Play a sound to client")]
|
||||
public void OnCommandSound(CCSPlayerController? player, CommandInfo command)
|
||||
{
|
||||
if (player == null) return;
|
||||
if (!player.PlayerPawn.IsValid) return;
|
||||
|
||||
player.ExecuteClientCommand($"play sounds/ui/counter_beep.vsnd");
|
||||
}
|
||||
|
||||
[ConsoleCommand("css_pause", "Pause Game")]
|
||||
public void OnCommandPause(CCSPlayerController? player, CommandInfo command)
|
||||
|
||||
@@ -47,9 +47,10 @@ bool CCoreConfig::Init(char* conf_error, int conf_error_size)
|
||||
m_json = json::parse(ifs);
|
||||
|
||||
try {
|
||||
PublicChatTrigger = m_json["PublicChatTrigger"];
|
||||
SilentChatTrigger = m_json["SilentChatTrigger"];
|
||||
FollowCS2ServerGuidelines = m_json["FollowCS2ServerGuidelines"];
|
||||
PublicChatTrigger = m_json.value("PublicChatTrigger", PublicChatTrigger);
|
||||
SilentChatTrigger = m_json.value("SilentChatTrigger", SilentChatTrigger);
|
||||
FollowCS2ServerGuidelines = m_json.value("FollowCS2ServerGuidelines", FollowCS2ServerGuidelines);
|
||||
PluginHotReloadEnabled = m_json.value("PluginHotReloadEnabled", PluginHotReloadEnabled);
|
||||
} catch (const std::exception& ex) {
|
||||
V_snprintf(conf_error, conf_error_size, "Failed to parse CoreConfig file: %s", ex.what());
|
||||
return false;
|
||||
|
||||
@@ -28,6 +28,7 @@ class CCoreConfig
|
||||
std::vector<std::string> PublicChatTrigger = { std::string("!") };
|
||||
std::vector<std::string> SilentChatTrigger = { std::string("/") };
|
||||
bool FollowCS2ServerGuidelines = true;
|
||||
bool PluginHotReloadEnabled = true;
|
||||
|
||||
using json = nlohmann::json;
|
||||
CCoreConfig(const std::string& path);
|
||||
|
||||
@@ -103,7 +103,6 @@ bool EventManager::HookEvent(const char* szName, CallbackT fnCallback, bool bPos
|
||||
} else {
|
||||
if (!pHook->m_pPreHook) {
|
||||
pHook->m_pPreHook = globals::callbackManager.CreateCallback("");
|
||||
;
|
||||
}
|
||||
|
||||
pHook->m_pPreHook->AddListener(fnCallback);
|
||||
@@ -130,18 +129,17 @@ bool EventManager::UnhookEvent(const char* szName, CallbackT fnCallback, bool bP
|
||||
pCallback = pHook->m_pPreHook;
|
||||
}
|
||||
|
||||
// Remove from function list
|
||||
if (pCallback == nullptr) {
|
||||
return false;
|
||||
}
|
||||
pCallback->RemoveListener(fnCallback);
|
||||
|
||||
if (bPost) {
|
||||
pHook->m_pPostHook = nullptr;
|
||||
} else {
|
||||
pHook->m_pPreHook = nullptr;
|
||||
}
|
||||
if (pCallback->GetFunctionCount() == 0) {
|
||||
globals::callbackManager.ReleaseCallback(pCallback);
|
||||
|
||||
// TODO: Clean up callback if theres noone left attached.
|
||||
if (bPost) {
|
||||
pHook->m_pPostHook = nullptr;
|
||||
} else {
|
||||
pHook->m_pPreHook = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CSSHARP_CORE_TRACE("Unhooking event: {0} with callback pointer: {1}", szName, (void*)fnCallback);
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <sourcehook/sourcehook.h>
|
||||
|
||||
#include "core/log.h"
|
||||
#include "core/timer_system.h"
|
||||
#include "scripting/callback_manager.h"
|
||||
#include <iplayerinfo.h>
|
||||
// extern CEntitySystem *g_pEntitySystem;
|
||||
@@ -303,9 +304,9 @@ int PlayerManager::NumPlayers() const { return m_player_count; }
|
||||
|
||||
int PlayerManager::MaxClients() const { return m_max_clients; }
|
||||
|
||||
CPlayer* PlayerManager::GetPlayerByIndex(int client) const
|
||||
CPlayer* PlayerManager::GetPlayerBySlot(int client) const
|
||||
{
|
||||
if (client > m_max_clients || client < 1) {
|
||||
if (client > m_max_clients || client < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -434,11 +435,11 @@ PlayerManager::PlayerManager()
|
||||
|
||||
void PlayerManager::RunAuthChecks()
|
||||
{
|
||||
if (globals::getGlobalVars()->curtime - m_last_auth_check_time < 0.5F) {
|
||||
if (globals::timerSystem.GetTickedTime() - m_last_auth_check_time < 0.5F) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_last_auth_check_time = globals::getGlobalVars()->curtime;
|
||||
m_last_auth_check_time = globals::timerSystem.GetTickedTime();
|
||||
|
||||
for (int i = 0; i <= m_max_clients; i++) {
|
||||
if (m_players[i].IsConnected()) {
|
||||
|
||||
@@ -151,7 +151,7 @@ public:
|
||||
public:
|
||||
int NumPlayers() const;
|
||||
int MaxClients() const;
|
||||
CPlayer *GetPlayerByIndex(int client) const;
|
||||
CPlayer *GetPlayerBySlot(int client) const;
|
||||
CPlayer *GetClientOfUserId(int user_id) const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -23,6 +23,9 @@ SH_DECL_HOOK1_void(ISource2Server, ServerHibernationUpdate, SH_NOATTRIB, 0, bool
|
||||
SH_DECL_HOOK0_void(ISource2Server, GameServerSteamAPIActivated, SH_NOATTRIB, 0);
|
||||
SH_DECL_HOOK0_void(ISource2Server, GameServerSteamAPIDeactivated, SH_NOATTRIB, 0);
|
||||
SH_DECL_HOOK1_void(ISource2Server, OnHostNameChanged, SH_NOATTRIB, 0, const char*);
|
||||
SH_DECL_HOOK0_void(ISource2Server, PreFatalShutdown, const, 0);
|
||||
SH_DECL_HOOK1_void(ISource2Server, UpdateWhenNotInGame, SH_NOATTRIB, 0, float);
|
||||
SH_DECL_HOOK1_void(ISource2Server, PreWorldUpdate, SH_NOATTRIB, 0, bool);
|
||||
|
||||
namespace counterstrikesharp {
|
||||
|
||||
@@ -39,11 +42,20 @@ void ServerManager::OnAllInitialized() {
|
||||
SH_MEMBER(this, &ServerManager::GameServerSteamAPIDeactivated), true);
|
||||
SH_ADD_HOOK(ISource2Server, OnHostNameChanged, globals::server,
|
||||
SH_MEMBER(this, &ServerManager::OnHostNameChanged), true);
|
||||
SH_ADD_HOOK(ISource2Server, PreFatalShutdown, globals::server,
|
||||
SH_MEMBER(this, &ServerManager::PreFatalShutdown), true);
|
||||
SH_ADD_HOOK(ISource2Server, UpdateWhenNotInGame, globals::server,
|
||||
SH_MEMBER(this, &ServerManager::UpdateWhenNotInGame), true);
|
||||
SH_ADD_HOOK(ISource2Server, PreWorldUpdate, globals::server,
|
||||
SH_MEMBER(this, &ServerManager::PreWorldUpdate), true);
|
||||
|
||||
on_server_hibernation_update_callback = globals::callbackManager.CreateCallback("OnServerHibernationUpdate");
|
||||
on_server_steam_api_activated_callback = globals::callbackManager.CreateCallback("OnGameServerSteamAPIActivated");
|
||||
on_server_steam_api_deactivated_callback = globals::callbackManager.CreateCallback("OnGameServerSteamAPIDeactivated");
|
||||
on_server_hostname_changed_callback = globals::callbackManager.CreateCallback("OnHostNameChanged");
|
||||
on_server_pre_fatal_shutdown = globals::callbackManager.CreateCallback("OnPreFatalShutdown");
|
||||
on_server_update_when_not_in_game = globals::callbackManager.CreateCallback("OnUpdateWhenNotInGame");
|
||||
on_server_pre_world_update = globals::callbackManager.CreateCallback("OnServerPreWorldUpdate");
|
||||
}
|
||||
|
||||
void ServerManager::OnShutdown() {
|
||||
@@ -55,11 +67,20 @@ void ServerManager::OnShutdown() {
|
||||
SH_MEMBER(this, &ServerManager::GameServerSteamAPIDeactivated), true);
|
||||
SH_REMOVE_HOOK(ISource2Server, OnHostNameChanged, globals::server,
|
||||
SH_MEMBER(this, &ServerManager::OnHostNameChanged), true);
|
||||
SH_REMOVE_HOOK(ISource2Server, PreFatalShutdown, globals::server,
|
||||
SH_MEMBER(this, &ServerManager::PreFatalShutdown), true);
|
||||
SH_REMOVE_HOOK(ISource2Server, UpdateWhenNotInGame, globals::server,
|
||||
SH_MEMBER(this, &ServerManager::UpdateWhenNotInGame), true);
|
||||
SH_REMOVE_HOOK(ISource2Server, PreWorldUpdate, globals::server,
|
||||
SH_MEMBER(this, &ServerManager::PreWorldUpdate), true);
|
||||
|
||||
globals::callbackManager.ReleaseCallback(on_server_hibernation_update_callback);
|
||||
globals::callbackManager.ReleaseCallback(on_server_steam_api_activated_callback);
|
||||
globals::callbackManager.ReleaseCallback(on_server_steam_api_deactivated_callback);
|
||||
globals::callbackManager.ReleaseCallback(on_server_hostname_changed_callback);
|
||||
globals::callbackManager.ReleaseCallback(on_server_pre_fatal_shutdown);
|
||||
globals::callbackManager.ReleaseCallback(on_server_update_when_not_in_game);
|
||||
globals::callbackManager.ReleaseCallback(on_server_pre_world_update);
|
||||
}
|
||||
|
||||
void* ServerManager::GetEconItemSystem()
|
||||
@@ -67,6 +88,11 @@ void* ServerManager::GetEconItemSystem()
|
||||
return globals::server->GetEconItemSystem();
|
||||
}
|
||||
|
||||
bool ServerManager::IsPaused()
|
||||
{
|
||||
return globals::server->IsPaused();
|
||||
}
|
||||
|
||||
void ServerManager::ServerHibernationUpdate(bool bHibernating)
|
||||
{
|
||||
CSSHARP_CORE_TRACE("Server hibernation update {0}", bHibernating);
|
||||
@@ -117,4 +143,41 @@ void ServerManager::OnHostNameChanged(const char *pHostname)
|
||||
}
|
||||
}
|
||||
|
||||
void ServerManager::PreFatalShutdown()
|
||||
{
|
||||
CSSHARP_CORE_TRACE("Pre fatal shutdown");
|
||||
|
||||
auto callback = globals::serverManager.on_server_pre_fatal_shutdown;
|
||||
|
||||
if (callback && callback->GetFunctionCount()) {
|
||||
callback->ScriptContext().Reset();
|
||||
callback->Execute();
|
||||
}
|
||||
}
|
||||
|
||||
void ServerManager::UpdateWhenNotInGame(float flFrameTime)
|
||||
{
|
||||
CSSHARP_CORE_TRACE("Update when not in game {}", flFrameTime);
|
||||
|
||||
auto callback = globals::serverManager.on_server_update_when_not_in_game;
|
||||
|
||||
if (callback && callback->GetFunctionCount()) {
|
||||
callback->ScriptContext().Reset();
|
||||
callback->ScriptContext().Push(flFrameTime);
|
||||
callback->Execute();
|
||||
}
|
||||
}
|
||||
|
||||
void ServerManager::PreWorldUpdate(bool bSimulating)
|
||||
{
|
||||
|
||||
auto callback = globals::serverManager.on_server_pre_world_update;
|
||||
|
||||
if (callback && callback->GetFunctionCount()) {
|
||||
callback->ScriptContext().Reset();
|
||||
callback->ScriptContext().Push(bSimulating);
|
||||
callback->Execute();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace counterstrikesharp
|
||||
@@ -30,17 +30,24 @@ public:
|
||||
void OnAllInitialized() override;
|
||||
void OnShutdown() override;
|
||||
void* GetEconItemSystem();
|
||||
bool IsPaused();
|
||||
|
||||
private:
|
||||
void ServerHibernationUpdate(bool bHibernating);
|
||||
void GameServerSteamAPIActivated();
|
||||
void GameServerSteamAPIDeactivated();
|
||||
void OnHostNameChanged(const char *pHostname);
|
||||
void PreFatalShutdown();
|
||||
void UpdateWhenNotInGame(float flFrameTime);
|
||||
void PreWorldUpdate(bool bSimulating);
|
||||
|
||||
ScriptCallback *on_server_hibernation_update_callback;
|
||||
ScriptCallback *on_server_steam_api_activated_callback;
|
||||
ScriptCallback *on_server_steam_api_deactivated_callback;
|
||||
ScriptCallback *on_server_hostname_changed_callback;
|
||||
ScriptCallback *on_server_pre_fatal_shutdown;
|
||||
ScriptCallback *on_server_update_when_not_in_game;
|
||||
ScriptCallback *on_server_pre_world_update;
|
||||
};
|
||||
|
||||
} // namespace counterstrikesharp
|
||||
@@ -1,4 +1,7 @@
|
||||
OnServerHibernationUpdate: isHibernating:bool
|
||||
OnGameServerSteamAPIActivated:
|
||||
OnGameServerSteamAPIDeactivated:
|
||||
OnHostNameChanged: hostname:string
|
||||
OnHostNameChanged: hostname:string
|
||||
PreFatalShutdown:
|
||||
UpdateWhenNotInGame: frameTime:float
|
||||
PreWorldUpdate: simulating:bool
|
||||
@@ -124,6 +124,23 @@ static void IssueClientCommand(ScriptContext& script_context)
|
||||
globals::engine->ClientCommand(CPlayerSlot(entity_index), command);
|
||||
}
|
||||
|
||||
static const char* GetClientConVarValue(ScriptContext& script_context)
|
||||
{
|
||||
auto playerSlot = script_context.GetArgument<int>(0);
|
||||
auto convarName = script_context.GetArgument<const char*>(1);
|
||||
|
||||
return globals::engine->GetClientConVarValue(CPlayerSlot(playerSlot), convarName);
|
||||
}
|
||||
|
||||
static void SetFakeClientConVarValue(ScriptContext& script_context)
|
||||
{
|
||||
auto playerSlot = script_context.GetArgument<int>(0);
|
||||
auto convarName = script_context.GetArgument<const char*>(1);
|
||||
auto convarValue = script_context.GetArgument<const char*>(2);
|
||||
|
||||
globals::engine->SetFakeClientConVarValue(CPlayerSlot(playerSlot), convarName, convarValue);
|
||||
}
|
||||
|
||||
ConVar* FindConVar(ScriptContext& script_context)
|
||||
{
|
||||
auto name = script_context.GetArgument<const char*>(0);
|
||||
@@ -163,5 +180,7 @@ REGISTER_NATIVES(commands, {
|
||||
ScriptEngine::RegisterNativeHandler("SET_CONVAR_STRING_VALUE", SetConVarStringValue);
|
||||
|
||||
ScriptEngine::RegisterNativeHandler("ISSUE_CLIENT_COMMAND", IssueClientCommand);
|
||||
ScriptEngine::RegisterNativeHandler("GET_CLIENT_CONVAR_VALUE", GetClientConVarValue);
|
||||
ScriptEngine::RegisterNativeHandler("SET_FAKE_CLIENT_CONVAR_VALUE", SetFakeClientConVarValue);
|
||||
})
|
||||
} // namespace counterstrikesharp
|
||||
|
||||
@@ -8,4 +8,6 @@ COMMAND_GET_COMMAND_STRING: command:pointer -> string
|
||||
COMMAND_GET_ARG_BY_INDEX: command:pointer,index:int -> string
|
||||
ISSUE_CLIENT_COMMAND: clientIndex:int,command:string -> void
|
||||
FIND_CONVAR: name:string -> pointer
|
||||
SET_CONVAR_STRING_VALUE: convar:pointer,value:string -> void
|
||||
SET_CONVAR_STRING_VALUE: convar:pointer,value:string -> void
|
||||
GET_CLIENT_CONVAR_VALUE: clientIndex:int,convarName:string -> string
|
||||
SET_FAKE_CLIENT_CONVAR_VALUE: clientIndex:int,convarName:string,convarValue:string -> void
|
||||
@@ -21,6 +21,8 @@
|
||||
#include "scripting/script_engine.h"
|
||||
#include "core/memory.h"
|
||||
#include "core/log.h"
|
||||
#include "core/managers/player_manager.h"
|
||||
|
||||
#include <public/entity2/entitysystem.h>
|
||||
|
||||
namespace counterstrikesharp {
|
||||
@@ -53,6 +55,52 @@ void* GetEntityPointerFromHandle(ScriptContext& scriptContext) {
|
||||
return globals::entitySystem->GetBaseEntity(*handle);
|
||||
}
|
||||
|
||||
void* GetEntityPointerFromRef(ScriptContext& scriptContext) {
|
||||
auto ref = scriptContext.GetArgument<unsigned int>(0);
|
||||
|
||||
if (ref == INVALID_EHANDLE_INDEX) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CBaseHandle hndl(ref);
|
||||
|
||||
return globals::entitySystem->GetBaseEntity(hndl);
|
||||
}
|
||||
|
||||
unsigned int GetRefFromEntityPointer(ScriptContext& scriptContext) {
|
||||
auto* pEntity = scriptContext.GetArgument<CBaseEntity*>(0);
|
||||
|
||||
if (pEntity == nullptr)
|
||||
{
|
||||
return INVALID_EHANDLE_INDEX;
|
||||
}
|
||||
|
||||
auto hndl = pEntity->GetRefEHandle();
|
||||
|
||||
if (hndl == INVALID_EHANDLE_INDEX)
|
||||
{
|
||||
return INVALID_EHANDLE_INDEX;
|
||||
}
|
||||
|
||||
return hndl.ToInt();
|
||||
}
|
||||
|
||||
bool IsRefValidEntity(ScriptContext& scriptContext) {
|
||||
auto ref = scriptContext.GetArgument<unsigned int>(0);
|
||||
|
||||
if (ref == INVALID_EHANDLE_INDEX) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CBaseHandle hndl(ref);
|
||||
|
||||
if (!hndl.IsValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return globals::entitySystem->GetBaseEntity(hndl) != nullptr;
|
||||
}
|
||||
|
||||
void PrintToConsole(ScriptContext& scriptContext) {
|
||||
auto index = scriptContext.GetArgument<int>(0);
|
||||
auto message = scriptContext.GetArgument<const char*>(1);
|
||||
@@ -64,13 +112,50 @@ CEntityIdentity* GetFirstActiveEntity(ScriptContext& script_context) {
|
||||
return globals::entitySystem->m_EntityList.m_pFirstActiveEntity;
|
||||
}
|
||||
|
||||
void* GetConcreteEntityListPointer(ScriptContext& script_context) {
|
||||
return &globals::entitySystem->m_EntityList;
|
||||
}
|
||||
|
||||
unsigned long GetPlayerAuthorizedSteamID(ScriptContext& script_context) {
|
||||
auto iSlot = script_context.GetArgument<int>(0);
|
||||
|
||||
auto pPlayer = globals::playerManager.GetPlayerBySlot(iSlot);
|
||||
if (pPlayer == nullptr || !pPlayer->m_is_authorized) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto pSteamId = pPlayer->GetSteamId();
|
||||
if (pSteamId == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pSteamId->ConvertToUint64();
|
||||
}
|
||||
|
||||
const char* GetPlayerIpAddress(ScriptContext& script_context) {
|
||||
auto iSlot = script_context.GetArgument<int>(0);
|
||||
|
||||
auto pPlayer = globals::playerManager.GetPlayerBySlot(iSlot);
|
||||
if (pPlayer == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return pPlayer->GetIpAddress();
|
||||
}
|
||||
|
||||
REGISTER_NATIVES(entities, {
|
||||
ScriptEngine::RegisterNativeHandler("GET_ENTITY_FROM_INDEX", GetEntityFromIndex);
|
||||
ScriptEngine::RegisterNativeHandler("GET_USERID_FROM_INDEX", GetUserIdFromIndex);
|
||||
ScriptEngine::RegisterNativeHandler("GET_DESIGNER_NAME", GetDesignerName);
|
||||
ScriptEngine::RegisterNativeHandler("GET_ENTITY_POINTER_FROM_HANDLE",
|
||||
GetEntityPointerFromHandle);
|
||||
ScriptEngine::RegisterNativeHandler("GET_ENTITY_POINTER_FROM_REF", GetEntityPointerFromRef);
|
||||
ScriptEngine::RegisterNativeHandler("GET_REF_FROM_ENTITY_POINTER", GetRefFromEntityPointer);
|
||||
ScriptEngine::RegisterNativeHandler("GET_CONCRETE_ENTITY_LIST_POINTER", GetConcreteEntityListPointer);
|
||||
ScriptEngine::RegisterNativeHandler("IS_REF_VALID_ENTITY", IsRefValidEntity);
|
||||
ScriptEngine::RegisterNativeHandler("PRINT_TO_CONSOLE", PrintToConsole);
|
||||
ScriptEngine::RegisterNativeHandler("GET_FIRST_ACTIVE_ENTITY", GetFirstActiveEntity);
|
||||
ScriptEngine::RegisterNativeHandler("GET_PLAYER_AUTHORIZED_STEAMID", GetPlayerAuthorizedSteamID);
|
||||
ScriptEngine::RegisterNativeHandler("GET_PLAYER_IP_ADDRESS", GetPlayerIpAddress);
|
||||
})
|
||||
} // namespace counterstrikesharp
|
||||
@@ -2,5 +2,11 @@ GET_ENTITY_FROM_INDEX: index:int -> pointer
|
||||
GET_USERID_FROM_INDEX: index:int -> int
|
||||
GET_DESIGNER_NAME: pointer:pointer -> string
|
||||
GET_ENTITY_POINTER_FROM_HANDLE: entityHandlePointer:pointer -> pointer
|
||||
GET_REF_FROM_ENTITY_POINTER: entityPointer:pointer -> uint
|
||||
GET_ENTITY_POINTER_FROM_REF: entityRef:uint -> pointer
|
||||
GET_CONCRETE_ENTITY_LIST_POINTER: -> pointer
|
||||
IS_REF_VALID_ENTITY: entityRef:uint -> bool
|
||||
PRINT_TO_CONSOLE: index:int, message:string -> void
|
||||
GET_FIRST_ACTIVE_ENTITY: -> pointer
|
||||
GET_FIRST_ACTIVE_ENTITY: -> pointer
|
||||
GET_PLAYER_AUTHORIZED_STEAMID: slot:int -> uint64
|
||||
GET_PLAYER_IP_ADDRESS: slot:int -> string
|
||||
@@ -24,6 +24,9 @@
|
||||
#include "schema.h"
|
||||
#include "core/function.h"
|
||||
#include "core/coreconfig.h"
|
||||
#include "interfaces/cschemasystem.h"
|
||||
#include "core/cs2_sdk/interfaces/cschemasystem.h"
|
||||
#include "interfaces/cs2_interfaces.h"
|
||||
|
||||
namespace counterstrikesharp {
|
||||
|
||||
@@ -39,6 +42,20 @@ int16 GetSchemaOffset(ScriptContext& script_context)
|
||||
return m_key.offset;
|
||||
}
|
||||
|
||||
int GetSchemaClassSize(ScriptContext& script_context)
|
||||
{
|
||||
auto className = script_context.GetArgument<const char*>(0);
|
||||
|
||||
CSchemaSystemTypeScope* pType =
|
||||
interfaces::pSchemaSystem->FindTypeScopeForModule(MODULE_PREFIX "server" MODULE_EXT);
|
||||
|
||||
SchemaClassInfoData_t* pClassInfo = pType->FindDeclaredClass(className);
|
||||
if (!pClassInfo)
|
||||
return -1;
|
||||
|
||||
return pClassInfo->m_size;
|
||||
}
|
||||
|
||||
void GetSchemaValueByName(ScriptContext& script_context)
|
||||
{
|
||||
auto instancePointer = script_context.GetArgument<void*>(0);
|
||||
@@ -224,5 +241,6 @@ REGISTER_NATIVES(schema, {
|
||||
ScriptEngine::RegisterNativeHandler("GET_SCHEMA_OFFSET", GetSchemaOffset);
|
||||
ScriptEngine::RegisterNativeHandler("GET_SCHEMA_VALUE_BY_NAME", GetSchemaValueByName);
|
||||
ScriptEngine::RegisterNativeHandler("SET_SCHEMA_VALUE_BY_NAME", SetSchemaValueByName);
|
||||
ScriptEngine::RegisterNativeHandler("GET_SCHEMA_CLASS_SIZE", GetSchemaClassSize);
|
||||
})
|
||||
} // namespace counterstrikesharp
|
||||
@@ -1,3 +1,4 @@
|
||||
GET_SCHEMA_OFFSET: className:string, propName:string -> short
|
||||
GET_SCHEMA_VALUE_BY_NAME: instance:pointer, returnType:int, className:string, propName:string -> any
|
||||
SET_SCHEMA_VALUE_BY_NAME: instance:pointer, returnType:int, className:string, propName:string, value:any -> void
|
||||
SET_SCHEMA_VALUE_BY_NAME: instance:pointer, returnType:int, className:string, propName:string, value:any -> void
|
||||
GET_SCHEMA_CLASS_SIZE: className:string -> int
|
||||
@@ -24,8 +24,14 @@ static void *GetEconItemSystem(ScriptContext& scriptContext) {
|
||||
return globals::serverManager.GetEconItemSystem();
|
||||
}
|
||||
|
||||
static bool IsServerPaused(ScriptContext& scriptContext)
|
||||
{
|
||||
return globals::serverManager.IsPaused();
|
||||
}
|
||||
|
||||
REGISTER_NATIVES(server, {
|
||||
ScriptEngine::RegisterNativeHandler("GET_ECON_ITEM_SYSTEM", GetEconItemSystem);
|
||||
ScriptEngine::RegisterNativeHandler("IS_SERVER_PAUSED", IsServerPaused);
|
||||
})
|
||||
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
GET_ECON_ITEM_SYSTEM: -> pointer
|
||||
GET_ECON_ITEM_SYSTEM: -> pointer
|
||||
IS_SERVER_PAUSED: -> bool
|
||||
Reference in New Issue
Block a user