Browse Source

Modified Seen to use it's own table for keeping track of last seen data.

tags/3.1.0
Teknikode 3 years ago
parent
commit
aae4ea1114
3 changed files with 150 additions and 161 deletions
  1. 22
    0
      Modules/Seen/CreateTable.sql
  2. 123
    161
      Modules/Seen/Seen.cs
  3. 5
    0
      Modules/Seen/Seen.csproj

+ 22
- 0
Modules/Seen/CreateTable.sql View File

@@ -0,0 +1,22 @@
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";

--
-- Database: `combot`
--

-- --------------------------------------------------------

--
-- Table structure for table `nicks`
--

CREATE TABLE IF NOT EXISTS `seen` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`server_id` int(11) NOT NULL,
`channel_id` int(11) NOT NULL,
`nick_id` int(11) NOT NULL,
`message` varchar(500) CHARACTER SET utf8mb4 NOT NULL,
`date_seen` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=25212 ;

+ 123
- 161
Modules/Seen/Seen.cs View File

@@ -2,6 +2,9 @@
using System.Collections.Generic;
using System.Linq;
using Combot.Databases;
using System.IO;
using Combot.IRCServices.Messaging;
using Combot.IRCServices;

namespace Combot.Modules.Plugins
{
@@ -9,7 +12,21 @@ namespace Combot.Modules.Plugins
{
public override void Initialize()
{
InitializeTable();
Bot.CommandReceivedEvent += HandleCommandEvent;

// Handle nick events and update last seen
Bot.IRC.Message.CTCPMessageReceivedEvent += CTCPRelayHandlerHandler;
Bot.IRC.Message.CTCPNoticeReceivedEvent += CTCPRelayHandlerHandler;
Bot.IRC.Message.ChannelMessageReceivedEvent += ChannelMessageHandler;
Bot.IRC.Message.ChannelNoticeReceivedEvent += ChannelNoticeHandler;
Bot.IRC.Message.JoinChannelEvent += ChannelJoinHandler;
Bot.IRC.Message.InviteChannelEvent += ChannelInviteHandler;
Bot.IRC.Message.PartChannelEvent += ChannelPartHandler;
Bot.IRC.Message.KickEvent += ChannelKickHandler;
Bot.IRC.Message.TopicChangeEvent += TopicChangeHandler;
Bot.IRC.Message.QuitEvent += QuitHandler;
Bot.IRC.Message.NickChangeEvent += NickChangeHandler;
}

public override void ParseCommand(CommandMessage command)
@@ -23,65 +40,28 @@ namespace Combot.Modules.Plugins
}
}

private void InitializeTable()
{
string sqlPath = Path.Combine(Directory.GetCurrentDirectory(), ConfigPath, "CreateTable.sql");
if (File.Exists(sqlPath))
{
string query = File.ReadAllText(sqlPath);
Bot.Database.Execute(query);
}
}

private void GetLastSeen(CommandMessage command)
{
string channel = command.Arguments.ContainsKey("Channel") ? command.Arguments["Channel"] : command.Location;
List<Dictionary<string, object>> channelList = GetChannelList(channel, command.Arguments["Nickname"]);
List<Dictionary<string, object>> partList = GetPartList(channel, command.Arguments["Nickname"]);
List<Dictionary<string, object>> joinList = GetJoinList(channel, command.Arguments["Nickname"]);
List<Dictionary<string, object>> kickList = GetKickList(channel, command.Arguments["Nickname"]);
List<Dictionary<string, object>> quitList = GetQuitList(command.Arguments["Nickname"]);

List<Dictionary<DateTime, string>> lastSeenList = new List<Dictionary<DateTime, string>>();
List<Dictionary<string, object>> lastSeenList = GetSeenList(channel, command.Arguments["Nickname"]);

if (channelList.Any())
{
DateTime chanTime = (DateTime)channelList.First()["date_added"];
TimeSpan difference = DateTime.Now.Subtract(chanTime);
string message = string.Format("I last saw \u0002{0}\u0002 {1} ago saying the following in \u0002{2}\u0002: {3}", command.Arguments["Nickname"], ConvertToDifference(difference), channelList.First()["name"], channelList.First()["message"]);
lastSeenList.Add(new Dictionary<DateTime, string>() { { chanTime, message } });
}
if (partList.Any())
{
DateTime partTime = (DateTime)partList.First()["date_added"];
TimeSpan difference = DateTime.Now.Subtract(partTime);
string message = string.Format("I last saw \u0002{0}\u0002 {1} ago leaving \u0002{2}\u0002.", command.Arguments["Nickname"], ConvertToDifference(difference), partList.First()["name"]);
lastSeenList.Add(new Dictionary<DateTime, string>() { { partTime, message } });
}
if (joinList.Any())
if (lastSeenList.Any())
{
DateTime joinTime = (DateTime)joinList.First()["date_added"];
TimeSpan difference = DateTime.Now.Subtract(joinTime);
string message = string.Format("I last saw \u0002{0}\u0002 {1} ago joining \u0002{2}\u0002.", command.Arguments["Nickname"], ConvertToDifference(difference), joinList.First()["name"]);
lastSeenList.Add(new Dictionary<DateTime, string>() { { joinTime, message } });
}
if (kickList.Any())
{
DateTime kickTime = (DateTime)kickList.First()["date_added"];
TimeSpan difference = DateTime.Now.Subtract(kickTime);
string message = string.Format("I last saw \u0002{0}\u0002 {1} ago being kicked from \u0002{2}\u0002 with the reason: {3}", command.Arguments["Nickname"], ConvertToDifference(difference), kickList.First()["name"], kickList.First()["reason"]);
lastSeenList.Add(new Dictionary<DateTime, string>() { { kickTime, message } });
}
if (quitList.Any())
{
DateTime quitTime = (DateTime)quitList.First()["date_added"];
TimeSpan difference = DateTime.Now.Subtract(quitTime);
string message = string.Format("I last saw \u0002{0}\u0002 {1} ago quitting.", command.Arguments["Nickname"], ConvertToDifference(difference));
lastSeenList.Add(new Dictionary<DateTime, string>() { { quitTime, message } });
}

if (lastSeenList.Count > 0)
{
DateTime bestTime = new DateTime(1990);
string seenMessage = string.Empty;
for (int i = 0; i < lastSeenList.Count; i++)
{
if (lastSeenList[i].Keys.First().CompareTo(bestTime) > 0)
{
bestTime = lastSeenList[i].Keys.First();
seenMessage = lastSeenList[i].Values.First();
}
}
Dictionary<string, object> lastSeen = lastSeenList.First();
DateTime bestTime = DateTime.Now;
DateTime.TryParse(lastSeen["date_seen"].ToString(), out bestTime);
string seenMessage = string.Format("I last saw \u0002{0}\u0002 {1} ago {2}", command.Arguments["Nickname"], ConvertToDifference(DateTime.Now.Subtract(bestTime)), lastSeen["message"].ToString());
SendResponse(command.MessageType, command.Location, command.Nick.Nickname, seenMessage);
}
else
@@ -99,138 +79,120 @@ namespace Combot.Modules.Plugins
}
}

private List<Dictionary<string, object>> GetChannelList(string channel, string nickname)
private List<Dictionary<string, object>> GetSeenList(string channel, string nickname)
{

string search = "SELECT `seen`.`id`, `seen`.`date_seen`, `seen`.`message`, `channels`.`name` FROM `seen` " +
"INNER JOIN `nicks` " +
"ON `seen`.`nick_id` = `nicks`.`id` " +
"INNER JOIN `channels` " +
"ON `seen`.`channel_id` = `channels`.`id` " +
"INNER JOIN `servers` " +
"ON `seen`.`server_id` = `servers`.`id` ";
if (channel != null)
{
string search = "SELECT `channelmessages`.`message`, `channelmessages`.`date_added`, `channels`.`name` FROM `channelmessages` " +
"INNER JOIN `nicks` " +
"ON `channelmessages`.`nick_id` = `nicks`.`id` " +
"INNER JOIN `channels` " +
"ON `channelmessages`.`channel_id` = `channels`.`id` " +
"INNER JOIN `servers` " +
"ON `channelmessages`.`server_id` = `servers`.`id` " +
"WHERE `servers`.`name` = {0} AND `channels`.`name` = {1} AND `nicks`.`nickname` = {2} " +
"ORDER BY date_added DESC LIMIT 1";
search += "WHERE `servers`.`name` = {0} AND `channels`.`name` = {1} AND `nicks`.`nickname` = {2} " +
"ORDER BY date_seen DESC";
return Bot.Database.Query(search, new object[] { Bot.ServerConfig.Name, channel, nickname });
}
else
{
string search = "SELECT `channelmessages`.`message`, `channelmessages`.`date_added`, `channels`.`name` FROM `channelmessages` " +
"INNER JOIN `nicks` " +
"ON `channelmessages`.`nick_id` = `nicks`.`id` " +
"INNER JOIN `channels` " +
"ON `channelmessages`.`channel_id` = `channels`.`id` " +
"INNER JOIN `servers` " +
"ON `channelmessages`.`server_id` = `servers`.`id` " +
"WHERE `servers`.`name` = {0} AND `nicks`.`nickname` = {1} " +
"ORDER BY date_added DESC LIMIT 1";
return Bot.Database.Query(search, new object[] { Bot.ServerConfig.Name, nickname });
search += "WHERE `servers`.`name` = {0} AND `nicks`.`nickname` = {1} " +
"ORDER BY date_seen DESC";
return Bot.Database.Query(search, new object[] { Bot.ServerConfig.Name, nickname });
}
}

private List<Dictionary<string, object>> GetPartList(string channel, string nickname)
private void NickChangeHandler(object sender, NickChangeInfo e)
{
if (channel != null)
{
string search = "SELECT `channelparts`.`date_added`, `channels`.`name` FROM `channelparts` " +
"INNER JOIN `nicks` " +
"ON `channelparts`.`nick_id` = `nicks`.`id` " +
"INNER JOIN `channels` " +
"ON `channelparts`.`channel_id` = `channels`.`id` " +
"INNER JOIN `servers` " +
"ON `channelparts`.`server_id` = `servers`.`id` " +
"WHERE `servers`.`name` = {0} AND `channels`.`name` = {1} AND `nicks`.`nickname` = {2} " +
"ORDER BY date_added DESC LIMIT 1";
return Bot.Database.Query(search, new object[] { Bot.ServerConfig.Name, channel, nickname });
}
else
{
string search = "SELECT `channelparts`.`date_added`, `channels`.`name` FROM `channelparts` " +
"INNER JOIN `nicks` " +
"ON `channelparts`.`nick_id` = `nicks`.`id` " +
"INNER JOIN `channels` " +
"ON `channelparts`.`channel_id` = `channels`.`id` " +
"INNER JOIN `servers` " +
"ON `channelparts`.`server_id` = `servers`.`id` " +
"WHERE `servers`.`name` = {0} AND `nicks`.`nickname` = {1} " +
"ORDER BY date_added DESC LIMIT 1";
return Bot.Database.Query(search, new object[] { Bot.ServerConfig.Name, nickname });
}
string message = string.Format("changing nicks to \u0002{0}\u0002", e.NewNick);
UpdateSeen(null, e.OldNick, message, e.TimeStamp);
}

