Merge branch 'Sanae6:master' into botupdates

This commit is contained in:
Piplup 2022-06-20 20:02:33 +01:00 committed by GitHub
commit d065253699
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 75 additions and 32 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ riderModule.iml
/_ReSharper.Caches/
.idea/
settings.json
.vs/

View File

@ -12,18 +12,31 @@ public class DiscordBot {
private string Prefix => Config.Prefix;
private readonly Logger Logger = new Logger("Discord");
private DiscordChannel? LogChannel;
private bool Reconnecting;
public DiscordBot() {
Token = Config.Token;
Logger.AddLogHandler(Log);
CommandHandler.RegisterCommand("dscrestart", _ => {
// this should be async'ed but i'm lazy
Reconnecting = true;
Task.Run(Reconnect);
return "Restarting Discord bot";
});
if (Config.Token == null) return;
Settings.LoadHandler += SettingsLoadHandler;
}
private async Task Reconnect() {
if (DiscordClient != null) // usually null prop works, not here though...`
await DiscordClient.DisconnectAsync();
await Run();
}
private async void SettingsLoadHandler() {
try {
if (DiscordClient == null || Token != Config.Token)
Run();
await Run();
if (Config.LogChannel != null)
LogChannel = await (DiscordClient?.GetChannelAsync(ulong.Parse(Config.LogChannel)) ??
throw new NullReferenceException("Discord client not setup yet!"));
@ -37,16 +50,17 @@ public class DiscordBot {
try {
if (DiscordClient != null && LogChannel != null) {
await DiscordClient.SendMessageAsync(LogChannel,
$"Console log:```{Logger.PrefixNewLines(text, $"{level} [{source}]")}```");
$"```{Logger.PrefixNewLines(text, $"{level} [{source}]")}```");
}
} catch (Exception e) {
// don't log again, it'll just stack overflow the server!
if (Reconnecting) return; // skip if reconnecting
await Console.Error.WriteLineAsync("Exception in discord logger");
await Console.Error.WriteLineAsync(e.ToString());
}
}
public async void Run() {
public async Task Run() {
Token = Config.Token;
DiscordClient?.Dispose();
if (Config.Token == null) {
@ -61,11 +75,19 @@ public class DiscordBot {
});
await DiscordClient.ConnectAsync(new DiscordActivity("Hide and Seek", ActivityType.Competing));
SettingsLoadHandler();
Logger.Info(
$"Discord bot logged in as {DiscordClient.CurrentUser.Username}#{DiscordClient.CurrentUser.Discriminator}");
Reconnecting = false;
string mentionPrefix = $"{DiscordClient.CurrentUser.Mention} ";
DiscordClient.MessageCreated += async (_, args) => {
if (args.Author.IsCurrent) return;
try {
DiscordMessage msg = args.Message;
if (msg.Content.StartsWith(Prefix)) {
if (string.IsNullOrEmpty(Prefix)) {
await msg.Channel.TriggerTypingAsync();
await msg.RespondAsync(string.Join('\n',
CommandHandler.GetResult(msg.Content).ReturnStrings));
} else if (msg.Content.StartsWith(Prefix)) {
await msg.Channel.TriggerTypingAsync();
await msg.RespondAsync(string.Join('\n',
CommandHandler.GetResult(msg.Content[Prefix.Length..]).ReturnStrings));

View File

@ -13,22 +13,22 @@ CancellationTokenSource cts = new CancellationTokenSource();
Task listenTask = server.Listen(cts.Token);
Logger consoleLogger = new Logger("Console");
DiscordBot bot = new DiscordBot();
bot.Run();
await bot.Run();
server.ClientJoined += (c, _) => {
if (Settings.Instance.BanList.Enabled && (Settings.Instance.BanList.Players.Contains(c.Id) || Settings.Instance.BanList.IpAddresses.Contains(
((IPEndPoint)c.Socket!.RemoteEndPoint!).Address.ToString())))
if (Settings.Instance.BanList.Enabled && (Settings.Instance.BanList.Players.Contains(c.Id) ||
Settings.Instance.BanList.IpAddresses.Contains(
((IPEndPoint) c.Socket!.RemoteEndPoint!).Address.ToString())))
throw new Exception($"Banned player attempted join: {c.Name}");
c.Metadata["shineSync"] = new ConcurrentBag<int>();
c.Metadata["loadedSave"] = false;
c.Metadata["scenario"] = (byte?)0;
c.Metadata["scenario"] = (byte?) 0;
c.Metadata["2d"] = false;
c.Metadata["speedrun"] = false;
foreach (Client client in server.Clients.Where(client => client.Metadata.ContainsKey("lastGamePacket")).ToArray()) {
try {
c.Send((GamePacket) client.Metadata["lastGamePacket"]!, client).Wait();
}
catch {
} catch {
// lol who gives a fuck
}
}
@ -44,8 +44,7 @@ async Task ClientSyncShineBag(Client client) {
ShineId = shine
});
}
}
catch {
} catch {
// errors that can happen when sending will crash the server :)
}
}
@ -53,8 +52,7 @@ async Task ClientSyncShineBag(Client client) {
async void SyncShineBag() {
try {
await Parallel.ForEachAsync(server.Clients.ToArray(), async (client, _) => await ClientSyncShineBag(client));
}
catch {
} catch {
// errors that can happen shines change will crash the server :)
}
}
@ -92,6 +90,7 @@ server.PacketHandler = (c, p) => {
});
break;
}
if (Settings.Instance.Scenario.MergeEnabled) {
server.BroadcastReplace(gamePacket, c, (from, to, gp) => {
gp.ScenarioNum = (byte?) to.Metadata["scenario"] ?? 200;
@ -99,11 +98,13 @@ server.PacketHandler = (c, p) => {
});
return false;
}
break;
}
case TagPacket tagPacket: {
if ((tagPacket.UpdateType & TagPacket.TagUpdate.State) != 0) c.Metadata["seeking"] = tagPacket.IsIt;
if ((tagPacket.UpdateType & TagPacket.TagUpdate.Time) != 0) c.Metadata["time"] = new Time(tagPacket.Minutes, tagPacket.Seconds, DateTime.Now);
if ((tagPacket.UpdateType & TagPacket.TagUpdate.Time) != 0)
c.Metadata["time"] = new Time(tagPacket.Minutes, tagPacket.Seconds, DateTime.Now);
break;
}
case CostumePacket:
@ -124,7 +125,8 @@ server.PacketHandler = (c, p) => {
&& Settings.Instance.Flip.Pov is FlipOptions.Both or FlipOptions.Others
&& Settings.Instance.Flip.Players.Contains(c.Id): {
playerPacket.Position += Vector3.UnitY * MarioSize((bool) c.Metadata["2d"]);
playerPacket.Rotation *= Quaternion.CreateFromRotationMatrix(Matrix4x4.CreateRotationX(MathF.PI)) * Quaternion.CreateFromRotationMatrix(Matrix4x4.CreateRotationY(MathF.PI));
playerPacket.Rotation *= Quaternion.CreateFromRotationMatrix(Matrix4x4.CreateRotationX(MathF.PI)) *
Quaternion.CreateFromRotationMatrix(Matrix4x4.CreateRotationY(MathF.PI));
server.Broadcast(playerPacket, c);
return false;
}
@ -134,7 +136,8 @@ server.PacketHandler = (c, p) => {
server.BroadcastReplace(playerPacket, c, (from, to, sp) => {
if (Settings.Instance.Flip.Players.Contains(to.Id)) {
sp.Position += Vector3.UnitY * MarioSize((bool) c.Metadata["2d"]);
sp.Rotation *= Quaternion.CreateFromRotationMatrix(Matrix4x4.CreateRotationX(MathF.PI)) * Quaternion.CreateFromRotationMatrix(Matrix4x4.CreateRotationY(MathF.PI));
sp.Rotation *= Quaternion.CreateFromRotationMatrix(Matrix4x4.CreateRotationX(MathF.PI)) *
Quaternion.CreateFromRotationMatrix(Matrix4x4.CreateRotationY(MathF.PI));
}
to.Send(sp, from);
@ -208,6 +211,7 @@ CommandHandler.RegisterCommand("ban", args => {
Settings.SaveSettings();
return $"Banned {builder}.";
}
return "Usage: ban <usernames...>";
});
@ -223,13 +227,17 @@ CommandHandler.RegisterCommand("send", args => {
stage = mapName;
}
if(!stage.Contains("Stage") && !stage.Contains("Zone")) {
if (!stage.Contains("Stage") && !stage.Contains("Zone")) {
return "Invalid Stage Name!";
}
if (!sbyte.TryParse(args[2], out sbyte scenario) || scenario < -1) return $"Invalid scenario number {args[2]} (range: [-1 to 127])";
Client[] players = args[3] == "*" ? server.Clients.Where(c => c.Connected).ToArray() : server.Clients.Where(c => c.Connected && args[3..].Any(x => c.Name.StartsWith(x) ||
(Guid.TryParse(x, out Guid result) && result == c.Id))).ToArray();
if (!sbyte.TryParse(args[2], out sbyte scenario) || scenario < -1)
return $"Invalid scenario number {args[2]} (range: [-1 to 127])";
Client[] players = args[3] == "*"
? server.Clients.Where(c => c.Connected).ToArray()
: server.Clients.Where(c => c.Connected && args[3..].Any(x => c.Name.StartsWith(x) ||
(Guid.TryParse(x, out Guid result) &&
result == c.Id))).ToArray();
Parallel.ForEachAsync(players, async (c, _) => {
await c.Send(new ChangeStagePacket {
Stage = stage,
@ -252,7 +260,7 @@ CommandHandler.RegisterCommand("sendall", args => {
stage = mapName;
}
if(!stage.Contains("Stage") && !stage.Contains("Zone")) {
if (!stage.Contains("Stage") && !stage.Contains("Zone")) {
return "Invalid Stage Name!";
}
@ -293,15 +301,18 @@ CommandHandler.RegisterCommand("scenario", args => {
});
CommandHandler.RegisterCommand("tag", args => {
const string optionUsage = "Valid options:\n\ttime <user/*> <minutes[0-65535]> <seconds[0-59]>\n\tseeking <user/*> <true/false>\n\tstart <time> <seekers>";
const string optionUsage =
"Valid options:\n\ttime <user/*> <minutes[0-65535]> <seconds[0-59]>\n\tseeking <user/*> <true/false>\n\tstart <time> <seekers>";
if (args.Length < 3)
return optionUsage;
switch (args[0]) {
case "time" when args.Length == 4: {
if (args[1] != "*" && server.Clients.All(x => x.Name != args[1])) return $"Cannot find user {args[1]}";
Client? client = server.Clients.FirstOrDefault(x => x.Name == args[1]);
if (!ushort.TryParse(args[2], out ushort minutes)) return $"Invalid time for minutes {args[2]} (range: 0-65535)";
if (!byte.TryParse(args[3], out byte seconds) || seconds >= 60) return $"Invalid time for seconds {args[3]} (range: 0-59)";
if (!ushort.TryParse(args[2], out ushort minutes))
return $"Invalid time for minutes {args[2]} (range: 0-65535)";
if (!byte.TryParse(args[3], out byte seconds) || seconds >= 60)
return $"Invalid time for seconds {args[3]} (range: 0-59)";
TagPacket tagPacket = new TagPacket {
UpdateType = TagPacket.TagUpdate.Time,
Minutes = minutes,
@ -332,7 +343,8 @@ CommandHandler.RegisterCommand("tag", args => {
string[] seekerNames = args[2..];
Client[] seekers = server.Clients.Where(c => seekerNames.Contains(c.Name)).ToArray();
if (seekers.Length != seekerNames.Length)
return $"Couldn't find seeker{(seekerNames.Length > 1 ? "s" : "")}: {string.Join(", ", seekerNames.Where(name => server.Clients.All(c => c.Name != name)))}";
return
$"Couldn't find seeker{(seekerNames.Length > 1 ? "s" : "")}: {string.Join(", ", seekerNames.Where(name => server.Clients.All(c => c.Name != name)))}";
Task.Run(async () => {
int realTime = 1000 * time;
await Task.Delay(realTime);
@ -369,10 +381,12 @@ CommandHandler.RegisterCommand("maxplayers", args => {
return $"Saved and set max players to {maxPlayers}";
});
CommandHandler.RegisterCommand("list", _ => $"List: {string.Join("\n\t", server.Clients.Where(x => x.Connected).Select(x => $"{x.Name} ({x.Id})"))}");
CommandHandler.RegisterCommand("list",
_ => $"List: {string.Join("\n\t", server.Clients.Where(x => x.Connected).Select(x => $"{x.Name} ({x.Id})"))}");
CommandHandler.RegisterCommand("flip", args => {
const string optionUsage = "Valid options: \n\tlist\n\tadd <user id>\n\tremove <user id>\n\tset <true/false>\n\tpov <both/self/others>";
const string optionUsage =
"Valid options: \n\tlist\n\tadd <user id>\n\tremove <user id>\n\tset <true/false>\n\tpov <both/self/others>";
if (args.Length < 1)
return optionUsage;
switch (args[0]) {
@ -389,7 +403,9 @@ CommandHandler.RegisterCommand("flip", args => {
}
case "remove" when args.Length == 2: {
if (Guid.TryParse(args[1], out Guid result)) {
string output = Settings.Instance.Flip.Players.Remove(result) ? $"Removed {result} to flipped players" : $"User {result} wasn't in the flipped players list";
string output = Settings.Instance.Flip.Players.Remove(result)
? $"Removed {result} to flipped players"
: $"User {result} wasn't in the flipped players list";
Settings.SaveSettings();
return output;
}
@ -428,7 +444,8 @@ CommandHandler.RegisterCommand("shine", args => {
return $"Shines: {string.Join(", ", shineBag)}";
case "clear" when args.Length == 1:
shineBag.Clear();
foreach (ConcurrentBag<int> playerBag in server.Clients.Select(serverClient => (ConcurrentBag<int>) serverClient.Metadata["shineSync"])) playerBag.Clear();
foreach (ConcurrentBag<int> playerBag in server.Clients.Select(serverClient =>
(ConcurrentBag<int>) serverClient.Metadata["shineSync"])) playerBag.Clear();
return "Cleared shine bags";
case "sync" when args.Length == 1:
@ -436,7 +453,9 @@ CommandHandler.RegisterCommand("shine", args => {
return "Synced shine bag automatically";
case "send" when args.Length >= 3:
if (int.TryParse(args[1], out int id)) {
Client[] players = args[2] == "*" ? server.Clients.Where(c => c.Connected).ToArray() : server.Clients.Where(c => c.Connected && args[3..].Contains(c.Name)).ToArray();
Client[] players = args[2] == "*"
? server.Clients.Where(c => c.Connected).ToArray()
: server.Clients.Where(c => c.Connected && args[3..].Contains(c.Name)).ToArray();
Parallel.ForEachAsync(players, async (c, _) => {
await c.Send(new ShinePacket {
ShineId = id

View File

@ -34,8 +34,9 @@ public class Logger {
static Logger() {
AddLogHandler((source, level, text, color) => {
DateTime logtime = DateTime.Now;
Console.ForegroundColor = color;
Console.Write(PrefixNewLines(text, $"{level} [{source}]"));
Console.Write(PrefixNewLines(text, $"{{{logtime}}} {level} [{source}]"));
});
}
}