Browse Source

Added Github Module.

Added error events for modules and database.
Fixed command empty string exception.
tags/3.0.3
Teknikode 4 years ago
parent
commit
97c4305d78

+ 7
- 0
Combot.sln View File

@@ -69,6 +69,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Console Interface", "Consol
{23E4C371-16E4-4FAC-8B11-44288399BB55} = {23E4C371-16E4-4FAC-8B11-44288399BB55}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Github", "Modules\Github\Github.csproj", "{7D7B5FCB-C9CC-4CB1-B5EF-827BD3398E39}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -183,6 +185,10 @@ Global
{F67D7423-812D-4B8E-A041-B82C448D8A7F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F67D7423-812D-4B8E-A041-B82C448D8A7F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F67D7423-812D-4B8E-A041-B82C448D8A7F}.Release|Any CPU.Build.0 = Release|Any CPU
{7D7B5FCB-C9CC-4CB1-B5EF-827BD3398E39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7D7B5FCB-C9CC-4CB1-B5EF-827BD3398E39}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7D7B5FCB-C9CC-4CB1-B5EF-827BD3398E39}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7D7B5FCB-C9CC-4CB1-B5EF-827BD3398E39}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -211,5 +217,6 @@ Global
{569F61C2-3B06-4313-A299-E643C3786D3D} = {D157677E-4D33-4156-B55E-E21C4B5A3024}
{0DAE9869-DE0E-442F-B8EF-B4F54EDE9559} = {D157677E-4D33-4156-B55E-E21C4B5A3024}
{6CB41404-02E8-4CA3-834C-CE8C30999450} = {D157677E-4D33-4156-B55E-E21C4B5A3024}
{7D7B5FCB-C9CC-4CB1-B5EF-827BD3398E39} = {D157677E-4D33-4156-B55E-E21C4B5A3024}
EndGlobalSection
EndGlobal

+ 35
- 8
Combot/Bot.cs View File

@@ -57,6 +57,7 @@ namespace Combot
IRC.Message.ChannelModeChangeEvent += HandleChannelModeChangeEvent;

Database = new Database(serverConfig.Database);
Database.MysqlErrorEvent += HandleMysqlErrorEvent;

LoadModules();
}
@@ -189,6 +190,7 @@ namespace Combot
Module loadedModule = newModule.CreateInstance(this);
if (loadedModule.Loaded)
{
loadedModule.ModuleErrorEvent += HandleModuleErrorEvent;
Modules.Add(loadedModule);
return true;
}
@@ -301,16 +303,19 @@ namespace Combot
{
bool isCommand = false;
string[] msgArgs = message.Split(new[] {' '}, 2, StringSplitOptions.RemoveEmptyEntries);
string command = msgArgs[0].Remove(0, ServerConfig.CommandPrefix.Length);
// Find the module that contains the command
Module module = Modules.Find(mod => mod.Commands.Exists(c => c.Triggers.Contains(command)) && mod.Loaded && mod.Enabled);
if (module != null)
if (msgArgs.Any())
{
// Find the command
Command cmd = module.Commands.Find(c => c.Triggers.Contains(command));
if (cmd != null)
string command = msgArgs[0].Remove(0, ServerConfig.CommandPrefix.Length);
// Find the module that contains the command
Module module = Modules.Find(mod => mod.Commands.Exists(c => c.Triggers.Contains(command)) && mod.Loaded && mod.Enabled);
if (module != null)
{
isCommand = true;
// Find the command
Command cmd = module.Commands.Find(c => c.Triggers.Contains(command));
if (cmd != null)
{
isCommand = true;
}
}
}
return isCommand;
@@ -616,5 +621,27 @@ namespace Combot
}
}
}

private void HandleMysqlErrorEvent(object sender, string message)
{
BotError error = new BotError();
error.Message = message;
error.Type = ErrorType.MySQL;
if (ErrorEvent != null)
{
ErrorEvent(error);
}
}

private void HandleModuleErrorEvent(object sender, string message)
{
BotError error = new BotError();
error.Message = message;
error.Type = ErrorType.Module;
if (ErrorEvent != null)
{
ErrorEvent(error);
}
}
}
}

+ 44
- 9
Combot/Databases/Database.cs View File

