using System; using System.Text; using System.Text.RegularExpressions; using Shadowsocks.Controller; namespace Shadowsocks.Model { [Serializable] public class Server { public string server; public int server_port; public string password; public string method; public string remarks; public bool auth; public override int GetHashCode() { return server.GetHashCode() ^ server_port; } public override bool Equals(object obj) { Server o2 = (Server)obj; return server == o2.server && server_port == o2.server_port; } public string FriendlyName() { if (server.IsNullOrEmpty()) { return I18N.GetString("New server"); } if (remarks.IsNullOrEmpty()) { return server + ":" + server_port; } else { return remarks + " (" + server + ":" + server_port + ")"; } } public Server() { server = ""; server_port = 8388; method = "aes-256-cfb"; password = ""; remarks = ""; auth = false; } public Server(string ssURL) : this() { string[] r1 = Regex.Split(ssURL, "ss://", RegexOptions.IgnoreCase); string base64 = r1[1].ToString(); byte[] bytes = null; for (var i = 0; i < 3; i++) { try { bytes = Convert.FromBase64String(base64); } catch (FormatException) { base64 += "="; } } if (bytes == null) { throw new FormatException(); } try { string data = Encoding.UTF8.GetString(bytes); int indexLastAt = data.LastIndexOf('@'); string afterAt = data.Substring(indexLastAt + 1); int indexLastColon = afterAt.LastIndexOf(':'); server_port = int.Parse(afterAt.Substring(indexLastColon + 1)); server = afterAt.Substring(0, indexLastColon); string beforeAt = data.Substring(0, indexLastAt); string[] parts = beforeAt.Split(new[] { ':' }); method = parts[0]; password = parts[1]; //TODO: read one_time_auth } catch (IndexOutOfRangeException) { throw new FormatException(); } } } }