private List<Dictionary<string, object>> GetJoinList(string channel, string nickname)
private void QuitHandler(object sender, QuitInfo e)
{
if (channel != null)
{
string search = "SELECT `channeljoins`.`date_added`, `channels`.`name` FROM `channeljoins` " +
"INNER JOIN `nicks` " +
"ON `channeljoins`.`nick_id` = `nicks`.`id` " +
"INNER JOIN `channels` " +
"ON `channeljoins`.`channel_id` = `channels`.`id` " +
"INNER JOIN `servers` " +
"ON `channeljoins`.`server_id` = `servers`.`id` " +
"WHERE `servers`.`name` = {0} AND `channels`.`name` = {1} AND `nicks`.`nickname` = {2} " +
"ORDER BY date_added DESC LIMIT 1";
return Bot.Database.Query(search, new object[] { Bot.ServerConfig.Name, channel, nickname });
}
else
{
string search = "SELECT `channeljoins`.`date_added`, `channels`.`name` FROM `channeljoins` " +
"INNER JOIN `nicks` " +
"ON `channeljoins`.`nick_id` = `nicks`.`id` " +
"INNER JOIN `channels` " +
"ON `channeljoins`.`channel_id` = `channels`.`id` " +
"INNER JOIN `servers` " +
"ON `channeljoins`.`server_id` = `servers`.`id` " +
"WHERE `servers`.`name` = {0} AND `nicks`.`nickname` = {1} " +
"ORDER BY date_added DESC LIMIT 1";
return Bot.Database.Query(search, new object[] { Bot.ServerConfig.Name, nickname });
}
string message = string.Format("quitting ({0})", e.Message);
UpdateSeen(null, e.Nick, message, e.TimeStamp);
}

private List<Dictionary<string, object>> GetKickList(string channel, string nickname)
private void TopicChangeHandler(object sender, TopicChangeInfo e)
{
if (channel != null)
string message = string.Format("changing the topic in \u0002{0}\u0002 to: {1}", e.Channel, e.Topic);
UpdateSeen(e.Channel, e.Nick, message, e.TimeStamp);
}

private void ChannelKickHandler(object sender, KickInfo e)
{
string message = string.Format("being kicked from \u0002{0}\u0002 by \u0002{1}\u0002 for the reason: {2}", e.Channel, e.Nick.Nickname, e.Reason);
UpdateSeen(e.Channel, e.KickedNick, message, e.TimeStamp);
}

private void ChannelPartHandler(object sender, PartChannelInfo e)
{
string message = string.Format("parting \u0002{0}\u0002", e.Channel);
UpdateSeen(e.Channel, e.Nick, message, e.TimeStamp);
}

private void ChannelInviteHandler(object sender, InviteChannelInfo e)
{
string message = string.Format("inviting \u0002{0}\u0002 into \u0002{0}\u0002", e.Recipient.Nickname, e.Channel);
UpdateSeen(e.Channel, e.Requester, message, e.TimeStamp);
}

private void ChannelJoinHandler(object sender, JoinChannelInfo e)
{
string message = string.Format("joining \u0002{0}\u0002", e.Channel);
UpdateSeen(e.Channel, e.Nick, message, e.TimeStamp);
}

private void ChannelNoticeHandler(object sender, ChannelNotice e)
{
string message = string.Format("saying the following notice in \u0002{0}\u0002: {1}", e.Channel, e.Message);
UpdateSeen(e.Channel, e.Sender, message, e.TimeStamp);
}

private void ChannelMessageHandler(object sender, ChannelMessage e)
{
string message = string.Format("saying the following in \u0002{0}\u0002: {1}", e.Channel, e.Message);
UpdateSeen(e.Channel, e.Sender, message, e.TimeStamp);
}

private void CTCPRelayHandlerHandler(object sender, CTCPMessage e)
{
string message = string.Format("saying the following CTCP command in \u0002{0}\u0002: [{1}] {2}", e.Location, e.Command, e.Arguments);
UpdateSeen(e.Location, e.Sender, message, e.TimeStamp);
}

