mirror of
https://github.com/Sanae6/SmoOnlineServer.git
synced 2024-11-22 03:05:16 +00:00
added !* variants for ban, crash, rejoin
This commit is contained in:
parent
3b8ba17217
commit
ba02c88b13
1 changed files with 94 additions and 92 deletions
|
@ -1,8 +1,7 @@
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
|
||||||
using Server;
|
using Server;
|
||||||
using Shared;
|
using Shared;
|
||||||
using Shared.Packet.Packets;
|
using Shared.Packet.Packets;
|
||||||
|
@ -16,47 +15,6 @@ Logger consoleLogger = new Logger("Console");
|
||||||
DiscordBot bot = new DiscordBot();
|
DiscordBot bot = new DiscordBot();
|
||||||
await bot.Run();
|
await bot.Run();
|
||||||
|
|
||||||
async Task PersistShines()
|
|
||||||
{
|
|
||||||
if (!Settings.Instance.PersistShines.Enabled)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string shineJson = JsonSerializer.Serialize(shineBag);
|
|
||||||
await File.WriteAllTextAsync(Settings.Instance.PersistShines.Filename, shineJson);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
consoleLogger.Error(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async Task LoadShines()
|
|
||||||
{
|
|
||||||
if (!Settings.Instance.PersistShines.Enabled)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string shineJson = await File.ReadAllTextAsync(Settings.Instance.PersistShines.Filename);
|
|
||||||
var loadedShines = JsonSerializer.Deserialize<HashSet<int>>(shineJson);
|
|
||||||
|
|
||||||
if (loadedShines is not null) shineBag = loadedShines;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
consoleLogger.Error(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load shines table from file
|
|
||||||
await LoadShines();
|
|
||||||
|
|
||||||
server.ClientJoined += (c, _) => {
|
server.ClientJoined += (c, _) => {
|
||||||
if (Settings.Instance.BanList.Enabled
|
if (Settings.Instance.BanList.Enabled
|
||||||
&& (Settings.Instance.BanList.Players.Contains(c.Id)
|
&& (Settings.Instance.BanList.Players.Contains(c.Id)
|
||||||
|
@ -94,7 +52,6 @@ async Task ClientSyncShineBag(Client client) {
|
||||||
|
|
||||||
async void SyncShineBag() {
|
async void SyncShineBag() {
|
||||||
try {
|
try {
|
||||||
await PersistShines();
|
|
||||||
await Parallel.ForEachAsync(server.Clients.ToArray(), async (client, _) => await ClientSyncShineBag(client));
|
await Parallel.ForEachAsync(server.Clients.ToArray(), async (client, _) => await ClientSyncShineBag(client));
|
||||||
} catch {
|
} catch {
|
||||||
// errors that can happen shines change will crash the server :)
|
// errors that can happen shines change will crash the server :)
|
||||||
|
@ -121,9 +78,6 @@ server.PacketHandler = (c, p) => {
|
||||||
c.Metadata["speedrun"] = true;
|
c.Metadata["speedrun"] = true;
|
||||||
((ConcurrentBag<int>) (c.Metadata["shineSync"] ??= new ConcurrentBag<int>())).Clear();
|
((ConcurrentBag<int>) (c.Metadata["shineSync"] ??= new ConcurrentBag<int>())).Clear();
|
||||||
shineBag.Clear();
|
shineBag.Clear();
|
||||||
Task.Run(async () => {
|
|
||||||
await PersistShines();
|
|
||||||
});
|
|
||||||
c.Logger.Info("Entered Cap on new save, preventing moon sync until Cascade");
|
c.Logger.Info("Entered Cap on new save, preventing moon sync until Cascade");
|
||||||
break;
|
break;
|
||||||
case "WaterfallWorldHomeStage":
|
case "WaterfallWorldHomeStage":
|
||||||
|
@ -206,40 +160,89 @@ server.PacketHandler = (c, p) => {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
CommandHandler.RegisterCommand("rejoin", args => {
|
(List<string> failToFind, List<Client> toActUpon, List<(string arg, IEnumerable<string> amb)> ambig) MultiUserCommandHelper(string[] args) {
|
||||||
if (args.Length == 0) {
|
List<string> failToFind = new();
|
||||||
return "Usage: rejoin <* | usernames...>";
|
List<Client> toActUpon;
|
||||||
|
List<(string arg, IEnumerable<string> amb)> ambig = new();
|
||||||
|
if (args[0] == "*")
|
||||||
|
toActUpon = new(server.Clients.Where(c => c.Connected));
|
||||||
|
else {
|
||||||
|
toActUpon = args[0] == "!*" ? new(server.Clients.Where(c => c.Connected)) : new();
|
||||||
|
for (int i = (args[0] == "!*" ? 1 : 0); i < args.Length; i++) {
|
||||||
|
string arg = args[i];
|
||||||
|
IEnumerable<Client> search = server.Clients.Where(c => c.Connected &&
|
||||||
|
(c.Name.ToLower().StartsWith(arg.ToLower()) || (Guid.TryParse(arg, out Guid res) && res == c.Id)));
|
||||||
|
if (!search.Any())
|
||||||
|
failToFind.Add(arg.ToLower()); //none found
|
||||||
|
else if (search.Count() > 1) {
|
||||||
|
Client? exact = search.FirstOrDefault(x => x.Name == arg);
|
||||||
|
if (!ReferenceEquals(exact, null)) {
|
||||||
|
//even though multiple matches, since exact match, it isn't ambiguous
|
||||||
|
if (args[0] == "!*")
|
||||||
|
toActUpon.Remove(exact);
|
||||||
|
else
|
||||||
|
toActUpon.Add(exact);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ambig.Add((arg.ToLower(), search.Select(x => x.Name))); //more than one match
|
||||||
|
foreach (var rem in search.ToList()) //need copy because can't remove from list while iterating over it
|
||||||
|
toActUpon.Remove(rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//only one match, so autocomplete
|
||||||
|
if (args[0] == "!*")
|
||||||
|
toActUpon.Remove(search.First());
|
||||||
|
else
|
||||||
|
toActUpon.Add(search.First());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bool moreThanOne = false;
|
return (failToFind, toActUpon, ambig);
|
||||||
StringBuilder builder = new StringBuilder();
|
}
|
||||||
Client[] clients = (args[0].Trim() == "*"
|
|
||||||
? server.Clients.Where(c => c.Connected)
|
CommandHandler.RegisterCommand("rejoin", args => {
|
||||||
: server.Clients.Where(c =>
|
if (args.Length == 0) {
|
||||||
c.Connected && args.Any(x => c.Name == x || (Guid.TryParse(x, out Guid result) && result == c.Id)))).ToArray();
|
return "Usage: rejoin <* | !* (usernames to not rejoin...) | (usernames to rejoin...)>";
|
||||||
foreach (Client user in clients) {
|
|
||||||
if (moreThanOne) builder.Append(", ");
|
|
||||||
builder.Append(user.Name);
|
|
||||||
user.Dispose();
|
|
||||||
moreThanOne = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return clients.Length > 0 ? $"Caused {builder} to rejoin" : "Usage: rejoin <usernames...>";
|
var res = MultiUserCommandHelper(args);
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.Append(res.toActUpon.Count > 0 ? "Crashed: " + string.Join(", ", res.toActUpon.Select(x => $"\"{x.Name}\"")) + "\n" : "");
|
||||||
|
sb.Append(res.failToFind.Count > 0 ? "Failed to find matches for: " + string.Join(", ", res.failToFind.Select(x => $"\"{x.ToLower()}\"")) + "\n" : "");
|
||||||
|
if (res.ambig.Count > 0) {
|
||||||
|
res.ambig.ForEach(x => {
|
||||||
|
sb.Append($"Ambiguous for {x.arg}: {string.Join(", ", x.amb.Select(x => $"\"{x}\""))}\n");
|
||||||
|
});
|
||||||
|
sb.Remove(sb.Length - 1, 1); //remove extra nl
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (Client user in res.toActUpon) {
|
||||||
|
user.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
});
|
});
|
||||||
|
|
||||||
CommandHandler.RegisterCommand("crash", args => {
|
CommandHandler.RegisterCommand("crash", args => {
|
||||||
if (args.Length == 0) {
|
if (args.Length == 0) {
|
||||||
return "Usage: crash <* | usernames...>";
|
return "Usage: crash <* | !* (usernames to not crash...) | (usernames to crash...)>";
|
||||||
}
|
}
|
||||||
bool moreThanOne = false;
|
|
||||||
StringBuilder builder = new StringBuilder();
|
var res = MultiUserCommandHelper(args);
|
||||||
Client[] clients = (args[0].Trim() == "*"
|
|
||||||
? server.Clients.Where(c => c.Connected)
|
StringBuilder sb = new StringBuilder();
|
||||||
: server.Clients.Where(c =>
|
sb.Append(res.toActUpon.Count > 0 ? "Crashed: " + string.Join(", ", res.toActUpon.Select(x => $"\"{x.Name}\"")) + "\n" : "");
|
||||||
c.Connected && args.Any(x => c.Name == x || (Guid.TryParse(x, out Guid result) && result == c.Id)))).ToArray();
|
sb.Append(res.failToFind.Count > 0 ? "Failed to find matches for: " + string.Join(", ", res.failToFind.Select(x => $"\"{x.ToLower()}\"")) + "\n" : "");
|
||||||
foreach (Client user in clients) {
|
if (res.ambig.Count > 0) {
|
||||||
if (moreThanOne) builder.Append(", ");
|
res.ambig.ForEach(x => {
|
||||||
moreThanOne = true;
|
sb.Append($"Ambiguous for {x.arg}: {string.Join(", ", x.amb.Select(x => $"\"{x}\""))}\n");
|
||||||
builder.Append(user.Name);
|
});
|
||||||
|
sb.Remove(sb.Length - 1, 1); //remove extra nl
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (Client user in res.toActUpon) {
|
||||||
Task.Run(async () => {
|
Task.Run(async () => {
|
||||||
await user.Send(new ChangeStagePacket {
|
await user.Send(new ChangeStagePacket {
|
||||||
Id = "$among$us/SubArea",
|
Id = "$among$us/SubArea",
|
||||||
|
@ -251,24 +254,27 @@ CommandHandler.RegisterCommand("crash", args => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return clients.Length > 0 ? $"Crashed {builder}" : "Usage: crash <usernames...>";
|
return sb.ToString();
|
||||||
});
|
});
|
||||||
|
|
||||||
CommandHandler.RegisterCommand("ban", args => {
|
CommandHandler.RegisterCommand("ban", args => {
|
||||||
if (args.Length == 0) {
|
if (args.Length == 0) {
|
||||||
return "Usage: ban <* | usernames...>";
|
return "Usage: ban <* | !* (usernames to not ban...) | (usernames to ban...)>";
|
||||||
}
|
}
|
||||||
bool moreThanOne = false;
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
|
|
||||||
Client[] clients = (args[0].Trim() == "*"
|
var res = MultiUserCommandHelper(args);
|
||||||
? server.Clients.Where(c => c.Connected)
|
|
||||||
: server.Clients.Where(c =>
|
StringBuilder sb = new StringBuilder();
|
||||||
c.Connected && args.Any(x => c.Name == x || (Guid.TryParse(x, out Guid result) && result == c.Id)))).ToArray();
|
sb.Append(res.toActUpon.Count > 0 ? "Banned: " + string.Join(", ", res.toActUpon.Select(x => $"\"{x.Name}\"")) + "\n" : "");
|
||||||
foreach (Client user in clients) {
|
sb.Append(res.failToFind.Count > 0 ? "Failed to find matches for: " + string.Join(", ", res.failToFind.Select(x => $"\"{x.ToLower()}\"")) + "\n" : "");
|
||||||
if (moreThanOne) builder.Append(", ");
|
if (res.ambig.Count > 0) {
|
||||||
moreThanOne = true;
|
res.ambig.ForEach(x => {
|
||||||
builder.Append(user.Name);
|
sb.Append($"Ambiguous for {x.arg}: {string.Join(", ", x.amb.Select(x => $"\"{x}\""))}\n");
|
||||||
|
});
|
||||||
|
sb.Remove(sb.Length - 1, 1); //remove extra nl
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (Client user in res.toActUpon) {
|
||||||
Task.Run(async () => {
|
Task.Run(async () => {
|
||||||
await user.Send(new ChangeStagePacket {
|
await user.Send(new ChangeStagePacket {
|
||||||
Id = "$agogus/banned4lyfe",
|
Id = "$agogus/banned4lyfe",
|
||||||
|
@ -283,12 +289,8 @@ CommandHandler.RegisterCommand("ban", args => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clients.Length > 0) {
|
Settings.SaveSettings();
|
||||||
Settings.SaveSettings();
|
return sb.ToString();
|
||||||
return $"Banned {builder}.";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "Usage: ban <usernames...>";
|
|
||||||
});
|
});
|
||||||
|
|
||||||
CommandHandler.RegisterCommand("send", args => {
|
CommandHandler.RegisterCommand("send", args => {
|
||||||
|
|
Loading…
Reference in a new issue