Skip to content

Instantly share code, notes, and snippets.

@miou-gh
Created January 26, 2017 12:04
Show Gist options
  • Save miou-gh/195951e6fc622be062f15bc5745da66f to your computer and use it in GitHub Desktop.
Save miou-gh/195951e6fc622be062f15bc5745da66f to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Xml;
using System.Xml.Serialization;
using ChatSharp;
namespace GergBot
{
class Program
{
static void Main(string[] args)
{
try {
new GergBot();
} catch {
// If disconnected, wait a few moments and try again.
Helpers.EasyTimer.SetTimeout(() => {
Main(new string[] { });
}, 1000 * 10);
}
Thread.Sleep(-1);
}
}
class GergBot
{
public IrcClient IrcClient { get; set; }
public EverybodyEditsForums Forums { get; set; }
public IDisposable ThreadWatcher { get; set; }
public IDisposable ConnectionWatcher { get; set; }
public bool ConnectionSuccessful { get; set; } = false;
public DateTime LastChecked { get; set; }
public GergBot() : base()
{
this.Forums = new EverybodyEditsForums();
this.IrcClient = new IrcClient("removed", new IrcUser("GergBot", "GergBot", "removed", "GergBot"), true) {
IgnoreInvalidSSL = true,
};
this.ConnectionWatcher = Helpers.EasyTimer.SetTimeout(() => {
if (!this.ConnectionSuccessful)
throw new Exception("GergBot did not successfully connect in time.");
}, 1000 * 60);
this.IrcClient.ConnectionComplete += (s, e) => {
this.ConnectionSuccessful = true;
this.IrcClient.JoinChannel("#EEForums");
this.LastChecked = DateTime.UtcNow;
this.ThreadWatcher = Helpers.EasyTimer.SetInterval(() => {
var feed = this.Forums.Refresh();
var posts = feed.Topic.Where(x => DateTime.Parse(x.Posted).ToUniversalTime() >= this.LastChecked);
foreach (var post in posts) {
var category = new EverybodyEditsForums.ForumCategory(0, "???", "???");
foreach (var forum in this.Forums.Forums) {
if (this.Forums.Refresh(forum).Topic.Any(x => x.Id == post.Id)) {
category = forum;
break;
}
}
var channel = this.IrcClient.Channels.FirstOrDefault(x => x.Name == "#EEForums");
if (channel != null) {
channel.SendMessage($"[{category.Alias}] [{ post.Author.Name }] { Helpers.Truncate(post.Title, 24) } http://gerg.cf/{post.Id}");
}
}
this.LastChecked = DateTime.UtcNow;
}, 1000 * 10);
};
this.IrcClient.NetworkError += (s, e) => {
this.ThreadWatcher.Dispose();
this.ConnectionWatcher.Dispose();
throw new Exception("IrcClient Network Error " + e.SocketError.ToString());
};
this.IrcClient.ChannelMessageRecieved += (s, e) => {
var channel = this.IrcClient.Channels[e.PrivateMessage.Source];
};
this.IrcClient.ConnectAsync();
}
}
public class EverybodyEditsForums
{
public List<ForumCategory> Forums { get; set; }
public EverybodyEditsForums()
{
this.Forums = new List<ForumCategory>() {
new ForumCategory(id:3, title:"Game Business", alias:"GB"),
new ForumCategory(id:2, title:"Forum Business", alias:"FB"),
new ForumCategory(id:4, title:"Game Discussion", alias:"GD"),
new ForumCategory(id:19, title:"Bots and Programming", alias:"B&P"),
new ForumCategory(id:9, title:"Crews", alias:"Crews"),
new ForumCategory(id:18, title:"Questions and Answers", alias:"Q&A"),
new ForumCategory(id:7, title:"Level Creation", alias:"Lvl Create"),
new ForumCategory(id:8, title:"Rooms", alias:"Rooms"),
new ForumCategory(id:20, title:"Graphics Suggestions", alias:"Gfx Sug."),
new ForumCategory(id:5, title:"Game Suggestions", alias:"Game Sug."),
new ForumCategory(id:24, title:"Campaign Suggestions", alias:"Camp Sug."),
new ForumCategory(id:11, title:"Forum Discussion", alias:"Forum Sug."),
new ForumCategory(id:12, title:"Bug Reports", alias:"Bugs"),
new ForumCategory(id:13, title:"Off-Topic Discussion", alias:"Off-Topic"),
new ForumCategory(id:26, title:"Debates", alias:"Debates"),
new ForumCategory(id:14, title:"Creative", alias:"Crtv"),
new ForumCategory(id:17, title:"Forum Games", alias:"FG"),
new ForumCategory(id:21, title:"Mod Discussion", alias:"MD"),
new ForumCategory(id:15, title:"Topic Graveyard", alias:"GY"),
};
}
[Serializable()]
public class ForumFeed
{
[XmlRoot(ElementName = "author")]
public class Author
{
[XmlElement(ElementName = "name")]
public string Name { get; set; }
[XmlElement(ElementName = "uri")]
public string Uri { get; set; }
[XmlElement(ElementName = "email")]
public string Email { get; set; }
}
[XmlRoot(ElementName = "topic"), Serializable()]
public class Topic
{
[XmlElement(ElementName = "title")]
public string Title { get; set; }
[XmlElement(ElementName = "link")]
public string Link { get; set; }
[XmlElement(ElementName = "content")]
public string Content { get; set; }
[XmlElement(ElementName = "author")]
public Author Author { get; set; }
[XmlElement(ElementName = "posted")]
public string Posted { get; set; }
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
}
[XmlRoot(ElementName = "source"), Serializable()]
public class Source
{
[XmlElement(ElementName = "url")]
public string Url { get; set; }
[XmlElement(ElementName = "topic")]
public List<Topic> Topic { get; set; }
}
}
public ForumFeed.Source Refresh(params ForumCategory[] categories)
{
var query = new Uri("http://forums.everybodyedits.com/extern.php?type=xml&fid=" + ((categories != null && categories.Length > 0) ? string.Join(",", from cat in categories select cat.Id) : ""));
var feed = new XmlDocument(); {
feed.LoadXml(new WebClient() { Proxy = null }.DownloadString(query));
}
// Remove the header prior to serialization.
feed.RemoveChild(feed.FirstChild);
var serializer = new XmlSerializer(typeof(ForumFeed.Source), new XmlRootAttribute("source"));
var deserialized = (ForumFeed.Source)serializer.Deserialize(new MemoryStream(Encoding.UTF8.GetBytes(feed.InnerXml)));
return deserialized;
}
public class ForumCategory
{
public int Id { get; set; }
public string Title { get; set; }
public string Alias { get; set; }
public ForumCategory(int id, string title, string alias)
{
this.Id = id;
this.Title = title;
this.Alias = alias;
}
}
}
public static class Helpers
{
public static class EasyTimer
{
public static IDisposable SetInterval(Action method, int delayInMilliseconds)
{
var timer = new System.Timers.Timer(delayInMilliseconds);
timer.Elapsed += (source, e) => {
method();
};
timer.Enabled = true;
timer.Start();
// Returns a stop handle which can be used for stopping
// the timer, if required
return timer as IDisposable;
}
public static IDisposable SetTimeout(Action method, int delayInMilliseconds)
{
var timer = new System.Timers.Timer(delayInMilliseconds);
timer.Elapsed += (source, e) => {
method();
};
timer.AutoReset = false;
timer.Enabled = true;
timer.Start();
// Returns a stop handle which can be used for stopping
// the timer, if required
return timer as IDisposable;
}
}
public static string Truncate(this string value, int maxChars)
{
return value.Length <= maxChars ? value : value.Substring(0, maxChars) + "...";
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment