mirror of
https://github.com/roflmuffin/CounterStrikeSharp.git
synced 2025-12-06 16:06:37 -08:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
319b116c5f | ||
|
|
e0dc053d22 | ||
|
|
f2e0dac32d |
@@ -152,17 +152,7 @@ namespace CounterStrikeSharp.API.Core
|
||||
true);
|
||||
break;
|
||||
}
|
||||
|
||||
var plugin = _pluginContextQueryHandler.FindPluginByModulePath(info.GetArg(2));
|
||||
|
||||
if (plugin == null)
|
||||
{
|
||||
info.ReplyToCommand("Could not find plugin to load.");
|
||||
break;
|
||||
}
|
||||
|
||||
plugin.Load(false);
|
||||
|
||||
|
||||
// If our arugment doesn't end in ".dll" - try and construct a path similar to PluginName/PluginName.dll.
|
||||
// We'll assume we have a full path if we have ".dll".
|
||||
var path = info.GetArg(2);
|
||||
@@ -175,15 +165,23 @@ namespace CounterStrikeSharp.API.Core
|
||||
path = Path.Combine(_scriptHostConfiguration.RootPath, path);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// LoadPlugin(path);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogError(e, "Failed to load plugin from {Path}", path);
|
||||
}
|
||||
var plugin = _pluginContextQueryHandler.FindPluginByModulePath(path);
|
||||
|
||||
if (plugin == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
_pluginManager.LoadPlugin(path);
|
||||
} catch (Exception e)
|
||||
{
|
||||
info.ReplyToCommand($"Could not load plugin \"{path}\")", true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
plugin.Load(false);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,5 +5,6 @@ namespace CounterStrikeSharp.API.Core.Plugin.Host;
|
||||
public interface IPluginManager
|
||||
{
|
||||
public void Load();
|
||||
public void LoadPlugin(string path);
|
||||
public IEnumerable<PluginContext> GetLoadedPlugins();
|
||||
}
|
||||
@@ -45,7 +45,7 @@ public class PluginManager : IPluginManager
|
||||
return _loadedPluginContexts;
|
||||
}
|
||||
|
||||
private void LoadPlugin(string path)
|
||||
public void LoadPlugin(string path)
|
||||
{
|
||||
var plugin = new PluginContext(_serviceProvider, _scriptHostConfiguration, path, _loadedPluginContexts.Select(x => x.PluginId).DefaultIfEmpty(0).Max() + 1);
|
||||
_loadedPluginContexts.Add(plugin);
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using CounterStrikeSharp.API.Modules.Commands.Targeting;
|
||||
|
||||
namespace CounterStrikeSharp.API.Modules.Commands;
|
||||
|
||||
public static class CommandExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Treats the argument at the specified index as a target string (@all, @me etc.) and returns the result.
|
||||
/// </summary>
|
||||
public static TargetResult GetArgTargetResult(this CommandInfo commandInfo, int index)
|
||||
{
|
||||
return new Target(commandInfo.GetArg(index)).GetTarget(commandInfo.CallingPlayer);
|
||||
}
|
||||
}
|
||||
@@ -25,13 +25,14 @@ namespace CounterStrikeSharp.API.Modules.Commands
|
||||
|
||||
public delegate HookResult CommandListenerCallback(CCSPlayerController? player, CommandInfo commandInfo);
|
||||
|
||||
private CCSPlayerController _player;
|
||||
public IntPtr Handle { get; private set; }
|
||||
public CCSPlayerController? CallingPlayer { get; }
|
||||
|
||||
public IntPtr Handle { get; }
|
||||
|
||||
internal CommandInfo(IntPtr pointer, CCSPlayerController player)
|
||||
{
|
||||
Handle = pointer;
|
||||
_player = player;
|
||||
CallingPlayer = player;
|
||||
}
|
||||
|
||||
public int ArgCount => NativeAPI.CommandGetArgCount(Handle);
|
||||
@@ -42,12 +43,12 @@ namespace CounterStrikeSharp.API.Modules.Commands
|
||||
|
||||
public string ArgByIndex(int index) => NativeAPI.CommandGetArgByIndex(Handle, index);
|
||||
public string GetArg(int index) => NativeAPI.CommandGetArgByIndex(Handle, index);
|
||||
|
||||
|
||||
public void ReplyToCommand(string message, bool console = false) {
|
||||
if (_player != null)
|
||||
if (CallingPlayer != null)
|
||||
{
|
||||
if (console) { _player.PrintToConsole(message); }
|
||||
else _player.PrintToChat(message);
|
||||
if (console) { CallingPlayer.PrintToConsole(message); }
|
||||
else CallingPlayer.PrintToChat(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
|
||||
namespace CounterStrikeSharp.API.Modules.Commands.Targeting;
|
||||
|
||||
public class Target
|
||||
{
|
||||
private TargetType Type { get; }
|
||||
private string Raw { get; }
|
||||
private string Slug { get; }
|
||||
|
||||
private static readonly Dictionary<string, TargetType> TargetTypeMap = new(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "@all", TargetType.GroupAll },
|
||||
{ "@bots", TargetType.GroupBots },
|
||||
{ "@human", TargetType.GroupHumans },
|
||||
{ "@alive", TargetType.GroupAlive },
|
||||
{ "@dead", TargetType.GroupDead },
|
||||
{ "@!me", TargetType.GroupNotMe },
|
||||
{ "@me", TargetType.PlayerMe },
|
||||
{ "@ct", TargetType.TeamCt },
|
||||
{ "@t", TargetType.TeamT },
|
||||
{ "@spec", TargetType.TeamSpec }
|
||||
};
|
||||
|
||||
|
||||
private static bool ConstTargetType(string target, out TargetType targetType)
|
||||
{
|
||||
targetType = TargetType.Invalid;
|
||||
if (!target.StartsWith("@"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return TargetTypeMap.TryGetValue(target, out targetType);
|
||||
}
|
||||
|
||||
private bool IdTargetType(string target,
|
||||
out TargetType targetType,
|
||||
[MaybeNullWhen(false)] out string slug)
|
||||
{
|
||||
targetType = TargetType.Invalid;
|
||||
slug = null!;
|
||||
if (!target.StartsWith("#"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
slug = target.TrimStart('#');
|
||||
if (slug.StartsWith("STEAM")) targetType = TargetType.IdSteamEscaped;
|
||||
else if (!ulong.TryParse(slug, out _)) targetType = TargetType.ExplicitName;
|
||||
else if (slug.Length == 17) targetType = TargetType.IdSteam64;
|
||||
else targetType = TargetType.IdUserid;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public Target(string target)
|
||||
{
|
||||
Raw = target.Trim();
|
||||
if (ConstTargetType(Raw, out var targetType))
|
||||
{
|
||||
Type = targetType;
|
||||
Slug = Raw;
|
||||
}
|
||||
else if (IdTargetType(Raw, out targetType, out var slug))
|
||||
{
|
||||
Type = targetType;
|
||||
Slug = slug;
|
||||
}
|
||||
else
|
||||
{
|
||||
Type = TargetType.ImplicitName;
|
||||
Slug = Raw;
|
||||
}
|
||||
}
|
||||
|
||||
private bool TargetPredicate(CCSPlayerController player, CCSPlayerController? caller)
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
case TargetType.TeamCt:
|
||||
return player.TeamNum == (byte)CsTeam.CounterTerrorist;
|
||||
case TargetType.TeamT:
|
||||
return player.TeamNum == (byte)CsTeam.Terrorist;
|
||||
case TargetType.TeamSpec:
|
||||
return player.TeamNum == (byte)CsTeam.Spectator;
|
||||
case TargetType.GroupAll:
|
||||
return true;
|
||||
case TargetType.GroupBots:
|
||||
return player.IsBot;
|
||||
case TargetType.GroupHumans:
|
||||
return !player.IsBot;
|
||||
case TargetType.GroupAlive:
|
||||
return player.PlayerPawn is { IsValid: true, Value.LifeState: (byte)LifeState_t.LIFE_ALIVE };
|
||||
case TargetType.GroupDead:
|
||||
return player.PlayerPawn is { IsValid: true, Value.LifeState: (byte)LifeState_t.LIFE_DEAD or (byte)LifeState_t.LIFE_DYING };
|
||||
case TargetType.GroupNotMe:
|
||||
return player.SteamID != caller?.SteamID;
|
||||
case TargetType.PlayerMe:
|
||||
return player.SteamID == caller?.SteamID;
|
||||
case TargetType.IdUserid:
|
||||
return player.UserId.ToString() == Slug;
|
||||
case TargetType.IdSteamEscaped:
|
||||
return ((SteamID)player.SteamID).SteamId2 == Slug;
|
||||
case TargetType.IdSteam64:
|
||||
return ((SteamID)player.SteamID).SteamId64.ToString() == Slug;
|
||||
case TargetType.ExplicitName:
|
||||
case TargetType.ImplicitName:
|
||||
return player.PlayerName.Contains(Slug, StringComparison.OrdinalIgnoreCase);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public TargetResult GetTarget(CCSPlayerController? caller)
|
||||
{
|
||||
var players = Utilities.GetPlayers().Where(player => TargetPredicate(player, caller)).ToList();
|
||||
|
||||
return new TargetResult() { Players = players };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace CounterStrikeSharp.API.Modules.Commands.Targeting;
|
||||
|
||||
public class TargetResult : IEnumerable<CCSPlayerController>
|
||||
{
|
||||
public List<CCSPlayerController> Players { get; set; } = new();
|
||||
|
||||
public IEnumerator<CCSPlayerController> GetEnumerator()
|
||||
{
|
||||
return Players.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
namespace CounterStrikeSharp.API.Modules.Commands.Targeting;
|
||||
|
||||
public enum TargetType
|
||||
{
|
||||
TeamCt, // @ct
|
||||
TeamT, // @t
|
||||
TeamSpec, // @spec
|
||||
|
||||
GroupAll, // @all
|
||||
GroupBots, // @bots
|
||||
GroupHumans, // @human
|
||||
GroupAlive, // @alive
|
||||
GroupDead, // @dead
|
||||
GroupNotMe, // @!me
|
||||
|
||||
PlayerMe, // @me
|
||||
|
||||
IdUserid, // #4
|
||||
IdSteamEscaped, // "#STEAM_0:1:8614"
|
||||
IdSteam64, // #76561198116940237
|
||||
|
||||
ExplicitName, // #name
|
||||
ImplicitName, // name
|
||||
Invalid
|
||||
}
|
||||
@@ -43,10 +43,11 @@ namespace CounterStrikeSharp.API.Modules.Config
|
||||
{
|
||||
string directoryPath = Path.Combine(_pluginConfigsFolderPath, pluginName);
|
||||
string configPath = Path.Combine(directoryPath, $"{pluginName}.json");
|
||||
string exampleConfigPath = Path.Combine(directoryPath, $"{pluginName}.example.json");
|
||||
|
||||
T config = (T)Activator.CreateInstance(typeof(T))!;
|
||||
|
||||
if (!File.Exists(configPath))
|
||||
if (!File.Exists(configPath) && !File.Exists(exampleConfigPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -56,8 +57,10 @@ namespace CounterStrikeSharp.API.Modules.Config
|
||||
}
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.Append($"// This configuration was automatically generated by CounterStrikeSharp for plugin '{pluginName}', at {DateTimeOffset.Now:yyyy/MM/dd hh:mm:ss}\n");
|
||||
builder.Append(JsonSerializer.Serialize<T>(config, new JsonSerializerOptions { WriteIndented = true }));
|
||||
builder.Append(
|
||||
$"// This configuration was automatically generated by CounterStrikeSharp for plugin '{pluginName}', at {DateTimeOffset.Now:yyyy/MM/dd hh:mm:ss}\n");
|
||||
builder.Append(JsonSerializer.Serialize<T>(config,
|
||||
new JsonSerializerOptions { WriteIndented = true }));
|
||||
File.WriteAllText(configPath, builder.ToString());
|
||||
return config;
|
||||
}
|
||||
@@ -65,6 +68,17 @@ namespace CounterStrikeSharp.API.Modules.Config
|
||||
{
|
||||
_logger.LogError(ex, "Failed to generate configuration file for {PluginName}", pluginName);
|
||||
}
|
||||
} else if (File.Exists(exampleConfigPath) && !File.Exists(configPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("Copying example configuration file for {PluginName}", pluginName);
|
||||
File.Copy(exampleConfigPath, configPath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to copy example configuration file for {PluginName}", pluginName);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
|
||||
@@ -14,15 +14,14 @@
|
||||
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
|
||||
*/
|
||||
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Modules.Memory;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using CounterStrikeSharp.API.Modules.Commands.Targeting;
|
||||
|
||||
namespace CounterStrikeSharp.API
|
||||
{
|
||||
@@ -64,6 +63,16 @@ namespace CounterStrikeSharp.API
|
||||
return Utilities.GetEntityFromIndex<CCSPlayerController>((userid & 0xFF) + 1);
|
||||
}
|
||||
|
||||
public static CCSPlayerController? GetPlayerFromSteamId(ulong steamId)
|
||||
{
|
||||
return Utilities.GetPlayers().FirstOrDefault(player => player.SteamID == steamId);
|
||||
}
|
||||
|
||||
public static TargetResult ProcessTargetString(string pattern, CCSPlayerController player)
|
||||
{
|
||||
return new Target(pattern).GetTarget(player);
|
||||
}
|
||||
|
||||
public static IEnumerable<T> FindAllEntitiesByDesignerName<T>(string designerName) where T : CEntityInstance
|
||||
{
|
||||
var pEntity = new CEntityIdentity(NativeAPI.GetFirstActiveEntity());
|
||||
|
||||
@@ -344,6 +344,24 @@ namespace TestPlugin
|
||||
giveItemMenu.AddMenuOption("weapon_ak47", handleGive);
|
||||
giveItemMenu.AddMenuOption("weapon_p250", handleGive);
|
||||
|
||||
AddCommand("css_target", "Target Test", (player, info) =>
|
||||
{
|
||||
if (player == null) return;
|
||||
|
||||
var targetResult = info.GetArgTargetResult(1);
|
||||
|
||||
if (!targetResult.Any())
|
||||
{
|
||||
player.PrintToChat("No players found.");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var result in targetResult.Players)
|
||||
{
|
||||
player.PrintToChat($"Target found: {result?.PlayerName}");
|
||||
}
|
||||
});
|
||||
|
||||
AddCommand("css_menu", "Opens example menu", (player, info) => { ChatMenus.OpenMenu(player, largeMenu); });
|
||||
AddCommand("css_gunmenu", "Gun Menu", (player, info) => { ChatMenus.OpenMenu(player, giveItemMenu); });
|
||||
|
||||
|
||||
@@ -26,11 +26,22 @@ CCoreConfig::~CCoreConfig() = default;
|
||||
|
||||
bool CCoreConfig::Init(char* conf_error, int conf_error_size)
|
||||
{
|
||||
std::ifstream ifs(m_sPath);
|
||||
std::ifstream ifs(std::string(m_sPath + ".json"));
|
||||
|
||||
if (!ifs) {
|
||||
V_snprintf(conf_error, conf_error_size, "CoreConfig file not found.");
|
||||
return false;
|
||||
std::ifstream exampleIfs(std::string(m_sPath + ".example.json"));
|
||||
|
||||
if (!exampleIfs) {
|
||||
V_snprintf(conf_error, conf_error_size, "CoreConfig file not found.");
|
||||
return false;
|
||||
}
|
||||
|
||||
CSSHARP_CORE_INFO("CoreConfig file not found, creating one from example.");
|
||||
std::ofstream ofs(std::string(m_sPath + ".json"));
|
||||
ofs << exampleIfs.rdbuf();
|
||||
ofs.close();
|
||||
|
||||
return Init(conf_error, conf_error_size);
|
||||
}
|
||||
|
||||
m_json = json::parse(ifs);
|
||||
|
||||
@@ -84,7 +84,7 @@ bool CounterStrikeSharpMMPlugin::Load(PluginId id, ISmmAPI* ismm, char* error, s
|
||||
GET_V_IFACE_ANY(GetEngineFactory, globals::gameEventSystem, IGameEventSystem,
|
||||
GAMEEVENTSYSTEM_INTERFACE_VERSION);
|
||||
|
||||
auto coreconfig_path = std::string(utils::ConfigsDirectory() + "/core.json");
|
||||
auto coreconfig_path = std::string(utils::ConfigsDirectory() + "/core");
|
||||
globals::coreConfig = new CCoreConfig(coreconfig_path);
|
||||
char coreconfig_error[255] = "";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user