C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
// Requires: Guardian
using Newtonsoft.Json;
using Oxide.Core.Plugins;
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Oxide.Plugins {
[Info("Guardian ADR", "Rockioux", "1.0.2")]
[Description("Starts demo recordings on Guardian Violations.")]
class GuardianADR : CovalencePlugin {
#region Config Classes
private class GuardianADRConfig {
[JsonProperty(PropertyName = "Gravity Violation Demo Config")]
public HookConfig GravityHookConfig {
get;
set;
}
= new HookConfig(true);
[JsonProperty(PropertyName = "Melee Rate Violation Demo Config")]
public HookConfig MeleeRateConfig {
get;
set;
}
= new HookConfig(true);
[JsonProperty(PropertyName = "NoClip Violation Demo Config")]
public HookConfig NoClipConfig {
get;
set;
}
= new HookConfig(false);
[JsonProperty(PropertyName = "InsideTerrain Violation Demo Config")]
public HookConfig InsideTerrainConfig {
get;
set;
}
= new HookConfig(false);
}
private class HookConfig {
[JsonProperty(PropertyName = "Enable Demo Recordings for this hook")]
public bool HookEnabled {
get;
set;
}
[JsonProperty(PropertyName = "Demo Duration in minutes")]
public int DemoDuration {
get;
set;
}
= 2;
[JsonProperty(PropertyName = "Discord Webhook")]
public string DiscordWebhook {
get;
set;
}
= "";
public HookConfig() {
}
public HookConfig(bool enabled) {
HookEnabled = enabled;
}
}
#endregion // Config Classes
#region Fields
[PluginReference]
private Plugin AutoDemoRecord;
private GuardianADRConfig _config;
#endregion // Fields
#region Covalence Plugin Implemented Members
private void Init() {
if(!_config.GravityHookConfig.HookEnabled) {
Unsubscribe(nameof(OnGuardianAntiCheatGravity));
}
if (!_config.MeleeRateConfig.HookEnabled) {
Unsubscribe(nameof(OnGuardianAntiCheatMeleeRate));
}
if(!_config.NoClipConfig.HookEnabled && !_config.InsideTerrainConfig.HookEnabled) {
Unsubscribe(nameof(OnGuardianServer));
}
}
protected override void LoadConfig() {
base.LoadConfig();
_config = Config.ReadObject<GuardianADRConfig>();
SaveConfig();
}
protected override void SaveConfig() => Config.WriteObject(_config);
protected override void LoadDefaultConfig() {
_config = new GuardianADRConfig();
}
#endregion // Covalence Plugin Implemented Members
#region Guardian Hooks
private void OnGuardianAntiCheatGravity(string playerID, Dictionary<string, string> details) {
try {
BasePlayer player;
if (!GetBasePlayer(playerID, out player)) {
return;
}
// Check if already recording
if (player.Connection.IsRecording) {
return;
}
Vector3 pos = player.transform.position;
string message = $"{player.displayName} ({playerID}) is defying gravity!\n\nElevation: {details["elevation"]}\nMovement speed: {details["movement_speed"]}\nViolation: {details["violation_id"]}\nPosition: teleportpos {pos.x}, {pos.y}, {pos.z}";
AutoDemoRecord?.Call("API_StartRecording4", player, message, _config.GravityHookConfig.DemoDuration, _config.GravityHookConfig.DiscordWebhook);
}
catch(Exception ex) {
LogError(ex.ToString());
}
}
private void OnGuardianAntiCheatMeleeRate(string playerID, Dictionary<string, string> details) {
try {
BasePlayer player;
if (!GetBasePlayer(playerID, out player)) {
return;
}
// Check if already recording
if (player.Connection.IsRecording) {
return;
}
string message = $"{player.displayName} ({playerID}) is meleeing too fast!\n\nWeapon Type: {details["weapon_type"]}\nMovement speed: {details["movement_speed"]}\nRate Percentage: {details["rate_percent"]}%\nViolation: {details["violation_id"]}";
AutoDemoRecord?.Call("API_StartRecording4", player, message, _config.MeleeRateConfig.DemoDuration, _config.MeleeRateConfig.DiscordWebhook);
}
catch(Exception ex) {
LogError(ex.ToString());
}
}
private void OnGuardianServer(string playerID, Dictionary<string, string> details) {
try {
AntiHackType antihackType = (AntiHackType)Enum.Parse(typeof(AntiHackType), details["antihack_type"]);
if ((antihackType != AntiHackType.NoClip || !_config.NoClipConfig.HookEnabled) && (antihackType != AntiHackType.InsideTerrain || !_config.InsideTerrainConfig.HookEnabled)) {
return;
}
BasePlayer player;
if (!GetBasePlayer(playerID, out player)) {
return;
}
// Check if already recording
if (player.Connection.IsRecording) {
return;
}
Vector3 pos = player.transform.position;
HookConfig config = antihackType == AntiHackType.NoClip ? _config.NoClipConfig : _config.InsideTerrainConfig;
string actionStr = antihackType == AntiHackType.NoClip ? "no clipping" : "inside terrain";
string message = $"{player.displayName} ({playerID}) is {actionStr}!\n\nViolation: {details["violation_id"]}\nPosition: teleportpos {pos.x}, {pos.y}, {pos.z}";
AutoDemoRecord?.Call("API_StartRecording4", player, message, config.DemoDuration, config.DiscordWebhook);
}
catch(Exception ex) {
LogError(ex.ToString());
}
}
#endregion // Guardian Hooks
#region Helper Methods
private bool GetBasePlayer(string playerID, out BasePlayer player) {
player = null;
ulong steamID;
if (!ulong.TryParse(playerID, out steamID)) {
LogError($"Unexpected error.Could not parse player steam id {playerID}.");
return false;
}
player = BasePlayer.FindByID(steamID);
if (player == null) {
LogError($"Unexpected error.Player with steam id {playerID} was not found.");
return false;
}
return true;
}
#endregion // Helper Methods
}
}