Compare commits

...

6 Commits
v24 ... v1.0.29

Author SHA1 Message Date
Nexd
2c4e9bca42 Small adjustments (#56) 2023-11-11 09:50:54 +10:00
Roflmuffin
8f3e0c226b docs: add information about flags and standard flags 2023-11-11 01:42:57 +10:00
Roflmuffin
5f6ccf2839 feat: change color marshalling to ABGR (tested against render color) 2023-11-11 00:05:13 +10:00
Roflmuffin
6c2f56793b hotfix: con command hot reload failing 2023-11-10 23:51:18 +10:00
Roflmuffin
cc7dd5ca96 ci: I have the utmost confidence 2023-11-10 20:16:04 +10:00
Roflmuffin
ebc361b2f8 ci: publish to api.nuget.org 2023-11-10 20:05:52 +10:00
8 changed files with 116 additions and 90 deletions

View File

@@ -94,6 +94,5 @@ jobs:
- name: Publish NuGet package
run: |
dotnet nuget add source --username USERNAME --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/NAMESPACE/index.json"
dotnet nuget push managed/CounterStrikeSharp.API/bin/Release/CounterStrikeSharp.API.1.0.${{ env.BUILD_NUMBER }}.nupkg --source "github" --skip-duplicate
dotnet nuget push managed/CounterStrikeSharp.API/bin/Release/CounterStrikeSharp.API.1.0.${{ env.BUILD_NUMBER }}.snupkg --source "github" --skip-duplicate
dotnet nuget push managed/CounterStrikeSharp.API/bin/Release/CounterStrikeSharp.API.1.0.${{ env.BUILD_NUMBER }}.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
dotnet nuget push managed/CounterStrikeSharp.API/bin/Release/CounterStrikeSharp.API.1.0.${{ env.BUILD_NUMBER }}.snupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate

View File

@@ -2,14 +2,26 @@
"Erikj": {
"identity": "76561197960265731",
"flags": [
"@css/reservation",
"@css/generic",
"@css/kick",
"@css/ban"
"@css/ban",
"@css/unban",
"@css/vip",
"@css/slay",
"@css/changemap",
"@css/cvar",
"@css/config",
"@css/chat",
"@css/vote",
"@css/password",
"@css/rcon",
"@css/cheats",
"@css/root"
]
},
"Another erikj": {
"identity": "STEAM_0:1:1",
"flags": [
"@anotherscope/foobar"
]
"flags": ["@mycustomplugin/admin"]
}
}
}

View File