@@ -8,6 +8,8 @@ namespace Combot.Databases
{
public class Database
{
public event EventHandler<string> MysqlErrorEvent;

private bool Connected { get; set; }
private MySqlConnection Connection { get; set; }
private ReaderWriterLockSlim DatabaseLock { get; set; }
@@ -27,17 +29,27 @@ namespace Combot.Databases
{
DatabaseLock.EnterWriteLock();
MySqlCommand cmd = PrepareQuery(query, args);
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
try
{
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Dictionary<string, object> row = new Dictionary<string, object>();
for (int i = 0; i < reader.FieldCount; i++)
{
row.Add(reader.GetName(i), reader.GetValue(i));
}
rows.Add(row);
}
reader.Close();
}
catch (MySqlException exception)
{
Dictionary<string, object> row = new Dictionary<string, object>();
for (int i = 0; i < reader.FieldCount; i++)
if (MysqlErrorEvent != null)
{
row.Add(reader.GetName(i), reader.GetValue(i));
MysqlErrorEvent(this, exception.Message);
}
rows.Add(row);
}
reader.Close();
DatabaseLock.ExitWriteLock();
}
return rows;
@@ -49,7 +61,19 @@ namespace Combot.Databases
{
DatabaseLock.EnterWriteLock();
MySqlCommand cmd = PrepareQuery(query, args);
object result = cmd.ExecuteScalar();
object result = null;
try
{

result = cmd.ExecuteScalar();
}
catch (MySqlException exception)
{
if (MysqlErrorEvent != null)
{
MysqlErrorEvent(this, exception.Message);
}
}
DatabaseLock.ExitWriteLock();
return result;
}
@@ -62,7 +86,18 @@ namespace Combot.Databases
{
DatabaseLock.EnterWriteLock();
MySqlCommand cmd = PrepareQuery(query, args);
int result = cmd.ExecuteNonQuery();
try
{

int result = cmd.ExecuteNonQuery();
}
catch (MySqlException exception)
{
if (MysqlErrorEvent != null)
{
MysqlErrorEvent(this, exception.Message);
}
}
DatabaseLock.ExitWriteLock();
}
}

+ 12
- 0
Combot/Modules/Module.cs View File

@@ -23,6 +23,8 @@ namespace Combot.Modules
public List<Command> Commands { get; set; }
public List<Option> Options { get; set; }

public event EventHandler<string> ModuleErrorEvent;

