Refactoring.
Bot: Split into multiple files. Bot: Add roles system to replace BotCommandFlags. BotClient: Split into separate directory.master
parent
8464c6ee6c
commit
a39a42ef40
|
@ -6,7 +6,7 @@
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Main bot class.
|
// Data for the Bot class.
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@ using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
using CommandFuncDict =
|
using CommandFuncDict =
|
||||||
System.Collections.Generic.Dictionary<
|
System.Collections.Generic.Dictionary<
|
||||||
|
@ -44,15 +43,15 @@ namespace ProjectGolan.Vrobot3
|
||||||
//
|
//
|
||||||
public partial class Bot
|
public partial class Bot
|
||||||
{
|
{
|
||||||
public List<IBotModule> modules = new List<IBotModule>();
|
private readonly Dictionary<ulong, String> lastLine;
|
||||||
public CommandFuncDict cmdfuncs = new CommandFuncDict();
|
private readonly IBotClient client;
|
||||||
|
|
||||||
|
public List<IBotModule> modules { get; private set; }
|
||||||
|
public CommandFuncDict cmdfuncs { get; private set; }
|
||||||
public readonly BotInfo info;
|
public readonly BotInfo info;
|
||||||
|
|
||||||
private Dictionary<ulong, String> lastLine = new Dictionary<ulong, String>();
|
public bool isInAudioChannel => client.isInAudioChannel();
|
||||||
private IBotClient client;
|
public BotClientInfo clientInfo => client.info;
|
||||||
|
|
||||||
public bool isInAudioChannel => false;
|
|
||||||
public ServerInfo serverInfo => client.info;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Bot constructor
|
// Bot constructor
|
||||||
|
@ -60,11 +59,15 @@ namespace ProjectGolan.Vrobot3
|
||||||
public Bot(BotInfo info)
|
public Bot(BotInfo info)
|
||||||
{
|
{
|
||||||
this.info = info;
|
this.info = info;
|
||||||
|
this.lastLine = new Dictionary<ulong, String>();
|
||||||
|
this.modules = new List<IBotModule>();
|
||||||
|
this.cmdfuncs = new CommandFuncDict();
|
||||||
|
|
||||||
switch(info.serverType)
|
switch(info.serverType)
|
||||||
{
|
{
|
||||||
case ServerType.IRC: client = new BotClientIRC(this); break;
|
case "IRC": this.client = new BotClientIRC(this); break;
|
||||||
case ServerType.Discord: client = new BotClientDiscord(this); break;
|
case "Discord": this.client = new BotClientDiscord(this); break;
|
||||||
|
default: throw new BotConfigurationException("Invalid server type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var modClasses =
|
var modClasses =
|
||||||
|
@ -82,10 +85,33 @@ namespace ProjectGolan.Vrobot3
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// connect
|
// client
|
||||||
//
|
//
|
||||||
public void connect() => client.connect();
|
public void connect() => client.connect();
|
||||||
|
|
||||||
|
public void action(Channel channel, String msg) =>
|
||||||
|
client.sendAction(channel, msg);
|
||||||
|
public void action(ulong id, String msg) =>
|
||||||
|
client.sendAction(client.getChannel(id), msg);
|
||||||
|
|
||||||
|
public void message(Channel channel, String msg) =>
|
||||||
|
client.sendMessage(channel, msg);
|
||||||
|
public void message(ulong id, String msg) =>
|
||||||
|
client.sendMessage(client.getChannel(id), msg);
|
||||||
|
|
||||||
|
public void messageRaw(Channel channel, String msg) =>
|
||||||
|
client.sendMessageRaw(channel, msg);
|
||||||
|
public void messageRaw(ulong id, String msg) =>
|
||||||
|
client.sendMessageRaw(client.getChannel(id), msg);
|
||||||
|
|
||||||
|
public void reply(User usr, Channel channel, String msg) =>
|
||||||
|
message(channel, usr.name + ": " + msg);
|
||||||
|
public void reply(User usr, ulong id, String msg) =>
|
||||||
|
message(id, usr.name + ": " + msg);
|
||||||
|
|
||||||
|
public void partAudioChannel() => client.partAudioChannel();
|
||||||
|
public Task playAudioFile(String file) => client.playAudioFile(file);
|
||||||
|
|
||||||
//
|
//
|
||||||
// disconnect
|
// disconnect
|
||||||
//
|
//
|
||||||
|
@ -96,30 +122,6 @@ namespace ProjectGolan.Vrobot3
|
||||||
client.disconnect();
|
client.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// reply
|
|
||||||
//
|
|
||||||
public void reply(User usr, Channel channel, String msg) =>
|
|
||||||
message(channel, usr.name + ": " + msg);
|
|
||||||
public void reply(User usr, ulong id, String msg) =>
|
|
||||||
message(id, usr.name + ": " + msg);
|
|
||||||
|
|
||||||
//
|
|
||||||
// message
|
|
||||||
//
|
|
||||||
public void message(Channel channel, String msg) =>
|
|
||||||
client.sendMessage(channel, msg);
|
|
||||||
public void message(ulong id, String msg) =>
|
|
||||||
client.sendMessage(client.getChannel(id), msg);
|
|
||||||
|
|
||||||
//
|
|
||||||
// action
|
|
||||||
//
|
|
||||||
public void action(Channel channel, String msg) =>
|
|
||||||
client.sendAction(channel, msg);
|
|
||||||
public void action(ulong id, String msg) =>
|
|
||||||
client.sendAction(client.getChannel(id), msg);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// joinAudioChannel
|
// joinAudioChannel
|
||||||
//
|
//
|
||||||
|
@ -135,16 +137,6 @@ namespace ProjectGolan.Vrobot3
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// partAudioChannel
|
|
||||||
//
|
|
||||||
public void partAudioChannel() => client.partAudioChannel();
|
|
||||||
|
|
||||||
//
|
|
||||||
// playAudioFile
|
|
||||||
//
|
|
||||||
public Task playAudioFile(String file) => client.playAudioFile(file);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// checkModPermissions
|
// checkModPermissions
|
||||||
//
|
//
|
||||||
|
@ -176,58 +168,6 @@ namespace ProjectGolan.Vrobot3
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// runCommand
|
|
||||||
//
|
|
||||||
private void runCommand(User usr, Channel channel, BotCommand cmd,
|
|
||||||
String rest)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
cmd(usr, channel, rest ?? String.Empty);
|
|
||||||
}
|
|
||||||
catch(CommandArgumentException exc)
|
|
||||||
{
|
|
||||||
if(exc.Message != null)
|
|
||||||
reply(usr, channel, exc.Message);
|
|
||||||
else
|
|
||||||
Console.WriteLine("{0}: Unknown CommandArgumentException",
|
|
||||||
info.serverName);
|
|
||||||
}
|
|
||||||
catch(Exception exc)
|
|
||||||
{
|
|
||||||
reply(usr, channel, "fug it borked");
|
|
||||||
Console.WriteLine("{0}: Unhandled exception in command: {1}",
|
|
||||||
info.serverName, exc?.Message ?? "unknown error");
|
|
||||||
File.WriteAllText(Program.Instance.dataDir + "/cmdexcdump.txt",
|
|
||||||
exc.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// moduleIsValid
|
|
||||||
//
|
|
||||||
private bool moduleIsValid(Type type)
|
|
||||||
{
|
|
||||||
if(!typeof(IBotModule).IsAssignableFrom(type) ||
|
|
||||||
!type.IsClass || type.IsAbstract)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
foreach(var attribute in type.GetCustomAttributes(false))
|
|
||||||
{
|
|
||||||
if((attribute is BotModuleIRCAttribute &&
|
|
||||||
info.serverType != ServerType.IRC) ||
|
|
||||||
(attribute is BotModuleDiscordAttribute &&
|
|
||||||
info.serverType != ServerType.Discord) ||
|
|
||||||
(attribute is BotModuleRequiresAudioAttribute &&
|
|
||||||
!serverInfo.hasAudio) ||
|
|
||||||
attribute is BotModuleDisabledAttribute)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace ProjectGolan.Vrobot3
|
namespace ProjectGolan.Vrobot3
|
||||||
|
@ -38,23 +37,25 @@ namespace ProjectGolan.Vrobot3
|
||||||
//
|
//
|
||||||
public void onMessage(User usr, Channel channel, String msg)
|
public void onMessage(User usr, Channel channel, String msg)
|
||||||
{
|
{
|
||||||
var validCmdPreceders = ".%".ToCharArray();
|
var validCmdPreceders = ".%$".ToCharArray();
|
||||||
String rest = null;
|
String rest = null;
|
||||||
|
|
||||||
if(msg.Length >= 1 && validCmdPreceders.Contains(msg[0]))
|
if(msg.Length >= 1 && validCmdPreceders.Contains(msg[0]))
|
||||||
{
|
{
|
||||||
Predicate<BotCommandStructure> pred;
|
Predicate<BotCommandStructure> pred;
|
||||||
|
|
||||||
if(msg[0] == '%')
|
switch(msg[0])
|
||||||
pred = fn => fn.flags.HasFlag(BotCommandFlags.AdminOnly);
|
{
|
||||||
else
|
case '%': pred = fn => fn.role == BotRole.Admin; break;
|
||||||
pred = fn => !fn.flags.HasFlag(BotCommandFlags.AdminOnly);
|
case '$': pred = fn => fn.role == BotRole.HalfAdmin; break;
|
||||||
|
default: pred = fn => fn.role == BotRole.User; break;
|
||||||
|
}
|
||||||
|
|
||||||
var dict = from fn in cmdfuncs where pred(fn.Value.Item2) select fn;
|
var dict = from fn in cmdfuncs where pred(fn.Value.Item2) select fn;
|
||||||
|
|
||||||
// Get the command name.
|
// Get the command name.
|
||||||
String[] splt = msg.Substring(1).Split(" ".ToCharArray(), 2);
|
var splt = msg.Substring(1).Split(" ".ToCharArray(), 2);
|
||||||
String cmdname = splt[0].ToLower();
|
var cmdname = splt[0].ToLower();
|
||||||
|
|
||||||
// Handle commands ending with "^".
|
// Handle commands ending with "^".
|
||||||
// These take the last message as input.
|
// These take the last message as input.
|
||||||
|
@ -71,9 +72,8 @@ namespace ProjectGolan.Vrobot3
|
||||||
var tcmdr = tcmd.First();
|
var tcmdr = tcmd.First();
|
||||||
|
|
||||||
// Check permissions.
|
// Check permissions.
|
||||||
if(usr.hostname != info.adminId &&
|
if(!client.userPermitted(usr, tcmdr.Item2.role) ||
|
||||||
(tcmdr.Item2.flags.HasFlag(BotCommandFlags.AdminOnly) ||
|
!checkModPermissions(channel, tcmdr.Item1.GetType()))
|
||||||
!checkModPermissions(channel, tcmdr.Item1.GetType())))
|
|
||||||
goto RaiseMessage;
|
goto RaiseMessage;
|
||||||
|
|
||||||
// If we have input, grab that too.
|
// If we have input, grab that too.
|
|
@ -16,24 +16,12 @@ using System.Collections.Generic;
|
||||||
namespace ProjectGolan.Vrobot3
|
namespace ProjectGolan.Vrobot3
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// ServerType
|
// RoleInfo
|
||||||
//
|
//
|
||||||
public enum ServerType
|
public struct RoleInfo
|
||||||
{
|
{
|
||||||
IRC,
|
public String[] admin;
|
||||||
Discord
|
public String[] halfadmin;
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// ServerInfo
|
|
||||||
//
|
|
||||||
public struct ServerInfo
|
|
||||||
{
|
|
||||||
public bool hasAudio;
|
|
||||||
public bool hasColors;
|
|
||||||
public bool hasNewlines;
|
|
||||||
public int messageSafeMaxLen;
|
|
||||||
public bool shortMessages;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -42,12 +30,12 @@ namespace ProjectGolan.Vrobot3
|
||||||
public struct BotInfo
|
public struct BotInfo
|
||||||
{
|
{
|
||||||
public Dictionary<String, String[]> enables;
|
public Dictionary<String, String[]> enables;
|
||||||
public ServerType serverType;
|
public String serverType;
|
||||||
public String serverName;
|
public String serverName;
|
||||||
public String serverPass;
|
public String serverPass;
|
||||||
public String serverAddr;
|
public String serverAddr;
|
||||||
public String adminId;
|
|
||||||
public String[] channels;
|
public String[] channels;
|
||||||
|
public RoleInfo roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
|
@ -54,15 +54,15 @@ namespace ProjectGolan.Vrobot3
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// BotCommandFlags
|
// BotRole
|
||||||
//
|
//
|
||||||
// Flags for command registration.
|
// Used for command role-checking.
|
||||||
//
|
//
|
||||||
[Flags]
|
public enum BotRole
|
||||||
public enum BotCommandFlags
|
|
||||||
{
|
{
|
||||||
AdminOnly = 1 << 0,
|
User,
|
||||||
Hidden = 1 << 1
|
HalfAdmin,
|
||||||
|
Admin
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -73,8 +73,9 @@ namespace ProjectGolan.Vrobot3
|
||||||
public struct BotCommandStructure
|
public struct BotCommandStructure
|
||||||
{
|
{
|
||||||
public BotCommand cmd;
|
public BotCommand cmd;
|
||||||
public BotCommandFlags flags;
|
|
||||||
public String help;
|
public String help;
|
||||||
|
public bool hidden;
|
||||||
|
public BotRole role;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -93,26 +94,17 @@ namespace ProjectGolan.Vrobot3
|
||||||
public event Modules.EventType.OnMessage onMessage;
|
public event Modules.EventType.OnMessage onMessage;
|
||||||
public event Modules.EventType.OnSeen onSeen;
|
public event Modules.EventType.OnSeen onSeen;
|
||||||
|
|
||||||
public void raiseOnCmdMessage(User usr, Channel channel, String msg)
|
public void raiseOnCmdMessage(User usr, Channel channel, String msg) =>
|
||||||
{
|
onCmdMessage?.Invoke(usr, channel, msg);
|
||||||
if(onCmdMessage != null)
|
|
||||||
onCmdMessage(usr, channel, msg);
|
public void raiseOnMessage(User usr, Channel channel, String msg) =>
|
||||||
|
onMessage?.Invoke(usr, channel, msg);
|
||||||
|
|
||||||
|
public void raiseOnSeen(User usr, Channel channel) =>
|
||||||
|
onSeen?.Invoke(usr, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void raiseOnMessage(User usr, Channel channel, String msg)
|
protected IBotModule(Bot bot) { this.bot = bot; }
|
||||||
{
|
|
||||||
if(onMessage != null)
|
|
||||||
onMessage(usr, channel, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void raiseOnSeen(User usr, Channel channel)
|
|
||||||
{
|
|
||||||
if(onSeen != null)
|
|
||||||
onSeen(usr, channel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IBotModule(Bot bot) { this.bot = bot; }
|
|
||||||
|
|
||||||
public CommandDict commands = new CommandDict();
|
public CommandDict commands = new CommandDict();
|
||||||
public Events events;
|
public Events events;
|
|
@ -0,0 +1,79 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright © 2016 Project Golan
|
||||||
|
//
|
||||||
|
// See "LICENSE" for more information.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Private functions for Bot.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace ProjectGolan.Vrobot3
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Bot
|
||||||
|
//
|
||||||
|
public partial class Bot
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// runCommand
|
||||||
|
//
|
||||||
|
private void runCommand(User usr, Channel channel, BotCommand cmd,
|
||||||
|
String rest)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
cmd(usr, channel, rest ?? String.Empty);
|
||||||
|
}
|
||||||
|
catch(CommandArgumentException exc)
|
||||||
|
{
|
||||||
|
reply(usr, channel, exc.Message);
|
||||||
|
}
|
||||||
|
catch(Exception exc)
|
||||||
|
{
|
||||||
|
reply(usr, channel, "fug it borked");
|
||||||
|
Console.WriteLine("{0}: Unhandled exception in command: {1}",
|
||||||
|
info.serverName, exc.Message);
|
||||||
|
File.WriteAllText(Program.Instance.dataDir + "/cmdexcdump.txt",
|
||||||
|
exc.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// moduleIsValid
|
||||||
|
//
|
||||||
|
private bool moduleIsValid(Type type)
|
||||||
|
{
|
||||||
|
if(!typeof(IBotModule).IsAssignableFrom(type) ||
|
||||||
|
!type.IsClass || type.IsAbstract)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
foreach(var attribute in type.GetCustomAttributes(false))
|
||||||
|
{
|
||||||
|
if(attribute is BotModuleDisabledAttribute)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(attribute is BotModuleIRCAttribute &&
|
||||||
|
!(client is BotClientIRC))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(attribute is BotModuleDiscordAttribute &&
|
||||||
|
!(client is BotClientDiscord))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(attribute is BotModuleRequiresAudioAttribute &&
|
||||||
|
!clientInfo.hasAudio)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EOF
|
|
@ -15,31 +15,52 @@ using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace ProjectGolan.Vrobot3
|
namespace ProjectGolan.Vrobot3
|
||||||
{
|
{
|
||||||
|
//
|
||||||
|
// BotClientInfo
|
||||||
|
//
|
||||||
|
public class BotClientInfo
|
||||||
|
{
|
||||||
|
public bool hasAudio;
|
||||||
|
public bool hasColors;
|
||||||
|
public bool hasNewlines;
|
||||||
|
public int messageSafeMaxLen;
|
||||||
|
public bool shortMessages;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// IBotClient
|
// IBotClient
|
||||||
//
|
//
|
||||||
public abstract class IBotClient
|
public abstract class IBotClient
|
||||||
{
|
{
|
||||||
protected Bot bot;
|
protected Bot bot;
|
||||||
public ServerInfo info;
|
public BotClientInfo info { get; protected set; }
|
||||||
|
|
||||||
public IBotClient(Bot bot) { this.bot = bot; }
|
protected IBotClient(Bot bot)
|
||||||
|
{
|
||||||
|
this.info = new BotClientInfo();
|
||||||
|
this.bot = bot;
|
||||||
|
}
|
||||||
|
|
||||||
// Connect
|
// connect
|
||||||
public abstract void connect();
|
public abstract void connect();
|
||||||
public abstract void disconnect();
|
public abstract void disconnect();
|
||||||
|
|
||||||
// Send
|
// send
|
||||||
public abstract void sendAction(Channel channel, String msg);
|
public abstract void sendAction(Channel channel, String msg);
|
||||||
public abstract void sendMessage(Channel channel, String msg);
|
public abstract void sendMessage(Channel channel, String msg);
|
||||||
|
public virtual void sendMessageRaw(Channel channel, String msg) =>
|
||||||
|
sendMessage(channel, msg);
|
||||||
|
|
||||||
// Channel
|
// channel
|
||||||
public abstract Channel getChannel(ulong id);
|
public abstract Channel getChannel(ulong id);
|
||||||
public virtual void joinChannel(Channel channel) {}
|
public virtual void joinChannel(Channel channel) {}
|
||||||
public virtual void partChannel(Channel channel) {}
|
public virtual void partChannel(Channel channel) {}
|
||||||
|
|
||||||
// Audio
|
// user
|
||||||
public virtual ChannelAudio getAudioChannel(User user) =>
|
public abstract bool userPermitted(User usr, BotRole role);
|
||||||
|
|
||||||
|
// audio
|
||||||
|
public virtual ChannelAudio getAudioChannel(User usr) =>
|
||||||
new ChannelAudio();
|
new ChannelAudio();
|
||||||
public virtual async Task joinAudioChannel(ChannelAudio channel) =>
|
public virtual async Task joinAudioChannel(ChannelAudio channel) =>
|
||||||
await Task.FromResult(0);
|
await Task.FromResult(0);
|
|
@ -24,25 +24,7 @@ namespace ProjectGolan.Vrobot3
|
||||||
//
|
//
|
||||||
public class BotClientDiscord : IBotClient
|
public class BotClientDiscord : IBotClient
|
||||||
{
|
{
|
||||||
//
|
private Discord.DiscordClient client;
|
||||||
// AudioBuffer
|
|
||||||
//
|
|
||||||
class AudioBuffer
|
|
||||||
{
|
|
||||||
// private static const int MaxSize = 20 * 1024 * 1024;
|
|
||||||
private readonly String name;
|
|
||||||
private ulong num = 0;
|
|
||||||
private ulong next = 1;
|
|
||||||
private ulong bufSize = 0;
|
|
||||||
public bool completed { get; private set; } = false;
|
|
||||||
|
|
||||||
public AudioBuffer()
|
|
||||||
{
|
|
||||||
name = System.IO.Path.GetRandomFileName() + ".";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Discord.DiscordClient client = new Discord.DiscordClient();
|
|
||||||
private Discord.Audio.IAudioClient audioClient;
|
private Discord.Audio.IAudioClient audioClient;
|
||||||
private Discord.Server server;
|
private Discord.Server server;
|
||||||
|
|
||||||
|
@ -52,13 +34,15 @@ namespace ProjectGolan.Vrobot3
|
||||||
public BotClientDiscord(Bot bot) :
|
public BotClientDiscord(Bot bot) :
|
||||||
base(bot)
|
base(bot)
|
||||||
{
|
{
|
||||||
info.hasAudio = true;
|
this.client = new Discord.DiscordClient();
|
||||||
info.hasColors = false;
|
|
||||||
info.hasNewlines = true;
|
|
||||||
info.messageSafeMaxLen = 1777;
|
|
||||||
info.shortMessages = false;
|
|
||||||
|
|
||||||
client.MessageReceived += (sender, evt) =>
|
this.info.hasAudio = true;
|
||||||
|
this.info.hasColors = false;
|
||||||
|
this.info.hasNewlines = true;
|
||||||
|
this.info.messageSafeMaxLen = 1777;
|
||||||
|
this.info.shortMessages = false;
|
||||||
|
|
||||||
|
this.client.MessageReceived += (sender, evt) =>
|
||||||
{
|
{
|
||||||
if(!evt.Message.IsAuthor && !evt.User.IsBot &&
|
if(!evt.Message.IsAuthor && !evt.User.IsBot &&
|
||||||
(bot.info.channels == null ||
|
(bot.info.channels == null ||
|
||||||
|
@ -78,7 +62,7 @@ namespace ProjectGolan.Vrobot3
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
client.UsingAudio(x => x.Mode = AudioMode.Outgoing);
|
this.client.UsingAudio(x => x.Mode = AudioMode.Outgoing);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -91,6 +75,33 @@ namespace ProjectGolan.Vrobot3
|
||||||
return server.GetUser(ulong.Parse(usr.hostname));
|
return server.GetUser(ulong.Parse(usr.hostname));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// checkRole
|
||||||
|
//
|
||||||
|
private bool checkRole(User usr, String[] strings)
|
||||||
|
{
|
||||||
|
var duser = getUser(usr);
|
||||||
|
|
||||||
|
foreach(var str in strings)
|
||||||
|
{
|
||||||
|
if(str[0] == '#')
|
||||||
|
{
|
||||||
|
var sel =
|
||||||
|
from role in duser.Roles
|
||||||
|
let strn = str.Substring(1)
|
||||||
|
where role.Name == strn
|
||||||
|
select role;
|
||||||
|
|
||||||
|
if(sel.Any())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(usr.hostname == str)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// connect
|
// connect
|
||||||
//
|
//
|
||||||
|
@ -130,6 +141,13 @@ namespace ProjectGolan.Vrobot3
|
||||||
public override void sendMessage(Channel channel, String msg) =>
|
public override void sendMessage(Channel channel, String msg) =>
|
||||||
client.GetChannel(channel.id)?.SendMessage(Discord.Format.Escape(msg));
|
client.GetChannel(channel.id)?.SendMessage(Discord.Format.Escape(msg));
|
||||||
|
|
||||||
|
//
|
||||||
|
// sendMessageRaw
|
||||||
|
//
|
||||||
|
public override void sendMessageRaw(Channel channel, String msg) =>
|
||||||
|
sendMessage(channel,
|
||||||
|
"```" + Discord.Format.Escape(msg ?? String.Empty) + "```");
|
||||||
|
|
||||||
//
|
//
|
||||||
// getChannel
|
// getChannel
|
||||||
//
|
//
|
||||||
|
@ -142,6 +160,14 @@ namespace ProjectGolan.Vrobot3
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// userPermitted
|
||||||
|
//
|
||||||
|
public override bool userPermitted(User usr, BotRole role) =>
|
||||||
|
role == BotRole.User ||
|
||||||
|
(role == BotRole.HalfAdmin && checkRole(usr, bot.info.roles.halfadmin)) ||
|
||||||
|
(role == BotRole.Admin && checkRole(usr, bot.info.roles.admin));
|
||||||
|
|
||||||
//
|
//
|
||||||
// getAudioChannel
|
// getAudioChannel
|
||||||
//
|
//
|
||||||
|
@ -209,12 +235,12 @@ namespace ProjectGolan.Vrobot3
|
||||||
|
|
||||||
var buf = new byte[3840 * 32];
|
var buf = new byte[3840 * 32];
|
||||||
var ostream = audioClient.OutputStream;
|
var ostream = audioClient.OutputStream;
|
||||||
var istream = proc.StandardOutput.BaseStream;
|
var istream = proc?.StandardOutput.BaseStream;
|
||||||
|
|
||||||
int count;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while(!proc.HasExited &&
|
int count;
|
||||||
|
while(proc?.HasExited == false &&
|
||||||
(count = await istream.ReadAsync(buf, 0, buf.Length)) != 0)
|
(count = await istream.ReadAsync(buf, 0, buf.Length)) != 0)
|
||||||
{
|
{
|
||||||
Thread.Sleep(8);
|
Thread.Sleep(8);
|
||||||
|
@ -228,7 +254,7 @@ namespace ProjectGolan.Vrobot3
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
istream.Dispose();
|
istream?.Dispose();
|
||||||
ostream.Dispose();
|
ostream.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -25,11 +25,11 @@ namespace ProjectGolan.Vrobot3
|
||||||
public BotClientIRC(Bot bot) :
|
public BotClientIRC(Bot bot) :
|
||||||
base(bot)
|
base(bot)
|
||||||
{
|
{
|
||||||
info.hasAudio = false;
|
this.info.hasAudio = false;
|
||||||
info.hasColors = true;
|
this.info.hasColors = true;
|
||||||
info.hasNewlines = false;
|
this.info.hasNewlines = false;
|
||||||
info.messageSafeMaxLen = 601;
|
this.info.messageSafeMaxLen = 601;
|
||||||
info.shortMessages = true;
|
this.info.shortMessages = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void connect() {}
|
public override void connect() {}
|
||||||
|
@ -39,6 +39,7 @@ namespace ProjectGolan.Vrobot3
|
||||||
public override void partChannel(Channel channel) {}
|
public override void partChannel(Channel channel) {}
|
||||||
public override void sendAction(Channel channel, String msg) {}
|
public override void sendAction(Channel channel, String msg) {}
|
||||||
public override void sendMessage(Channel channel, String msg) {}
|
public override void sendMessage(Channel channel, String msg) {}
|
||||||
|
public override bool userPermitted(User usr, BotRole role) => true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,19 @@ namespace ProjectGolan.Vrobot3
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// BotConfigurationException
|
||||||
|
//
|
||||||
|
public class BotConfigurationException : Exception
|
||||||
|
{
|
||||||
|
public BotConfigurationException() {}
|
||||||
|
public BotConfigurationException(String message) : base(message) {}
|
||||||
|
public BotConfigurationException(String message, Exception inner) :
|
||||||
|
base(message, inner)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
|
|
@ -29,14 +29,14 @@ namespace ProjectGolan.Vrobot3.Modules
|
||||||
{
|
{
|
||||||
commands["kill"] = new BotCommandStructure{
|
commands["kill"] = new BotCommandStructure{
|
||||||
cmd = cmdKill,
|
cmd = cmdKill,
|
||||||
flags = BotCommandFlags.AdminOnly,
|
role = BotRole.Admin,
|
||||||
help = "Kills all bot instances.\n" +
|
help = "Kills all bot instances.\n" +
|
||||||
"Syntax: %kill"
|
"Syntax: %kill"
|
||||||
};
|
};
|
||||||
|
|
||||||
commands["msg"] = new BotCommandStructure{
|
commands["msg"] = new BotCommandStructure{
|
||||||
cmd = cmdMsg,
|
cmd = cmdMsg,
|
||||||
flags = BotCommandFlags.AdminOnly,
|
role = BotRole.Admin,
|
||||||
help = "Sends a message.\n" +
|
help = "Sends a message.\n" +
|
||||||
"Syntax: %msg channel, msg\n" +
|
"Syntax: %msg channel, msg\n" +
|
||||||
"Example: %msg #general, ur all dumb"
|
"Example: %msg #general, ur all dumb"
|
||||||
|
@ -44,7 +44,7 @@ namespace ProjectGolan.Vrobot3.Modules
|
||||||
|
|
||||||
commands["action"] = new BotCommandStructure{
|
commands["action"] = new BotCommandStructure{
|
||||||
cmd = cmdAction,
|
cmd = cmdAction,
|
||||||
flags = BotCommandFlags.AdminOnly,
|
role = BotRole.Admin,
|
||||||
help = "Sends an action.\n" +
|
help = "Sends an action.\n" +
|
||||||
"Syntax: %action channel, msg\n" +
|
"Syntax: %action channel, msg\n" +
|
||||||
"Example: %action #general, explodes violently"
|
"Example: %action #general, explodes violently"
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace ProjectGolan.Vrobot3.Modules
|
||||||
//
|
//
|
||||||
class QueueItem
|
class QueueItem
|
||||||
{
|
{
|
||||||
Utils.URI uri;
|
private Utils.URI uri;
|
||||||
|
|
||||||
public QueueItem(Utils.URI uri)
|
public QueueItem(Utils.URI uri)
|
||||||
{
|
{
|
||||||
|
@ -44,9 +44,9 @@ namespace ProjectGolan.Vrobot3.Modules
|
||||||
//
|
//
|
||||||
class Queue
|
class Queue
|
||||||
{
|
{
|
||||||
TimeSpan curTime;
|
private TimeSpan curTime;
|
||||||
List<QueueItem> items;
|
private List<QueueItem> items;
|
||||||
int pos;
|
private int pos;
|
||||||
|
|
||||||
public Queue()
|
public Queue()
|
||||||
{
|
{
|
||||||
|
@ -63,9 +63,9 @@ namespace ProjectGolan.Vrobot3.Modules
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] validMethods = { "http", "https", "ftp", "ftps" };
|
private readonly String[] validMethods =
|
||||||
Random rnd = Utils.GetRND();
|
{ "http", "https", "ftp", "ftps" };
|
||||||
Queue queue = new Queue();
|
private Queue queue = new Queue();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Mod_Audio constructor
|
// Mod_Audio constructor
|
||||||
|
@ -95,12 +95,6 @@ namespace ProjectGolan.Vrobot3.Modules
|
||||||
"Syntax: .lsqueue"
|
"Syntax: .lsqueue"
|
||||||
};
|
};
|
||||||
|
|
||||||
commands["fugoff"] = new BotCommandStructure{
|
|
||||||
cmd = cmdFugOff,
|
|
||||||
help = "GET ME COGS OR FUG OFF",
|
|
||||||
flags = BotCommandFlags.AdminOnly
|
|
||||||
};
|
|
||||||
|
|
||||||
commands["summon"] = new BotCommandStructure{
|
commands["summon"] = new BotCommandStructure{
|
||||||
cmd = cmdSummon,
|
cmd = cmdSummon,
|
||||||
help = "Makes the bot join your audio channel.\n" +
|
help = "Makes the bot join your audio channel.\n" +
|
||||||
|
@ -111,14 +105,14 @@ namespace ProjectGolan.Vrobot3.Modules
|
||||||
cmd = cmdVanquish,
|
cmd = cmdVanquish,
|
||||||
help = "Makes the bot leave their audio channel.\n" +
|
help = "Makes the bot leave their audio channel.\n" +
|
||||||
"Syntax: %vanquish",
|
"Syntax: %vanquish",
|
||||||
flags = BotCommandFlags.AdminOnly
|
role = BotRole.HalfAdmin
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// summon
|
// summon
|
||||||
//
|
//
|
||||||
async Task<bool> summon(User usr, Channel channel)
|
private async Task<bool> summon(User usr, Channel channel)
|
||||||
{
|
{
|
||||||
if(bot.isInAudioChannel)
|
if(bot.isInAudioChannel)
|
||||||
return true;
|
return true;
|
||||||
|
@ -158,7 +152,7 @@ namespace ProjectGolan.Vrobot3.Modules
|
||||||
}
|
}
|
||||||
|
|
||||||
bot.reply(usr, channel,
|
bot.reply(usr, channel,
|
||||||
$"Added {loadPass} item{loadPass == 1 ? "" : "s"} to the queue.");
|
$"Added {loadPass} item{loadPass != 1 ? "s" : ""} to the queue.");
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -175,17 +169,6 @@ namespace ProjectGolan.Vrobot3.Modules
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// cmdFugOff
|
|
||||||
//
|
|
||||||
public async void cmdFugOff(User usr, Channel channel, String msg)
|
|
||||||
{
|
|
||||||
if(!await summon(usr, channel))
|
|
||||||
return;
|
|
||||||
|
|
||||||
await bot.playAudioFile("\"/home/marrub/musix/MusixDL/Shadowfax - Shadowdance/01 New Electric India.mp3\"").ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// cmdSummon
|
// cmdSummon
|
||||||
//
|
//
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace ProjectGolan.Vrobot3.Modules
|
namespace ProjectGolan.Vrobot3.Modules
|
||||||
{
|
{
|
||||||
|
@ -74,30 +75,60 @@ namespace ProjectGolan.Vrobot3.Modules
|
||||||
public Mod_Fun(Bot bot) :
|
public Mod_Fun(Bot bot) :
|
||||||
base(bot)
|
base(bot)
|
||||||
{
|
{
|
||||||
commands["carmack"] = new BotCommandStructure{
|
commands["carmack"] = new BotCommandStructure {
|
||||||
cmd = new ShitpostingDevice("MM", "", 3, 20, bot).run,
|
cmd = new ShitpostingDevice("MM", "", 3, 20, bot).run,
|
||||||
flags = BotCommandFlags.Hidden
|
hidden = true
|
||||||
};
|
};
|
||||||
commands["revenant"] = new BotCommandStructure{
|
|
||||||
|
commands["revenant"] = new BotCommandStructure {
|
||||||
cmd = new ShitpostingDevice("AA", "", 3, 20, bot).run,
|
cmd = new ShitpostingDevice("AA", "", 3, 20, bot).run,
|
||||||
flags = BotCommandFlags.Hidden
|
hidden = true
|
||||||
};
|
};
|
||||||
commands["wan"] = new BotCommandStructure{
|
|
||||||
|
commands["wan"] = new BotCommandStructure {
|
||||||
cmd = new ShitpostingDevice("wan ", "- !", 2, 12, bot).run,
|
cmd = new ShitpostingDevice("wan ", "- !", 2, 12, bot).run,
|
||||||
flags = BotCommandFlags.Hidden
|
hidden = true
|
||||||
};
|
};
|
||||||
commands["nyan"] = new BotCommandStructure{
|
|
||||||
|
commands["nyan"] = new BotCommandStructure {
|
||||||
cmd = new ShitpostingDevice("nyan ", "!~", 2, 12, bot).run,
|
cmd = new ShitpostingDevice("nyan ", "!~", 2, 12, bot).run,
|
||||||
flags = BotCommandFlags.Hidden
|
hidden = true
|
||||||
};
|
};
|
||||||
commands[":^)"] = new BotCommandStructure{
|
|
||||||
|
commands[":^)"] = new BotCommandStructure {
|
||||||
cmd = (usr, channel, msg) => bot.message(channel, ":^)"),
|
cmd = (usr, channel, msg) => bot.message(channel, ":^)"),
|
||||||
flags = BotCommandFlags.Hidden
|
hidden = true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// commands["box"] = new BotCommandStructure {
|
||||||
|
// cmd = cmdBox,
|
||||||
|
// hidden = true,
|
||||||
|
// role = BotRole.HalfAdmin
|
||||||
|
// };
|
||||||
|
|
||||||
events.onMessage += onMessage;
|
events.onMessage += onMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// cmdBox
|
||||||
|
//
|
||||||
|
// public void cmdBox(User usr, Channel channel, String msg)
|
||||||
|
// {
|
||||||
|
// var outp = msg + '\n';
|
||||||
|
//
|
||||||
|
// for(var i = 1; i < msg.Length; i++)
|
||||||
|
// {
|
||||||
|
// var ln = msg[i].ToString();
|
||||||
|
// ln = ln.PadRight(msg.Length);
|
||||||
|
// ln += msg[msg.Length - i];
|
||||||
|
// outp += ln + '\n';
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// outp += msg.Reverse();
|
||||||
|
//
|
||||||
|
// bot.messageRaw(channel, outp);
|
||||||
|
// }
|
||||||
|
|
||||||
//
|
//
|
||||||
// onMessage
|
// onMessage
|
||||||
//
|
//
|
||||||
|
|
|
@ -63,24 +63,24 @@ namespace ProjectGolan.Vrobot3.Modules
|
||||||
throw new CommandArgumentException("invalid quote ID");
|
throw new CommandArgumentException("invalid quote ID");
|
||||||
|
|
||||||
var quote = Utils.GetResponseString(APIURI + id.ToString(),
|
var quote = Utils.GetResponseString(APIURI + id.ToString(),
|
||||||
bot.serverInfo.messageSafeMaxLen);
|
bot.clientInfo.messageSafeMaxLen);
|
||||||
|
|
||||||
if(String.IsNullOrEmpty(quote))
|
if(String.IsNullOrEmpty(quote))
|
||||||
throw new CommandArgumentException("QDB exploded try again later");
|
throw new CommandArgumentException("QDB exploded try again later");
|
||||||
|
|
||||||
if(bot.serverInfo.shortMessages)
|
if(bot.clientInfo.shortMessages)
|
||||||
quote = Regex.Replace(quote, "\n+", "\n").Trim();
|
quote = Regex.Replace(quote, "\n+", "\n").Trim();
|
||||||
|
|
||||||
var lines = quote.Split('\n');
|
var lines = quote.Split('\n');
|
||||||
|
|
||||||
if(bot.serverInfo.shortMessages &&
|
if(bot.clientInfo.shortMessages &&
|
||||||
(lines.Length > 5 || quote.Length > 600))
|
(lines.Length > 5 || quote.Length > 600))
|
||||||
{
|
{
|
||||||
bot.reply(usr, channel, "Quote is too long.");
|
bot.reply(usr, channel, "Quote is too long.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bot.serverInfo.hasNewlines)
|
if(bot.clientInfo.hasNewlines)
|
||||||
bot.message(channel, quote);
|
bot.message(channel, quote);
|
||||||
else
|
else
|
||||||
foreach(var ln_ in lines)
|
foreach(var ln_ in lines)
|
||||||
|
|
|
@ -114,9 +114,8 @@ namespace ProjectGolan.Vrobot3.Modules
|
||||||
var outp = String.Empty;
|
var outp = String.Empty;
|
||||||
var en =
|
var en =
|
||||||
from kvp in bot.cmdfuncs
|
from kvp in bot.cmdfuncs
|
||||||
let f = kvp.Value.Item2.flags
|
let fhidden = kvp.Value.Item2.hidden
|
||||||
let fhidden = f.HasFlag(BotCommandFlags.Hidden)
|
let fadmin = kvp.Value.Item2.role != BotRole.User
|
||||||
let fadmin = f.HasFlag(BotCommandFlags.AdminOnly)
|
|
||||||
where
|
where
|
||||||
bot.checkModPermissions(channel, this.GetType()) &&
|
bot.checkModPermissions(channel, this.GetType()) &&
|
||||||
(admin || !fadmin) && !fhidden
|
(admin || !fadmin) && !fhidden
|
||||||
|
|
|
@ -40,13 +40,6 @@ namespace ProjectGolan.Vrobot3
|
||||||
public BotInfo[] servers;
|
public BotInfo[] servers;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly List<Bot> bots = new List<Bot>();
|
|
||||||
private readonly List<Thread> threads = new List<Thread>();
|
|
||||||
public String dataDir = "../data";
|
|
||||||
public ProgramInfo info;
|
|
||||||
|
|
||||||
public static Program Instance;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Main
|
// Main
|
||||||
//
|
//
|
||||||
|
@ -95,6 +88,13 @@ namespace ProjectGolan.Vrobot3
|
||||||
bots.Clear();
|
bots.Clear();
|
||||||
threads.Clear();
|
threads.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly List<Bot> bots = new List<Bot>();
|
||||||
|
private readonly List<Thread> threads = new List<Thread>();
|
||||||
|
public String dataDir = "../data";
|
||||||
|
public ProgramInfo info;
|
||||||
|
|
||||||
|
public static Program Instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,17 +70,14 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Properties/AssemblyInfo.cs" />
|
<Compile Include="Properties/AssemblyInfo.cs" />
|
||||||
<Compile Include="Source/Bot.cs" />
|
<Compile Include="Source/Bot/Data.cs" />
|
||||||
<Compile Include="Source/BotClient.cs" />
|
<Compile Include="Source/Bot/Events.cs" />
|
||||||
<Compile Include="Source/BotClientDiscord.cs" />
|
<Compile Include="Source/Bot/Info.cs" />
|
||||||
<Compile Include="Source/BotClientIRC.cs" />
|
<Compile Include="Source/Bot/Module.cs" />
|
||||||
<Compile Include="Source/BotEvents.cs" />
|
<Compile Include="Source/Bot/PrivateFuncs.cs" />
|
||||||
<Compile Include="Source/BotInfo.cs" />
|
<Compile Include="Source/Client/Client.cs" />
|
||||||
<Compile Include="Source/BotModule.cs" />
|
<Compile Include="Source/Client/Discord.cs" />
|
||||||
<Compile Include="Source/Exceptions.cs" />
|
<Compile Include="Source/Client/IRC.cs" />
|
||||||
<Compile Include="Source/Links.cs" />
|
|
||||||
<Compile Include="Source/Program.cs" />
|
|
||||||
<Compile Include="Source/Utils.cs" />
|
|
||||||
<Compile Include="Source/Modules/Mod_Admin.cs" />
|
<Compile Include="Source/Modules/Mod_Admin.cs" />
|
||||||
<Compile Include="Source/Modules/Mod_Audio.cs" />
|
<Compile Include="Source/Modules/Mod_Audio.cs" />
|
||||||
<Compile Include="Source/Modules/Mod_Fun.cs" />
|
<Compile Include="Source/Modules/Mod_Fun.cs" />
|
||||||
|
@ -88,6 +85,10 @@
|
||||||
<Compile Include="Source/Modules/Mod_Idgames.cs" />
|
<Compile Include="Source/Modules/Mod_Idgames.cs" />
|
||||||
<Compile Include="Source/Modules/Mod_Quote.cs" />
|
<Compile Include="Source/Modules/Mod_Quote.cs" />
|
||||||
<Compile Include="Source/Modules/Mod_Shittalk.cs" />
|
<Compile Include="Source/Modules/Mod_Shittalk.cs" />
|
||||||
|
<Compile Include="Source/Exceptions.cs" />
|
||||||
|
<Compile Include="Source/Links.cs" />
|
||||||
|
<Compile Include="Source/Program.cs" />
|
||||||
|
<Compile Include="Source/Utils.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)/Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)/Microsoft.CSharp.targets" />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
Loading…
Reference in New Issue