@@ -15,7 +15,7 @@ Adding an Admin is as simple as creating a new entry in the `configs/admins.json
{
"ZoNiCaL": {
"identity": "76561198808392634",
"flags": ["can_manipulate_players", "admin_messages"]
"flags": ["@css/changemap", "@css/generic"]
}
}
```
@@ -27,7 +27,7 @@ You can also manually assign permissions to players in code with `AddPlayerPermi
Assigning permissions to a Command is as easy as tagging the Command method (function callback) with a `RequiresPermissions` attribute.
```csharp
[RequiresPermissions("can_execute_test_command", "other_permission")]
[RequiresPermissions("@css/slay", "@custom/permission")]
public void OnMyCommand(CCSPlayerController? caller, CommandInfo info)
{
...
@@ -35,3 +35,28 @@ public void OnMyCommand(CCSPlayerController? caller, CommandInfo info)
```
CounterStrikeSharp handles all of the permission checks behind the scenes for you.
### Standard Permissions
Because the flag system is just a list of strings associated with a user, there is no real list of letter based flags like there was previously in something like SourceMod. This means as a plugin author you can declare your own flags, scoped with an `@` symbol, like `@roflmuffin/guns`, which might be the permission to allow spawning of guns in a given command.
However there is a somewhat standardised list of flags that it is advised you use if you are adding functionality that aligns with their purpose, and these are based on the original SourceMod flags:
```shell
@css/reservation # Reserved slot access.
@css/generic # Generic admin.
@css/kick # Kick other players.
@css/ban # Ban other players.
@css/unban # Remove bans.
@css/vip # General vip status.
@css/slay # Slay/harm other players.
@css/changemap # Change the map or major gameplay features.
@css/cvar # Change most cvars.
@css/config # Execute config files.
@css/chat # Special chat privileges.
@css/vote # Start or create votes.
@css/password # Set a password on the server.
@css/rcon # Use RCON commands.
@css/cheats # Change sv_cheats or use cheating commands.
@css/root # Magically enables all flags and ignores immunity values.
```

View File

@@ -1,26 +0,0 @@
/*
* 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/>. *
*/
using CounterStrikeSharp.API.Modules.Memory;
namespace CounterStrikeSharp.API.Core;
public partial class CGlowProperty
{
// m_bGlowing
public ref bool IsGlowing => ref Schema.GetRef<bool>(this.Handle, "CGlowProperty", "m_bGlowing");
}

View File

@@ -20,11 +20,16 @@ public class ColorMarshaler : ICustomMarshal<Color>
{
public Color NativeToManaged(IntPtr pointer)
{
return Color.FromArgb(Marshal.ReadInt32(pointer));
var color = Marshal.ReadInt32(pointer);
var alpha = (byte)((color >> 24) & 0xFF);
var blue = (byte)((color >> 16) & 0xFF);
var green = (byte)((color >> 8) & 0xFF);
var red = (byte)(color & 0xFF);
return Color.FromArgb(alpha, red, green, blue);
}
public void ManagedToNative(IntPtr pointer, Color managedObj)
{
Marshal.WriteInt32(pointer, managedObj.ToArgb());
Marshal.WriteInt32(pointer, (managedObj.A << 24) | (managedObj.B << 16) | (managedObj.G << 8) | managedObj.R);
}
}

View File

@@ -155,10 +155,11 @@ CON_COMMAND(dump_schema, "dump schema symbols")
output << std::setw(2) << j << std::endl;
}
SH_DECL_HOOK2_void(
ConCommandHandle, Dispatch, SH_NOATTRIB, false, const CCommandContext&, const CCommand&);
SH_DECL_HOOK2_void(ConCommandHandle, Dispatch, SH_NOATTRIB, false, const CCommandContext&,
const CCommand&);
void ConCommandInfo::HookChange(CallbackT cb, bool post) {
void ConCommandInfo::HookChange(CallbackT cb, bool post)
{
if (post) {
this->callback_post->AddListener(cb);
} else {
@@ -166,7 +167,8 @@ void ConCommandInfo::HookChange(CallbackT cb, bool post) {
}
}
void ConCommandInfo::UnhookChange(CallbackT cb, bool post) {
void ConCommandInfo::UnhookChange(CallbackT cb, bool post)
{
if (post) {
if (this->callback_post && this->callback_post->GetFunctionCount()) {
callback_post->RemoveListener(cb);
@@ -178,8 +180,7 @@ void ConCommandInfo::UnhookChange(CallbackT cb, bool post) {
}
}
ConCommandManager::ConCommandManager()
: last_command_client(-1) {}
ConCommandManager::ConCommandManager() : last_command_client(-1) {}
ConCommandManager::~ConCommandManager() {}
@@ -187,16 +188,17 @@ void ConCommandManager::OnAllInitialized() {}
void ConCommandManager::OnShutdown() {}
void CommandCallback(const CCommandContext& context, const CCommand& command) {
bool rval = globals::conCommandManager.InternalDispatch(
context.GetPlayerSlot(), &command);
void CommandCallback(const CCommandContext& context, const CCommand& command)
{
bool rval = globals::conCommandManager.InternalDispatch(context.GetPlayerSlot(), &command);
if (rval) {
RETURN_META(MRES_SUPERCEDE);
}
}
void CommandCallback_Post(const CCommandContext& context, const CCommand& command) {
void CommandCallback_Post(const CCommandContext& context, const CCommand& command)
{
bool rval = globals::conCommandManager.InternalDispatch_Post(context.GetPlayerSlot(), &command);
if (rval) {
@@ -204,14 +206,14 @@ void CommandCallback_Post(const CCommandContext& context, const CCommand& comman
}
}
ConCommandInfo* ConCommandManager::AddOrFindCommand(const char* name,
const char* description,
bool server_only,
int flags) {
ConCommandInfo* ConCommandManager::AddOrFindCommand(const char* name, const char* description,
bool server_only, int flags)
{
ConCommandInfo* p_info = m_cmd_lookup[std::string(name)];
if (!p_info) {
CSSHARP_CORE_TRACE("[ConCommandManager] Could not find command in existing lookup {}", name);
CSSHARP_CORE_TRACE("[ConCommandManager] Could not find command in existing lookup {}",
name);
// auto found = std::find_if(m_cmd_list.begin(), m_cmd_list.end(),
// [&](ConCommandInfo* info) {
// return V_strcasecmp(info->command->GetName(), name) == 0;
@@ -234,11 +236,13 @@ ConCommandInfo* ConCommandManager::AddOrFindCommand(const char* name,
char* new_name = strdup(name);
char* new_desc = strdup(description);
CSSHARP_CORE_TRACE("[ConCommandManager] Creating new command {}, {}, {}, {}, {}", (void*)&pointerConCommand, new_name, (void*)CommandCallback, new_desc, flags);
CSSHARP_CORE_TRACE("[ConCommandManager] Creating new command {}, {}, {}, {}, {}",
(void*)&pointerConCommand, new_name, (void*)CommandCallback,
new_desc, flags);
auto conCommand =
new ConCommand(&pointerConCommand, new_name, CommandCallback, new_desc, flags);
CSSHARP_CORE_TRACE("[ConCommandManager] Creating callbacks for command {}", name);
p_info->command = conCommand;
@@ -246,24 +250,22 @@ ConCommandInfo* ConCommandManager::AddOrFindCommand(const char* name,
p_info->callback_post = globals::callbackManager.CreateCallback(name);
p_info->server_only = server_only;
CSSHARP_CORE_TRACE("[ConCommandManager] Adding hooks for command callback for command {}", name);
CSSHARP_CORE_TRACE(
"[ConCommandManager] Adding hooks for command callback for command {}", name);
SH_ADD_HOOK(ConCommandHandle, Dispatch, &pointerConCommand.handle, SH_STATIC(CommandCallback), false);
SH_ADD_HOOK(ConCommandHandle, Dispatch, &pointerConCommand.handle, SH_STATIC(CommandCallback_Post), true);
SH_ADD_HOOK(ConCommandHandle, Dispatch, &pointerConCommand.handle,
SH_STATIC(CommandCallback), false);
SH_ADD_HOOK(ConCommandHandle, Dispatch, &pointerConCommand.handle,
SH_STATIC(CommandCallback_Post), true);
CSSHARP_CORE_TRACE("[ConCommandManager] Adding command to internal lookup {}", name);
m_cmd_list.push_back(p_info);
m_cmd_lookup[name] = p_info;
} else {
// p_info->callback_pre = globals::callbackManager.CreateCallback(name);
// p_info->callback_post = globals::callbackManager.CreateCallback(name);
// p_info->server_only = server_only;
//
// SH_ADD_HOOK(ConCommandHandle, Dispatch, pointerConCommand->handle,
// SH_STATIC(CommandCallback), false); SH_ADD_HOOK(ConCommandHandle,
// Dispatch, pointerConCommand->handle, SH_STATIC(CommandCallback_Post),
// true);
p_info->callback_pre = globals::callbackManager.CreateCallback(name);
p_info->callback_post = globals::callbackManager.CreateCallback(name);
p_info->server_only = server_only;
}
return p_info;
@@ -272,8 +274,9 @@ ConCommandInfo* ConCommandManager::AddOrFindCommand(const char* name,
return p_info;
}
ConCommandInfo* ConCommandManager::AddCommand(
const char* name, const char* description, bool server_only, int flags, CallbackT callback) {
ConCommandInfo* ConCommandManager::AddCommand(const char* name, const char* description,
bool server_only, int flags, CallbackT callback)
{
ConCommandInfo* p_info = AddOrFindCommand(name, description, server_only, flags);
if (!p_info || !p_info->callback_pre) {
return nullptr;
@@ -284,10 +287,12 @@ ConCommandInfo* ConCommandManager::AddCommand(
return p_info;
}
bool ConCommandManager::RemoveCommand(const char* name, CallbackT callback) {
bool ConCommandManager::RemoveCommand(const char* name, CallbackT callback)
{
auto strName = std::string(strdup(name));
ConCommandInfo* p_info = m_cmd_lookup[strName];
if (!p_info) return false;
if (!p_info)
return false;
if (p_info->callback_pre && p_info->callback_pre->GetFunctionCount()) {
p_info->callback_pre->RemoveListener(callback);
@@ -304,10 +309,10 @@ bool ConCommandManager::RemoveCommand(const char* name, CallbackT callback) {
auto it = std::remove_if(m_cmd_list.begin(), m_cmd_list.end(),
[p_info](ConCommandInfo* i) { return p_info == i; });
if ((success = it != m_cmd_list.end())) m_cmd_list.erase(it, m_cmd_list.end());
// if (success) {
// m_cmd_lookup[strName] = nullptr;
// }
if ((success = it != m_cmd_list.end()))
m_cmd_list.erase(it, m_cmd_list.end());
if (success)
m_cmd_lookup[std::string(name)] = nullptr;
return success;
}
@@ -315,7 +320,8 @@ bool ConCommandManager::RemoveCommand(const char* name, CallbackT callback) {
return true;
}
ConCommandInfo* ConCommandManager::FindCommand(const char* name) {
ConCommandInfo* ConCommandManager::FindCommand(const char* name)
{
ConCommandInfo* p_info = m_cmd_lookup[std::string(name)];
if (p_info == nullptr) {
@@ -327,7 +333,8 @@ ConCommandInfo* ConCommandManager::FindCommand(const char* name) {
}
ConCommandHandle p_cmd = globals::cvars->FindCommand(name);
if (!p_cmd.IsValid()) return nullptr;
if (!p_cmd.IsValid())
return nullptr;
p_info = new ConCommandInfo();
p_info->command = globals::cvars->GetCommand(p_cmd);
@@ -350,12 +357,14 @@ int ConCommandManager::GetCommandClient() { return last_command_client; }
void ConCommandManager::SetCommandClient(int client) { last_command_client = client + 1; }
bool ConCommandManager::InternalDispatch(CPlayerSlot slot, const CCommand* args) {
bool ConCommandManager::InternalDispatch(CPlayerSlot slot, const CCommand* args)
{
const char* cmd = args->Arg(0);
ConCommandInfo* p_info = m_cmd_lookup[cmd];
if (p_info == nullptr) {
if (slot.Get() == 0 && !globals::engine->IsDedicatedServer()) return false;
if (slot.Get() == 0 && !globals::engine->IsDedicatedServer())
return false;
for (ConCommandInfo* cmdInfo : m_cmd_list) {
if ((cmdInfo != nullptr) && strcasecmp(cmdInfo->command->GetName(), cmd) == 0) {
@@ -384,12 +393,14 @@ bool ConCommandManager::InternalDispatch(CPlayerSlot slot, const CCommand* args)
return result;
}
bool ConCommandManager::InternalDispatch_Post(CPlayerSlot slot, const CCommand* args) {
bool ConCommandManager::InternalDispatch_Post(CPlayerSlot slot, const CCommand* args)
{
const char* cmd = args->Arg(0);
ConCommandInfo* p_info = m_cmd_lookup[cmd];
if (p_info == nullptr) {
if (slot.Get() == 0 && !globals::engine->IsDedicatedServer()) return false;
if (slot.Get() == 0 && !globals::engine->IsDedicatedServer())
return false;
for (ConCommandInfo* cmdInfo : m_cmd_list) {
if ((cmdInfo != nullptr) && strcasecmp(cmdInfo->command->GetName(), cmd) == 0) {
@@ -414,9 +425,9 @@ bool ConCommandManager::InternalDispatch_Post(CPlayerSlot slot, const CCommand*
return result;
}
bool ConCommandManager::DispatchClientCommand(CPlayerSlot slot,
const char* cmd,
const CCommand* args) {
bool ConCommandManager::DispatchClientCommand(CPlayerSlot slot, const char* cmd,
const CCommand* args)
{
ConCommandInfo* p_info = m_cmd_lookup[cmd];
if (p_info == nullptr) {
auto found =
@@ -430,7 +441,8 @@ bool ConCommandManager::DispatchClientCommand(CPlayerSlot slot,
p_info = *found;
}
if (p_info->server_only) return false;
if (p_info->server_only)
return false;
bool result = false;
if (p_info->callback_pre) {
@@ -455,4 +467,4 @@ bool ConCommandManager::DispatchClientCommand(CPlayerSlot slot,
return result;
}
} // namespace counterstrikesharp
} // namespace counterstrikesharp

View File

@@ -0,0 +1,4 @@
OnServerHibernationUpdate: isHibernating:bool
OnGameServerSteamAPIActivated:
OnGameServerSteamAPIDeactivated:
OnHostNameChanged: hostname:string

View File

@@ -37,11 +37,6 @@ static ConCommandInfo* AddCommand(ScriptContext& script_context)
CSSHARP_CORE_TRACE("Adding command {}, {}, {}, {}, {}", name, description, server_only, flags,
(void*)callback);
if (globals::conCommandManager.FindCommand(name)) {
script_context.ThrowNativeError("Failed to add command \"%s\", command already exists.", name);
return nullptr;
}
return globals::conCommandManager.AddCommand(name, description, server_only, flags, callback);
}