2023-03-22 20:33:37 +00:00
|
|
|
using System.Net;
|
2023-03-22 20:39:47 +00:00
|
|
|
using System.Net.Sockets;
|
2023-03-22 20:33:37 +00:00
|
|
|
using System.Text;
|
|
|
|
|
|
|
|
using Shared.Packet.Packets;
|
|
|
|
|
|
|
|
namespace Server;
|
|
|
|
|
|
|
|
using MUCH = Func<string[], (HashSet<string> failToFind, HashSet<Client> toActUpon, List<(string arg, IEnumerable<string> amb)> ambig)>;
|
|
|
|
|
|
|
|
public static class BanLists {
|
|
|
|
public static bool Enabled {
|
|
|
|
get {
|
|
|
|
return Settings.Instance.BanList.Enabled;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static List<string> IPs {
|
|
|
|
get {
|
|
|
|
return Settings.Instance.BanList.IpAddresses;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static List<Guid> Profiles {
|
|
|
|
get {
|
|
|
|
return Settings.Instance.BanList.Players;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-03-22 20:39:47 +00:00
|
|
|
private static bool IsIPv4(string str) {
|
|
|
|
return IPAddress.TryParse(str, out IPAddress? ip)
|
|
|
|
&& ip != null
|
|
|
|
&& ip.AddressFamily == AddressFamily.InterNetwork;
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-03-22 20:33:37 +00:00
|
|
|
public static bool IsIPv4Banned(Client user) {
|
|
|
|
IPEndPoint? ipv4 = (IPEndPoint?) user.Socket?.RemoteEndPoint;
|
|
|
|
if (ipv4 == null) { return false; }
|
|
|
|
return IsIPv4Banned(ipv4.Address);
|
|
|
|
}
|
|
|
|
public static bool IsIPv4Banned(IPAddress ipv4) {
|
|
|
|
return IsIPv4Banned(ipv4.ToString());
|
|
|
|
}
|
|
|
|
public static bool IsIPv4Banned(string ipv4) {
|
|
|
|
return IPs.Contains(ipv4);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static bool IsProfileBanned(Client user) {
|
|
|
|
return IsProfileBanned(user.Id);
|
|
|
|
}
|
|
|
|
public static bool IsProfileBanned(string str) {
|
|
|
|
if (!Guid.TryParse(str, out Guid id)) { return false; }
|
|
|
|
return IsProfileBanned(id);
|
|
|
|
}
|
|
|
|
public static bool IsProfileBanned(Guid id) {
|
|
|
|
return Profiles.Contains(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static bool IsClientBanned(Client user) {
|
|
|
|
return IsProfileBanned(user) || IsIPv4Banned(user);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static void BanIPv4(Client user) {
|
|
|
|
IPEndPoint? ipv4 = (IPEndPoint?) user.Socket?.RemoteEndPoint;
|
|
|
|
if (ipv4 != null) {
|
|
|
|
BanIPv4(ipv4.Address);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
private static void BanIPv4(IPAddress ipv4) {
|
|
|
|
BanIPv4(ipv4.ToString());
|
|
|
|
}
|
|
|
|
private static void BanIPv4(string ipv4) {
|
|
|
|
IPs.Add(ipv4);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void BanProfile(Client user) {
|
|
|
|
BanProfile(user.Id);
|
|
|
|
}
|
|
|
|
private static void BanProfile(string str) {
|
|
|
|
if (!Guid.TryParse(str, out Guid id)) { return; }
|
|
|
|
BanProfile(id);
|
|
|
|
}
|
|
|
|
private static void BanProfile(Guid id) {
|
|
|
|
Profiles.Add(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void BanClient(Client user) {
|
|
|
|
BanProfile(user);
|
|
|
|
BanIPv4(user);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static void Save() {
|
|
|
|
Settings.SaveSettings(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static void Crash(Client user, bool permanent = false) {
|
|
|
|
Task.Run(async () => {
|
|
|
|
await user.Send(new ChangeStagePacket {
|
|
|
|
Id = (permanent ? "$agogus/ban4lyfe" : "$among$us/cr4sh%"),
|
|
|
|
Stage = (permanent ? "$ejected" : "$agogusStage"),
|
|
|
|
Scenario = (sbyte) (permanent ? 69 : 21),
|
|
|
|
SubScenarioType = (byte) (permanent ? 21 : 69),
|
|
|
|
});
|
|
|
|
user.Dispose();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-03-22 20:39:47 +00:00
|
|
|
private static void CrashMultiple(string[] args, MUCH much) {
|
|
|
|
foreach (Client user in much(args).toActUpon) {
|
|
|
|
Crash(user, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-22 20:33:37 +00:00
|
|
|
|
|
|
|
public static string HandleBanCommand(string[] args, MUCH much) {
|
|
|
|
if (args.Length == 0) {
|
2023-03-22 20:39:47 +00:00
|
|
|
return "Usage: ban {player|ip} ...";
|
2023-03-22 20:33:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
string cmd = args[0];
|
|
|
|
args = args.Skip(1).ToArray();
|
|
|
|
|
|
|
|
switch (cmd) {
|
|
|
|
default:
|
2023-03-22 20:39:47 +00:00
|
|
|
return "Usage: ban {player|ip} ...";
|
2023-03-22 20:33:37 +00:00
|
|
|
|
|
|
|
case "player":
|
|
|
|
if (args.Length == 0) {
|
|
|
|
return "Usage: ban player <* | !* (usernames to not ban...) | (usernames to ban...)>";
|
|
|
|
}
|
|
|
|
|
|
|
|
var res = much(args);
|
|
|
|
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
sb.Append(res.toActUpon.Count > 0 ? "Banned players: " + string.Join(", ", res.toActUpon.Select(x => $"\"{x.Name}\"")) : "");
|
|
|
|
sb.Append(res.failToFind.Count > 0 ? "\nFailed to find matches for: " + string.Join(", ", res.failToFind.Select(x => $"\"{x.ToLower()}\"")) : "");
|
|
|
|
if (res.ambig.Count > 0) {
|
|
|
|
res.ambig.ForEach(x => {
|
|
|
|
sb.Append($"\nAmbiguous for \"{x.arg}\": {string.Join(", ", x.amb.Select(x => $"\"{x}\""))}");
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach (Client user in res.toActUpon) {
|
|
|
|
BanClient(user);
|
|
|
|
Crash(user, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
Save();
|
|
|
|
return sb.ToString();
|
2023-03-22 20:39:47 +00:00
|
|
|
|
|
|
|
case "ip":
|
|
|
|
if (args.Length != 1) {
|
|
|
|
return "Usage: ban ip <ipv4-address>";
|
|
|
|
}
|
|
|
|
if (!IsIPv4(args[0])) {
|
|
|
|
return "Invalid IPv4 address!";
|
|
|
|
}
|
|
|
|
if (IsIPv4Banned(args[0])) {
|
|
|
|
return "IP " + args[0] + " is already banned.";
|
|
|
|
}
|
|
|
|
BanIPv4(args[0]);
|
|
|
|
CrashMultiple(args, much);
|
|
|
|
Save();
|
|
|
|
return "Banned ip: " + args[0];
|
2023-03-22 20:33:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|