public bool Loaded { get; set; }
public bool ShouldSerializeLoaded()
{
@@ -95,6 +97,16 @@ namespace Combot.Modules

virtual public void ParseCommand(CommandMessage command) { }

protected void OnError(string e)
{
string errorMsg = string.Format("[{0}] {1}", Name, e);
EventHandler<string> handler = ModuleErrorEvent;
if (handler != null)
{
handler(this, errorMsg);
}
}

public void SetDefaults()
{
Name = string.Empty;

+ 3
- 1
Combot/Types.cs View File

@@ -14,7 +14,9 @@ namespace Combot
Bot = 0,
TCP = 1,
IRC = 2,
Framework = 3
Framework = 3,
MySQL = 4,
Module = 5
}

public class BotError

+ 20
- 8
IRCServices/Commanding/Commands.cs View File

@@ -91,12 +91,18 @@ namespace Combot.IRCServices.Commanding
}
subMessage = string.Join(" ", subMessage, splitMessage[i]);
}
_IRC.SendTCPMessage(string.Format("PRIVMSG {0} :{1}", recipient, subMessage.Remove(0, 1)));
if (PrivateMessageCommandEvent != null)
if (subMessage != string.Empty)
{
_IRC.SendTCPMessage(string.Format("PRIVMSG {0} :{1}", recipient, subMessage.Remove(0, 1)));
if (PrivateMessageCommandEvent != null)
{
PrivateMessageCommandEvent(this, new PrivateMessageCommand {Message = subMessage.Remove(0, 1), Recipient = recipient});
}
}
if (nextMessage != string.Empty)
{
PrivateMessageCommandEvent(this, new PrivateMessageCommand { Message = subMessage.Remove(0, 1), Recipient = recipient });
SendPrivateMessage(recipient, nextMessage);
}
SendPrivateMessage(recipient, nextMessage);
}
else
{
@@ -147,12 +153,18 @@ namespace Combot.IRCServices.Commanding
}
subMessage = string.Join(" ", subMessage, splitMessage[i]);
}
_IRC.SendTCPMessage(string.Format("NOTICE {0} :{1}", recipient, subMessage.Remove(0, 1)));
if (PrivateNoticeCommandEvent != null)
if (subMessage != string.Empty)
{
_IRC.SendTCPMessage(string.Format("NOTICE {0} :{1}", recipient, subMessage.Remove(0, 1)));
if (PrivateNoticeCommandEvent != null)
{
PrivateNoticeCommandEvent(this, new PrivateNoticeCommand {Message = subMessage.Remove(0, 1), Recipient = recipient});
}
}
if (nextMessage != string.Empty)
{
PrivateNoticeCommandEvent(this, new PrivateNoticeCommand { Message = subMessage.Remove(0, 1), Recipient = recipient });
SendNotice(recipient, nextMessage);
}
SendNotice(recipient, nextMessage);
}
else
{

BIN
Module Template.zip View File


+ 141
- 0
Modules/Github/Github.cs View File

@@ -0,0 +1,141 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Octokit;

namespace Combot.Modules.Plugins
{
public class Github : Module
{
public override void Initialize()
{
Bot.CommandReceivedEvent += HandleCommandEvent;
}

public override void ParseCommand(CommandMessage command)
{
Command foundCommand = Commands.Find(c => c.Triggers.Contains(command.Command));

switch (foundCommand.Name)
{
case "Github Information":
GetGithubInformation(command);
break;
case "Repository Information":
GetRepositoryInformation(command);
break;
}
}

private async void GetGithubInformation(CommandMessage command)
{
try
{
string username = (command.Arguments.ContainsKey("Username")) ? command.Arguments["Username"] : command.Nick.Nickname;
GitHubClient github = new GitHubClient(new ProductHeaderValue("CombotIRCBot"));
if (GetOptionValue("Username").ToString() != string.Empty && GetOptionValue("Password").ToString() != string.Empty)
{
github.Credentials = new Credentials(GetOptionValue("Username").ToString(), GetOptionValue("Password").ToString());
NewAuthorization newAuth = new NewAuthorization();
newAuth.Note = "Get Git Information";
try
{
Authorization auth = await github.Authorization.Create(newAuth);
}
catch (Octokit.AuthorizationException ex)
{
OnError(ex.Message);
return;
}
}
SearchUsersResult foundUser = await github.Search.SearchUsers(new SearchUsersRequest(username));
if (foundUser.TotalCount > 0)
{
User user = await github.User.Get(foundUser.Items.First().Login);
if (command.Arguments.ContainsKey("Repository ID"))
{
string repo = command.Arguments["Repository ID"];
int id;
if (int.TryParse(repo, out id))
{
IReadOnlyList<Repository> repos = await github.Repository.GetAllForUser(user.Login);
if (repos != null && repos.Count >= id && id > 0)
{
Repository foundRepo = repos[id - 1];
string repoMessage = string.Format("\u0002{0}\u0002 | Created On \u0002{1}\u0002 | \u0002{2}\u0002 Open Issues | \u0002{3}\u0002 Forks | \u0002{4}\u0002 Stargazers | {5}", foundRepo.FullName, foundRepo.CreatedAt.ToString("d"), foundRepo.OpenIssuesCount, foundRepo.ForksCount, foundRepo.StargazersCount, foundRepo.HtmlUrl);
SendResponse(command.MessageType, command.Location, command.Nick.Nickname, repoMessage);
if (foundRepo.Description != string.Empty)
{
SendResponse(command.MessageType, command.Location, command.Nick.Nickname, foundRepo.Description);
}
}
else
{
SendResponse(command.MessageType, command.Location, command.Nick.Nickname, "Invalid Repository ID");
}
}
else
{
SendResponse(command.MessageType, command.Location, command.Nick.Nickname, "Invalid Repository ID");
}
}
else
{
string userMessage = string.Format("\u0002{0}\u0002 - \u0002{1}\u0002 Followers - Following \u0002{2}\u0002 Users - \u0002{3}\u0002 Repositories | {4}", user.Login, user.Followers, user.Following, user.PublicRepos, user.HtmlUrl);
SendResponse(command.MessageType, command.Location, command.Nick.Nickname, userMessage);
}
}
else
{
SendResponse(command.MessageType, command.Location, command.Nick.Nickname, string.Format("Github user \u0002{0}\u0002 does not exist.", username));
}
}
catch (Octokit.RateLimitExceededException ex)
{
OnError(ex.Message);
}
}

private async void GetRepositoryInformation(CommandMessage command)
{
try
{
GitHubClient github = new GitHubClient(new ProductHeaderValue("CombotIRCBot"));
if (GetOptionValue("Username").ToString() != string.Empty && GetOptionValue("Password").ToString() != string.Empty)
{
github.Credentials = new Credentials(GetOptionValue("Username").ToString(), GetOptionValue("Password").ToString());
NewAuthorization newAuth = new NewAuthorization();
newAuth.Note = "Get Git Information";
try
{
Authorization auth = await github.Authorization.Create(newAuth);
}
catch (Octokit.AuthorizationException ex)
{
OnError(ex.Message);
return;
}
}
SearchRepositoryResult foundRepo = await github.Search.SearchRepo(new SearchRepositoriesRequest(command.Arguments["Repository"]));
if (foundRepo.TotalCount > 0)
{
Repository repo = foundRepo.Items.First();
string repoMessage = string.Format("\u0002{0}\u0002 | Created On \u0002{1}\u0002 | \u0002{2}\u0002 Open Issues | \u0002{3}\u0002 Forks | \u0002{4}\u0002 Stargazers | {5}", repo.FullName, repo.CreatedAt.ToString("d"), repo.OpenIssuesCount, repo.ForksCount, repo.StargazersCount, repo.HtmlUrl);
SendResponse(command.MessageType, command.Location, command.Nick.Nickname, repoMessage);
if (repo.Description != string.Empty)
{
SendResponse(command.MessageType, command.Location, command.Nick.Nickname, repo.Description);
}
}
else
{
SendResponse(command.MessageType, command.Location, command.Nick.Nickname, string.Format("Repository \u0002{0}\u0002 does not exist.", command.Arguments["Repository"]));
}
}
catch (Octokit.RateLimitExceededException ex)
{
OnError(ex.Message);
}
}
}
}

+ 88
- 0
Modules/Github/Github.csproj View File

@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7D7B5FCB-C9CC-4CB1-B5EF-827BD3398E39}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Github</RootNamespace>
<AssemblyName>Github</AssemblyName>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\Bin\Debug\Modules\Github\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\Bin\Release\Modules\Github\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Octokit">
<HintPath>..\..\packages\Octokit.0.6.2\lib\net45\Octokit.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Github.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Combot\Combot.csproj">
<Project>{23e4c371-16e4-4fac-8b11-44288399bb55}</Project>
<Name>Combot</Name>
</ProjectReference>
<ProjectReference Include="..\..\IRCServices\IRCServices.csproj">
<Project>{65fcbf1c-8c9e-4688-becc-185d9030899f}</Project>
<Name>IRCServices</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="Module.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<SubType>Designer</SubType>
</None>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>md "$(SolutionDir)$(ConfigurationName)\Modules\$(TargetName)"
copy /Y "$(TargetPath)" "$(SolutionDir)$(ConfigurationName)\Modules\$(TargetName)"
copy /Y "$(TargetDir)Module.config" "$(SolutionDir)$(ConfigurationName)\Modules\$(TargetName)"
copy /Y "$(TargetDir)Octokit.dll" "$(SolutionDir)$(ConfigurationName)\Modules\$(TargetName)"</PostBuildEvent>
</PropertyGroup>
<Import Project="..\..\packages\GitVersionTask.2.0.1\Build\GitVersionTask.targets" Condition="Exists('..\..\packages\GitVersionTask.2.0.1\Build\GitVersionTask.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\GitVersionTask.2.0.1\Build\GitVersionTask.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\GitVersionTask.2.0.1\Build\GitVersionTask.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

