void IModule.Install(ModuleManager manager) { manager.CreateDynCommands("verm", PermissionLevel.User, group => { group.CreateCommand("roulette") .Description( "Picks a random mission and a random difficulty. (Can be overriden with an optional param.)") .Parameter("difficulty", ParameterType.Optional) .Do(async e => { string diff = e.GetArg("difficulty"); if (string.IsNullOrEmpty(diff)) diff = _difficulties.PickRandom(); await e.Channel.SafeSendMessage($"{_missions.PickRandom()} on {diff}"); }); }); }
void IModule.Install(ModuleManager manager) { _client = manager.Client; _client.MessageReceived += (s, e) => { StringBuilder builder = new StringBuilder($"Msg: "); if (e.Server != null) builder.Append($"{e.Server.Name} "); builder.Append(e.Channel.Name); Logger.FormattedWrite(builder.ToString(), e.Message.ToString(), ConsoleColor.White); }; _io = _client.GetService<DataIoService>(); manager.CreateCommands("", group => { group.MinPermissions((int) PermissionLevel.BotOwner); group.CreateCommand("io save") .Description("Saves data used by the bot.") .Do(e => _io.Save()); group.CreateCommand("io load") .Description("Loads data that the bot loads at runtime.") .Do(e => _io.Load()); group.CreateCommand("set name") .Description("Changes the name of the bot") .Parameter("name", ParameterType.Unparsed) .Do(async e => await _client.CurrentUser.Edit(Config.Pass, e.GetArg("name"))); group.CreateCommand("set avatar") .Description("Changes the avatar of the bot") .Parameter("name") .Do(async e => { string avDir = Constants.DataFolderDir + e.GetArg("name"); using (FileStream stream = new FileStream(avDir, FileMode.Open)) { ImageType type; switch (Path.GetExtension(avDir)) { case ".jpg": case ".jpeg": type = ImageType.Jpeg; break; case ".png": type = ImageType.Png; break; default: return; } await _client.CurrentUser.Edit(Config.Pass, avatar: stream, avatarType: type); } }); group.CreateCommand("set game") .Description("Sets the current played game for the bot.") .Parameter("game", ParameterType.Unparsed) .Do(e => _client.SetGame(e.GetArg("game"))); group.CreateCommand("killbot") .Description("Kills the bot.") .Do(x => { _io.Save(); Environment.Exit(0); }); group.CreateCommand("gc") .Description("Lists used memory, then collects it.") .Do(async e => { await PrintMemUsage(e); await Collect(e); }); group.CreateCommand("gc collect") .Description("Calls GC.Collect()") .Do(async e => await Collect(e)); group.CreateCommand("gencmdmd") .AddCheck((cmd, usr, chnl) => !chnl.IsPrivate) .Do(async e => await DiscordUtils.GenerateCommandMarkdown(_client)); }); manager.CreateDynCommands("", PermissionLevel.User, group => { group.CreateCommand("join") .Description("Joins a server by invite.") .Parameter("invite") .Do(async e => await DiscordUtils.JoinInvite(e.GetArg("invite"), e.Channel)); group.CreateCommand("leave") .Description("Instructs the bot to leave this server.") .MinDynPermissions((int) PermissionLevel.ServerModerator) .Do(async e => await e.Server.Leave()); group.CreateCommand("cleanmsg") .Description("Removes the last 100 messages sent by the bot in this channel.") .MinPermissions((int) PermissionLevel.ChannelModerator) .Do(async e => { foreach (Message msg in (await e.Channel.DownloadMessages()).Where(m => m.IsAuthor)) await msg.Delete(); }); group.CreateCommand("gc list") .Description("Calls GC.GetTotalMemory()") .Do(async e => await PrintMemUsage(e)); }); manager.MessageReceived += async (s, e) => { if (!e.Channel.IsPrivate) return; if (e.Message.Text.StartsWith("https://discord")) { string invite = string.Empty; try { invite = e.Message.Text.Split(' ').FirstOrDefault(); } catch { } // ignored if (!string.IsNullOrEmpty(invite)) await DiscordUtils.JoinInvite(invite, e.Channel); } }; }
void IModule.Install(ModuleManager manager) { _client = manager.Client; _moduleService = _client.GetService<ModuleService>(); manager.CreateDynCommands("module", PermissionLevel.ServerAdmin, group => { group.AddCheck((cmd, usr, chnl) => !chnl.IsPrivate); group.CreateCommand("channel enable") .Description("Enables a module on the current channel.") .Parameter("module", ParameterType.Unparsed) .Do(async e => { ModuleManager module = await VerifyFindModule(e.GetArg("module"), e.Channel); if (module == null) return; if (!await CanChangeModuleStateInServer(module, ModuleFilter.ChannelWhitelist, e)) return; Channel channel = e.Channel; if (!module.EnableChannel(channel)) { await e.Channel.SafeSendMessage( $"Module `{module.Id}` was already enabled for channel `{channel.Name}`."); return; } _channelModulesDictionary.AddModuleToSave(module.Id, e.Channel.Id); await e.Channel.SafeSendMessage($"Module `{module.Id}` was enabled for channel `{channel.Name}`."); }); group.CreateCommand("channel disable") .Description("Disable a module on the current channel.") .Parameter("module", ParameterType.Unparsed) .Do(async e => { ModuleManager module = await VerifyFindModule(e.GetArg("module"), e.Channel); if (module == null) return; if (!await CanChangeModuleStateInServer(module, ModuleFilter.ChannelWhitelist, e, false)) return; Channel channel = e.Channel; if (!module.DisableChannel(channel)) { await e.Channel.SafeSendMessage( $"Module `{module.Id}` was not enabled for channel `{channel.Name}`."); return; } _channelModulesDictionary.DeleteModuleFromSave(module.Id, e.Channel.Id); await e.Channel.SafeSendMessage($"Module `{module.Id}` was disabled for channel `{channel.Name}`."); }); group.CreateCommand("server enable") .Description("Enables a module on the current server.") .Parameter("module", ParameterType.Unparsed) .Do(async e => { ModuleManager module = await VerifyFindModule(e.GetArg("module"), e.Channel); if (module == null) return; if (!await CanChangeModuleStateInServer(module, ModuleFilter.ServerWhitelist, e)) return; Server server = e.Server; if (!module.EnableServer(server)) { await e.Channel.SafeSendMessage( $"Module `{module.Id}` was already enabled for server `{server.Name}`."); return; } _serverModulesDictionary.AddModuleToSave(module.Id, e.Server.Id); await e.Channel.SafeSendMessage($"Module `{module.Id}` was enabled for server `{server.Name}`."); }); group.CreateCommand("server disable") .Description("Disables a module for the current server.") .Parameter("module", ParameterType.Unparsed) .Do(async e => { ModuleManager module = await VerifyFindModule(e.GetArg("module"), e.Channel); if (module == null) return; if (!await CanChangeModuleStateInServer(module, ModuleFilter.ServerWhitelist, e, false)) return; Server server = e.Server; if (!module.DisableServer(server)) { await e.Channel.SafeSendMessage( $"Module `{module.Id}` was not enabled for server `{server.Name}`."); return; } _serverModulesDictionary.DeleteModuleFromSave(module.Id, e.Server.Id); await e.Channel.SafeSendMessage($"Module `{module.Id}` was disabled for server `{server.Name}`."); }); group.CreateCommand("list") .Description("Lists all available modules.") .Do(async e => { StringBuilder builder = new StringBuilder("**Available modules:**\r\n"); foreach (ModuleManager module in _moduleService.Modules) { builder.Append($"`* {module.Id,-20} "); if (e.Channel.IsPrivate) { if (module.FilterType.HasFlag(ModuleFilter.AlwaysAllowPrivate)) builder.Append($"Always available on prviate."); } else { if (module.FilterType.HasFlag(ModuleFilter.ServerWhitelist)) builder.Append($"Globally server: {module.EnabledServers.Contains(e.Server),-5} "); if (module.FilterType.HasFlag(ModuleFilter.ChannelWhitelist)) builder.Append($"Channel: {module.EnabledChannels.Contains(e.Channel),-5}"); } builder.AppendLine("`"); } await e.Channel.SafeSendMessage(builder.ToString()); }); }); _client.JoinedServer += async (s, e) => { foreach (string moduleName in DefaultModules) { ModuleManager module = await VerifyFindModule(moduleName, null, false); if (module == null) return; if (!module.FilterType.HasFlag(ModuleFilter.ServerWhitelist)) throw new InvalidOperationException(); Server server = e.Server; module.EnableServer(server); _serverModulesDictionary.AddModuleToSave(module.Id, server.Id); } }; }
void IModule.Install(ModuleManager manager) { _client = manager.Client; _http = _client.GetService<HttpService>(); Task.Run(async () => { foreach (EmoteSourceBase source in _emoteSources) { try { await source.DownloadData(_http); } catch (Exception ex) { Logger.FormattedWrite( GetType().Name, $"Failed loading emotes for {source.GetType().Name}. Exception: {ex}"); } } GC.Collect(); }); manager.CreateDynCommands("bttv", PermissionLevel.User, group => { group.CreateCommand("") .Parameter("channel") .Description("Add a BTTV channel to the emote sources.") .Do(async e => { string channel = e.GetArg("channel"); if (_bttvChannelEmoteSources.FirstOrDefault(s => s.Channel == channel) != null) { await e.Channel.SendMessage("This channel is already in the emote source list."); return; } BttvChannelEmoteSource source = await BttvChannelEmoteSource.Create(_client, channel); if (source == null) { await e.Channel.SafeSendMessage("Failed getting emote data."); return; } _bttvChannelEmoteSources.Add(source); await e.Channel.SafeSendMessage($"Added channel {channel} to the emote source."); }); }); manager.CreateDynCommands("emote", PermissionLevel.User, group => { group.CreateCommand("") .Parameter("emote", ParameterType.Unparsed) .Do(async e => { string emotePath = await ResolveEmoteDir(e.GetArg("emote")); if (!File.Exists(emotePath)) return; // todo : lower case == upper case in this case. KAPPA = Kappa await e.Channel.SafeSendFile(emotePath); }); }); }
void IModule.Install(ModuleManager manager) { manager.CreateDynCommands("channel", PermissionLevel.ServerAdmin, group => { group.CreateCommand("list text") .Description("Lists all text channels in server") .Do(async e => { StringBuilder builder = new StringBuilder(); builder.AppendLine("**Listing text channels in server:**"); CreateNameIdList(builder, e.Server.TextChannels); await e.Channel.SafeSendMessage(builder.ToString()); }); group.CreateCommand("list voice") .Description("Lists all voice channels in server") .Do(async e => { StringBuilder builder = new StringBuilder(); builder.AppendLine("**Listing voice channels in server:**"); CreateNameIdList(builder, e.Server.VoiceChannels); await e.Channel.SafeSendMessage(builder.ToString()); }); group.CreateCommand("prune") .AddCheck((cmd, usr, chnl) => chnl.Server.CurrentUser.ServerPermissions.ManageMessages || chnl.Server.CurrentUser.GetPermissions(chnl).ManageMessages) .Description("Deletes the last 100 messages sent in this channel.") .Do(async e => { foreach (Message msg in await e.Channel.DownloadMessages()) { if (msg != null) await msg.Delete(); } }); group.CreateCommand("topic") .Description("Sets the topic of a channel, found by its id.") .Parameter(Constants.ChannelIdArg) .Parameter("topic", ParameterType.Unparsed) .Do(async e => { Channel channel = e.GetChannel(); string topic = e.GetArg("topic"); if (channel == null) { await e.Channel.SendMessage($"Channel not found."); return; } if (!await channel.SafeEditChannel(topic: topic)) { await e.Channel.SendMessage($"I don't have sufficient permissions to edit {channel.Mention}"); return; } await e.Channel.SendMessage($"Set the topic of {channel.Mention} to `{topic}`."); }); group.CreateCommand("name") .Description("Sets the name of a channel, found by its id.") .Parameter(Constants.ChannelIdArg) .Parameter("name") .Do(async e => { Channel channel = e.GetChannel(); string name = e.GetArg("name"); if (channel == null) { await e.Channel.SendMessage($"Channel not found."); return; } string nameBefore = channel.Name; if (!await channel.SafeEditChannel(name)) { await e.Channel.SendMessage($"I don't have sufficient permissions to edit {channel.Mention}"); return; } await e.Channel.SendMessage($"Set the name of `{nameBefore}` to `{name}`."); }); }); manager.CreateDynCommands("role", PermissionLevel.ServerAdmin, group => { group.CreateCommand("list") .Description("Lists all the roles the server has") .Do(async e => { StringBuilder builder = new StringBuilder(); builder.AppendLine("**Listing roles in server:**"); CreateNameIdList(builder, e.Server.Roles); await e.Channel.SafeSendMessage(builder.ToString()); }); // commands, which can only be called if the bot user has rights to manager roles. group.CreateGroup("", manageRolesGroup => { manageRolesGroup.AddCheck((cmd, usr, chnl) => chnl.Server.CurrentUser.ServerPermissions.ManageRoles); manageRolesGroup.CreateCommand("add") .Description("Adds a role with the given name if it doesn't exist.") .Parameter("name", ParameterType.Unparsed) .Do(async e => { string name = e.GetArg("name"); Role role = FindRole(name, e); if (role != null) { await e.Channel.SendMessage("Role not found."); return; } await e.Server.CreateRole(name); await e.Channel.SafeSendMessage($"Created role `{name}`"); }); manageRolesGroup.CreateCommand("rem") .Description("Removes a role with the given id if it exists.") .Parameter(Constants.RoleIdArg) .Do(async e => { Role role = e.GetRole(); if (role == null) { await e.Channel.SendMessage("Role not found."); return; } if (role.IsEveryone || role.IsHoisted || role.IsManaged) { await e.Channel.SendMessage("You cannot remove this role."); return; } await role.Delete(); await e.Channel.SafeSendMessage($"Removed role `{role.Name}`"); }); manageRolesGroup.CreateCommand("edit perm") .Description("Edits permissions for a given role, found by id, if it exists.") .Parameter(Constants.RoleIdArg) .Parameter("permission") .Parameter("value") .Do(async e => { Role role = e.GetRole(); if (role == null) { await e.Channel.SendMessage("Role not found."); return; } ServerPermissions edited = role.Permissions; PropertyInfo prop = edited.GetType().GetProperty(e.GetArg("permission")); bool value = bool.Parse(e.GetArg("value")); prop.SetValue(edited, value); await role.SafeEdit(perm: edited); await e.Channel.SafeSendMessage( $"Set permission `{prop.Name}` in `{role.Name}` to `{value}`"); }); manageRolesGroup.CreateCommand("edit color") .Description("Edits the color (RRGGBB) for a given role, found by id, if it exists. ") .Parameter(Constants.RoleIdArg) .Parameter("hex") .Do(async e => { Role role = e.GetRole(); if (role == null) { await e.Channel.SendMessage("Role not found."); return; } uint hex; if (!DiscordUtils.ToHex(e.GetArg("hex"), out hex)) return; if (!await role.SafeEdit(color: new Color(hex))) await e.Channel.SendMessage( $"Failed editing role. Make sure it's not everyone or managed."); }); }); group.CreateCommand("listperm") .Description("Lists the permissions for a given roleid") .Parameter(Constants.RoleIdArg) .Do(async e => { Role role = e.GetRole(); if (role == null) { await e.Channel.SendMessage("Role not found."); return; } ServerPermissions perms = role.Permissions; await e.Channel.SafeSendMessage($"**Listing permissions for {role.Name}**\r\n:" + $"{"CreateInstantInvite",-25}: {perms.CreateInstantInvite}\r\n" + $"{"KickMembers",-25}: {perms.KickMembers}\r\n" + $"{"BanMembers",-25}: {perms.BanMembers}\r\n" + $"{"ManageRoles",-25}: {perms.ManageRoles}\r\n" + $"{"ManageChannels",-25}: {perms.ManageChannels}\r\n" + $"{"ManageServer",-25}: {perms.ManageServer}\r\n" + $"{"ReadMessages",-25}: {perms.ReadMessages}\r\n" + $"{"SafeSendMessages",-25}: {perms.SendMessages}\r\n" + $"{"SendTTSMessages",-25}: {perms.SendTTSMessages}\r\n" + $"{"ManageMessages",-25}: {perms.ManageMessages}\r\n" + $"{"EmbedLinks",-25}: {perms.EmbedLinks}\r\n" + $"{"AttachFiles",-25}: {perms.AttachFiles}\r\n" + $"{"ReadMessageHistory",-25}: {perms.ReadMessageHistory}\r\n" + $"{"MentionEveryone",-25}: {perms.MentionEveryone}\r\n" + $"{"Connect",-25}: {perms.Connect}\r\n" + $"{"Speak",-25}: {perms.Speak}\r\n" + $"{"MuteMembers",-25}: {perms.MuteMembers}\r\n" + $"{"DeafenMembers",-25}: {perms.DeafenMembers}\r\n" + $"{"MoveMembers",-25}: {perms.MoveMembers}\r\n" + $"{"UseVoiceActivation",-25}: {perms.UseVoiceActivation}`" ); }); }); manager.CreateDynCommands("ued", PermissionLevel.ServerModerator, group => { group.CreateCommand("list") .Description("Lists users in server and their UIDs") .Do(async e => { StringBuilder builder = new StringBuilder(); builder.AppendLine("**Listing users in server:**"); CreateNameIdList(builder, e.Server.Users); await e.Channel.SafeSendMessage(builder.ToString()); }); group.CreateCommand("mute") .AddCheck((cmd, usr, chnl) => chnl.Server.CurrentUser.ServerPermissions.MuteMembers) .Description("Mutes(true)/unmutes(false) the userid") .Parameter(Constants.UserMentionArg) .Parameter("val") .Do(async e => { User user = e.GetUser(); if (user == null) { await e.Channel.SendMessage("User not found."); return; } await user.Edit(bool.Parse(e.GetArg("val"))); await e.Channel.SafeSendMessage($"Muted `{user.Name}`"); }); group.CreateCommand("deaf") .AddCheck((cmd, usr, chnl) => chnl.Server.CurrentUser.ServerPermissions.DeafenMembers) .Description("Deafens(true)/Undeafens(false) @user") .Parameter(Constants.UserMentionArg) .Parameter("val") .Do(async e => { User user = e.GetUser(); if (user == null) { await e.Channel.SendMessage("User not found."); return; } await user.Edit(isDeafened: bool.Parse(e.GetArg("val"))); await e.Channel.SafeSendMessage($"Deafened `{user.Name}`"); }); group.CreateCommand("move") .AddCheck((cmd, usr, chnl) => chnl.Server.CurrentUser.ServerPermissions.MoveMembers) .Description("Moves a @user to a given voice channel") .Parameter(Constants.UserMentionArg) .Parameter("channelid", ParameterType.Unparsed) .Do(async e => { User user = e.GetUser(); if (user == null) { await e.Channel.SendMessage("User not found."); return; } Channel moveChnl = e.Server.GetChannel(ulong.Parse(e.GetArg("channelid"))); await user.Edit(voiceChannel: moveChnl); await e.Channel.SafeSendMessage($"Moved `{user.Name}` to `{moveChnl.Name}`"); }); group.CreateCommand("role add") .AddCheck((cmd, usr, chnl) => chnl.Server.CurrentUser.ServerPermissions.ManageRoles) .Description("Adds a role, found by id, to @user if they dont have it.") .Parameter(Constants.UserMentionArg) .Parameter(Constants.RoleIdArg) .Do(async e => { User user = e.GetUser(); Role role = e.GetRole(); if (user == null) { await e.Channel.SendMessage("User not found."); return; } if (role == null) { await e.Channel.SendMessage("Role not found."); return; } if (!user.HasRole(role)) { await user.Edit(roles: user.Roles.Concat(new[] {role})); await e.Channel.SafeSendMessage($"Given role `{role.Name}` to `{user.Mention}`"); } }); group.CreateCommand("role list") .Description("Returns a list of roles a @user has.") .Parameter(Constants.UserMentionArg) .Do(async e => { StringBuilder builder = new StringBuilder(); User user = e.GetUser(); builder.AppendLine($"**Listing roles for {user.Name}:**"); CreateNameIdList(builder, e.Server.Roles); await e.Channel.SafeSendMessage(builder.ToString()); }); group.CreateCommand("role rem") .AddCheck((cmd, usr, chnl) => chnl.Server.CurrentUser.ServerPermissions.ManageRoles) .Description("Removes a roleid from a @user if they have it.") .Parameter(Constants.UserMentionArg) .Parameter(Constants.RoleIdArg) .Do(async e => { User user = e.GetUser(); Role role = e.GetRole(); if (user == null) { await e.Channel.SendMessage("User not found."); return; } if (role == null) { await e.Channel.SendMessage("Role not found."); return; } if (user.HasRole(role)) { await user.RemoveRoles(role); await e.Channel.SafeSendMessage($"Removed role `{role.Name}` from `{user.Name}`."); } }); group.CreateCommand("kick") .Description("Kicks a @user.") .AddCheck((cmd, usr, chnl) => chnl.Server.CurrentUser.ServerPermissions.KickMembers) .Parameter("userMention") .Do(async e => { User user = e.Server.GetUser(DiscordUtils.ParseMention(e.GetArg("userMention")).First()); if (user == null) { await e.Channel.SendMessage($"User not found."); return; } string userName = user.Name; // in case user is disposed right after we kick them. await user.Kick(); await e.Channel.SendMessage($"Kicked {userName}."); }); group.CreateCommand("ban") .Description("Bans an @user. Also allows for message pruning for a given amount of days.") .AddCheck((cmd, usr, chnl) => chnl.Server.CurrentUser.ServerPermissions.BanMembers) .Parameter("userMention") .Parameter("pruneDays", ParameterType.Optional) .Do(async e => { User user = e.Server.GetUser(DiscordUtils.ParseMention(e.GetArg("userMention")).First()); int pruneDays = 0; string pruneRaw = e.GetArg("pruneDays"); if (!string.IsNullOrEmpty(pruneRaw)) pruneDays = int.Parse(pruneRaw); if (user == null) { await e.Channel.SendMessage($"User not found."); return; } string userName = user.Name; // in case user is disposed right after we kick them. await e.Server.Ban(user, pruneDays); await e.Channel.SendMessage($"Banned {userName}"); }); }); }
void IModule.Install(ModuleManager manager) { _client = manager.Client; manager.CreateDynCommands("", PermissionLevel.User, group => { group.CreateCommand("remind list") .Description("Lists the reminders you have set.") .Do(async e => { List<ReminderData> userRem = _reminders.Where(r => r.User == e.User.Id).ToList(); if (!userRem.Any()) { await e.Channel.SafeSendMessage($"I have no reminders set for `{e.User.Name}`"); return; } StringBuilder builder = new StringBuilder(); builder.AppendLine($"**Listing reminders for {e.User.Name}:**"); foreach (ReminderData rem in userRem) builder.AppendLine( $"`{rem.EndTime,-20}` Remaining time: `{(rem.EndTime - DateTime.Now).ToString(@"hh\:mm\:ss")}`"); await e.Channel.SafeSendMessage(builder.ToString()); }); group.CreateCommand("remind") .Description("Reminds you about something after the given time span has passed.") .Parameter("timespan") .Parameter("reason", ParameterType.Unparsed) .Do(async e => { string rawSpan = e.GetArg("timespan"); _reminders.Add(new ReminderData(e.User.Id, TimeSpan.Parse(rawSpan), e.GetArg("reason"))); await e.Channel.SafeSendMessage($"Reminding `{e.User.Name}` in `{rawSpan}`"); }); group.CreateCommand("google") .Description("Lmgtfy") .Parameter("query", ParameterType.Unparsed) .Do(async e => { string query = e.GetArg("query"); if (string.IsNullOrEmpty(query)) return; await e.Channel.SafeSendMessage($"http://lmgtfy.com/?q={HttpUtility.UrlEncode(query)}"); }); group.CreateCommand("quote") .Description("Prints a quote out from your servers' quote list.") .Do(async e => { string quote = GetQuotes(e.Server).PickRandom(); if (quote == null) { await e.Channel.SafeSendMessage($"Server quote list is empty."); return; } await e.Channel.SafeSendMessage($"`{quote}`"); }); group.CreateCommand("addquote") .Description("Adds a quote to your servers' quote list.") .Parameter("quote", ParameterType.Unparsed) .Do(async e => { string input = e.GetArg("quote"); if (input.Length < MinQuoteSize) { await e.Channel.SafeSendMessage($"Quote too short. (min {MinQuoteSize})"); return; } if (string.IsNullOrEmpty(input)) { await e.Channel.SafeSendMessage("Input cannot be empty."); return; } GetQuotes(e.Server).Add(input); await e.Channel.SafeSendMessage("Added quote."); }); group.CreateCommand("coin") .Description("Flips a coin.") .Do(async e => { StringBuilder builder = new StringBuilder("**Coin flip**: "); builder.Append(StaticRandom.Bool() ? "Heads!" : "Tails!"); await e.Channel.SafeSendMessage(builder.ToString()); }); }); manager.CreateDynCommands("color", PermissionLevel.User, group => { // make sure we have permission to manage roles group.AddCheck((cmd, usr, chnl) => chnl.Server.CurrentUser.ServerPermissions.ManageRoles); group.CreateCommand("set") .Description("Sets your username to a hex color. Format: RRGGBB") .Parameter("hex") .Do(async e => { string stringhex = e.GetArg("hex"); uint hex; if (!DiscordUtils.ToHex(stringhex, out hex)) { await e.Channel.SendMessage("Failed parsing input. Valid format: `RRGGBB`"); return; } Role role = e.Server.Roles.FirstOrDefault(x => x.Name == ColorRoleName + stringhex); if (role == null || !e.User.HasRole(role)) { role = await e.Server.CreateRole(ColorRoleName + stringhex); if (!await role.SafeEdit(color: new Color(hex))) await e.Channel.SendMessage( $"Failed editing role. Make sure it's not everyone or managed."); } await e.User.AddRoles(role); await CleanColorRoles(e.Server); }); group.CreateCommand("clear") .Description("Removes your username color, returning it to default.") .Do(async e => { foreach (Role role in e.User.Roles.Where(role => role.Name.StartsWith(ColorRoleName))) await e.User.RemoveRoles(role); }); group.CreateCommand("clean") .MinDynPermissions((int) PermissionLevel.ServerModerator) .Description("Removes unused color roles. Gets automatically called whenever a color is set.") .Do(async e => await CleanColorRoles(e.Server)); }); if (!_isReminderTimerRunning) { Task.Run(() => StartReminderTimer()); _isReminderTimerRunning = true; } }
void IModule.Install(ModuleManager manager) { _client = manager.Client; manager.CreateDynCommands("announce", PermissionLevel.ServerModerator, group => { group.CreateCommand("disable") .AddCheck((cmd, usr, chnl) => { if (_defaultAnnounceChannels.ContainsKey(chnl.Server.Id)) return _defaultAnnounceChannels[chnl.Server.Id].IsEnabled; return true; }) .Description("Disables bot owner announcements on this server.") .Do(async e => { if (_defaultAnnounceChannels.ContainsKey(e.Server.Id)) _defaultAnnounceChannels[e.Server.Id].IsEnabled = false; else _defaultAnnounceChannels.TryAdd(e.Server.Id, new AnnounceChannelData(e.Server.DefaultChannel) {IsEnabled = false}); await e.Channel.SendMessage("Disabled owner announcements for this server."); }); group.CreateCommand("enable") .AddCheck((cmd, usr, chnl) => { if (_defaultAnnounceChannels.ContainsKey(chnl.Server.Id)) return !_defaultAnnounceChannels[chnl.Server.Id].IsEnabled; return false; }) .Description("Enabled but owner announcements on this server.") .Do(async e => { _defaultAnnounceChannels[e.Server.Id].IsEnabled = true; await e.Channel.SendMessage("Enabled owner announcements for this server."); }); group.CreateCommand("channel") .Description("Sets the default channel of any announcements from the bot's owner.") .Parameter("channelname", ParameterType.Unparsed) .Do(async e => { string channelQuery = e.GetArg("channelname").ToLowerInvariant(); Channel channel = e.Server.TextChannels.FirstOrDefault(c => c.Name.ToLowerInvariant() == channelQuery); if (channel == null) { await e.Channel.SafeSendMessage($"Channel with the name of `{channelQuery}` wasn't found."); return; } AnnounceChannelData newVal = new AnnounceChannelData(channel); _defaultAnnounceChannels.AddOrUpdate(e.Server.Id, newVal, (k, v) => newVal); await e.Channel.SendMessage($"Set annoucement channel to `{channel.Name}`"); }); group.CreateCommand("current") .Description("Returns the current announcement channel.") .Do(async e => { StringBuilder builder = new StringBuilder("**Announcement channel**: "); if (!_defaultAnnounceChannels.ContainsKey(e.Server.Id)) builder.Append(e.Server.DefaultChannel); else builder.Append(_defaultAnnounceChannels[e.Server.Id].Channel.Channel.Name); await e.Channel.SafeSendMessage(builder.ToString()); }); group.CreateCommand("message") .MinPermissions((int) PermissionLevel.BotOwner) .Parameter("msg", ParameterType.Unparsed) .Do(async e => { string message = e.GetArg("msg"); foreach (Server server in _client.Servers) { AnnounceChannelData announceData; _defaultAnnounceChannels.TryGetValue(server.Id, out announceData); if (announceData == null) await server.DefaultChannel.SafeSendMessage(message); else { if (announceData.IsEnabled) await _defaultAnnounceChannels[server.Id].Channel.Channel.SafeSendMessage(message); } } }); }); manager.CreateDynCommands("autorole", PermissionLevel.ServerAdmin, group => { // commands that are available when the server doesnt have an auto role set on join. group.CreateGroup("", noSubGroup => { noSubGroup.AddCheck((cmd, usr, chnl) => !_joinedRoleSubs.ContainsKey(chnl.Server.Id)); noSubGroup.CreateCommand("create") .Description("Enables the bot to add a given role to newly joined users.") .Parameter("rolename", ParameterType.Unparsed) .Do(async e => { string roleQuery = e.GetArg("rolename"); Role role = e.Server.FindRoles(roleQuery).FirstOrDefault(); if (role == null) { await e.Channel.SafeSendMessage($"A role with the name of `{roleQuery}` was not found."); return; } _joinedRoleSubs.TryAdd(e.Server.Id, role.Id); await e.Channel.SafeSendMessage( $"Created an auto role asigned for new users. Role: {role.Name}"); }); }); // commands that are available when the server does have an auto role set on join. group.CreateGroup("", subGroup => { subGroup.AddCheck((cmd, usr, chnl) => (_joinedRoleSubs.ContainsKey(chnl.Server.Id))); subGroup.CreateCommand("destroy") .Description("Destoys the auto role assigner for this server.") .Do(e => RemoveAutoRoleAssigner(e.Server.Id, e.Channel)); subGroup.CreateCommand("role") .Parameter("rolename", ParameterType.Unparsed) .Description("Changes the role of the auto role assigner for this server.") .Do(async e => { string roleQuery = e.GetArg("rolename"); Role role = e.Server.FindRoles(roleQuery, false).FirstOrDefault(); if (role == null) { await e.Channel.SafeSendMessage($"A role with the name of `{roleQuery}` was not found."); return; } _joinedRoleSubs[e.Server.Id] = role.Id; await e.Channel.SafeSendMessage($"Set the auto role assigner role to `{role.Name}`."); }); }); }); manager.CreateDynCommands("newuser", PermissionLevel.ServerModerator, group => { group.CreateCommand("syntax") .Description("Syntax rules for newuser commands.") .Do( async e => await e.Channel.SafeSendMessage( $"Syntax: `{UserNameKeyword}` - replaced with the name of the user who triggered the event, `{LocationKeyword}` - replaced with the location (server or channel) where the event occured.```")); group.CreateGroup("join", joinGroup => { // joinGroup callback exists commands joinGroup.CreateGroup("", existsJoin => { existsJoin.AddCheck((cmd, usr, chnl) => { if (_userJoinedSubs.ContainsKey(chnl.Server.Id)) return _userJoinedSubs[chnl.Server.Id].IsEnabled; return false; }); existsJoin.CreateCommand("message") .Description($"Sets the join message for this current server.") .Parameter("message", ParameterType.Unparsed) .Do(async e => { string msg = e.GetArg("message"); _userJoinedSubs[e.Server.Id].Message = msg; await e.Channel.SafeSendMessage($"Set join message to {msg}"); }); existsJoin.CreateCommand("channel") .Description("Sets the callback channel for this servers join announcements.") .Parameter("channelName", ParameterType.Unparsed) .Do(async e => { string channelName = e.GetArg("channelName").ToLowerInvariant(); Channel channel = e.Server.TextChannels.FirstOrDefault(c => c.Name.ToLowerInvariant() == channelName); if (channel == null) { await e.Channel.SafeSendMessage($"Channel with the name {channelName} was not found."); return; } _userJoinedSubs[e.Server.Id].Channel = channel; await e.Channel.SafeSendMessage($"Set join callback to channel {channel.Name}"); }); existsJoin.CreateCommand("destroy") .Description("Stops announcing when new users have joined this server.") .Do(async e => { _userJoinedSubs[e.Server.Id].IsEnabled = false; await e.Channel.SafeSendMessage( "Disabled user join messages. You can re-enable them at any time."); }); }); // no join callback exists commands joinGroup.CreateGroup("", doesntExistJoin => { doesntExistJoin.AddCheck((cmd, usr, chnl) => { if (!_userJoinedSubs.ContainsKey(chnl.Server.Id)) return true; return !_userJoinedSubs[chnl.Server.Id].IsEnabled; }); doesntExistJoin.CreateCommand("enable") .Description("Enables announcing for when a new user joins this server.") .Do(async e => { if (_userJoinedSubs.ContainsKey(e.Server.Id)) _userJoinedSubs[e.Server.Id].IsEnabled = true; else _userJoinedSubs.TryAdd(e.Server.Id, new UserEventCallback(e.Channel, DefaultMessage)); await e.Channel.SafeSendMessage( "Enabled user join messages.\r\nYou can now change the channel and the message by typing !help announce join."); }); }); }); group.CreateGroup("leave", leaveGroup => { // joinGroup callback exists commands leaveGroup.CreateGroup("", existsLeave => { existsLeave.AddCheck((cmd, usr, chnl) => { if (_userLeftSubs.ContainsKey(chnl.Server.Id)) return _userLeftSubs[chnl.Server.Id].IsEnabled; return false; }); existsLeave.CreateCommand("message") .Description($"Sets the leave message for this current server.") .Parameter("message", ParameterType.Unparsed) .Do(async e => { string msg = e.GetArg("message"); _userLeftSubs[e.Server.Id].Message = msg; await e.Channel.SafeSendMessage($"Set leave message to {msg}"); }); existsLeave.CreateCommand("channel") .Description("Sets the callback channel for this servers leave announcements.") .Parameter("channelName", ParameterType.Unparsed) .Do(async e => { string channelName = e.GetArg("channelName").ToLowerInvariant(); Channel channel = e.Server.TextChannels.FirstOrDefault(c => c.Name.ToLowerInvariant() == channelName); if (channel == null) { await e.Channel.SafeSendMessage($"Channel with the name {channelName} was not found."); return; } _userLeftSubs[e.Server.Id].Channel = channel; await e.Channel.SafeSendMessage($"Set leave callback to channel {channel.Name}"); }); existsLeave.CreateCommand("destroy") .Description("Stops announcing when users have left joined this server.") .Do(async e => { _userLeftSubs[e.Server.Id].IsEnabled = false; await e.Channel.SafeSendMessage( "Disabled user join messages. You can re-enable them at any time."); }); }); // no leavea callback exists commands leaveGroup.CreateGroup("", doesntExistLeave => { doesntExistLeave.AddCheck((cmd, usr, chnl) => { if (!_userLeftSubs.ContainsKey(chnl.Server.Id)) return true; return !_userLeftSubs[chnl.Server.Id].IsEnabled; }); doesntExistLeave.CreateCommand("enable") .Description("Enables announcing for when a user leaves this server.") .Do(async e => { if (_userLeftSubs.ContainsKey(e.Server.Id)) _userLeftSubs[e.Server.Id].IsEnabled = true; else _userLeftSubs.TryAdd(e.Server.Id, new UserEventCallback(e.Channel, DefaultMessage)); await e.Channel.SafeSendMessage( "Enabled user leave messages.\r\nYou can now change the channel and the message by typing !help announce leave."); }); }); }); }); manager.UserJoined += async (s, e) => { if (!manager.EnabledServers.Contains(e.Server)) return; if (_userJoinedSubs.ContainsKey(e.Server.Id)) { UserEventCallback callback = _userJoinedSubs[e.Server.Id]; if (callback.IsEnabled) await callback.Channel.SafeSendMessage(ParseString(callback.Message, e.User, e.Server)); } if (_joinedRoleSubs.ContainsKey(e.Server.Id)) { // verify that the role still exists. Role role = e.Server.GetRole(_joinedRoleSubs[e.Server.Id]); if (role == null) { await RemoveAutoRoleAssigner(e.Server.Id, null, false); Channel callback = e.Server.TextChannels.FirstOrDefault(); if (callback != null) await callback.SafeSendMessage("Auto role assigner was given a non existant role. Removing."); return; } await e.User.SafeAddRoles(e.Server.CurrentUser, role); } }; manager.UserLeft += async (s, e) => { if (!manager.EnabledServers.Contains(e.Server)) return; if (!_userLeftSubs.ContainsKey(e.Server.Id)) return; UserEventCallback callback = _userLeftSubs[e.Server.Id]; if (callback.IsEnabled) await callback.Channel.SafeSendMessage(ParseString(callback.Message, e.User, e.Server)); }; }
void IModule.Install(ModuleManager manager) { _client = manager.Client; manager.CreateDynCommands("stream", PermissionLevel.User, group => { // commands which can only be called when there is a track currently playing. group.CreateGroup("", playingGroup => { playingGroup.AddCheck((cmd, usr, chnl) => GetAudio(chnl).IsPlaying); playingGroup.CreateCommand("goto") .Description("Skips to the given point in the track.") .Parameter("time") .Do(e => GetAudio(e.Channel).SkipToTimeInTrack(TimeSpan.Parse(e.GetArg("time")))); playingGroup.CreateCommand("stop") .Description("Stops playback of the playlist.") .Do(e => GetAudio(e.Channel).StopPlaylist()); playingGroup.CreateCommand("forcestop") .Description("Forcefully stops playback of the playlist, track and leaves the voice channel.") .MinPermissions((int) PermissionLevel.ChannelAdmin) .Do(e => GetAudio(e.Channel).ForceStop()); playingGroup.CreateCommand("next") .Description("Skips the current track and plays the next track in the playlist.") .Do(e => GetAudio(e.Channel).StopPlayback()); playingGroup.CreateCommand("prev") .Description("Skips the current track and plays the previus track in the playlist.") .Do(e => GetAudio(e.Channel).Previous()); playingGroup.CreateCommand("current") .Description("Displays information about the currently played track.") .Do(async e => await GetAudio(e.Channel).PrintCurrentTrack()); playingGroup.CreateCommand("pause") .Description("Pauses/unpauses playback of the current track.") .Do(e => GetAudio(e.Channel).Pause()); }); // commands which can only be called when there is no track playing. group.CreateGroup("", idleGroup => { idleGroup.AddCheck((cmd, usr, chnl) => !GetAudio(chnl).IsPlaying); idleGroup.CreateCommand("start") .Alias("play") .Description("Starts the playback of the playlist.") .Parameter("channel", ParameterType.Unparsed) .Do(async e => { AudioState audio = GetAudio(e.Channel); string channelQuery = e.GetArg("channel"); if (string.IsNullOrEmpty(channelQuery)) { if (e.User.VoiceChannel != null) audio.PlaybackChannel = e.User.VoiceChannel; } else { channelQuery = channelQuery.ToLowerInvariant(); Channel voiceChannel = e.Server.VoiceChannels.FirstOrDefault( c => c.Name.ToLowerInvariant().StartsWith(channelQuery)); if (voiceChannel == null) { await e.Channel.SafeSendMessage( $"Voice channel with the name of {channelQuery} was not found."); return; } audio.PlaybackChannel = voiceChannel; } if (audio.PlaybackChannel == null) { await e.Channel.SafeSendMessage("Playback channel not set."); return; } await audio.StartPlaylist(); }); idleGroup.CreateCommand("startat") .Alias("playat") .Description("Starts playback at at given point in the track") .Parameter("time") .Do(async e => { AudioState audio = GetAudio(e.Channel); if (audio.PlaybackChannel == null) { await e.Channel.SafeSendMessage("Playback channel not set."); return; } audio.SkipToTimeInTrack(TimeSpan.Parse(e.GetArg("time"))); await audio.StartPlaylist(); }); }); group.CreateCommand("add") .Description("Adds a track to the music playlist.") .Parameter("location", ParameterType.Unparsed) .Do(async e => { string loc = e.GetArg("location"); TrackData result = await TrackData.Parse(loc); if (result == null) { await e.Channel.SafeSendMessage($"Failed getting the stream url for `{loc}."); return; } GetAudio(e.Channel).Playlist.Add(result); await e.Channel.SafeSendMessage($"Added `{result.Name}` to the playlist."); }); group.CreateCommand("setpos") .Alias("set") .Description("Sets the position of the current played track index to a given number.") .Parameter("index") .Do(e => GetAudio(e.Channel).SkipToTrack(int.Parse(e.GetArg("index")) - 1)); group.CreateCommand("remove") .Alias("rem") .Description("Removes a track at the given position from the playlist.") .Parameter("index") .Do(async e => { AudioState audio = GetAudio(e.Channel); int remIndex = int.Parse(e.GetArg("index")) - 1; TrackData remData = audio.Playlist[remIndex]; audio.Playlist.RemoveAt(remIndex); await e.Channel.SafeSendMessage($"Removed track `{remData.Name}` from the playlist."); }); group.CreateCommand("list") .Description("List the songs in the current playlist.") .Do(async e => { AudioState audio = GetAudio(e.Channel); if (!audio.Playlist.Any()) { await e.Channel.SafeSendMessage("Playlist is empty."); return; } StringBuilder builder = new StringBuilder(); builder.AppendLine("**Playlist:**"); for (int i = 0; i < audio.Playlist.Count; i++) { if (i == audio.TrackIndex && audio.IsPlaying) builder.Append("Playing: "); builder.AppendLine($"`{i + 1}: {audio.Playlist[i].Name}`"); } await e.Channel.SafeSendMessage(builder.ToString()); }); group.CreateCommand("clear") .Description("Stops music and clears the playlist.") .MinPermissions((int) PermissionLevel.ServerModerator) .Do(async e => { GetAudio(e.Channel).ClearPlaylist(); await e.Channel.SafeSendMessage("Cleared playlist."); }); group.CreateCommand("channel") .Description( "Sets the channel in which the audio will be played in. Use .c to set it to your current channel.") .Parameter("channel", ParameterType.Unparsed) .Do(async e => { AudioState audio = GetAudio(e.Channel); string channelQuery = e.GetArg("channel"); Channel channel = channelQuery == ".c" ? e.User.VoiceChannel : e.Server.FindChannels(channelQuery, ChannelType.Voice).FirstOrDefault(); if (channel == null) { await e.Channel.SafeSendMessage($"Voice channel `{channelQuery}` not found."); return; } if (audio.IsPlaying) await audio.SwitchChannel(channel); else { audio.PlaybackChannel = channel; await e.Channel.SafeSendMessage($"Set playback channel to \"`{audio.PlaybackChannel.Name}`\""); } }); }); }
void IModule.Install(ModuleManager manager) { _client = manager.Client; manager.CreateDynCommands("", PermissionLevel.User, group => { group.CreateCommand("whois") .Description("Displays information about the given user.") .Parameter("username") .Do( async e => { await PrintUserInfo(e.Server.FindUsers(e.GetArg("username")).FirstOrDefault(), e.Channel); }); group.CreateCommand("whoami") .Description("Displays information about the callers user.") .Do(async e => { await PrintUserInfo(e.User, e.Channel); }); group.CreateCommand("chatinfo") .Description("Displays information about the current chat channel.") .Do(async e => { Channel channel = e.Channel; StringBuilder builder = new StringBuilder($"**Info for {channel.Name}:\r\n**```"); builder.AppendLine($"- Id: {channel.Id}"); builder.AppendLine($"- Position: {channel.Position}"); builder.AppendLine($"- Parent server id: {channel.Server.Id}"); await e.Channel.SafeSendMessage($"{builder}```"); }); group.CreateCommand("info") .Description("Displays information about the bot.") .Do(async e => { Tuple<int, int> serverData = GetServerData(); StringBuilder builder = new StringBuilder("**Bot info:\r\n**```") .AppendLine("- Owner: " + (Config.Owner == null ? "Not found." : $"{Config.Owner.Name} ({Config.Owner.Id})")) .AppendLine( $"- Uptime: {(DateTime.Now - Process.GetCurrentProcess().StartTime).ToString(@"dd\.hh\:mm\:ss")}") .AppendLine("- GitHub: https://github.com/SSStormy/Stormbot") .AppendLine( $"- Memory Usage: {Math.Round(GC.GetTotalMemory(false)/(1024.0*1024.0), 2)} MB") .AppendLine($"- Audio streaming jobs: {AudioStreamer.StreamingJobs}") .AppendLine($"- Servers: {_client.Servers.Count()}") .AppendLine($"- Channels: {serverData.Item1}") .AppendLine($"- Users: {serverData.Item2}") .AppendLine("- Test server: https://discord.gg/0lHgknA1Q2RIJK0m"); await e.Channel.SafeSendMessage($"{builder}```"); }); group.CreateCommand("contact") .Description("Contact @SSStormy") .Do(async e => { await e.Channel.SafeSendMessage( $"**Reach my developer at**:\r\n" + $"- http://steamcommunity.com/profiles/76561198035041409/" + $"- https://discord.gg/0lHgknA1Q2RIJK0m"); }); }); }
void IModule.Install(ModuleManager manager) { _client = manager.Client; _twitch = new TwitchBot(); manager.CreateDynCommands("twitch", PermissionLevel.ChannelModerator, group => { group.CreateCommand("connect") .Description("Connects this channel to a given twitch channel, relaying the messages between them.") .Parameter("channel") .Do(async e => { string channel = e.GetArg("channel"); if (await IsValidTwitchChannelAndIsStreaming(channel)) { int? viewers = await GetViewerCount(channel); if (viewers != null && viewers.Value <= MaxViewsPerChannel) await Subscribe(channel, e.Channel); else await e.Channel.SafeSendMessage( $"{channel}'s view count ({viewers}) is currently over the view barrier ({MaxViewsPerChannel}), therefore, for the sake of not getting a cooldown for spamming Discord, we cannot connect to this channel."); } else await e.Channel.SafeSendMessage($"{channel} channel is currently offline."); }); group.CreateCommand("disconnect") .Description("Disconnects this channel from the given twitch channel.") .Parameter("channel") .Do(async e => { await Unsubscribe(e.GetArg("channel"), e.Channel); }); group.CreateCommand("list") .MinDynPermissions((int) PermissionLevel.User) .Description("Lists all the twitch channels this discord channel is connected to.") .Do(async e => { List<string> twitchSub = GetTwitchChannels(e.Channel).ToList(); if (!twitchSub.Any()) { await e.Channel.SafeSendMessage("This channel isin't subscribed to any twitch channels."); return; } StringBuilder builder = new StringBuilder($"**{e.Channel.Name} is subscribed to:**\r\n```"); foreach (string twitchChannel in twitchSub) builder.AppendLine($"* {twitchChannel}"); await e.Channel.SafeSendMessage($"{builder.ToString()}```"); }); }); _twitch.DisconnectFromTwitch += async (s, e) => { Logger.FormattedWrite("Twitch", "Disconnected from twitch", ConsoleColor.Red); // try to reconnect to twitch while (!_twitch.IsConnected) { Logger.FormattedWrite("Twitch", "Attempting to reconnect to twitch...", ConsoleColor.Red); await TwitchTryConnect(); await Task.Delay(5000); } Logger.FormattedWrite("Twitch", "Reconnected to twitch.", ConsoleColor.Red); }; _twitch.ChatMessageReceived += async (s, e) => { if (!_relays.ContainsKey(e.Message.Channel)) return; if (e.Message.Username == Config.TwitchUsername) return; if (e.Message.Text.StartsWith(EscapePrefix)) return; foreach (JsonChannel relay in _relays[e.Message.Channel]) await relay.Channel.SafeSendMessage($"**Twitch**: `<{e.Message.Username}> {e.Message.Text}`"); }; _twitch.ChannelLeave += (s, e) => _relays.Remove(e.Channel); _client.MessageReceived += (s, e) => { if (e.Message.IsAuthor) return; if (e.Message.Text.StartsWith(EscapePrefix)) return; foreach (string twitchChannel in GetTwitchChannels(e.Channel)) _twitch.SendMessage(twitchChannel, $"{e.User.Name}@{e.Channel.Name}: {e.Message.Text}"); }; }
void IModule.Install(ModuleManager manager) { _client = manager.Client; manager.CreateDynCommands("terraria", PermissionLevel.User, mainGroup => { // commands which can only be used when caller channel is connected to a terraria server. mainGroup.CreateGroup("", connectedGroup => { connectedGroup.AddCheck( (cmd, usr, chnl) => GetRelay(chnl) != null); /* todo : command for getting player info */ connectedGroup.CreateCommand("info") .Description("Shows the info for the terraria server connected to this channel.") .Do(async e => { TerrChannelRelay relay = GetRelay(e.Channel); await e.Channel.SafeSendMessage( $"This channel is connected to:\r\n```* Ip: {relay.Host}\r\n* Port:{relay.Port}\r\n* World: {relay.Client.World.WorldName}\r\n* Players: {relay.Client.Players.Count()}```"); }); connectedGroup.CreateCommand("disconnect") .MinDynPermissions((int) PermissionLevel.ChannelModerator) .Description("Disconnects from the terraria server connected to this channel.") .Do(e => { TerrChannelRelay relay = GetRelay(e.Channel); CleanRelay(relay); }); connectedGroup.CreateCommand("world") .Description("Displays information about the servers world.") .Do(async e => { TerrChannelRelay relay = GetRelay(e.Channel); StringBuilder builder = new StringBuilder($"**World data on {relay.Host}:{relay.Port}:**```"); builder.AppendLine($"- Name: {relay.Client.World.WorldName}"); builder.AppendLine($"- Time: {relay.Client.World.Time}"); builder.AppendLine($"- Is Raining: {relay.Client.World.Rain > 0}"); builder.AppendLine($"- Is Expert Mode: {relay.Client.World.IsExpertMode}"); builder.AppendLine($"- Is Hardmode: {relay.Client.World.IsHardmode}"); builder.AppendLine($"- Is Crimson: {relay.Client.World.IsCrimson}"); await e.Channel.SafeSendMessage($"{builder}```"); }); connectedGroup.CreateCommand("travmerch") .Description( "Displays what the travelling merchant has in stock if they are currently present in the world.") .Do(async e => { TerrChannelRelay relay = GetRelay(e.Channel); Npc travelingMerchant = relay.Client.Npcs.FirstOrDefault(n => n.NpcId == NpcId.TravellingMerchant); if (travelingMerchant == null) { await e.Channel.SafeSendMessage( "The travelling merchant is not currently present in the world."); return; } StringBuilder builder = new StringBuilder("**Travelling merchant stock:**```"); int index = 1; foreach (GameItem item in travelingMerchant.Shop) { builder.AppendLine($"{index}: {item.Name()}"); index++; } await e.Channel.SafeSendMessage($"{builder}```"); }); }); // commands which can only be used when caller channel is not connected to a terraria server. mainGroup.CreateGroup("", disconnectedGroup => { disconnectedGroup.AddCheck((cmd, usr, chnl) => GetRelay(chnl) == null); disconnectedGroup.CreateCommand("connect") .MinDynPermissions((int) PermissionLevel.ChannelModerator) .Description("Connects this channel to a terraria server.") .Parameter("ip") .Parameter("port") .Parameter("password", ParameterType.Optional) .Do(async e => { TerrChannelRelay newRelay = new TerrChannelRelay(e.Channel, e.GetArg("ip"), int.Parse(e.GetArg("port")), e.GetArg("password")); _relays.Add(newRelay); await StartClient(newRelay); }); }); }); }