private void UpdateSeen(string channel, Nick nick, string message, DateTime time)
{
List<Dictionary<string, object>> results = GetSeenList(channel, nick.Nickname);
if (results.Any())
{
string search = "SELECT `channelkicks`.`date_added`, `channelkicks`.`reason`, `channels`.`name` FROM `channelkicks` " +
"INNER JOIN `nicks` " +
"ON `channelkicks`.`kicked_nick_id` = `nicks`.`id` " +
"INNER JOIN `channels` " +
"ON `channelkicks`.`channel_id` = `channels`.`id` " +
"INNER JOIN `servers` " +
"ON `channelkicks`.`server_id` = `servers`.`id` " +
"WHERE `servers`.`name` = {0} AND `channels`.`name` = {1} AND `nicks`.`nickname` = {2} " +
"ORDER BY date_added DESC LIMIT 1";
return Bot.Database.Query(search, new object[] { Bot.ServerConfig.Name, channel, nickname });
foreach (Dictionary<string, object> row in results)
{
// Update the table
string query = "UPDATE `seen` SET " +
"`message` = {0}, " +
"`date_seen` = {1} " +
"WHERE `id` = {2}";
Bot.Database.Execute(query, new object[] { message, time, row["id"].ToString() });
}
}
else
{
string search = "SELECT `channelkicks`.`date_added`, `channelkicks`.`reason`, `channels`.`name` FROM `channelkicks` " +
"INNER JOIN `nicks` " +
"ON `channelkicks`.`kicked_nick_id` = `nicks`.`id` " +
"INNER JOIN `channels` " +
"ON `channelkicks`.`channel_id` = `channels`.`id` " +
"INNER JOIN `servers` " +
"ON `channelkicks`.`server_id` = `servers`.`id` " +
"WHERE `servers`.`name` = {0} AND `nicks`.`nickname` = {1} " +
"ORDER BY date_added DESC LIMIT 1";
return Bot.Database.Query(search, new object[] { Bot.ServerConfig.Name, nickname });
// Add a new record
AddNick(nick);
AddChannel(channel);
string query = "INSERT INTO `seen` SET " +
"`server_id` = (SELECT `id` FROM `servers` WHERE `name` = {0}), " +
"`channel_id` = (SELECT `channels`.`id` FROM `channels` INNER JOIN `servers` ON `servers`.`id` = `channels`.`server_id` WHERE `servers`.`name` = {1} && `channels`.`name` = {2}), " +
"`nick_id` = (SELECT `nicks`.`id` FROM `nicks` INNER JOIN `servers` ON `servers`.`id` = `nicks`.`server_id` WHERE `servers`.`name` = {3} && `nickname` = {4}), " +
"`message` = {5}, " +
"`date_seen` = {6}";
Bot.Database.Execute(query, new object[] { Bot.ServerConfig.Name, Bot.ServerConfig.Name, channel, Bot.ServerConfig.Name, nick.Nickname, message, time });
}
}

private List<Dictionary<string, object>> GetQuitList(string nickname)
{
string search = "SELECT `quits`.`date_added` FROM `quits` " +
"INNER JOIN `nicks` " +
"ON `quits`.`nick_id` = `nicks`.`id` " +
"INNER JOIN `servers` " +
"ON `quits`.`server_id` = `servers`.`id` " +
"WHERE `servers`.`name` = {0} AND `nicks`.`nickname` = {1} " +
"ORDER BY date_added DESC LIMIT 1";
return Bot.Database.Query(search, new object[] { Bot.ServerConfig.Name, nickname });
}

private string ConvertToDifference(TimeSpan time)
{
string timeString = string.Empty;

+ 5
- 0
Modules/Seen/Seen.csproj View File

@@ -93,6 +93,11 @@
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<Content Include="CreateTable.sql">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>md "$(SolutionDir)$(ConfigurationName)\Modules\$(TargetName)"

Loading…
Cancel
Save