+ 114
- 0
Modules/Github/Module.config View File

@@ -0,0 +1,114 @@
{
"Name": "Github",
"ClassName": "Github",
"Enabled": true,
"ChannelBlacklist": [],
"NickBlacklist": [],
"Commands": [
{
"Name": "Github Information",
"Description": "Gets a nicks Github information.",
"Enabled": true,
"ChannelBlacklist": [],
"NickBlacklist": [],
"Triggers": [
"git",
"github"
],
"Arguments": [
{
"Name": "Username",
"Description": "The Github username for the information you want.",
"AllowedValues": [],
"DependentArguments": [],
"MessageTypes": [
0,
1,
2
],
"Required": false
},
{
"Name": "Repository ID",
"Description": "The repository you want information on.",
"AllowedValues": [],
"MessageTypes": [
0,
1,
2
],
"Required": false
}
],
"AllowedMessageTypes": [
0,
1,
2
],
"AllowedAccess": [
0,
1,
2,
3,
4,
5,
6
],
"ShowHelp": true,
"SpamCheck": true
},
{
"Name": "Repository Information",
"Description": "Search for a Github repository.",
"Enabled": true,
"ChannelBlacklist": [],
"NickBlacklist": [],
"Triggers": [
"repo",
"repository"
],
"Arguments": [
{
"Name": "Repository",
"Description": "The name of the repository you want to view.",
"AllowedValues": [],
"DependentArguments": [],
"MessageTypes": [
0,
1,
2
],
"Required": true
}
],
"AllowedMessageTypes": [
0,
1,
2
],
"AllowedAccess": [
0,
1,
2,
3,
4,
5,
6
],
"ShowHelp": true,
"SpamCheck": true
}
],
"Options": [
{
"Name": "Username",
"Description": "The bot's github username",
"Value": ""
},
{
"Name": "Password",
"Description": "The bot's github password",
"Value": ""
}
]
}

+ 33
- 0
Modules/Github/Properties/AssemblyInfo.cs View File

@@ -0,0 +1,33 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Github Module")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Teknik")]
[assembly: AssemblyProduct("Combot")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("5c350b8e-5820-4034-9d67-49d2ddbfcc6f")]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:

+ 5
- 0
Modules/Github/packages.config View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="GitVersionTask" version="2.0.1" targetFramework="net451" developmentDependency="true" />
<package id="Octokit" version="0.6.2" targetFramework="net451" />
</packages>

Loading…
Cancel
Save