Code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Xml;
using KNLib;
namespace Lyralabs.Knuddels.Nickcrawler
{
public class Program
{
private static readonly Regex channelParser = new Regex("(?<channel>([^"]{2,}))\n[0-9]{1,3}", RegexOptions.Compiled);
private static readonly Regex chatterParser = new Regex("°>_h(?<nick>(.+?))\\|/serverpp", RegexOptions.Compiled);
private static readonly Regex channelNameParser = new Regex("Chatter im (?<name>(.+)) \\(", RegexOptions.Compiled);
private static readonly string ApiUrl = "http://k-script.cc/api3.php";
private static readonly int SpamWait = 3000;
private static List<string> channels = null;
private static List<string> nicks = null;
private static string currentChannel = null;
private static string butlerName = null;
private static bool cancelCrawl = false;
private static void Main(string[] args)
{
while (true)
{
Console.Write("Willst du eine GUI haben? (Y/N)");
ConsoleKeyInfo cki = Console.ReadKey();
if (cki.KeyChar == 'Y' || cki.KeyChar == 'y')
{
// show gui
}
else if (cki.KeyChar == 'N' || cki.KeyChar == 'n')
{
break;
}
else
{
Console.WriteLine("Falsche Eingabe!\n");
continue;
}
}
Console.Write("K-Script Username: ");
string ksUser = Console.ReadLine();
string ksPass = ReadPassword("K-Script Passwort: ");
Console.WriteLine();
StartWaiter();
bool isValidUser = AsyncAuth(ksUser, ksPass, 10, 20, null);
StopWaiter();
if (waiterThread != null && waiterThread.IsAlive)
waiterThread.Join();
if (isValidUser)
{
Console.WriteLine("Okay, du bist authentifiziert!\n");
}
else
{
Console.WriteLine("Fehler! Du hast keine 10 Posts oder mehr als 20 Warnpunkte!");
Thread.Sleep(3000);
return;
}
KNClient client = new KNClient();
client.OnReceive += new KNMessageEventHandler(client_OnReceive);
RemoteEndpoint endpoint = (RemoteEndpoint)ChooseFromEnum<RemoteEndpoint>("Chatsystem auswählen: ");
Console.WriteLine("Ausgewähltes Chatsystem: {0}\n", endpoint.ToString());
Console.Write("Connecting... ");
client.Connect(endpoint);
Console.WriteLine("done\n");
Console.Write("Nickname: ");
string nick = Console.ReadLine();
string pass = ReadPassword("Passwort: ");
Console.Write("Channel: ");
string chan = Console.ReadLine();
Console.Write("\nEinloggen... ");
client.Login(nick, pass, chan);
Console.WriteLine("done\n");
while (channels == null)
Thread.Sleep(100);
Console.WriteLine("Es gibt {0} Channels.", channels.Count);
TimeSpan time = new TimeSpan(0, 0, channels.Count * 3);
Console.CancelKeyPress += ((object sender, ConsoleCancelEventArgs e) =>
{
e.Cancel = true;
cancelCrawl = true;
});
Console.WriteLine("Alle Channels zu crawlen dauert ca. {0} Minuten.\nDrücke CRTL + C um den Crawlvorgang abzubrechen und mit dem Spammen zu beginnen\n", (int)time.TotalMinutes);
nicks = new List<string>();
foreach (string channel in channels)
{
if (cancelCrawl)
break;
client.Send(String.Concat("e\0", currentChannel, "\0/wc ", channel));
try
{
Thread.Sleep(SpamWait);
}
catch (Exception) { cancelCrawl = true; }
}
StringBuilder sb = new StringBuilder();
foreach (string crawledNick in nicks)
sb.AppendLine(crawledNick);
File.WriteAllText("nick.log", sb.ToString());
Console.WriteLine("Alle nicks Gespeichert in nick.log ({0} Stück)\n", nicks.Count);
SpamTypes spamType = (SpamTypes)ChooseFromEnum<SpamTypes>("Bitte wähle den Spam-Typ: ");
Console.WriteLine("Ausgewählter Spam-Typ: {0}\n", spamType);
Console.Write("Spamtext: ");
string text = Console.ReadLine();
Spam(spamType, text, client);
Console.WriteLine("\nEs wurden {0} Nachrichten versendet.", nicks.Count);
Console.ReadKey();
}
private static void Spam(SpamTypes spamType, string text, KNClient client)
{
for (int i = 0; i < nicks.Count; i++)
{
Thread.Sleep(SpamWait);
string token = String.Concat("e\0", currentChannel, "\0/", spamType.ToString().ToLower(), " ", nicks[i], ":", text);
if (client != null)
client.Send(token);
Console.WriteLine("Sent {0} to {1}", spamType, nicks[i]);
}
}
static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
{
e.Cancel = true;
cancelCrawl = true;
}
private static string ReadPassword(string label)
{
StringBuilder sb = new StringBuilder();
Console.Write(label);
while (true)
{
ConsoleKeyInfo cki = Console.ReadKey();
if (cki.Key == ConsoleKey.Enter)
{
Console.WriteLine();
return sb.ToString();
}
if (cki.Key == ConsoleKey.Backspace)
{
if (sb.Length > 0)
{
sb.Remove(sb.Length - 1, 1);
Console.Write(" ");
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
}
}
else
{
sb.Append(cki.KeyChar);
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
Console.Write("*");
}
}
}
private static int ChooseFromEnum<T>(string label)
{
Console.WriteLine(label);
string[] chats = Enum.GetNames(typeof(T));
for (int i = 0; i < chats.Length; i++)
Console.WriteLine("\t[{0}] - {1}", i + 1, chats[i]);
Console.SetCursorPosition(label.Length, Console.CursorTop - (chats.Length + 1));
while (true)
{
ConsoleKeyInfo key = Console.ReadKey();
if (key.KeyChar > '0' && key.KeyChar <= '0' + chats.Length)
{
int chatSystem = (Convert.ToInt32(Convert.ToString(key.KeyChar)) - 1);
Console.WriteLine();
for (int i = 0; i < chats.Length; i++)
{
Console.WriteLine(new String(' ', Console.WindowWidth - 1));
}
Console.SetCursorPosition(0, Console.CursorTop - chats.Length);
return chatSystem;
}
else
{
if (key.Key == ConsoleKey.Backspace)
Console.Write(" ");
System.Media.SystemSounds.Exclamation.Play();
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
Console.Write(" ");
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
}
}
}
private static void client_OnReceive(KNClient client, KNMessageEventArgs e)
{
File.AppendAllText("token.log", e.Token + "\r\n");
string[] token = e.Token.Split('\0');
if (token.Length > 0)
{
switch (token[0])
{
case "b":
channels = new List<string>();
foreach (string t in token)
{
Match match = channelParser.Match(t);
if (match.Success)
{
channels.Add(match.Groups["channel"].Value);
}
}
break;
case "u":
currentChannel = token[1];
butlerName = token[2];
break;
case "k":
Match channelName = channelNameParser.Match(token[1]);
if (channelName.Success)
{
MatchCollection mc = chatterParser.Matches(token[7]);
foreach (Match m in mc)
{
if (m.Success)
{
string n = Regex.Unescape(m.Groups["nick"].Value);
if (n != butlerName && !nicks.Contains(n))
nicks.Add(n);
}
}
Console.WriteLine("{1}\tOnline @ {0}", channelName.Groups["name"].Value, mc.Count);
}
break;
}
}
}
private static bool AsyncAuth(string nick, string pass, int minposts, int maxwarn, int[] whitelistGroups)
{
WebRequest webRequest = WebRequest.Create(ApiUrl);
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(String.Concat("username=", nick, "&password=", Md5(pass)));
webRequest.ContentLength = bytes.Length;
using (Stream os = webRequest.GetRequestStream())
{
os.Write(bytes, 0, bytes.Length);
}
XmlDocument doc = new XmlDocument();
string xml = null;
WebResponse webResponse = webRequest.GetResponse();
if (webResponse == null)
return false;
StreamReader sr = new StreamReader(webResponse.GetResponseStream());
xml = sr.ReadToEnd().Trim();
doc.LoadXml(xml);
string status = doc.SelectSingleNode("/API/status").InnerText;
if (status.Equals("success"))
{
string username = doc.SelectSingleNode("/API/username").InnerText;
int group = Convert.ToInt32(doc.SelectSingleNode("/API/group").InnerText);
if (whitelistGroups != null && whitelistGroups.Length > 0)
{
foreach (int whiteGroup in whitelistGroups)
if (group.Equals(whiteGroup))
return true;
}
int posts = Convert.ToInt32(doc.SelectSingleNode("/API/posts").InnerText);
if (posts < minposts)
return false;
int warn = Convert.ToInt32(doc.SelectSingleNode("/API/warn").InnerText);
if (warn > maxwarn)
return false;
return true;
}
else
{
return false;
}
}
private static string Md5(string data)
{
byte[] bytes = Encoding.Default.GetBytes(data);
MD5 md5 = new MD5CryptoServiceProvider();
return System.BitConverter.ToString(md5.ComputeHash(bytes)).Replace("-", "").ToLower();
}
private static void StartWaiter()
{
waiterEnabled = true;
waiterThread = new Thread(DisplayWaiter);
waiterThread.Start();
}
private static Thread waiterThread = null;
private static bool waiterEnabled = false;
private static int waitPos = 0;
private static char[] waiters = new char[]
{
'|',
'/',
'-',
'\\',
};
private static void DisplayWaiter()
{
Console.Write(waiters[waitPos++]);
while (true)
{
try
{
Thread.Sleep(75);
}
catch (ThreadInterruptedException) { }
if (!waiterEnabled)
{
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
Console.Write(" ");
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
return;
}
if (waitPos >= waiters.Length)
{
waitPos = 0;
}
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
Console.Write(waiters[waitPos++]);
}
}
private static void StopWaiter()
{
waiterEnabled = false;
}
private enum SpamTypes
{
M,
P
}
}
}