C#:
// Reference: Oxide.Core.MySql
// Reference: Oxide.Core.SQLite
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Database;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using System;
using System.Collections.Generic;
using System.Linq;
using Oxide.Core.SQLite.Libraries;
namespace Oxide.Plugins {
[Info("EnhancedBanSystem", "Reneb", "5.0.9", ResourceId = 1951)]
class EnhancedBanSystem : CovalencePlugin {
[PluginReference]
Plugin PlayerDatabase;
////////////////////////////////////////////////////////////
// Static fields
////////////////////////////////////////////////////////////
static DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0);
char[] ipChrArray = new char[] {
'.'
}
;
static BanSystem banSystem;
static Hash<int, BanData> cachedBans = new Hash<int, BanData>();
static List<int> wasBanned = new List<int>();
////////////////////////////////////////////////////////////
// Config fields
////////////////////////////////////////////////////////////
static string Platform = "Steam";
static string Server = "1.1.1.1:28015";
static string Game = "Rust";
string PermissionBan = "enhancedbansystem.ban";
string PermissionUnban = "enhancedbansystem.unban";
string PermissionBanlist = "enhancedbansystem.banlist";
string PermissionKick = "enhancedbansystem.kick";
static bool SQLite_use = false;
static string SQLite_DB = "banlist.db";
static bool MySQL_use = false;
static string MySQL_Host = "localhost";
static int MySQL_Port = 3306;
static string MySQL_DB = "banlist";
static string MySQL_User = "root";
static string MySQL_Pass = "toor";
static bool PlayerDatabase_use = false;
static string PlayerDatabase_IPFile = "EnhancedBanSystem_IPs.json";
static bool Files_use = false;
static bool WebAPI_use = false;
static string WebAPI_Ban_Request = "http://webpage.com/api.php?action=ban&pass=mypassword&id={id}&steamid={steamid}&name={name}&ip={ip}&reason={reason}&source={source}&game={game}&platform={platform}&server={server}&tempban={expiration}";
static string WebAPI_Unban_Request = "http://webpage.com/api.php?action=unban&pass=mypassword&steamid={steamid}&name={name}&ip={ip}&name={name}&source={source}";
static string WebAPI_IsBanned_Request = "http://webpage.com/api.php?action=isbanned&pass=mypassword&id={id}&update={update}&steamid={steamid}&ip={ip}&time={time}&name={name}&game=Rust&server=rust.kortal.org:28015";
static string WebAPI_Banlist_Request = "http://webpage.com/banlist.php?startid={startid}";
static bool Native_use = false;
static string BanDefaultReason = "Banned";
static string BanEvadeReason = "Ban Evade";
static bool Kick_Broadcast = true;
static bool Kick_Log = true;
static bool Kick_OnBan = true;
static bool Ban_Broadcast = true;
static bool Ban_Log = true;
static bool Ban_Escape = true;
static bool Log_Denied = true;
protected override void LoadDefaultConfig() {
}
private void CheckCfg<T>(string Key, ref T var) {
if (Config[Key] is T) var = (T)Config[Key];
else Config[Key] = var;
}
void Init() {
CheckCfg<string>("Server Info - Platform", ref Platform);
CheckCfg<string>("Server Info - Game", ref Game);
CheckCfg<string>("Server Info - IP:PORT", ref Server);
CheckCfg<string>("Permissions - Ban", ref PermissionBan);
CheckCfg<string>("Permissions - Unban", ref PermissionUnban);
CheckCfg<string>("Permissions - Banlist", ref PermissionBanlist);
CheckCfg<string>("Permissions - Kick", ref PermissionKick);
CheckCfg<bool>("DataType - SQLite - use", ref SQLite_use);
CheckCfg<string>("DataType - SQLite - Database Filename", ref SQLite_DB);
CheckCfg<bool>("DataType - MySQL - use", ref MySQL_use);
CheckCfg<string>("DataType - MySQL - Host", ref MySQL_Host);
CheckCfg<int>("DataType - MySQL - Port", ref MySQL_Port);
CheckCfg<string>("DataType - MySQL - Database", ref MySQL_DB);
CheckCfg<string>("DataType - MySQL - User", ref MySQL_User);
CheckCfg<string>("DataType - MySQL - Pass", ref MySQL_Pass);
CheckCfg<bool>("DataType - Files - use", ref Files_use);
CheckCfg<bool>("DataType - PlayerDatabase - use", ref PlayerDatabase_use);
CheckCfg<string>("DataType - PlayerDatabase - IP Filename", ref PlayerDatabase_IPFile);
CheckCfg<bool>("DataType - WebAPI - use", ref WebAPI_use);
CheckCfg<string>("DataType - WebAPI - Host", ref WebAPI_Ban_Request);
CheckCfg<string>("DataType - WebAPI - Unban", ref WebAPI_Unban_Request);
CheckCfg<string>("DataType - WebAPI - IsBanned", ref WebAPI_IsBanned_Request);
CheckCfg<string>("DataType - WebAPI - Banlist", ref WebAPI_Banlist_Request);
CheckCfg<bool>("DataType - Native - use", ref Native_use);
CheckCfg<bool>("Ban - Evade", ref Ban_Escape);
CheckCfg<string>("Ban - Default Reason", ref BanDefaultReason);
CheckCfg<string>("Ban - Evade Reason", ref BanEvadeReason);
CheckCfg<bool>("Ban - Broadcast", ref Ban_Broadcast);
CheckCfg<bool>("Ban - Log", ref Ban_Log);
CheckCfg<bool>("Kick - Broadcast", ref Kick_Broadcast);
CheckCfg<bool>("Kick - Log", ref Kick_Log);
CheckCfg<bool>("Kick - On Ban", ref Kick_OnBan);
CheckCfg<bool>("Denied Connection - Log", ref Log_Denied);
SaveConfig();
if (SQLite_use) banSystem |= BanSystem.SQLite;
if (MySQL_use) banSystem |= BanSystem.MySQL;
if (Native_use) banSystem |= BanSystem.Native;
if (PlayerDatabase_use) banSystem |= BanSystem.PlayerDatabase;
if (Files_use) banSystem |= BanSystem.Files;
if (WebAPI_use) banSystem |= BanSystem.WebAPI;
InitializeLang();
}
void InitializeLang() {
lang.RegisterMessages(new Dictionary<string, string> {
{
"No matching player was found.\n", "No matching player was found.\n"
}
, {
"You are temporarily banned from this server ({0}).{1} left", "You are temporarily banned from this server ({0}).{1} left"
}
, {
"You are banned from this server ({0}).", "You are banned from this server ({0})."
}
, {
"Loaded {0} bans\n\r", "Loaded {0} bans\n\r"
}
, {
"This ban already exists ({0}).", "This ban already exists ({0})."
}
, {
"Successfully added {0} to the banlist.", "Successfully added {0} to the banlist."
}
, {
"Multiple Bans Found:\n\r", "Multiple Bans Found:\n\r"
}
, {
"{0} matching bans were removed", "{0} matching bans were removed"
}
, {
"{0} - {1} isn't banned.\n", "{0} - {1} isn't banned.\n"
}
, {
"Loaded\n\r", "Loaded\n\r"
}
, {
"You don't have the permission to use this command.", "You don't have the permission to use this command."
}
, {
"Syntax: kick < Name | SteamID | IP | IP Range > < reason(optional) >", "Syntax: kick < Name | SteamID | IP | IP Range > < reason(optional) >"
}
, {
"Syntax: unban < Name | SteamID | IP | IP Range >", "Syntax: unban < Name | SteamID | IP | IP Range >"
}
, {
"Syntax: ban < Name | SteamID | IP | IP Range > < reason(optional) > < time in secondes(optional) > ", "Syntax: ban < Name | SteamID | IP | IP Range > < reason(optional) > < time in secondes(optional) > "
}
, {
"Syntax: banlist <BanSystem> <startid>", "Syntax: banlist <BanSystem> <startid>"
}
, {
"Avaible BanSystems:\n", "Avaible BanSystems:\n"
}
, {
"Wrong usage of /banlist", "Wrong usage of /banlist"
}
, {
"Index is out of range.Current bans recorded: {0}", "Index is out of range.Current bans recorded: {0}"
}
, {
"Banlist - {0}-{1}/{2}\n", "Banlist - {0}-{1}/{2}\n"
}
}
, this);
}
////////////////////////////////////////////////////////////
// ID Save
////////////////////////////////////////////////////////////
static DynamicConfigFile Ban_ID_File;
static int Ban_ID = 0;
void Load_ID() {
try {
Ban_ID_File = Interface.GetMod().DataFileSystem.GetDatafile("EnhancedBanSystem_ID");
Ban_ID = (int)Ban_ID_File["id"];
}
catch {
Ban_ID = 0;
Ban_ID_File["id"] = Ban_ID;
Save_ID();
}
}
void Save_ID() {
Interface.GetMod().DataFileSystem.SaveDatafile("EnhancedBanSystem_ID");
}
static int GetNewID() {
Ban_ID++;
Ban_ID_File["id"] = Ban_ID;
return Ban_ID;
}
////////////////////////////////////////////////////////////
// Enum & Class
////////////////////////////////////////////////////////////
enum BanSystem {
Native = 1, MySQL = 2, SQLite = 4, WebAPI = 8, PlayerDatabase = 16, Files = 32,
}
class BanData {
public int id;
public string steamid;
public string ip;
public string name;
public string game;
public string server;
public string source;
public double date;
public double expire;
public string reason;
public string platform;
public BanData() {
}
public BanData(object source, string userID, string name, string ip, string reason, double duration) {
this.id = GetNewID();
this.source = source is IPlayer ? ((IPlayer)source).Name : source is string ? (string)source : "Console";
this.steamid = userID;
this.name = name;
this.ip = ip;
this.reason = reason;
this.expire = duration != 0.0 ? LogTime() + duration : 0.0;
this.date = LogTime();
this.platform = Platform;
this.game = Game;
this.server = Server;
}
public BanData(int id, string source, string userID, string name, string ip, string reason, string duration) {
this.id = id;
this.source = source;
this.steamid = userID;
this.name = name;
this.ip = ip;
this.reason = reason;
this.expire = double.Parse(duration);
this.date = LogTime();
this.platform = Platform;
this.game = Game;
this.server = Server;
}
public string ToJson() {
return JsonConvert.SerializeObject(this);
}
public override string ToString() {
return string.Format("{0} - {1} - {2} - {3} - {4}", steamid, name, ip, reason, expire == 0.0 ? "Permanent" : expire < LogTime() ? "Expired" : string.Format("Temporary: {0}s", (expire - LogTime()).ToString()));
}
}
////////////////////////////////////////////////////////////
// General Methods
////////////////////////////////////////////////////////////
static double LogTime() => DateTime.UtcNow.Subtract(epoch).TotalSeconds;
string GetMsg(string key, object steamid = null) {
return lang.GetMessage(key, this, steamid is IPlayer ? ((IPlayer)steamid).Id : steamid == null ? null : steamid.ToString());
}
//string GetMsg(string key, object steamid = null) { return key; }
bool hasPermission(IPlayer player, string permissionName) {
if (player.IsAdmin) return true;
return permission.UserHasPermission(player.Id.ToString(), permissionName);
}
bool isIPAddress(string arg) {
int subIP;
string[] strArray = arg.Split(ipChrArray);
if (strArray.Length != 4) {
return false;
}
foreach (string str in strArray) {
if (str.Length == 0) {
return false;
}
if (!int.TryParse(str, out subIP) && str != "*") {
return false;
}
if (!(str == "*" || (subIP >= 0 && subIP <= 255))) {
return false;
}
}
return true;
}
bool IPRange(string sourceIP, string targetIP) {
string[] srcArray = sourceIP.Split(ipChrArray);
string[] trgArray = targetIP.Split(ipChrArray);
for (int i = 0; i < 4; i++) {
if (srcArray[i] != trgArray[i] && srcArray[i] != "*") {
return false;
}
}
return true;
}
bool RangeFromIP(string sourceIP, out string range1, out string range2, out string range3) {
range1 = string.Empty;
range2 = string.Empty;
range3 = string.Empty;
if (sourceIP == string.Empty) return false;
string[] strArray = sourceIP.Split(ipChrArray);
if (strArray.Length != 4) {
return false;
}
range1 = string.Format("{0}.*.*.*", strArray[0]);
range2 = string.Format("{0}.{1}.*.*", strArray[0], strArray[1]);
range3 = string.Format("{0}.{1}.{2}.*", strArray[0], strArray[1], strArray[2]);
return true;
}
List<IPlayer> FindPlayers(string userIDorNameorIP, object source, out string reason) {
reason = string.Empty;
var FoundPlayers = players.FindPlayers(userIDorNameorIP).ToList();
if (FoundPlayers.Count == 0) {
reason = GetMsg("No matching player was found.\n", source);
}
if (FoundPlayers.Count > 1) {
foreach (var iplayer in FoundPlayers) {
reason += string.Format("{0} {1}\r\n", iplayer.Id, iplayer.Name);
}
}
return FoundPlayers;
}
List<IPlayer> FindConnectedPlayers(string userIDorNameorIP, object source, out string reason) {
reason = string.Empty;
ulong steamid = 0L;
var FoundPlayers = new List<IPlayer>();
ulong.TryParse(userIDorNameorIP, out steamid);
if (isIPAddress(userIDorNameorIP)) {
FoundPlayers = players.All.Where(x => x.IsConnected).Where(w => IPRange(userIDorNameorIP, w.Address)).ToList();
}
else if (steamid != 0L) {
var p = players.FindPlayer(userIDorNameorIP);
if (p != null && p.IsConnected) {
FoundPlayers.Add(p);
}
}
else {
FoundPlayers = players.FindPlayers(userIDorNameorIP).Where(x => x.IsConnected).ToList();
if (FoundPlayers.Count > 1) {
foreach (var iplayer in FoundPlayers) {
reason += string.Format("{0} {1}\r\n", iplayer.Id, iplayer.Name);
}
}
}
if (FoundPlayers.Count == 0) {
reason = GetMsg("No matching player was found.\n", source);
}
return FoundPlayers;
}
string GetPlayerIP(IPlayer iplayer) {
if (iplayer.IsConnected) return iplayer.Address;
return GetPlayerIP(iplayer.Id);
}
string GetPlayerIP(string userID) {
if (PlayerDatabase != null) {
return (string)PlayerDatabase.Call("GetPlayerData", userID, "ip") ?? string.Empty;
}
return string.Empty;
}
string GetPlayerName(string userID) {
if (PlayerDatabase != null) {
return (string)PlayerDatabase.Call("GetPlayerData", userID, "name") ?? string.Empty;
}
return string.Empty;
}
string FormatTimeLeft(double timeleft) {
var d = 0.0;
var h = 0.0;
var m = 0.0;
var s = 0.0;
if (timeleft >= 86400.0) {
d = Math.Floor(timeleft / 86400.0);
timeleft -= d * 86400.0;
}
if (timeleft >= 3600) {
h = Math.Floor(timeleft / 3600.0);
timeleft -= h * 3600.0;
}
if (timeleft >= 60) {
m = Math.Floor(timeleft / 60.0);
timeleft -= m * 60.0;
}
if (timeleft >= 0) {
s = Math.Floor(timeleft);
}
return string.Format("{0}{1}{2}{3}", d > 0 ? $"{d.ToString()}d " : string.Empty, h > 0 ? $"{h.ToString()}h " : string.Empty, m > 0 ? $"{m.ToString()}m " : string.Empty, s > 0 ? $"{s.ToString()}s " : string.Empty);
}
bool HasDelayedAnswer() => BanSystemHasFlag(banSystem, BanSystem.MySQL) || BanSystemHasFlag(banSystem, BanSystem.SQLite) || (BanSystemHasFlag(banSystem, BanSystem.WebAPI));
bool BanSystemHasFlag(BanSystem b, BanSystem t) => (b & t) == t;
string FormatReturn(BanSystem system, string msg, params object[] args) => string.Format("{0}: {1}", system.ToString(), string.Format(msg, args));
void SendReply(object source, string msg) {
if (source is IPlayer) ((IPlayer)source).Reply(msg);
else if (source is string) return;
else Interface.Oxide.LogInfo(msg);
}
public static string ToShortString(TimeSpan timeSpan) {
return string.Format("{0:00}:{1:00}:{2:00}", (int)timeSpan.TotalHours, timeSpan.Minutes, timeSpan.Seconds);
}
////////////////////////////////////////////////////////////
// Oxide Hooks
////////////////////////////////////////////////////////////
void OnServerInitialized() {
Load_ID();
string returnstring = string.Empty;
if (BanSystemHasFlag(banSystem, BanSystem.PlayerDatabase)) {
returnstring += PlayerDatabase_Load();
}
if (BanSystemHasFlag(banSystem, BanSystem.Files)) {
returnstring += Files_Load();
}
if (BanSystemHasFlag(banSystem, BanSystem.MySQL)) {
returnstring += MySQL_Load();
}
if (BanSystemHasFlag(banSystem, BanSystem.SQLite)) {
returnstring += SQLite_Load();
}
if (BanSystemHasFlag(banSystem, BanSystem.WebAPI)) {
returnstring += WebAPI_Load();
}
if (BanSystemHasFlag(banSystem, BanSystem.Native)) {
returnstring += Native_Load();
}
permission.RegisterPermission(PermissionBan, this);
permission.RegisterPermission(PermissionBanlist, this);
permission.RegisterPermission(PermissionKick, this);
permission.RegisterPermission(PermissionUnban, this);
Interface.Oxide.LogInfo(returnstring);
}
void OnServerSave() {
Save_ID();
if (BanSystemHasFlag(banSystem, BanSystem.PlayerDatabase)) {
Save_PlayerDatabaseIP();
}
if (BanSystemHasFlag(banSystem, BanSystem.Files)) {
Save_Files();
}
if (BanSystemHasFlag(banSystem, BanSystem.MySQL)) {
// Nothing to save
}
if (BanSystemHasFlag(banSystem, BanSystem.SQLite)) {
// Nothing to save
}
if (BanSystemHasFlag(banSystem, BanSystem.WebAPI)) {
// Nothing to save
}
}
object CanUserLogin(string name, string steamid, string ip) {
BanData bd = null;
#if RUST
using (TimeWarning.New("CanUserLogin", 0.01f)) {
#endif
if (isBanned_NonDelayed(name, steamid, ip, Ban_Escape, out bd)) {
if (bd != null && bd.expire != 0.0) {
return string.Format(GetMsg("You are temporarily banned from this server ({0}).{1} left", steamid), bd.reason, FormatTimeLeft(bd.expire - LogTime()));
}
return string.Format(GetMsg("You are banned from this server ({0}).", steamid), bd == null ? string.Empty : bd.reason);
}
#if RUST
}
#endif
return null;
}
void OnUserConnected(IPlayer player) {
#if RUST
using (TimeWarning.New("OnUserConnected", 0.01f)) {
#endif
if (player == null) return;
string ip = player.Address;
string name = player.Name;
string steamid = player.Id;
isBanned_Delayed(name, steamid, ip, Ban_Escape);
#if RUST
}
#endif
}
////////////////////////////////////////////////////////////
// Files
////////////////////////////////////////////////////////////
static StoredData storedData;
class StoredData {
public HashSet<string> Banlist = new HashSet<string>();
public StoredData() {
}
}
string Files_Load() {
try {
storedData = Interface.GetMod().DataFileSystem.ReadObject<StoredData>("EnhancedBanSystem");
}
catch {
storedData = new StoredData();
}
foreach (var b in storedData.Banlist) {
var bd = JsonConvert.DeserializeObject<BanData>(b);
if (!cachedBans.ContainsKey(bd.id)) cachedBans.Add(bd.id, bd);
}
return FormatReturn(BanSystem.Files, GetMsg("Loaded {0} bans\n\r", null), storedData.Banlist.Count.ToString());
}
void Save_Files() {
Interface.GetMod().DataFileSystem.WriteObject("EnhancedBanSystem", storedData);
}
string Files_UpdateBan(BanData bandata) {
if (!cachedBans.ContainsKey(bandata.id)) return FormatReturn(BanSystem.Files, "No such ban id {0}", bandata.id);
storedData.Banlist.Remove(cachedBans[bandata.id].ToJson());
cachedBans.Remove(bandata.id);
storedData.Banlist.Add(bandata.ToJson());
if (!cachedBans.ContainsKey(bandata.id)) cachedBans.Add(bandata.id, bandata);
return FormatReturn(BanSystem.Files, GetMsg("Successfully updated {0} in the banlist."), bandata.ToString());
}
string Files_ExecuteBan(BanData bandata) {
var f = cachedBans.Values.Where(x => x.ip == bandata.ip).Where(x => x.steamid == bandata.steamid).ToList();
if (f.Count > 0) {
return FormatReturn(BanSystem.Files, GetMsg("This ban already exists ({0})."), f[0].ToString());
}
storedData.Banlist.Add(bandata.ToJson());
if (!cachedBans.ContainsKey(bandata.id)) cachedBans.Add(bandata.id, bandata);
return FormatReturn(BanSystem.Files, GetMsg("Successfully added {0} to the banlist."), bandata.ToString());
}
string Files_RawUnban(List<BanData> unbanList) {
int i = 0;
foreach (var u in unbanList) {
var json = u.ToJson();
if (storedData.Banlist.Contains(json)) {
i++;
storedData.Banlist.Remove(json);
}
}
return FormatReturn(BanSystem.Files, GetMsg("{0} matching bans were removed"), i.ToString());
}
string Files_ExecuteUnban(string steamid, string name, string ip, out List<BanData> unbanList) {
unbanList = new List<BanData>();
if (ip != string.Empty) {
unbanList = cachedBans.Values.Where(x => x.ip == ip).ToList();
}
else if (steamid != string.Empty) {
unbanList = cachedBans.Values.Where(x => x.steamid == steamid).ToList();
}
else {
unbanList = cachedBans.Values.Where(x => x.name == name).ToList();
if (unbanList.Count == 0) {
var lname = name.ToLower();
unbanList = cachedBans.Values.Where(x => x.name.ToLower().Contains(lname)).ToList();
if (unbanList.Count > 1) {
var ret = FormatReturn(BanSystem.Files, GetMsg("Multiple Bans Found:\n\r"));
foreach (var b in unbanList) {
ret += string.Format("{0} - {1} - {2}\n\r", b.steamid, b.name, b.reason);
}
return ret;
}
}
}
return Files_RawUnban(unbanList);
}
bool Files_IsBanned(string steamid, string ip, out BanData bandata) {
bandata = null;
double cTime = LogTime();
bool permanent = false;
List<BanData> unbanList = new List<BanData>();
List<BanData> list = new List<BanData>();
{
// check by ID then IP
var b_steamid = cachedBans.Values.Where(x => x.steamid == steamid).ToList();
var b_steamid_ip = b_steamid.Where(w => w.ip == ip).ToList();
foreach (var b in b_steamid_ip) {
if (b.expire != 0.0 && cTime >= b.expire) {
unbanList.Add(b);
}
else {
if (b.expire == 0.0) {
permanent = true;
}
if (b.ip == ip) {
bandata = b;
}
}
}
if (unbanList.Count > 0) {
Files_RawUnban(unbanList);
foreach (var u in unbanList) {
b_steamid_ip.Remove(u);
}
unbanList.Clear();
}
foreach (var b in b_steamid) {
if (b.expire != 0.0 && cTime >= b.expire) {
unbanList.Add(b);
}
else {
if (b.expire == 0.0) {
permanent = true;
}
if (b.ip == ip) {
bandata = b;
}
}
}
if (unbanList.Count > 0) {
Files_RawUnban(unbanList);
foreach (var u in unbanList) {
b_steamid.Remove(u);
}
unbanList.Clear();
}
if (bandata == null) {
if (b_steamid_ip.Count > 0) {
bandata = b_steamid_ip[0];
}
else if (b_steamid.Count > 0) {
bandata = b_steamid[0];
}
}
}
if (bandata == null && !permanent) {
// check by IP & IP Range
list = cachedBans.Values.Where(x => IPRange(x.ip, ip)).ToList();
foreach (var b in list) {
if (b.expire != 0.0 && cTime >= b.expire) {
unbanList.Add(b);
}
else {
if (b.expire == 0.0) {
permanent = true;
}
}
}
if (unbanList.Count > 0) {
Files_RawUnban(unbanList);
foreach (var u in unbanList) {
list.Remove(u);
}
unbanList.Clear();
}
if (list.Count > 0) {
bandata = list[0];
}
}
if (bandata != null && bandata.expire != 0.0 && permanent) {
bandata.expire = 0.0;
Files_UpdateBan(bandata);
}
return bandata != null;
}
string Files_Banlist(object source, int startid) {
if (startid > cachedBans.Count) {
return FormatReturn(BanSystem.Files, "Index is out of range.Current bans recorded: {0}", cachedBans.Count.ToString());
}
int i = -1;
int max = startid + 9;
string returnstring = FormatReturn(BanSystem.Files, GetMsg("Banlist - {0}-{1}/{2}\n"), startid.ToString(), max.ToString(), cachedBans.Count.ToString());
var bans = from pair in cachedBans orderby pair.Key descending select pair;
foreach (KeyValuePair<int, BanData> b in bans) {
i++;
if (i < startid) continue;
if (i > max) break;
returnstring += b.ToString() + "\n";
}
return returnstring;
}
////////////////////////////////////////////////////////////
// PlayerDatabase
////////////////////////////////////////////////////////////
static StoredIPData storedIPData;
class StoredIPData {
public HashSet<string> Banlist = new HashSet<string>();
public StoredIPData() {
}
}
string PlayerDatabase_Load() {
if (PlayerDatabase == null) return FormatReturn(BanSystem.PlayerDatabase, "Missing plugin: oxidemod.org/threads/playerdatabase.18409/");
try {
storedIPData = Interface.GetMod().DataFileSystem.ReadObject<StoredIPData>(PlayerDatabase_IPFile);
}
catch {
storedIPData = new StoredIPData();
}
foreach (var b in storedIPData.Banlist) {
var bd = JsonConvert.DeserializeObject<BanData>(b);
if (!cachedBans.ContainsKey(bd.id)) cachedBans.Add(bd.id, bd);
}
var getKnownPlayers = (List<string>)PlayerDatabase.Call("GetAllKnownPlayers");
if (getKnownPlayers == null) return FormatReturn(BanSystem.PlayerDatabase, "Error P01");
int i = 0;
List<BanData> list = new List<BanData>();
foreach (var steamid in getKnownPlayers) {
var success = PlayerDatabase.Call("GetPlayerDataRaw", steamid, "Banned");
if (!(success is string)) continue;
list = JsonConvert.DeserializeObject<List<BanData>>((string)success);
foreach (var b in list) {
i++;
if (!cachedBans.ContainsKey(b.id)) cachedBans.Add(b.id, b);
}
}
return FormatReturn(BanSystem.PlayerDatabase, GetMsg("Loaded {0} bans\n\r"), i.ToString());
}
void Save_PlayerDatabaseIP() {
Interface.GetMod().DataFileSystem.WriteObject(PlayerDatabase_IPFile, storedIPData);
}
string PlayerDatabase_ExecuteBan(BanData bandata) {
if (bandata.steamid != string.Empty) {
List<BanData> list = new List<BanData>();
var success = PlayerDatabase.Call("GetPlayerDataRaw", bandata.steamid, "Banned");
if (success is string) {
list = JsonConvert.DeserializeObject<List<BanData>>((string)success);
}
var f = list.Where(x => x.ip == bandata.ip).ToList();
if (f.Count > 0) {
return FormatReturn(BanSystem.PlayerDatabase, GetMsg("This ban already exists ({0})."), f[0].ToString());
}
f.Add(bandata);
PlayerDatabase.Call("SetPlayerData", bandata.steamid, "Banned", f);
}
else {
var f2 = cachedBans.Values.Where(x => x.ip == bandata.ip).Where(x => x.steamid == string.Empty).ToList();
if (f2.Count > 0) {
return FormatReturn(BanSystem.PlayerDatabase, GetMsg("This ban already exists ({0})."), f2[0].ToString());
}
storedIPData.Banlist.Add(bandata.ToJson());
}
if (!cachedBans.ContainsKey(bandata.id)) cachedBans.Add(bandata.id, bandata);
return FormatReturn(BanSystem.PlayerDatabase, GetMsg("Successfully added {0} to the banlist."), bandata.ToString());
}
string PlayerDatabase_UpdateBan(BanData bandata, double expire) {
if (bandata.steamid == string.Empty) {
if (cachedBans.ContainsKey(bandata.id)) {
var json = bandata.ToJson();
if (storedIPData.Banlist.Contains(json)) {
cachedBans.Remove(bandata.id);
storedIPData.Banlist.Remove(json);
bandata.expire = expire;
storedIPData.Banlist.Add(bandata.ToJson());
cachedBans.Add(bandata.id, bandata);
return FormatReturn(BanSystem.Files, GetMsg("Successfully updated {0} in the banlist."), bandata.ToString());
}
}
}
else {
List<BanData> list = new List<BanData>();
bandata.expire = expire;
var b_steamid = PlayerDatabase.Call("GetPlayerDataRaw", bandata.steamid, "Banned");
if (b_steamid is string) {
list = JsonConvert.DeserializeObject<List<BanData>>((string)b_steamid);
}
if (list.Count > 0) {
foreach (var b in list) {
b.expire = expire;
}
PlayerDatabase.Call("SetPlayerData", bandata.steamid, "Banned", list);
return FormatReturn(BanSystem.Files, GetMsg("Successfully updated {0} in the banlist."), bandata.ToString());
}
}
return string.Empty;
}
string PlayerDatabase_RawUnban(List<BanData> unbanList) {
int i = 0;
foreach (var u in unbanList) {
if (u.steamid == string.Empty) {
var json = u.ToJson();
if (storedIPData.Banlist.Contains(json)) {
i++;
storedIPData.Banlist.Remove(json);
}
}
else {
i++;
PlayerDatabase.Call("SetPlayerData", u.steamid, "Banned", new List<BanData>());
}
}
return FormatReturn(BanSystem.PlayerDatabase, GetMsg("{0} matching bans were removed"), i.ToString());
}
string PlayerDatabase_ExecuteUnban(string steamid, string name, string ip, out List<BanData> unbanList) {
unbanList = new List<BanData>();
if (ip != string.Empty) {
unbanList = cachedBans.Values.Where(x => x.ip == ip).ToList();
}
else if (steamid != string.Empty) {
unbanList = cachedBans.Values.Where(x => x.steamid == steamid).ToList();
}
else {
unbanList = cachedBans.Values.Where(x => x.name == name).ToList();
if (unbanList.Count == 0) {
var lname = name.ToLower();
unbanList = cachedBans.Values.Where(x => x.name.ToLower().Contains(lname)).ToList();
if (unbanList.Count > 1) {
var ret = FormatReturn(BanSystem.PlayerDatabase, GetMsg("Multiple Bans Found:\n\r"));
foreach (var b in unbanList) {
ret += string.Format("{0} - {1} - {2}\n\r", b.steamid, b.name, b.reason);
}
return ret;
}
}
}
return PlayerDatabase_RawUnban(unbanList);
}
bool PlayerDatabase_IsBanned(string steamid, string ip, out BanData bandata) {
bandata = null;
BanData possibleData = null;
double cTime = LogTime();
bool permanent = false;
List<BanData> unbanList = new List<BanData>();
List<BanData> list = new List<BanData>();
{
// check by ID then IP
var b_steamid = PlayerDatabase.Call("GetPlayerDataRaw", steamid, "Banned");
if (b_steamid is string) {
list = JsonConvert.DeserializeObject<List<BanData>>((string)b_steamid);
}
foreach (var b in list) {
if (b.expire != 0.0 && cTime >= b.expire) {
unbanList.Add(b);
}
else {
if (b.expire == 0.0) {
permanent = true;
}
if (b.ip == ip) {
bandata = b;
}
}
}
if (unbanList.Count > 0) {
PlayerDatabase_RawUnban(unbanList);
foreach (var b in unbanList) {
list.Remove(b);
}
unbanList.Clear();
}
if (list.Count > 0 && bandata == null) {
possibleData = list[0];
}
}
{
// check by IP & IP Range
list = cachedBans.Values.Where(x => IPRange(x.ip, ip)).ToList();
foreach (var b in list) {
if (b.expire != 0.0 && cTime >= b.expire) {
unbanList.Add(b);
}
else {
if (b.expire == 0.0) {
permanent = true;
}
}
}
if (unbanList.Count > 0) {
PlayerDatabase_RawUnban(unbanList);
foreach (var b in unbanList) {
list.Remove(b);
}
unbanList.Clear();
}
if (list.Count > 0 && bandata == null && possibleData == null) {
possibleData = list[0];
}
}
if (bandata == null && possibleData != null) {
bandata = possibleData;
}
if (bandata != null && bandata.expire != 0.0 && permanent) {
PlayerDatabase_UpdateBan(bandata, 0.0);
}
return bandata != null;
}
string PlayerDatabase_Banlist(object source, int startid) {
if (startid > cachedBans.Count) {
return FormatReturn(BanSystem.PlayerDatabase, GetMsg("Index is out of range.Current bans recorded: {0}"), cachedBans.Count.ToString());
}
int i = -1;
int max = startid + 9;
string returnstring = FormatReturn(BanSystem.PlayerDatabase, GetMsg("Banlist - {0}-{1}/{2}\n"), startid.ToString(), max.ToString(), cachedBans.Count.ToString());
var bans = from pair in cachedBans orderby pair.Key descending select pair;
foreach (KeyValuePair<int, BanData> b in bans) {
i++;
if (i < startid) continue;
if (i > max) break;
returnstring += b.ToString() + "\n";
}
return returnstring;
}
////////////////////////////////////////////////////////////
// WebAPI
////////////////////////////////////////////////////////////
string FormatOnlineBansystem(string line, Dictionary<string, string> args) {
foreach (KeyValuePair<string, string> pair in args) {
line = line.Replace(pair.Key, pair.Value);
}
return line;
}
string WebAPI_ExecuteBan(object source, BanData bandata) {
webrequest.EnqueueGet(FormatOnlineBansystem(WebAPI_Ban_Request, new Dictionary<string, string> {
{
"{id}", bandata.id.ToString()
}
, {
"{steamid}", bandata.steamid
}
, {
"{name}", bandata.name
}
, {
"{ip}", bandata.ip
}
, {
"{reason}", bandata.reason
}
, {
"{source}", bandata.source
}
, {
"{expiration}", bandata.expire.ToString()
}
, {
"{game}", bandata.game
}
, {
"{platform}", bandata.platform
}
, {
"{server}", bandata.server
}
}
), (code, response) => {
if (response == null && code == 200) {
response = FormatReturn(BanSystem.WebAPI, "Couldn't contact the WebAPI");
}
if (source is IPlayer) ((IPlayer)source).Reply(response);
else Interface.Oxide.LogInfo(response);
}
, this);
return string.Empty;
}
string WebAPI_ExecuteUnban(object source, string steamid, string name, string ip) {
webrequest.EnqueueGet(FormatOnlineBansystem(WebAPI_Unban_Request, new Dictionary<string, string> {
{
"{steamid}", steamid
}
, {
"{name}", name
}
, {
"{ip}", ip
}
}
), (code, response) => {
if (response == null && code == 200) {
response = FormatReturn(BanSystem.WebAPI, "Couldn't contact the WebAPI");
}
if (source is IPlayer) ((IPlayer)source).Reply(response);
else Interface.Oxide.LogInfo(response);
}
, this);
return string.Empty;
}
string WebAPI_IsBanned(BanData bandata, bool update) {
webrequest.EnqueueGet(FormatOnlineBansystem(WebAPI_IsBanned_Request, new Dictionary<string, string> {
{
"{id}", bandata.id.ToString()
}
, {
"{steamid}", bandata.steamid
}
, {
"{name}", bandata.name
}
, {
"{ip}", bandata.ip
}
, {
"{source}", "EBS"
}
, {
"{update}", update.ToString()
}
, {
"{time}", LogTime().ToString()
}
}
), (code, response) => {
if (response != null || code != 200) {
if (response == "false" || response == "0") return;
timer.Once(0.01f, () => Kick(null, bandata.steamid, response == "true" || response == "1" ? "Banned" : response, false));
}
else {
Interface.Oxide.LogWarning("WebAPI couldn't be contacted or is not valid");
}
}
, this);
return string.Empty;
}
string WebAPI_Banlist(object source, int startid) {
webrequest.EnqueueGet(FormatOnlineBansystem(WebAPI_Banlist_Request, new Dictionary<string, string> {
{
"{startid}", startid.ToString()
}
}
), (code, response) => {
if (response != null || code != 200) {
SendReply(source, response);
}
}
, this);
return string.Empty;
}
string WebAPI_Load() {
return FormatReturn(BanSystem.WebAPI, GetMsg("Loaded\n\r"));
}
////////////////////////////////////////////////////////////
// SQLite
////////////////////////////////////////////////////////////
SQLite Sqlite = Interface.GetMod().GetLibrary<SQLite>();
Connection Sqlite_conn;
string SQLite_Load() {
var returnstring = string.Empty;
try {
Sqlite_conn = Sqlite.OpenDb(SQLite_DB, this);
if (Sqlite_conn == null) {
returnstring = FormatReturn(BanSystem.SQLite, "Couldn't open the SQLite.");
}
else {
Sqlite.Insert(Core.Database.Sql.Builder.Append("CREATE TABLE IF NOT EXISTS EnhancedBanSystem ( id INTEGER NOT NULL PRIMARY KEY UNIQUE, steamid TEXT, name TEXT, ip TEXT, reason TEXT, source TEXT, game TEXT, platform TEXT, server TEXT, expire INTEGER );"), Sqlite_conn);
returnstring = FormatReturn(BanSystem.SQLite, GetMsg("Loaded\n\r"));
}
}
catch (Exception e) {
returnstring = e.Message;
}
return FormatReturn(BanSystem.SQLite, returnstring);
}
string SQLite_RawBan(BanData bandata) {
try {
Sqlite.Insert(Core.Database.Sql.Builder.Append("INSERT OR REPLACE INTO EnhancedBanSystem ( id, steamid, name, ip, reason, source, game, platform, server, expire ) VALUES ( @0, @1, @2, @3, @4, @5, @6, @7, @8, @9 )", bandata.id, bandata.steamid, bandata.name, band
// ... [Code preview truncated due to length. Full source in attached file] ...