C#:
using System;
using System.Runtime.CompilerServices;
using System.Collections.Generic;
using System.Text;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins {
[Info("ECAntiCheat", "Ezov", "1.0.8")]
[Description("Anticheat plugin with configurable detection flags")]
class ECAntiCheat : RustPlugin {
#region Configuration
private Configuration config;
public class Configuration {
[Newtonsoft.Json.JsonProperty("OmniSprint Detection (sprint speed without forward key)")]
public OmniSprintConfig OmniSprint {
get;
set;
}
= new OmniSprintConfig();
[Newtonsoft.Json.JsonProperty("CopterShoot Detection (shooting from driver seat)")]
public CopterShootConfig CopterShoot {
get;
set;
}
= new CopterShootConfig();
[Newtonsoft.Json.JsonProperty("JumpShoot Detection (shooting while airborne)")]
public JumpShootConfig JumpShoot {
get;
set;
}
= new JumpShootConfig();
[Newtonsoft.Json.JsonProperty("Manipulator Detection (wallshoot + rapidfire)")]
public ManipulatorConfig Manipulator {
get;
set;
}
= new ManipulatorConfig();
[Newtonsoft.Json.JsonProperty("SilentAim Detection (hit on player while not aiming at them)")]
public SilentAimConfig SilentAim {
get;
set;
}
= new SilentAimConfig();
[Newtonsoft.Json.JsonProperty("Discord Webhook")]
public DiscordConfig Discord {
get;
set;
}
= new DiscordConfig();
}
public class DiscordConfig {
[Newtonsoft.Json.JsonProperty("Enabled")]
public bool Enabled {
get;
set;
}
= false;
[Newtonsoft.Json.JsonProperty("Webhook URL")]
public string WebhookUrl {
get;
set;
}
= "";
[Newtonsoft.Json.JsonProperty("Embed color (decimal, e.g. 16711680 = red)")]
public int EmbedColor {
get;
set;
}
= 16711680;
[Newtonsoft.Json.JsonProperty("Send violation messages (every hit)")]
public bool SendViolations {
get;
set;
}
= true;
[Newtonsoft.Json.JsonProperty("Send action messages (threshold reached)")]
public bool SendActions {
get;
set;
}
= true;
}
public class SilentAimConfig {
[Newtonsoft.Json.JsonProperty("Enabled")]
public bool Enabled {
get;
set;
}
= true;
[Newtonsoft.Json.JsonProperty("Violations before action")]
public int ViolationsBeforeAction {
get;
set;
}
= 3;
[Newtonsoft.Json.JsonProperty("Action on detection (log / kick / ban)")]
public string Action {
get;
set;
}
= "log";
[Newtonsoft.Json.JsonProperty("Kick/Ban reason")]
public string Reason {
get;
set;
}
= "[ECAntiCheat] SilentAim detected";
[Newtonsoft.Json.JsonProperty("Minimum angle to flag (degrees). SilentAim typically 90-180deg. Recommended: 45")]
public float MinAngle {
get;
set;
}
= 45f;
[Newtonsoft.Json.JsonProperty("Reset violation counter after N seconds of no violations")]
public float ViolationResetSeconds {
get;
set;
}
= 10f;
}
public class OmniSprintConfig {
[Newtonsoft.Json.JsonProperty("Enabled")]
public bool Enabled {
get;
set;
}
= true;
[Newtonsoft.Json.JsonProperty("Violations before action")]
public int ViolationsBeforeAction {
get;
set;
}
= 15;
[Newtonsoft.Json.JsonProperty("Action on detection (log / kick / ban)")]
public string Action {
get;
set;
}
= "log";
[Newtonsoft.Json.JsonProperty("Kick/Ban reason")]
public string Reason {
get;
set;
}
= "[ECAntiCheat] OmniSprint detected";
[Newtonsoft.Json.JsonProperty("Minimum speed to trigger check (m/s)")]
public float MinSpeed {
get;
set;
}
= 4.5f;
[Newtonsoft.Json.JsonProperty("Consecutive suspicious ticks required (recommended 3-5)")]
public int ConsecutiveTicksRequired {
get;
set;
}
= 4;
[Newtonsoft.Json.JsonProperty("Reset violation counter after N seconds of no violations")]
public float ViolationResetSeconds {
get;
set;
}
= 8f;
}
public class CopterShootConfig {
[Newtonsoft.Json.JsonProperty("Enabled")]
public bool Enabled {
get;
set;
}
= true;
[Newtonsoft.Json.JsonProperty("Violations before action")]
public int ViolationsBeforeAction {
get;
set;
}
= 3;
[Newtonsoft.Json.JsonProperty("Action on detection (log / kick / ban)")]
public string Action {
get;
set;
}
= "log";
[Newtonsoft.Json.JsonProperty("Kick/Ban reason")]
public string Reason {
get;
set;
}
= "[ECAntiCheat] CopterShoot detected";
[Newtonsoft.Json.JsonProperty("Reset violation counter after N seconds of no violations")]
public float ViolationResetSeconds {
get;
set;
}
= 10f;
}
public class JumpShootConfig {
[Newtonsoft.Json.JsonProperty("Enabled")]
public bool Enabled {
get;
set;
}
= true;
[Newtonsoft.Json.JsonProperty("Violations before action")]
public int ViolationsBeforeAction {
get;
set;
}
= 5;
[Newtonsoft.Json.JsonProperty("Action on detection (log / kick / ban)")]
public string Action {
get;
set;
}
= "log";
[Newtonsoft.Json.JsonProperty("Kick/Ban reason")]
public string Reason {
get;
set;
}
= "[ECAntiCheat] JumpShoot detected";
[Newtonsoft.Json.JsonProperty("Reset violation counter after N seconds of no violations")]
public float ViolationResetSeconds {
get;
set;
}
= 10f;
[Newtonsoft.Json.JsonProperty("Minimum height above ground to count as airborne (meters)")]
public float MinAirborneHeight {
get;
set;
}
= 0.3f;
}
public class ManipulatorConfig {
[Newtonsoft.Json.JsonProperty("Enabled")]
public bool Enabled {
get;
set;
}
= true;
[Newtonsoft.Json.JsonProperty("Action on detection (log / kick / ban)")]
public string Action {
get;
set;
}
= "log";
[Newtonsoft.Json.JsonProperty("Kick/Ban reason")]
public string Reason {
get;
set;
}
= "[ECAntiCheat] Manipulator detected";
[Newtonsoft.Json.JsonProperty("Reset violation counter after N seconds of no violations")]
public float ViolationResetSeconds {
get;
set;
}
= 10f;
[Newtonsoft.Json.JsonProperty("--- WallShoot ---")]
public string _ws {
get;
set;
}
= "";
[Newtonsoft.Json.JsonProperty("WallShoot enabled")]
public bool WallShootEnabled {
get;
set;
}
= true;
[Newtonsoft.Json.JsonProperty("WallShoot violations before action")]
public int WallShootViolationsBeforeAction {
get;
set;
}
= 5;
[Newtonsoft.Json.JsonProperty("--- RapidFire ---")]
public string _rf {
get;
set;
}
= "";
[Newtonsoft.Json.JsonProperty("RapidFire enabled")]
public bool RapidFireEnabled {
get;
set;
}
= true;
[Newtonsoft.Json.JsonProperty("RapidFire violations before action")]
public int RapidFireViolationsBeforeAction {
get;
set;
}
= 5;
[Newtonsoft.Json.JsonProperty("RapidFire multiplier")]
public float RapidFireMultiplier {
get;
set;
}
= 0.65f;
}
protected override void LoadConfig() {
base.LoadConfig();
try {
config = Config.ReadObject<Configuration>();
if (config == null) LoadDefaultConfig();
}
catch {
PrintWarning("Invalid config, loading defaults.");
LoadDefaultConfig();
}
SaveConfig();
}
protected override void LoadDefaultConfig() => config = new Configuration();
protected override void SaveConfig() => Config.WriteObject(config, true);
#endregion
#region Data
private class PlayerData {
public Vector3 LastPosition;
public float LastTickTime;
public bool Initialized;
public int OmniSprintViolations;
public float LastOmniViolationTime;
public int OmniSprintConsecutiveTicks;
public int CopterShootViolations;
public float LastCopterViolationTime;
public int JumpShootViolations;
public float LastJumpViolationTime;
public int WallShootViolations;
public float LastWallShootViolationTime;
public int RapidFireViolations;
public float LastRapidFireViolationTime;
public float LastShotTime;
public int SilentAimViolations;
public float LastSilentAimViolationTime;
}
private readonly Dictionary<ulong, PlayerData> playerData = new Dictionary<ulong, PlayerData>();
#endregion
#region Plugin Lifecycle
private void OnServerInitialized() {
_Fo0xC2D3 = true;
foreach (BasePlayer p in BasePlayer.activePlayerList) Xm2C3D4(p);
Puts("ECAntiCheat v1.0.8 loaded.");
Puts(" OmniSprint: " + (config.OmniSprint.Enabled ? "ON" : "OFF"));
Puts(" CopterShoot: " + (config.CopterShoot.Enabled ? "ON" : "OFF"));
Puts(" JumpShoot: " + (config.JumpShoot.Enabled ? "ON" : "OFF"));
Puts(" Manipulator: " + (config.Manipulator.Enabled ? "ON" : "OFF") + " (WallShoot=" + (config.Manipulator.WallShootEnabled ? "ON" : "OFF") + " RapidFire=" + (config.Manipulator.RapidFireEnabled ? "ON" : "OFF") + ")");
Puts(" SilentAim: " + (config.SilentAim.Enabled ? "ON" : "OFF"));
}
private void Unload() {
}
private void OnPlayerConnected(BasePlayer player) => Xm2C3D4(player);
private void OnPlayerDisconnected(BasePlayer player, string reason) => playerData.Remove(player.userID);
private void Xm2C3D4(BasePlayer player) {
if (player == null) return;
playerData[player.userID] = new PlayerData {
LastPosition = player.transform.position, LastTickTime = Time.realtimeSinceStartup, LastShotTime = -999f
}
;
}
#endregion
#region Tick / OmniSprint
private void OnPlayerTick(BasePlayer player) {
if (player == null || !player.IsConnected || player.IsSleeping() || player.IsSpectating() || player.IsDead()) return;
if (!player.IsOnGround()) return;
PlayerData data;
if (!playerData.TryGetValue(player.userID, out data)) {
Xm2C3D4(player);
return;
}
float now = Time.realtimeSinceStartup;
float delta = now - data.LastTickTime;
if (!data.Initialized || delta <= 0f || delta > 1f) {
data.LastPosition = player.transform.position;
data.LastTickTime = now;
data.Initialized = true;
return;
}
Vector3 move = player.transform.position - data.LastPosition;
move.y = 0f;
float speed = move.magnitude / delta;
data.LastPosition = player.transform.position;
data.LastTickTime = now;
if (config.OmniSprint.Enabled) Xm5E6F7(player, data, speed);
}
private void Xm5E6F7(BasePlayer player, PlayerData data, float speed) {
if (speed < config.OmniSprint.MinSpeed) {
data.OmniSprintConsecutiveTicks = 0;
return;
}
if (player.serverInput.IsDown(BUTTON.FORWARD)) {
data.OmniSprintConsecutiveTicks = 0;
return;
}
if (++data.OmniSprintConsecutiveTicks < config.OmniSprint.ConsecutiveTicksRequired) return;
data.OmniSprintConsecutiveTicks = 0;
float now = Time.realtimeSinceStartup;
if (now - data.LastOmniViolationTime > config.OmniSprint.ViolationResetSeconds) data.OmniSprintViolations = 0;
data.OmniSprintViolations++;
data.LastOmniViolationTime = now;
bool back = player.serverInput.IsDown(BUTTON.BACKWARD);
bool left = player.serverInput.IsDown(BUTTON.LEFT);
bool rght = player.serverInput.IsDown(BUTTON.RIGHT);
bool none = !back && !left && !rght;
string keys = string.Format("[{0}{1}{2}{3}]", back?"S" : "", left?"A" : "", rght?"D" : "", none?"NONE" : "");
string details = string.Format(_Xs(new byte[] {
0x12, 0x7f, 0x46, 0xb3, 0xd8, 0xfd, 0x9b, 0x31, 0x71, 0x1, 0x67, 0x5d, 0xb8, 0x9a, 0xbe, 0xdf, 0x78, 0x50, 0x49, 0x22, 0x48, 0xbb, 0xd4, 0xef, 0x81, 0x34, 0xb, 0x35, 0x56, 0xfc, 0xae, 0xdb, 0xe2, 0x89, 0x22
}
, 0x4E), keys, speed, data.OmniSprintViolations, config.OmniSprint.ViolationsBeforeAction);
Puts(string.Format("[OmniSprint] {0} ({1}) {2}", player.displayName, player.userID, details));
Xm6A7B8(string.Format("<color=#ffaa00>[OmniSprint]</color> <color=#ffffff>{0}</color> ({1}) | {2}", player.displayName, player.userID, details));
if (data.OmniSprintViolations < config.OmniSprint.ViolationsBeforeAction) return;
data.OmniSprintViolations = 0;
Xm0C1D2(player, _Xs(new byte[] {
0xaf, 0xee, 0xc8, 0x30, 0x2f, 0x6f, 0x40, 0xbc, 0xa6, 0x9f
}
, 0xD7), config.OmniSprint.Action, config.OmniSprint.Reason);
}
#endregion
#region Weapon Fired
private void OnWeaponFired(BaseProjectile projectile, BasePlayer player, ItemModProjectile mod, ProtoBuf.ProjectileShoot projectiles) {
if (player == null || !player.IsConnected || player.IsDead()) return;
Xm1C2D3(player);
Xm8A9B0(projectile, player);
Xm4E5F6(projectile, player);
}
private void Xm8A9B0(BaseProjectile projectile, BasePlayer player) {
if (!config.CopterShoot.Enabled) return;
BaseMountable mounted = player.GetMounted();
if (mounted == null) return;
MiniCopter copter = mounted.GetComponentInParent<MiniCopter>();
if (copter == null || copter.mountPoints == null || copter.mountPoints.Count == 0) return;
if (mounted != copter.mountPoints[0].mountable) return;
PlayerData data;
if (!playerData.TryGetValue(player.userID, out data)) {
Xm2C3D4(player);
return;
}
float now = Time.realtimeSinceStartup;
if (now - data.LastCopterViolationTime > config.CopterShoot.ViolationResetSeconds) data.CopterShootViolations = 0;
data.CopterShootViolations++;
data.LastCopterViolationTime = now;
string details = string.Format(_Xs(new byte[] {
0x2e, 0x57, 0x23, 0x9a, 0xf4, 0xda, 0xa5, 0x16, 0x41, 0x2e
}
, 0x6F), data.CopterShootViolations, config.CopterShoot.ViolationsBeforeAction);
Puts(string.Format("[CopterShoot] {0} ({1}) {2}", player.displayName, player.userID, details));
Xm6A7B8(string.Format("<color=#00ccff>[CopterShoot]</color> <color=#ffffff>{0}</color> ({1}) | {2}", player.displayName, player.userID, details));
if (data.CopterShootViolations < config.CopterShoot.ViolationsBeforeAction) return;
data.CopterShootViolations = 0;
Xm0C1D2(player, _Xs(new byte[] {
0x3a, 0x75, 0x4f, 0xb4, 0x80, 0xf4, 0xf8, 0x24, 0x3e, 0x1d, 0x63
}
, 0x4E), config.CopterShoot.Action, config.CopterShoot.Reason);
}
private void Xm1C2D3(BasePlayer player) {
if (!config.JumpShoot.Enabled || player.IsOnGround() || player.GetMounted() != null) return;
RaycastHit hit;
if (Physics.Raycast(player.transform.position, Vector3.down, out hit, config.JumpShoot.MinAirborneHeight, LayerMask.GetMask(_Xs(new byte[] {
0x2d, 0x7f, 0x4d, 0xb2, 0x84, 0xef, 0xc5
}
, 0x4E), _Xs(new byte[] {
0xf, 0x54, 0x6c, 0x8d, 0xa0
}
, 0x6F), _Xs(new byte[] {
0xc7, 0x88, 0xac, 0x4e, 0x6c, 0x9, 0x23, 0xd2, 0xd8, 0xe6, 0x85, 0xab
}
, 0xB3)))) return;
PlayerData data;
if (!playerData.TryGetValue(player.userID, out data)) {
Xm2C3D4(player);
return;
}
float now = Time.realtimeSinceStartup;
if (now - data.LastJumpViolationTime > config.JumpShoot.ViolationResetSeconds) data.JumpShootViolations = 0;
data.JumpShootViolations++;
data.LastJumpViolationTime = now;
string details = string.Format(_Xs(new byte[] {
0x2e, 0x57, 0x23, 0x9a, 0xf4, 0xda, 0xa5, 0x16, 0x41, 0x2e
}
, 0x6F), data.JumpShootViolations, config.JumpShoot.ViolationsBeforeAction);
Puts(string.Format("[JumpShoot] {0} ({1}) {2}", player.displayName, player.userID, details));
Xm6A7B8(string.Format("<color=#ff66ff>[JumpShoot]</color> <color=#ffffff>{0}</color> ({1}) | {2}", player.displayName, player.userID, details));
if (data.JumpShootViolations < config.JumpShoot.ViolationsBeforeAction) return;
data.JumpShootViolations = 0;
Xm0C1D2(player, _Xs(new byte[] {
0x12, 0x4e, 0x73, 0x91, 0x97, 0xcf, 0xe5, 0x2, 0x4
}
, 0x6F), config.JumpShoot.Action, config.JumpShoot.Reason);
}
private void Xm4E5F6(BaseProjectile projectile, BasePlayer player) {
if (!config.Manipulator.Enabled || !config.Manipulator.RapidFireEnabled) return;
if (projectile.repeatDelay <= 0f) return;
PlayerData data;
if (!playerData.TryGetValue(player.userID, out data)) {
Xm2C3D4(player);
return;
}
float now = Time.realtimeSinceStartup;
float elapsed = now - data.LastShotTime;
data.LastShotTime = now;
if (elapsed > 5f) return;
float threshold = projectile.repeatDelay * config.Manipulator.RapidFireMultiplier;
if (elapsed >= threshold) return;
if (now - data.LastRapidFireViolationTime > config.Manipulator.ViolationResetSeconds) data.RapidFireViolations = 0;
data.RapidFireViolations++;
data.LastRapidFireViolationTime = now;
string details = string.Format(_Xs(new byte[] {
0xf3, 0x82, 0xa3, 0x4d, 0x77, 0x15, 0x6b, 0xca, 0x9c, 0xf2, 0xca, 0xac, 0x4e, 0x77, 0x1b, 0x2b, 0xc2, 0xf6, 0x9e, 0xd0, 0xb3, 0x1a, 0x3c, 0x27, 0x6f, 0xc2, 0xe9, 0xd5, 0xbd, 0x5a, 0x40, 0x34, 0x1f, 0x75, 0x98, 0xdb, 0xcb, 0xa6, 0x45, 0x31, 0x7a, 0x3, 0x77, 0xde, 0xb3, 0x9e, 0xf1, 0x42, 0x20, 0xa
}
, 0xB3), projectile.ShortPrefabName, elapsed, threshold, data.RapidFireViolations, config.Manipulator.RapidFireViolationsBeforeAction);
Puts(string.Format("[RapidFire] {0} ({1}) {2}", player.displayName, player.userID, details));
Xm6A7B8(string.Format("<color=#ff8800>[Manipulator/RapidFire]</color> <color=#ffffff>{0}</color> ({1}) | {2}", player.displayName, player.userID, details));
if (data.RapidFireViolations < config.Manipulator.RapidFireViolationsBeforeAction) return;
data.RapidFireViolations = 0;
Xm0C1D2(player, _Xs(new byte[] {
0x34, 0x7b, 0x51, 0xa9, 0x95, 0xf3, 0xc7, 0x2d, 0x25, 0x1d, 0x65, 0x17, 0x8f, 0x9f, 0xf3, 0xcd, 0x2d, 0x2c, 0x66, 0x62, 0x50
}
, 0x4E), config.Manipulator.Action, config.Manipulator.Reason);
}
#endregion
#region WallShoot + SilentAim
private void OnPlayerAttack(BasePlayer attacker, HitInfo info) {
if (attacker == null || info == null || info.HitEntity == null) return;
BasePlayer victim = info.HitEntity as BasePlayer;
if (victim == null || victim == attacker) return;
if (Vector3.Distance(attacker.transform.position, victim.transform.position) < 6f) return;
Xm7A8B9(attacker, info, victim);
if (!config.Manipulator.Enabled || !config.Manipulator.WallShootEnabled) return;
Vector3 origin = attacker.eyes.position;
Vector3 dir = (info.HitPositionWorld - origin).normalized;
float hitDist = Vector3.Distance(origin, info.HitPositionWorld);
RaycastHit wallHit;
if (!Physics.Raycast(origin, dir, out wallHit, hitDist - 0.1f, LayerMask.GetMask(_Xs(new byte[] {
0xf, 0x54, 0x6c, 0x8d, 0xa0
}
, 0x6F), _Xs(new byte[] {
0xc7, 0x88, 0xac, 0x4e, 0x6c, 0x9, 0x23, 0xd2, 0xd8, 0xe6, 0x85, 0xab
}
, 0xB3), _Xs(new byte[] {
0x2d, 0x7f, 0x4d, 0xb2, 0x84, 0xef, 0xc5
}
, 0x4E), _Xs(new byte[] {
0xa4, 0xe6, 0xd6, 0x35, 0x13, 0x66, 0x57, 0xb1
}
, 0xD7)))) return;
BaseEntity hitEnt = wallHit.collider?.GetComponentInParent<BaseEntity>();
if (hitEnt != null && hitEnt == victim) return;
PlayerData data;
if (!playerData.TryGetValue(attacker.userID, out data)) {
Xm2C3D4(attacker);
return;
}
float now2 = Time.realtimeSinceStartup;
if (now2 - data.LastWallShootViolationTime > config.Manipulator.ViolationResetSeconds) data.WallShootViolations = 0;
data.WallShootViolations++;
data.LastWallShootViolationTime = now2;
string obstacle = wallHit.collider != null ? wallHit.collider.name : _Xs(new byte[] {
0x95, 0xed, 0xcd, 0x37, 0x13, 0x68, 0x5c
}
, 0xD7);
string details = string.Format(_Xs(new byte[] {
0x16, 0x78, 0x4c, 0xb4, 0x84, 0xe5, 0xc7, 0x29, 0x6c, 0x9, 0x27, 0x45, 0xfd, 0x9a, 0xea, 0xd7, 0x3d, 0x57, 0x74, 0x21, 0xf, 0x90, 0xca, 0xe1, 0xcc, 0x62, 0x11, 0x61, 0x4e, 0xba, 0xba, 0x99, 0xa4, 0xc1, 0x6d, 0x1d, 0x25, 0x50, 0xa7, 0xd1, 0x8a, 0xa1, 0xca, 0x77, 0x6, 0x2a, 0x5e
}
, 0x4E), obstacle, hitDist, victim.displayName, data.WallShootViolations, config.Manipulator.WallShootViolationsBeforeAction);
Puts(string.Format("[WallShoot] {0} ({1}) {2}", attacker.displayName, attacker.userID, details));
Xm6A7B8(string.Format("<color=#ff8800>[Manipulator/WallShoot]</color> <color=#ffffff>{0}</color> ({1}) | {2}", attacker.displayName, attacker.userID, details));
if (data.WallShootViolations < config.Manipulator.WallShootViolationsBeforeAction) return;
data.WallShootViolations = 0;
Xm0C1D2(attacker, _Xs(new byte[] {
0x15, 0x5a, 0x70, 0x88, 0xb4, 0xd2, 0xe6, 0xc, 0x4, 0x3c, 0x44, 0x36, 0xab, 0xbe, 0xce, 0xe9, 0x3b, 0x23, 0x41, 0x5e, 0x60
}
, 0x6F), config.Manipulator.Action, config.Manipulator.Reason);
}
private void Xm7A8B9(BasePlayer attacker, HitInfo info, BasePlayer victim) {
if (!config.SilentAim.Enabled) return;
float angle = Vector3.Angle(attacker.eyes.HeadForward().normalized, (victim.transform.position + Vector3.up * 0.9f - attacker.eyes.position).normalized);
if (angle < config.SilentAim.MinAngle) return;
PlayerData data;
if (!playerData.TryGetValue(attacker.userID, out data)) {
Xm2C3D4(attacker);
return;
}
float now = Time.realtimeSinceStartup;
if (now - data.LastSilentAimViolationTime > config.SilentAim.ViolationResetSeconds) data.SilentAimViolations = 0;
data.SilentAimViolations++;
data.LastSilentAimViolationTime = now;
string details = string.Format(_Xs(new byte[] {
0x81, 0xed, 0xc1, 0x35, 0x19, 0x22, 0x49, 0xe5, 0xf2, 0xad, 0xbf, 0xdc, 0x20, 0x2, 0x7d, 0x1d, 0xa6, 0x9a, 0xf5, 0xfd, 0xc5, 0x22, 0x5f, 0x7e, 0x9, 0xa6, 0xde, 0xe7, 0xd8, 0x6a, 0x31, 0x5f, 0x7d, 0xc, 0xbd, 0xca, 0xe1
}
, 0xD7), angle, victim.displayName, data.SilentAimViolations, config.SilentAim.ViolationsBeforeAction);
Puts(string.Format("[SilentAim] {0} ({1}) {2}", attacker.displayName, attacker.userID, details));
Xm6A7B8(string.Format("<color=#ff2222>[SilentAim]</color> <color=#ffffff>{0}</color> ({1}) | {2}", attacker.displayName, attacker.userID, details));
if (data.SilentAimViolations < config.SilentAim.ViolationsBeforeAction) return;
data.SilentAimViolations = 0;
Xm0C1D2(attacker, _Xs(new byte[] {
0xd7, 0x8e, 0xae, 0x58, 0x76, 0xf, 0x17, 0xd8, 0xc1
}
, 0xB3), config.SilentAim.Action, config.SilentAim.Reason);
}
#endregion
#region Action
private void Xm0C1D2(BasePlayer player, string detection, string action, string reason) {
Puts(string.Format("[ECAntiCheat] ACTION={0} player={1} ({2}) detection={3}", action, player.displayName, player.userID, detection));
Xm6A7B8(string.Format("<color=#ff4444>[ACTION]</color> {0} on <color=#ffffff>{1}</color> ({2}) for <color=#ffaa00>{3}</color>", action.ToUpper(), player.displayName, player.userID, detection), true);
if (action.ToLower() == _Xs(new byte[] {
0x1b, 0x7b, 0x51
}
, 0x4E)) {
player.Kick(reason);
Server.Command(string.Format("ban {0} \"{1}\"", player.userID, reason));
}
else if (action.ToLower() == _Xs(new byte[] {
0x33, 0x52, 0x7d, 0x8a
}
, 0x6F)) {
player.Kick(reason);
}
}
#endregion
#region Helpers
private bool Xm3E4F5(BasePlayer player) {
ServerUsers.User u = ServerUsers.Get(player.userID);
return u != null && u.group == ServerUsers.UserGroup.Owner;
}
private void Xm6A7B8(string message, bool isAction = false) {
string plain = System.Text.RegularExpressions.Regex.Replace(message, "<.*?>", "");
foreach (BasePlayer p in BasePlayer.activePlayerList) if (p != null && Xm3E4F5(p)) p.ChatMessage("<color=#ff4444><b>[ECAntiCheat]</b></color> " + message);
if (!config.Discord.Enabled || string.IsNullOrEmpty(config.Discord.WebhookUrl)) return;
if (isAction && !config.Discord.SendActions) return;
if (!isAction && !config.Discord.SendViolations) return;
Xm9C0D1(plain, isAction);
}
private void Xm9C0D1(string message, bool isAction) {
string title = isAction ? "ECAntiCheat - ACTION" : "ECAntiCheat - Violation";
string json = string.Format("{{\"embeds\":[{{\"title\":\"{0}\",\"description\":\"{1}\",\"color\":{2}," + "\"footer\":{{\"text\":\"ECAntiCheat - {3}\"}}}}]}}", Xm2E3F4(title), Xm2E3F4(message), isAction ? 16711680 : config.Discord.EmbedColor, Xm2E3F4(DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss")) + " UTC");
webrequest.Enqueue(config.Discord.WebhookUrl, json, (code, r) => {
if (code != 200 && code != 204) PrintWarning(string.Format("[Discord] Webhook failed: HTTP {0}", code));
}
, this, Oxide.Core.Libraries.RequestMethod.POST, new Dictionary<string, string> {
{
"Content-Type", "application/json"
}
}
);
}
private static string Xm2E3F4(string s) => string.IsNullOrEmpty(s) ? "" : s.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\n", "\\n").Replace("\r", "");
#endregion
#region _ObfHelpers
private bool _Fo0xC2D3 = false;
[MethodImpl(MethodImplOptions.NoInlining|MethodImplOptions.NoOptimization)]
private static string _Xs(byte[] _b, byte _k) {
char[] _c=new char[_b.Length];
for(int _i=0;_i<_b.Length;_i++) _c[_i]=(char)((_b[_i]^_k^((_i*0x1D+0x37)&0xFF))&0xFF);
uint _ck=_Jx2((uint)_b.Length^(uint)_k^0xDEADu);
if(_ck==0u&&_b.Length<0) throw new System.Exception();
return new string(_c);
}
private static int _Jx1(int _a, int _b2) {
int _r=_a^_b2;
_r=(_r<<3)|(int)((uint)_r>>29);
if(_r==unchecked((int)0xDEADBEEF))_r+=unchecked((int)0xCAFEBABE);
return _r^unchecked((int)0xCAFEF00D);
}
private static uint _Jx2(uint _v) {
_v^=(_v>>17);
_v*=0xBF324731u;
_v^=(_v>>13);
_v*=0x9F5169B3u;
_v^=(_v>>16);
return _v;
}
private static byte _Jx3(byte _b3, int _i) {
return(byte)((_b3^0xAA^((_i*0x1D+0x37)&0xFF))&0xFF);
}
private static long _Jx4(long _l) {
_l^=(_l<<21);
_l^=(long)((ulong)_l>>35);
_l^=(_l<<4);
return _l;
}
private static bool _Jx5(int _n) {
return((_Jx1(_n, 0x5F)^unchecked((int)0xCAFEF00D))!=unchecked((int)0xDEADBEEF))||((_n&0x7FFFFFFF)>0);
}
#endregion
#region Commands
[ChatCommand("eac")]
private void Xm8C9D0(BasePlayer player, string command, string[] args) {
if (!Xm3E4F5(player)) {
player.ChatMessage("<color=#ff4444>[ECAntiCheat]</color> No permission.");
return;
}
player.ChatMessage("<color=#ff4444><b>[ECAntiCheat]</b></color> v1.0.8\n" + " OmniSprint: " + Xm5A6B7(config.OmniSprint.Enabled) + " | " + config.OmniSprint.Action + " @" + config.OmniSprint.ViolationsBeforeAction + "vl\n" + " CopterShoot: " + Xm5A6B7(config.CopterShoot.Enabled) + " | " + config.CopterShoot.Action + " @" + config.CopterShoot.ViolationsBeforeAction + "vl\n" + " JumpShoot: " + Xm5A6B7(config.JumpShoot.Enabled) + " | " + config.JumpShoot.Action + " @" + config.JumpShoot.ViolationsBeforeAction + "vl\n" + " Manipulator: " + Xm5A6B7(config.Manipulator.Enabled) + " | WallShoot=" + (config.Manipulator.WallShootEnabled?"ON" : "OFF") + " RapidFire=" + (config.Manipulator.RapidFireEnabled?"ON" : "OFF") + "\n" + " SilentAim: " + Xm5A6B7(config.SilentAim.Enabled) + " | " + config.SilentAim.Action + " @" + config.SilentAim.ViolationsBeforeAction + "vl | min " + config.SilentAim.MinAngle + "deg" );
}
private string Xm5A6B7(bool on) => on ? "<color=#00ff88>ON</color>" : "<color=#ff4444>OFF</color>";
[ChatCommand("eac.violations")]
private void Xm1E2F3(BasePlayer player, string command, string[] args) {
if (!Xm3E4F5(player)) {
player.ChatMessage("<color=#ff4444>[ECAntiCheat]</color> No permission.");
return;
}
bool any = false;
foreach (KeyValuePair<ulong, PlayerData> kvp in playerData) {
if (kvp.Value.OmniSprintViolations <= 0 && kvp.Value.CopterShootViolations <= 0 && kvp.Value.JumpShootViolations <= 0 && kvp.Value.WallShootViolations <= 0 && kvp.Value.RapidFireViolations <= 0 && kvp.Value.SilentAimViolations <= 0) continue;
BasePlayer t = BasePlayer.FindByID(kvp.Key);
player.ChatMessage(string.Format(_Xs(new byte[] {
0x78, 0x1b, 0x65, 0xd1, 0xb9, 0x87, 0xa7, 0x4d, 0x3f, 0x3e, 0x58, 0x70, 0xc6, 0xa4, 0x93, 0xf8, 0x47, 0x30, 0x1c, 0x4c, 0x34, 0xb4, 0xb5, 0xcd, 0xf4, 0x6, 0x34, 0x13, 0x77, 0xdc, 0x8f, 0xfa, 0xc3, 0xaf, 0x3, 0x61, 0x6e, 0x72, 0x87, 0xbd, 0xea, 0xc8, 0xa3, 0x4, 0x73, 0x44, 0x34, 0x98, 0xe8, 0xfc, 0xef, 0xfd, 0x18, 0x6d, 0x41, 0x2a, 0x9d, 0xec, 0xdd, 0xb1, 0x11, 0x6f, 0x0, 0x54, 0x68, 0x92, 0xba, 0x9b, 0xff, 0x5e, 0x37, 0x2, 0x4b, 0x22, 0xc6, 0xa4, 0x9c, 0xcc, 0x23, 0x7f, 0x53, 0x3a, 0xdf, 0x8c, 0xfb, 0xcc, 0xab, 0x4f, 0x3d
}
, 0x6F), t != null ? t.displayName : kvp.Key.ToString(), kvp.Value.OmniSprintViolations, config.OmniSprint.ViolationsBeforeAction, kvp.Value.CopterShootViolations, config.CopterShoot.ViolationsBeforeAction, kvp.Value.JumpShootViolations, config.JumpShoot.ViolationsBeforeAction, kvp.Value.WallShootViolations, config.Manipulator.WallShootViolationsBeforeAction, kvp.Value.RapidFireViolations, config.Manipulator.RapidFireViolationsBeforeAction, kvp.Value.SilentAimViolations, config.SilentAim.ViolationsBeforeAction));
any = true;
}
if (!any) player.ChatMessage("<color=#ff4444>[ECAntiCheat]</color> No active violations.");
}
#endregion
}
}