Created
July 14, 2012 05:28
-
-
Save mfakane/3109524 to your computer and use it in GitHub Desktop.
Royal/RoyalFlare/Selena/SelenaClient.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Text; | |
using System.Net; | |
using System.Collections.Specialized; | |
using System.IO; | |
using System.Text.RegularExpressions; | |
using System.Threading; | |
namespace Royal.Selena | |
{ | |
public class SelenaClient | |
{ | |
public event EventHandler LoggingIn; | |
public event EventHandler LoggedIn; | |
public event EventHandler LoggedOut; | |
private int logSize = 0; | |
private DateTime lastNames = DateTime.MinValue; | |
public bool IsLoggedIn | |
{ | |
get | |
{ | |
return this.ID != null; | |
} | |
} | |
public string Name | |
{ | |
get; | |
private set; | |
} | |
public string ID | |
{ | |
get; | |
private set; | |
} | |
public Uri BaseUri | |
{ | |
get; | |
private set; | |
} | |
private string IndexUri | |
{ | |
get | |
{ | |
return this.BaseUri.AbsoluteUri + "index.php"; | |
} | |
} | |
private string LogUri | |
{ | |
get | |
{ | |
return this.BaseUri.AbsoluteUri + "dat/log.txt"; | |
} | |
} | |
private string NamesUri | |
{ | |
get | |
{ | |
return this.BaseUri.AbsoluteUri + "dat/names.dat"; | |
} | |
} | |
public List<ChatEntry> Log | |
{ | |
get; | |
private set; | |
} | |
public IList<string> Names | |
{ | |
get; | |
private set; | |
} | |
public SelenaClient(Uri baseUri) | |
{ | |
this.Log = new List<ChatEntry>(); | |
this.BaseUri = baseUri; | |
} | |
private Dictionary<string, string> GetJson(byte[] p) | |
{ | |
var s = Encoding.GetEncoding(932).GetString(p); | |
return GetJson(s); | |
} | |
private Dictionary<string, string> GetJson(string s) | |
{ | |
var rt = new Dictionary<string, string>(); | |
s = s.Trim().Trim('{', '}'); | |
foreach (var i in Regex.Split(s, "\",\"")) | |
{ | |
if (string.IsNullOrEmpty(i)) | |
continue; | |
var set = Regex.Split(i.Trim(), "\": \""); | |
if (set.Length >= 2) | |
rt.Add(set[0].Trim('"'), set[1].Trim('"').Replace("\\\"", "\"").Replace("\\'", "'").Replace("\\\\", "\\")); | |
} | |
return rt; | |
} | |
private NameValueCollection CreateNameValueCollection(params string[] nvset) | |
{ | |
var rt = new NameValueCollection(); | |
for (int i = 0; i < nvset.Length; i += 2) | |
rt.Add(nvset[i], nvset[i + 1]); | |
return rt; | |
} | |
public void SendPing() | |
{ | |
if (!this.IsLoggedIn) | |
return; | |
try | |
{ | |
using (var wc = new WebClient()) | |
wc.UploadValues(this.IndexUri + "?mode=ping", CreateNameValueCollection("id", this.ID)); | |
} | |
catch | |
{ | |
} | |
} | |
public List<string> GetNames() | |
{ | |
try | |
{ | |
var req = (HttpWebRequest)WebRequest.Create(this.NamesUri); | |
req.Timeout = 5000; | |
if (lastNames != DateTime.MinValue) | |
req.IfModifiedSince = lastNames; | |
var res = (HttpWebResponse)req.GetResponse(); | |
if (res.StatusCode == HttpStatusCode.OK) | |
using (var sr = new StreamReader(res.GetResponseStream())) | |
{ | |
lastNames = res.LastModified; | |
var l = new List<string>(); | |
foreach (var i in Regex.Split(sr.ReadToEnd(), @"\},\n*\{")) | |
if (!string.IsNullOrEmpty(i) && !string.IsNullOrEmpty(i.Trim().Trim('\0'))) | |
{ | |
var set = GetJson(i.Trim('\0')); | |
l.Add(set["name"]); | |
} | |
this.Names = l; | |
return l; | |
} | |
} | |
catch (WebException) | |
{ | |
} | |
return null; | |
} | |
public IList<ChatEntry> GetNewEntries() | |
{ | |
var req = (HttpWebRequest)WebRequest.Create(this.LogUri); | |
req.Timeout = 5000; | |
if (logSize != 0) | |
req.AddRange(logSize - 1); | |
try | |
{ | |
var res = (HttpWebResponse)req.GetResponse(); | |
using (var sr = new StreamReader(res.GetResponseStream())) | |
{ | |
var s = sr.ReadToEnd().Substring(logSize == 0 ? 0 : 1); | |
if (!string.IsNullOrEmpty(s.Trim())) | |
{ | |
if (res.StatusCode == HttpStatusCode.OK) | |
logSize = (int)res.ContentLength; | |
else if (res.StatusCode == HttpStatusCode.PartialContent) | |
logSize += (int)res.ContentLength - 1; | |
var entries = new List<ChatEntry>(); | |
foreach (var i in s.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)) | |
{ | |
var set = GetJson(i.Trim(',')); | |
if (set.ContainsKey("time") && set.ContainsKey("message")) | |
if (!set.ContainsKey("name") || string.IsNullOrEmpty(set["name"])) | |
entries.Add(new ChatEntry(set["time"], null, set["message"])); | |
else | |
entries.Add(new ChatEntry(set["time"], set["name"], set["message"])); | |
} | |
this.Log.AddRange(entries); | |
return entries; | |
} | |
} | |
} | |
catch (WebException ex) | |
{ | |
var res = (HttpWebResponse)ex.Response; | |
if (res != null && res.StatusCode == HttpStatusCode.RequestedRangeNotSatisfiable) | |
logSize = 0; | |
} | |
return null; | |
} | |
public void SendMessage(string message) | |
{ | |
SendMessage(this.Name, message); | |
} | |
public void SendMessage(string name, string message) | |
{ | |
if (message != null) | |
using (var wc = new WebClient()) | |
wc.UploadValues(this.IndexUri + "?mode=post", CreateNameValueCollection("id", this.ID, "name", name, "msg", message.Replace("\r", "").Replace("\n", ""))); | |
} | |
public void Login(string name) | |
{ | |
if (this.IsLoggedIn) | |
return; | |
if (LoggingIn != null) | |
LoggingIn(this, EventArgs.Empty); | |
using (var wc = new WebClient()) | |
{ | |
var dat = GetJson(wc.UploadValues(this.IndexUri + "?mode=login", CreateNameValueCollection("name", name))); | |
this.Name = dat["name"]; | |
this.ID = dat["id"]; | |
if (LoggedIn != null) | |
LoggedIn(this, EventArgs.Empty); | |
} | |
} | |
public void Logout(string message) | |
{ | |
if (!this.IsLoggedIn) | |
return; | |
using (var wc = new WebClient()) | |
wc.UploadValues(this.IndexUri + "?mode=logout", CreateNameValueCollection("name", this.Name, "id", this.ID, "msg", message)); | |
this.ID = null; | |
this.Name = null; | |
if (LoggedOut != null) | |
LoggedOut(this, EventArgs.Empty); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment