1
0
mirror of https://e.coding.net/circlecloud/CTZLauncher.git synced 2024-11-22 02:08:49 +00:00

添加服务器数据类 客户端从服务器获取大区数据...

This commit is contained in:
j502647092 2015-08-08 17:39:17 +08:00
parent 8ccf09c1dd
commit b21b606132
6 changed files with 988 additions and 859 deletions

View File

@ -1,74 +1,79 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Windows.Threading; using System.Windows.Threading;
using KMCCC.Authentication; using KMCCC.Authentication;
using CityCraft; using CityCraft;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Threading; using System.Threading;
namespace KMCCC.Authentication namespace KMCCC.Authentication
{ {
class CTZAuthenticator class CTZAuthenticator
{ {
/// <summary> /// <summary>
/// 玩家的名字 /// 玩家的名字
/// </summary> /// </summary>
public readonly string Username; public readonly string Username;
public readonly string Password; public readonly string Password;
HttpHelper http = new HttpHelper(); HttpHelper http = new HttpHelper();
/// <summary> /// <summary>
/// 验证服务器地址 /// 验证服务器地址
/// </summary> /// </summary>
public readonly string Address; public readonly string Address;
/// <summary> /// <summary>
/// 验证服务器端口 /// 验证服务器端口
/// </summary> /// </summary>
public readonly int Port; public readonly int Port;
/// <summary> /// <summary>
/// 构造离线验证器 /// 构造离线验证器
/// </summary> /// </summary>
/// <param name="username">玩家的名字</param> /// <param name="username">玩家的名字</param>
public CTZAuthenticator(string username, string password, string address, int port = 25565) public CTZAuthenticator(string username, string password, string address, int port = 25565)
{ {
Username = username; Username = username;
Password = password; Password = password;
Address = address.IndexOf("http") > 0 ? address : "http://" + address; Address = address.IndexOf("http") > 0 ? address : "http://" + address;
Port = port; Port = port;
} }
/// <summary> /// <summary>
/// 标注外部登陆验证器 /// 标注外部登陆验证器
/// </summary> /// </summary>
public string Type public string Type
{ {
get { return "KMCCC.CTZ"; } get { return "KMCCC.CTZ"; }
} }
public bool isRegistered() public bool isRegistered()
{ {
return getResult(Address + ":" + Port + "/isregistered?username=" + Username); return getResult(Address + ":" + Port + "/isregistered?username=" + Username);
} }
public bool Register() public bool Register()
{ {
return getResult(Address + ":" + Port + "/register?username=" + Username + "&password=" + Password); return getResult(Address + ":" + Port + "/register?username=" + Username + "&password=" + Password);
} }
public bool isLogin() public bool isLogin()
{ {
return getResult(Address + ":" + Port + "/islogin?username=" + Username); return getResult(Address + ":" + Port + "/islogin?username=" + Username);
} }
public bool Login() public bool Login()
{ {
return getResult(Address + ":" + Port + "/login?username=" + Username + "&password=" + Password); return getResult(Address + ":" + Port + "/login?username=" + Username + "&password=" + Password);
} }
public bool getResult(string url) public string getServerList()
{ {
return http.Send(HttpMethod.GET, url).Contains("true") ? true : false; return http.Send(HttpMethod.GET, Address + ":" + Port + "/serverlist");
} }
}
} public bool getResult(string url)
{
return http.Send(HttpMethod.GET, url).Contains("true") ? true : false;
}
}
}

View File

@ -5,7 +5,7 @@
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{EC25362D-5BA7-4CB3-BDA2-C575B9318086}</ProjectGuid> <ProjectGuid>{EC25362D-5BA7-4CB3-BDA2-C575B9318086}</ProjectGuid>
<OutputType>WinExe</OutputType> <OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>CTZLauncher</RootNamespace> <RootNamespace>CTZLauncher</RootNamespace>
<AssemblyName>CTZLauncher</AssemblyName> <AssemblyName>CTZLauncher</AssemblyName>
@ -94,6 +94,7 @@
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
</ApplicationDefinition> </ApplicationDefinition>
<Compile Include="Modules\CTZServer\CTZServer.cs" />
<Compile Include="Tools\SystemTools.cs" /> <Compile Include="Tools\SystemTools.cs" />
<Compile Include="Tools\UsefulTools.cs" /> <Compile Include="Tools\UsefulTools.cs" />
<Compile Include="Tools\ZipTools.cs" /> <Compile Include="Tools\ZipTools.cs" />
@ -171,7 +172,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="image\" /> <Folder Include="image\" />
<Folder Include="Modules\CTZServer\" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.0"> <BootstrapperPackage Include=".NETFramework,Version=v4.0">

View File

@ -1,415 +1,415 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.IO.Compression; using System.IO.Compression;
using System.Net; using System.Net;
using System.Net.Security; using System.Net.Security;
using System.Net.Sockets; using System.Net.Sockets;
using System.Security.Authentication; using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading; using System.Threading;
using System.Windows.Threading; using System.Windows.Threading;
namespace CityCraft namespace CityCraft
{ {
public enum HttpMethod public enum HttpMethod
{ {
GET, GET,
POST POST
} }
public class HttpArgs public class HttpArgs
{ {
public string Url { get; set; } public string Url { get; set; }
public string Host { get; set; } public string Host { get; set; }
public int Port { get; set; } public int Port { get; set; }
public string Accept { get; set; } public string Accept { get; set; }
public string Referer { get; set; } public string Referer { get; set; }
public string Cookie { get; set; } public string Cookie { get; set; }
public string Data { get; set; } public string Data { get; set; }
public string UA { get; set; } public string UA { get; set; }
public HttpMethod Method { get; set; } public HttpMethod Method { get; set; }
} }
public enum HttpReadyState public enum HttpReadyState
{ {
, ,
, ,
, ,
, ,
} }
public class HttpHelper public class HttpHelper
{ {
public HttpReadyState readyState = HttpReadyState.; public HttpReadyState readyState = HttpReadyState.;
public int Status = 0; public int Status = 0;
public string responseBody = ""; public string responseBody = "";
public string responseText = ""; public string responseText = "";
public byte[] responseByte = null; public byte[] responseByte = null;
public HttpArgs args = new HttpArgs(); public HttpArgs args = new HttpArgs();
public string ErrMsg = string.Empty; public string ErrMsg = string.Empty;
/// <summary> /// <summary>
/// 提交方法 /// 提交方法
/// </summary> /// </summary>
#region HttpWebRequest & HttpWebResponse #region HttpWebRequest & HttpWebResponse
/// <summary> /// <summary>
/// Get方法 /// Get方法
/// </summary> /// </summary>
/// <param name="geturl">请求地址</param> /// <param name="geturl">请求地址</param>
/// <param name="cookieser">Cookies存储器</param> /// <param name="cookieser">Cookies存储器</param>
/// <returns>请求返回的Stream</returns> /// <returns>请求返回的Stream</returns>
public string Send(HttpMethod method, string url, bool Async = false) public string Send(HttpMethod method, string url, bool Async = false)
{ {
if (string.IsNullOrEmpty(url)) if (string.IsNullOrEmpty(url))
{ {
return string.Empty; return string.Empty;
} }
readyState = HttpReadyState.; readyState = HttpReadyState.;
ParseURL(url); ParseURL(url);
args.Method = method; args.Method = method;
new Thread(new ThreadStart(ReciveData)).Start(); new Thread(new ThreadStart(ReciveData)).Start();
if (!Async) if (!Async)
{ {
while (readyState != HttpReadyState.) { this.DoEvent(); } while (readyState != HttpReadyState.) { this.DoEvent(); }
return responseBody; return responseBody;
} }
return null; return null;
} }
/// <summary> /// <summary>
/// 模仿C#的Application.Doevent函数。可以适当添加try catch 模块 /// 模仿C#的Application.Doevent函数。可以适当添加try catch 模块
/// </summary> /// </summary>
public void DoEvent() public void DoEvent()
{ {
DispatcherFrame frame = new DispatcherFrame(); DispatcherFrame frame = new DispatcherFrame();
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(ExitFrame), frame); Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(ExitFrame), frame);
Dispatcher.PushFrame(frame); Dispatcher.PushFrame(frame);
} }
public object ExitFrame(object f) public object ExitFrame(object f)
{ {
((DispatcherFrame)f).Continue = false; ((DispatcherFrame)f).Continue = false;
return null; return null;
} }
public void ReciveData() public void ReciveData()
{ {
responseBody = InternalSocketHttp(); responseBody = InternalSocketHttp();
readyState = HttpReadyState.; readyState = HttpReadyState.;
} }
/// <summary> /// <summary>
/// Post方法 /// Post方法
/// </summary> /// </summary>
/// <param name="posturl">请求地址</param> /// <param name="posturl">请求地址</param>
/// <param name="bytes">Post数据</param> /// <param name="bytes">Post数据</param>
/// <param name="cookieser">Cllkies存储器</param> /// <param name="cookieser">Cllkies存储器</param>
/// <returns>请求返回的流</returns> /// <returns>请求返回的流</returns>
public string Post(string url, public string Post(string url,
byte[] bytes, byte[] bytes,
CookieContainer cookies, CookieContainer cookies,
Encoding encoding) Encoding encoding)
{ {
return null; return null;
} }
/// <summary> /// <summary>
/// 根据Url得到host /// 根据Url得到host
/// </summary> /// </summary>
/// <param name="strUrl">url字符串</param> /// <param name="strUrl">url字符串</param>
/// <returns>host字符串</returns> /// <returns>host字符串</returns>
private void ParseURL(string strUrl) private void ParseURL(string strUrl)
{ {
if (args == null) if (args == null)
args = new HttpArgs(); args = new HttpArgs();
args.Host = ""; args.Host = "";
args.Port = 80; args.Port = 80;
args.Referer = ""; args.Referer = "";
args.Cookie = ""; args.Cookie = "";
args.Url = ""; args.Url = "";
args.Accept = "text/html";//,application/xhtml+xml,application/xml,application/json;"; args.Accept = "text/html";//,application/xhtml+xml,application/xml,application/json;";
args.UA = "Mozilla/5.0+(Compatible;+Baiduspider/2.0;++http://www.baidu.com/search/spider.html)"; args.UA = "Mozilla/5.0+(Compatible;+Baiduspider/2.0;++http://www.baidu.com/search/spider.html)";
//http://www.alibaba.com/products/Egg_Laying_Block_Machine/1.html //http://www.alibaba.com/products/Egg_Laying_Block_Machine/1.html
int iIndex = strUrl.IndexOf(@"//"); int iIndex = strUrl.IndexOf(@"//");
if (iIndex <= 0) if (iIndex <= 0)
args = null; args = null;
//www.alibaba.com:80/products/Egg_Laying_Block_Machine/1.html //www.alibaba.com:80/products/Egg_Laying_Block_Machine/1.html
string nohttpurl = strUrl.Substring(iIndex + 2); string nohttpurl = strUrl.Substring(iIndex + 2);
string address = nohttpurl; string address = nohttpurl;
iIndex = nohttpurl.IndexOf(@"/"); iIndex = nohttpurl.IndexOf(@"/");
if (iIndex > 0) if (iIndex > 0)
{ {
//www.alibaba.com:80 //www.alibaba.com:80
address = nohttpurl.Substring(0, iIndex); address = nohttpurl.Substring(0, iIndex);
args.Url = nohttpurl.Substring(iIndex); args.Url = nohttpurl.Substring(iIndex);
} }
else else
{ {
args.Url = "/"; args.Url = "/";
} }
iIndex = nohttpurl.IndexOf(@":"); iIndex = nohttpurl.IndexOf(@":");
if (iIndex > 0) if (iIndex > 0)
{ {
string[] tempargs = address.Trim().Split(char.Parse(":")); string[] tempargs = address.Trim().Split(char.Parse(":"));
args.Host = tempargs[0]; args.Host = tempargs[0];
args.Port = int.Parse(tempargs[1]); args.Port = int.Parse(tempargs[1]);
} }
else else
{ {
//www.alibaba.com:80 //www.alibaba.com:80
args.Host = address; args.Host = address;
args.Port = 80; args.Port = 80;
} }
} }
#endregion #endregion
#region Socket #region Socket
string InternalSocketHttp() string InternalSocketHttp()
{ {
using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{ {
try try
{ {
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 1000); socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 1000);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 5000); socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 5000);
socket.Connect(args.Host, args.Port); socket.Connect(args.Host, args.Port);
if (socket.Connected) if (socket.Connected)
{ {
byte[] buff = ParseHttpArgs(); byte[] buff = ParseHttpArgs();
if (socket.Send(buff) > 0) if (socket.Send(buff) > 0)
{ {
List<byte> responseBytes = new List<byte>(); List<byte> responseBytes = new List<byte>();
byte[] buffer = new byte[1024]; byte[] buffer = new byte[1024];
int iNumber = socket.Receive(buffer, buffer.Length, SocketFlags.None); int iNumber = socket.Receive(buffer, buffer.Length, SocketFlags.None);
while (iNumber > 0)//使用了Connection: Close 所以判断长度为0 时停止接受 while (iNumber > 0)//使用了Connection: Close 所以判断长度为0 时停止接受
{ {
responseBytes.AddRange(new List<byte>(buffer));//添加数据到List responseBytes.AddRange(new List<byte>(buffer));//添加数据到List
iNumber = socket.Receive(buffer, buffer.Length, SocketFlags.None);//继续接收数据 iNumber = socket.Receive(buffer, buffer.Length, SocketFlags.None);//继续接收数据
} }
responseByte = responseBytes.ToArray(); responseByte = responseBytes.ToArray();
readyState = HttpReadyState.; readyState = HttpReadyState.;
return ParseResponse(responseByte); return ParseResponse(responseByte);
} }
} }
} }
catch (Exception e) catch (Exception e)
{ {
ErrMsg = e.Message; ErrMsg = e.Message;
} }
return string.Empty; return string.Empty;
} }
} }
private string ParseResponse(byte[] responseBytes) private string ParseResponse(byte[] responseBytes)
{ {
string responseStr = Encoding.UTF8.GetString(responseBytes); string responseStr = Encoding.UTF8.GetString(responseBytes);
int splitindex = responseStr.IndexOf("\r\n\r\n"); int splitindex = responseStr.IndexOf("\r\n\r\n");
if (splitindex > 0) if (splitindex > 0)
{ {
string responseHeader = responseStr.Substring(0, splitindex); string responseHeader = responseStr.Substring(0, splitindex);
string responseBody = responseStr.Substring(splitindex + 4); string responseBody = responseStr.Substring(splitindex + 4);
//Console.WriteLine(responseHeader); //Console.WriteLine(responseHeader);
if (responseHeader.StartsWith("HTTP/1.1 400")) if (responseHeader.StartsWith("HTTP/1.1 400"))
{ {
Status = 400; Status = 400;
return string.Empty; return string.Empty;
} }
else if (responseHeader.StartsWith("HTTP/1.1 404")) else if (responseHeader.StartsWith("HTTP/1.1 404"))
{ {
Status = 404; Status = 404;
return string.Empty; return string.Empty;
} }
else if (responseHeader.StartsWith("HTTP/1.1 302") || responseHeader.StartsWith("HTTP/1.1 301")) else if (responseHeader.StartsWith("HTTP/1.1 302") || responseHeader.StartsWith("HTTP/1.1 301"))
{ {
Status = 302; Status = 302;
int start = responseHeader.ToUpper().IndexOf("LOCATION"); int start = responseHeader.ToUpper().IndexOf("LOCATION");
if (start > 0) if (start > 0)
{ {
string temp = responseHeader.Substring(start, responseHeader.Length - start); string temp = responseHeader.Substring(start, responseHeader.Length - start);
string[] sArry = Regex.Split(temp, "\r\n"); string[] sArry = Regex.Split(temp, "\r\n");
args.Url = sArry[0].Remove(0, 10); args.Url = sArry[0].Remove(0, 10);
if (args.Url == "") if (args.Url == "")
return string.Empty; return string.Empty;
return InternalSocketHttp(); //注意302协议需要重定向 return InternalSocketHttp(); //注意302协议需要重定向
} }
} }
else if (responseHeader.StartsWith("HTTP/1.1 200")) //读取内容 else if (responseHeader.StartsWith("HTTP/1.1 200")) //读取内容
{ {
Status = 200; Status = 200;
//解压 //解压
DecompressWebPage(ref responseBytes, responseHeader); DecompressWebPage(ref responseBytes, responseHeader);
//转码 //转码
responseBody = DecodeWebStringByHttpHeader(responseBytes, responseHeader); responseBody = DecodeWebStringByHttpHeader(responseBytes, responseHeader);
responseBody = DecodeWebStringByHtmlPageInfo(responseBytes, responseBody); responseBody = DecodeWebStringByHtmlPageInfo(responseBytes, responseBody);
} }
splitindex = responseBody.IndexOf("\r\n\r\n"); splitindex = responseBody.IndexOf("\r\n\r\n");
if (splitindex > 0) if (splitindex > 0)
responseBody = responseBody.Substring(splitindex + 4); responseBody = responseBody.Substring(splitindex + 4);
else else
responseBody = string.Empty; responseBody = string.Empty;
return responseBody; return responseBody;
} }
return string.Empty; return string.Empty;
} }
#endregion #endregion
#region Helper #region Helper
/// <summary> /// <summary>
/// 解压网页 /// 解压网页
/// </summary> /// </summary>
/// <param name="responseBytes">网页字节数组含http头</param> /// <param name="responseBytes">网页字节数组含http头</param>
/// <param name="iTotalCount">数组长度</param> /// <param name="iTotalCount">数组长度</param>
/// <param name="strHeader">Http头字符串</param> /// <param name="strHeader">Http头字符串</param>
/// <param name="iStart">网页正文开始位置</param> /// <param name="iStart">网页正文开始位置</param>
private void DecompressWebPage(ref byte[] responseBytes, string strHeader) private void DecompressWebPage(ref byte[] responseBytes, string strHeader)
{ {
Regex regZip = new Regex(@"Content-Encoding:\s+gzip[^\n]*\r\n", RegexOptions.IgnoreCase); Regex regZip = new Regex(@"Content-Encoding:\s+gzip[^\n]*\r\n", RegexOptions.IgnoreCase);
if (regZip.IsMatch(strHeader)) if (regZip.IsMatch(strHeader))
{ {
responseBytes = Decompress(responseBytes); responseBytes = Decompress(responseBytes);
} }
} }
/// <summary> /// <summary>
/// 解压gzip网页 /// 解压gzip网页
/// </summary> /// </summary>
/// <param name="szSource">压缩过的字符串字节数组</param> /// <param name="szSource">压缩过的字符串字节数组</param>
/// <returns>解压后的字节数组</returns> /// <returns>解压后的字节数组</returns>
private byte[] Decompress(byte[] szSource) private byte[] Decompress(byte[] szSource)
{ {
MemoryStream msSource = new MemoryStream(szSource); MemoryStream msSource = new MemoryStream(szSource);
//DeflateStream 也可以这儿 //DeflateStream 也可以这儿
GZipStream stream = new GZipStream(msSource, CompressionMode.Decompress); GZipStream stream = new GZipStream(msSource, CompressionMode.Decompress);
byte[] szTotal = new byte[40 * 1024]; byte[] szTotal = new byte[40 * 1024];
long lTotal = 0; long lTotal = 0;
byte[] buffer = new byte[8]; byte[] buffer = new byte[8];
int iCount = 0; int iCount = 0;
do do
{ {
iCount = stream.Read(buffer, 0, 8); iCount = stream.Read(buffer, 0, 8);
if (szTotal.Length <= lTotal + iCount) //放大数组 if (szTotal.Length <= lTotal + iCount) //放大数组
{ {
byte[] temp = new byte[szTotal.Length * 10]; byte[] temp = new byte[szTotal.Length * 10];
szTotal.CopyTo(temp, 0); szTotal.CopyTo(temp, 0);
szTotal = temp; szTotal = temp;
} }
buffer.CopyTo(szTotal, lTotal); buffer.CopyTo(szTotal, lTotal);
lTotal += iCount; lTotal += iCount;
} while (iCount != 0); } while (iCount != 0);
byte[] szDest = new byte[lTotal]; byte[] szDest = new byte[lTotal];
Array.Copy(szTotal, 0, szDest, 0, lTotal); Array.Copy(szTotal, 0, szDest, 0, lTotal);
return szDest; return szDest;
} }
/// <summary> /// <summary>
/// 根据Http头标记里面的字符编码解析字符串 /// 根据Http头标记里面的字符编码解析字符串
/// </summary> /// </summary>
/// <param name="responseBytes">网页内容字节数组(除http头以外的内容)</param> /// <param name="responseBytes">网页内容字节数组(除http头以外的内容)</param>
/// <param name="iTotalCount">网页内容字节数组长度</param> /// <param name="iTotalCount">网页内容字节数组长度</param>
/// <param name="strHeader">http头的字符串</param> /// <param name="strHeader">http头的字符串</param>
/// <returns>转好的字符串</returns> /// <returns>转好的字符串</returns>
private string DecodeWebStringByHttpHeader(byte[] responseBytes, string strHeader) private string DecodeWebStringByHttpHeader(byte[] responseBytes, string strHeader)
{ {
string strResponse = ""; string strResponse = "";
if (strHeader.Contains("charset=GBK") || strHeader.Contains("charset=gb2312")) if (strHeader.Contains("charset=GBK") || strHeader.Contains("charset=gb2312"))
{ {
strResponse = Encoding.GetEncoding("GBK").GetString(responseBytes); strResponse = Encoding.GetEncoding("GBK").GetString(responseBytes);
} }
else else
strResponse = Encoding.UTF8.GetString(responseBytes); strResponse = Encoding.UTF8.GetString(responseBytes);
return strResponse; return strResponse;
} }
/// <summary> /// <summary>
/// 根据网页meta标记里面的字符编码解析字符串 /// 根据网页meta标记里面的字符编码解析字符串
/// </summary> /// </summary>
/// <param name="responseBytes">网页内容字节数组(除http头以外的内容)</param> /// <param name="responseBytes">网页内容字节数组(除http头以外的内容)</param>
/// <param name="iTotalCount">网页内容字节数组长度</param> /// <param name="iTotalCount">网页内容字节数组长度</param>
/// <param name="strResponse">网页内容字符串, 可能已经根据其它转码要求转换过的字符串</param> /// <param name="strResponse">网页内容字符串, 可能已经根据其它转码要求转换过的字符串</param>
/// <returns>转好的字符串</returns> /// <returns>转好的字符串</returns>
private string DecodeWebStringByHtmlPageInfo(byte[] responseBytes, string strResponse) private string DecodeWebStringByHtmlPageInfo(byte[] responseBytes, string strResponse)
{ {
Regex regGB2312 = new Regex(@"<meta[^>]+Content-Type[^>]+gb2312[^>]*>", RegexOptions.IgnoreCase); Regex regGB2312 = new Regex(@"<meta[^>]+Content-Type[^>]+gb2312[^>]*>", RegexOptions.IgnoreCase);
Regex regGBK = new Regex(@"<meta[^>]+Content-Type[^>]+gbk[^>]*>", RegexOptions.IgnoreCase); Regex regGBK = new Regex(@"<meta[^>]+Content-Type[^>]+gbk[^>]*>", RegexOptions.IgnoreCase);
Regex regBig5 = new Regex(@"<meta[^>]+Content-Type[^>]+Big5[^>]*>", RegexOptions.IgnoreCase); Regex regBig5 = new Regex(@"<meta[^>]+Content-Type[^>]+Big5[^>]*>", RegexOptions.IgnoreCase);
if (regGB2312.IsMatch(strResponse) || regGBK.IsMatch(strResponse)) if (regGB2312.IsMatch(strResponse) || regGBK.IsMatch(strResponse))
strResponse = Encoding.GetEncoding("GBK").GetString(responseBytes); strResponse = Encoding.GetEncoding("GBK").GetString(responseBytes);
if (regBig5.IsMatch(strResponse)) if (regBig5.IsMatch(strResponse))
strResponse = Encoding.GetEncoding("Big5").GetString(responseBytes); strResponse = Encoding.GetEncoding("Big5").GetString(responseBytes);
return strResponse; return strResponse;
} }
private byte[] ParseHttpArgs() private byte[] ParseHttpArgs()
{ {
StringBuilder bulider = new StringBuilder(); StringBuilder bulider = new StringBuilder();
if (args.Method == HttpMethod.POST) if (args.Method == HttpMethod.POST)
{ {
bulider.AppendLine(string.Format("POST {0} HTTP/1.1", args.Url)); bulider.AppendLine(string.Format("POST {0} HTTP/1.1", args.Url));
bulider.AppendLine("Content-Type: application/x-www-form-urlencoded"); bulider.AppendLine("Content-Type: application/x-www-form-urlencoded");
} }
else else
{ {
bulider.AppendLine(string.Format("GET {0} HTTP/1.1", args.Url)); bulider.AppendLine(string.Format("GET {0} HTTP/1.1", args.Url));
} }
bulider.AppendLine(string.Format("Host: {0}:{1}", args.Host, args.Port)); bulider.AppendLine(string.Format("Host: {0}:{1}", args.Host, args.Port));
bulider.AppendLine("User-Agent: " + args.UA); bulider.AppendLine("User-Agent: " + args.UA);
//"User-Agent: Mozilla/5.0+(Compatible;+Baiduspider/2.0;++http://www.baidu.com/search/spider.html)";Mozilla/5.0 (Windows NT 6.1; IE 9.0) //"User-Agent: Mozilla/5.0+(Compatible;+Baiduspider/2.0;++http://www.baidu.com/search/spider.html)";Mozilla/5.0 (Windows NT 6.1; IE 9.0)
if (!string.IsNullOrEmpty(args.Referer)) if (!string.IsNullOrEmpty(args.Referer))
bulider.AppendLine(string.Format("Referer: {0}", args.Referer)); bulider.AppendLine(string.Format("Referer: {0}", args.Referer));
//bulider.AppendLine("Connection: close"); //bulider.AppendLine("Connection: close");
bulider.AppendLine("Connection: Close"); bulider.AppendLine("Connection: Close");
if (!string.IsNullOrEmpty(args.Accept)) if (!string.IsNullOrEmpty(args.Accept))
bulider.AppendLine(string.Format("Accept: {0}", args.Accept)); bulider.AppendLine(string.Format("Accept: {0}", args.Accept));
if (!string.IsNullOrEmpty(args.Cookie)) if (!string.IsNullOrEmpty(args.Cookie))
bulider.AppendLine(string.Format("Cookie: {0}", args.Cookie)); bulider.AppendLine(string.Format("Cookie: {0}", args.Cookie));
if (args.Method == HttpMethod.POST) if (args.Method == HttpMethod.POST)
{ {
bulider.AppendLine(string.Format("Content-Length: {0}\r\n", Encoding.Default.GetBytes(args.Data).Length)); bulider.AppendLine(string.Format("Content-Length: {0}\r\n", Encoding.Default.GetBytes(args.Data).Length));
bulider.Append(args.Data); bulider.Append(args.Data);
} }
else else
{ {
bulider.Append("\r\n"); bulider.Append("\r\n");
} }
string header = bulider.ToString(); string header = bulider.ToString();
//Console.WriteLine(header); //Console.WriteLine(header);
return Encoding.Default.GetBytes(header); return Encoding.Default.GetBytes(header);
} }
#endregion #endregion
} }
public class MilliTimer public class MilliTimer
{ {
private static double times { get; set; } private static double times { get; set; }
public static void start() public static void start()
{ {
times = getTotalMilliseconds(); times = getTotalMilliseconds();
} }
public static double getTimes() public static double getTimes()
{ {
return getTotalMilliseconds() - times; return getTotalMilliseconds() - times;
} }
public static double getTotalMilliseconds() public static double getTotalMilliseconds()
{ {
return DateTime.Now.Subtract(DateTime.Parse("1970-1-1")).TotalMilliseconds; return DateTime.Now.Subtract(DateTime.Parse("1970-1-1")).TotalMilliseconds;
} }
} }
} }

View File

@ -1,170 +1,168 @@
<Window <Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:s="clr-namespace:System;assembly=mscorlib"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="CTZLauncher.MainWindow" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="CTZLauncher.MainWindow"
ResizeMode = "NoResize" ResizeMode = "NoResize"
Title="MainWindow" Height="600" Width="800" Background="#FF3A3A3A" AllowsTransparency="True" WindowStyle="None" Visibility="Visible" HorizontalContentAlignment="Center" HorizontalAlignment="Center" Icon="ico.ico" VerticalAlignment="Center" VerticalContentAlignment="Center" WindowStartupLocation="CenterScreen" Initialized="Window_Initialized" FontFamily="Microsoft YaHei" Loaded="s"> Title="MainWindow" Height="600" Width="800" Background="#FF3A3A3A" AllowsTransparency="True" WindowStyle="None" Visibility="Visible" HorizontalContentAlignment="Center" HorizontalAlignment="Center" Icon="ico.ico" VerticalAlignment="Center" VerticalContentAlignment="Center" WindowStartupLocation="CenterScreen" Initialized="Window_Initialized" FontFamily="Microsoft YaHei">
<Window.Resources> <Window.Resources>
<!-- s:Double表示了变量类型 x:key表示了变量名 --> <!-- s:Double表示了变量类型 x:key表示了变量名 -->
<s:Double x:Key="m_nFontSize">32</s:Double> <s:Double x:Key="m_nFontSize">32</s:Double>
<!-- <!--
<ControlTemplate x:Key="CornerButton" TargetType="{x:Type Button}"> <ControlTemplate x:Key="CornerButton" TargetType="{x:Type Button}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1" CornerRadius="10" Background="{TemplateBinding Background}"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1" CornerRadius="10" Background="{TemplateBinding Background}">
<ContentPresenter Content="{TemplateBinding ContentControl.Content}" HorizontalAlignment="Center" VerticalAlignment="Center" /> <ContentPresenter Content="{TemplateBinding ContentControl.Content}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border> </Border>
</ControlTemplate> </ControlTemplate>
<ControlTemplate x:Key="CornerTextBox" TargetType="{x:Type TextBox}"> <ControlTemplate x:Key="CornerTextBox" TargetType="{x:Type TextBox}">
<Border BorderBrush="#FFA1A1A1" BorderThickness="3" CornerRadius="10" Background="#FFA1A1A1"> <Border BorderBrush="#FFA1A1A1" BorderThickness="3" CornerRadius="10" Background="#FFA1A1A1">
<ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center" Background="#FFA1A1A1"/> <ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center" Background="#FFA1A1A1"/>
</Border> </Border>
</ControlTemplate> </ControlTemplate>
--> -->
<ControlTemplate x:Key="CornerButton" TargetType="{x:Type Button}"> <ControlTemplate x:Key="CornerButton" TargetType="{x:Type Button}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1" CornerRadius="0" Background="{TemplateBinding Background}"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1" CornerRadius="0" Background="{TemplateBinding Background}">
<ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" /> <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border> </Border>
</ControlTemplate> </ControlTemplate>
<ControlTemplate x:Key="CornerTextBox" TargetType="{x:Type TextBox}"> <ControlTemplate x:Key="CornerTextBox" TargetType="{x:Type TextBox}">
<Border BorderBrush="#FF3299CC" BorderThickness="1" CornerRadius="0" Background="#FF3299CC"> <Border BorderBrush="#FF3299CC" BorderThickness="1" CornerRadius="0" Background="#FF3299CC">
<ScrollViewer x:Name="PART_ContentHost" Background="White"/> <ScrollViewer x:Name="PART_ContentHost" Background="White"/>
</Border> </Border>
</ControlTemplate> </ControlTemplate>
</Window.Resources> </Window.Resources>
<Grid x:Name="outline" Background="#FF3299CC" Height="600" Width="800" VerticalAlignment="Top" MouseLeftButtonDown="outline_MouseLeftButtonDown"> <Grid x:Name="outline" Background="#FF3299CC" Height="600" Width="800" VerticalAlignment="Top" MouseLeftButtonDown="outline_MouseLeftButtonDown">
<Grid Margin="20,0" Background="#FF3299CC" Height="60" VerticalAlignment="Top" d:IsLocked="True" > <Grid Margin="20,0" Background="#FF3299CC" Height="60" VerticalAlignment="Top" d:IsLocked="True" >
<Label x:Name="barl1" Content="论坛" HorizontalAlignment="Left" Margin="245,15,0,0" VerticalAlignment="Top" Width="100" Height="30" FontSize="15" Background="{x:Null}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="White" MouseDown="barclick_MouseDown"/> <Label x:Name="barl1" Content="论坛" HorizontalAlignment="Left" Margin="245,15,0,0" VerticalAlignment="Top" Width="100" Height="30" FontSize="15" Background="{x:Null}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="White" MouseDown="barclick_MouseDown"/>
<Label x:Name="barl2" Content="资源下载" HorizontalAlignment="Left" Margin="350,15,0,0" VerticalAlignment="Top" Width="100" Height="30" FontSize="15" Background="{x:Null}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="White" MouseDown="barclick_MouseDown"/> <Label x:Name="barl2" Content="资源下载" HorizontalAlignment="Left" Margin="350,15,0,0" VerticalAlignment="Top" Width="100" Height="30" FontSize="15" Background="{x:Null}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="White" MouseDown="barclick_MouseDown"/>
<Label x:Name="barl3" Content="新手指南" HorizontalAlignment="Left" Margin="455,15,0,0" VerticalAlignment="Top" Width="100" Height="30" FontSize="15" Background="{x:Null}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="White" MouseDown="barclick_MouseDown"/> <Label x:Name="barl3" Content="新手指南" HorizontalAlignment="Left" Margin="455,15,0,0" VerticalAlignment="Top" Width="100" Height="30" FontSize="15" Background="{x:Null}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="White" MouseDown="barclick_MouseDown"/>
<Label x:Name="barl4" Content="赞助我们" HorizontalAlignment="Left" Margin="560,15,0,0" VerticalAlignment="Top" Width="100" Height="30" FontSize="15" Background="{x:Null}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="White" MouseDown="barclick_MouseDown"/> <Label x:Name="barl4" Content="赞助我们" HorizontalAlignment="Left" Margin="560,15,0,0" VerticalAlignment="Top" Width="100" Height="30" FontSize="15" Background="{x:Null}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="White" MouseDown="barclick_MouseDown"/>
<Image HorizontalAlignment="Left" Height="50" Margin="15,5,0,0" VerticalAlignment="Top" Width="50" Source="ico.ico" RenderTransformOrigin="0.56,0.24"/> <Image HorizontalAlignment="Left" Height="50" Margin="15,5,0,0" VerticalAlignment="Top" Width="50" Source="ico.ico" RenderTransformOrigin="0.56,0.24"/>
<Label Content="魔方" HorizontalAlignment="Left" Height="50" Margin="90,5,0,0" VerticalAlignment="Top" Width="74" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" FontFamily="STXingkai" Foreground="White" FontSize="35" /> <Label Content="魔方" HorizontalAlignment="Left" Height="50" Margin="90,5,0,0" VerticalAlignment="Top" Width="74" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" FontFamily="STXingkai" Foreground="White" FontSize="35" />
</Grid> </Grid>
<Grid Name="LoginWindow" Margin="20,60,20,20" Background="White"> <Grid Name="LoginWindow" Margin="20,60,20,20" Background="White">
<Grid Height="269" VerticalAlignment="Top"> <Grid Height="270" VerticalAlignment="Top">
<Grid Margin="20,20,0,0" HorizontalAlignment="Left" Width="400" > <Grid Margin="20,20,0,0" HorizontalAlignment="Left" Width="400" >
<Image /> <Image />
</Grid> </Grid>
<Grid Margin="0,20,20,0" HorizontalAlignment="Right" Width="300"> <Grid Margin="0,20,20,0" HorizontalAlignment="Right" Width="300">
<Grid> <Grid>
<Grid Margin="10,10,10,0" Height="174" VerticalAlignment="Top"> <Grid Margin="10,10,10,0" Height="174" VerticalAlignment="Top">
<Label Content="————— 游 戏 帐 号 —————" VerticalAlignment="Top" Margin="10,0" HorizontalContentAlignment="Center" FontSize="15"/> <Label Content="————— 游 戏 帐 号 —————" VerticalAlignment="Top" Margin="10,0" HorizontalContentAlignment="Center" FontSize="15"/>
<TextBox x:Name="username" Template="{StaticResource CornerTextBox}" Height="34" TextWrapping="Wrap" Text="" VerticalAlignment="Top" HorizontalContentAlignment="Center" FontFamily="微软雅黑" FontSize="20" Margin="30,30,30,0" /> <TextBox x:Name="username" Template="{StaticResource CornerTextBox}" Height="34" TextWrapping="Wrap" Text="" VerticalAlignment="Top" HorizontalContentAlignment="Center" FontFamily="微软雅黑" FontSize="20" Margin="30,30,30,0" />
<Label Content="————— 游 戏 密 码 —————" VerticalAlignment="Top" Margin="10,69,10,0" HorizontalContentAlignment="Center" FontSize="15"/> <Label Content="————— 游 戏 密 码 —————" VerticalAlignment="Top" Margin="10,69,10,0" HorizontalContentAlignment="Center" FontSize="15"/>
<TextBox x:Name="password" Template="{StaticResource CornerTextBox}" TextWrapping="Wrap" HorizontalContentAlignment="Center" FontFamily="微软雅黑" FontSize="20" Margin="30,104,30,0" Height="34" VerticalAlignment="Top" /> <TextBox x:Name="password" Template="{StaticResource CornerTextBox}" TextWrapping="Wrap" HorizontalContentAlignment="Center" FontFamily="微软雅黑" FontSize="20" Margin="30,104,30,0" Height="34" VerticalAlignment="Top" />
<Button Margin="217,106,33,0" Template="{StaticResource CornerButton}" Height="30" Content="?" VerticalAlignment="Top" /> <Button x:Name="forget" Margin="217,106,33,0" Template="{StaticResource CornerButton}" Height="30" Content="?" VerticalAlignment="Top" Click="forget_Click" />
</Grid> </Grid>
<Grid Margin="10,0,10,10" Height="50" VerticalAlignment="Bottom"> <Grid Margin="10,0,10,10" Height="50" VerticalAlignment="Bottom">
<Button x:Name="Login" Margin="30,10,160,10" Template="{StaticResource CornerButton}" BorderBrush="#FF3299CC" Content="登录" Click="Login_Click"/> <Button x:Name="Login" Margin="30,10,160,10" Template="{StaticResource CornerButton}" BorderBrush="#FF3299CC" Content="登录" Click="Login_Click"/>
<Button x:Name="register" Margin="160,10,30,10" Template="{StaticResource CornerButton}" BorderBrush="#FF3299CC" Content="注册" Click="register_Click" /> <Button x:Name="register" Margin="160,10,30,10" Template="{StaticResource CornerButton}" BorderBrush="#FF3299CC" Content="注册" Click="register_Click" />
</Grid> </Grid>
</Grid> </Grid>
</Grid> </Grid>
</Grid> </Grid>
<Grid Height="246" VerticalAlignment="Bottom"> <Grid Height="246" VerticalAlignment="Bottom">
<Grid Margin="20,20,0,20" HorizontalAlignment="Left" Width="391" > <Grid Margin="20,20,0,20" HorizontalAlignment="Left" Width="391" >
<TabControl Background="White" BorderThickness="0"> <TabControl Background="White" BorderThickness="0">
<TabItem Header="动态" Background="White" BorderThickness="0" Margin="0" Height="30" FontSize="15" > <TabItem Header="动态" Background="White" BorderThickness="0" Margin="0" Height="30" FontSize="15" >
<ListBox BorderThickness="0" FontSize="15"> <ListBox BorderThickness="0" FontSize="15">
<ListBoxItem Content="动态" /> <ListBoxItem Content="动态" />
<ListBoxItem Content="动态" /> <ListBoxItem Content="动态" />
<ListBoxItem Content="动态" /> <ListBoxItem Content="动态" />
<ListBoxItem Content="动态" /> <ListBoxItem Content="动态" />
<ListBoxItem Content="动态" /> <ListBoxItem Content="动态" />
<ListBoxItem Content="动态" /> <ListBoxItem Content="动态" />
</ListBox> </ListBox>
</TabItem> </TabItem>
<TabItem Header="新闻" Background="White" BorderThickness="0" Margin="0" Height="30" FontSize="15" > <TabItem Header="新闻" Background="White" BorderThickness="0" Margin="0" Height="30" FontSize="15" >
<ListBox BorderThickness="0" FontSize="15"> <ListBox BorderThickness="0" FontSize="15">
<ListBoxItem Content="新闻" /> <ListBoxItem Content="新闻" />
<ListBoxItem Content="新闻" /> <ListBoxItem Content="新闻" />
<ListBoxItem Content="新闻" /> <ListBoxItem Content="新闻" />
<ListBoxItem Content="新闻" /> <ListBoxItem Content="新闻" />
<ListBoxItem Content="新闻" /> <ListBoxItem Content="新闻" />
</ListBox> </ListBox>
</TabItem> </TabItem>
<TabItem Header="公告" Background="White" BorderThickness="0" Margin="0" Height="30" FontSize="15" /> <TabItem Header="公告" Background="White" BorderThickness="0" Margin="0" Height="30" FontSize="15" />
<TabItem Header="活动" Background="White" BorderThickness="0" Margin="0" Height="30" FontSize="15" /> <TabItem Header="活动" Background="White" BorderThickness="0" Margin="0" Height="30" FontSize="15" />
</TabControl> </TabControl>
</Grid> </Grid>
<Grid Margin="0,20,20,20" HorizontalAlignment="Right" Width="300" ShowGridLines="True"> <Grid Margin="0,20,20,20" HorizontalAlignment="Right" Width="300" ShowGridLines="True">
<!--<Label Margin="10,15,0,0" Content="最大内存" VerticalAlignment="Top" Height="30" FontSize="17" Background="{x:Null}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="Black" HorizontalAlignment="Left" Width="100"/> <!--<Label Margin="10,15,0,0" Content="最大内存" VerticalAlignment="Top" Height="30" FontSize="17" Background="{x:Null}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="Black" HorizontalAlignment="Left" Width="100"/>
<TextBox x:Name="maxmem" Template="{StaticResource CornerTextBox}" Text="" Height="30" Width="174" TextWrapping="Wrap" Margin="0,15,10,161" FontSize="20" TextChanged="maxmem_TextChanged" HorizontalAlignment="Right" /> <TextBox x:Name="maxmem" Template="{StaticResource CornerTextBox}" Text="" Height="30" Width="174" TextWrapping="Wrap" Margin="0,15,10,161" FontSize="20" TextChanged="maxmem_TextChanged" HorizontalAlignment="Right" />
<ComboBox x:Name="javacombo" Height="30" Width="174" FontSize="15" Margin="0,50,10,0" VerticalAlignment="Top" HorizontalAlignment="Right"/> <ComboBox x:Name="javacombo" Height="30" Width="174" FontSize="15" Margin="0,50,10,0" VerticalAlignment="Top" HorizontalAlignment="Right"/>
<Label Margin="10,50,0,126" Content="JAVA版本" FontSize="17" Background="{x:Null}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="Black" HorizontalAlignment="Left" Width="100"/> <Label Margin="10,50,0,126" Content="JAVA版本" FontSize="17" Background="{x:Null}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="Black" HorizontalAlignment="Left" Width="100"/>
<ComboBox x:Name="gamecombo" Height="30" Width="174" FontSize="15" Margin="0,85,10,0" VerticalAlignment="Top" HorizontalAlignment="Right"/> <ComboBox x:Name="gamecombo" Height="30" Width="174" FontSize="15" Margin="0,85,10,0" VerticalAlignment="Top" HorizontalAlignment="Right"/>
<Label Margin="10,85,0,91" Content="游戏版本" FontSize="17" Background="{x:Null}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="Black" HorizontalAlignment="Left" Width="100"/> <Label Margin="10,85,0,91" Content="游戏版本" FontSize="17" Background="{x:Null}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="Black" HorizontalAlignment="Left" Width="100"/>
<Button x:Name="StartGame" BorderBrush="#FF3299CC" Content="启动游戏" Template="{StaticResource CornerButton}" HorizontalAlignment="Right" Margin="0,0,10,10" Width="100" Height="46" VerticalAlignment="Bottom" FontSize="16" Click="StartGame_Click" IsEnabled="False"/> <Button x:Name="StartGame" BorderBrush="#FF3299CC" Content="启动游戏" Template="{StaticResource CornerButton}" HorizontalAlignment="Right" Margin="0,0,10,10" Width="100" Height="46" VerticalAlignment="Bottom" FontSize="16" Click="StartGame_Click" IsEnabled="False"/>
<Button x:Name="SelServer" BorderBrush="#FF3299CC" Content="选择服务器" Template="{StaticResource CornerButton}" Margin="20,0,0,10" Height="40" Width="100" FontSize="13" Click="StartGame_Click" VerticalAlignment="Bottom" HorizontalAlignment="Left" IsEnabled="False"/>--> <Button x:Name="SelServer" BorderBrush="#FF3299CC" Content="选择服务器" Template="{StaticResource CornerButton}" Margin="20,0,0,10" Height="40" Width="100" FontSize="13" Click="StartGame_Click" VerticalAlignment="Bottom" HorizontalAlignment="Left" IsEnabled="False"/>-->
</Grid> </Grid>
</Grid> </Grid>
</Grid> </Grid>
<Grid Margin="20,60,20,20" Background="White" x:Name="ServerWindow" > <Grid Margin="20,60,20,20" Background="White" x:Name="ServerWindow" Visibility="Hidden">
<!--Visibility="Hidden"--> <!--Visibility="Hidden"-->
<Grid HorizontalAlignment="Left" Width="400" Margin="20,20,0,20"> <Grid HorizontalAlignment="Left" Width="400" Margin="20,20,0,20">
<Grid Height="80" VerticalAlignment="Top" Margin="0,0,0,0"> <Grid Height="80" VerticalAlignment="Top" Margin="0,0,0,0">
<Label Content="选择大区" Margin="155,20" FontSize="20" VerticalAlignment="Center" VerticalContentAlignment="Center"/> <Label Content="选择大区" Margin="155,20" FontSize="20" VerticalAlignment="Center" VerticalContentAlignment="Center"/>
</Grid> </Grid>
<Grid Height="100" VerticalAlignment="Top" Margin="0,80,0,0"> <Grid Height="100" VerticalAlignment="Top" Margin="0,80,0,0" Name="GameArea">
<RadioButton Content="纯净大区" Margin="30,30,0,0" VerticalAlignment="Top" IsChecked="True" HorizontalAlignment="Left" Width="70"/> <RadioButton Name="a1" Content="X X大区" Margin="30,30,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="70" Visibility="Hidden" Checked="area_Checked"/>
<RadioButton Content="模组大区" Margin="120,30,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="70"/> <RadioButton Name="a2" Content="X X大区" Margin="120,30,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="70" Visibility="Hidden" Checked="area_Checked"/>
<RadioButton Content="X X大区" Margin="215,30,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="70"/> <RadioButton Name="a3" Content="X X大区" Margin="215,30,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="70" Visibility="Hidden" Checked="area_Checked"/>
<RadioButton Content="X X大区" Margin="305,30,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="70"/> <RadioButton Name="a4" Content="X X大区" Margin="305,30,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="70" Visibility="Hidden" Checked="area_Checked"/>
<RadioButton Content="X X大区" Margin="30,60,0,0" VerticalAlignment="Top" IsChecked="True" HorizontalAlignment="Left" Width="70"/> <RadioButton Name="a5" Content="X X大区" Margin="30,60,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="70" Visibility="Hidden" Checked="area_Checked"/>
<RadioButton Content="X X大区" Margin="120,60,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="70"/> <RadioButton Name="a6" Content="X X大区" Margin="120,60,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="70" Visibility="Hidden" Checked="area_Checked"/>
<RadioButton Content="X X大区" Margin="215,60,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="70"/> <RadioButton Name="a7" Content="X X大区" Margin="215,60,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="70" Visibility="Hidden" Checked="area_Checked"/>
<RadioButton Content="X X大区" Margin="305,60,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="70"/> <RadioButton Name="a8" Content="X X大区" Margin="305,60,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="70" Visibility="Hidden" Checked="area_Checked"/>
</Grid> </Grid>
<Grid Height="285" VerticalAlignment="Top" Margin="10,185,10,0"> <Grid Height="285" VerticalAlignment="Top" Margin="10,185,10,0">
<Grid Height="50" VerticalAlignment="Top" Margin="10,0,10,0"> <Grid Height="50" VerticalAlignment="Top" Margin="10,0,10,0">
<Label Content="选择服务器" Margin="125,8" FontSize="20" VerticalContentAlignment="Center" VerticalAlignment="Center"/> <Label Content="选择服务器" Margin="125,8" FontSize="20" VerticalContentAlignment="Center" VerticalAlignment="Center"/>
</Grid> </Grid>
<Grid Margin="10,55,10,10"> <Grid Margin="10,55,10,10" Name="GameServer">
<RadioButton Name="server1" Content="光坂小镇" Margin="50,40,0,0" VerticalAlignment="Top" IsChecked="True" HorizontalAlignment="Left" Width="80"/> <RadioButton Name="s1" Content="服务器1" Margin="50,40,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80" Visibility="Hidden" Checked="server_Checked"/>
<RadioButton Content="服务器2" Margin="150,40,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80"/> <RadioButton Name="s2" Content="服务器2" Margin="150,40,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80" Visibility="Hidden" Checked="server_Checked"/>
<RadioButton Content="服务器3" Margin="252,40,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80"/> <RadioButton Name="s3" Content="服务器3" Margin="252,40,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80" Visibility="Hidden" Checked="server_Checked"/>
<RadioButton Content="服务器4" Margin="50,80,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80"/> <RadioButton Name="s4" Content="服务器4" Margin="50,80,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80" Visibility="Hidden" Checked="server_Checked"/>
<RadioButton Content="服务器5" Margin="150,80,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80"/> <RadioButton Name="s5" Content="服务器5" Margin="150,80,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80" Visibility="Hidden" Checked="server_Checked" />
<RadioButton Content="服务器6" Margin="252,80,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80"/> <RadioButton Name="s6" Content="服务器6" Margin="252,80,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80" Visibility="Hidden" Checked="server_Checked"/>
<RadioButton Content="服务器7" Margin="50,120,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80"/> <RadioButton Name="s7" Content="服务器7" Margin="50,120,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80" Visibility="Hidden" Checked="server_Checked"/>
<RadioButton Content="服务器8" Margin="150,120,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80"/> <RadioButton Name="s8" Content="服务器8" Margin="150,120,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80" Visibility="Hidden" Checked="server_Checked"/>
<RadioButton Content="服务器9" Margin="252,120,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80"/> <RadioButton Name="s9" Content="服务器9" Margin="252,120,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80" Visibility="Hidden" Checked="server_Checked"/>
<RadioButton Content="服务器10" Margin="50,160,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80"/> <RadioButton Name="s10" Content="服务器10" Margin="50,160,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80" Visibility="Hidden" Checked="server_Checked"/>
<RadioButton Content="服务器11" Margin="150,160,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80"/> <RadioButton Name="s11" Content="服务器11" Margin="150,160,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80" Visibility="Hidden" Checked="server_Checked"/>
<RadioButton Content="服务器12" Margin="252,160,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80"/> <RadioButton Name="s12" Content="服务器12" Margin="252,160,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="80" Visibility="Hidden" Checked="server_Checked"/>
</Grid> </Grid>
</Grid> </Grid>
</Grid> </Grid>
<Grid HorizontalAlignment="Right" Width="300" Margin="0,20,20,20"> <Grid HorizontalAlignment="Right" Width="300" Margin="0,20,20,20">
<Grid Height="269" VerticalAlignment="Top"> <Grid Height="269" VerticalAlignment="Top">
<Grid Height="40" VerticalAlignment="Top" Margin="10,10,10,0"> <Grid Height="40" VerticalAlignment="Top" Margin="10,10,10,0">
<Label Content="服务器介绍" Margin="85,2" FontSize="20" VerticalContentAlignment="Center" VerticalAlignment="Center"/> <Label Content="服务器介绍" Margin="85,2" FontSize="20" VerticalContentAlignment="Center" VerticalAlignment="Center"/>
</Grid> </Grid>
<Grid Height="200" VerticalAlignment="Bottom" Margin="10,0,10,10"> <Grid Height="200" VerticalAlignment="Bottom" Margin="10,0,10,10">
<Label Content="友爱" HorizontalAlignment="Left" Margin="190,30,0,0" VerticalAlignment="Top"/> <Label Content="友爱" Margin="50,35,50,35"/>
<Label Content="友爱" HorizontalAlignment="Left" Margin="50,30,0,0" VerticalAlignment="Top"/> </Grid>
<Label Content="友爱个篮子" HorizontalAlignment="Left" Margin="103,30,0,0" VerticalAlignment="Top"/> </Grid>
</Grid> <Grid HorizontalAlignment="Right" Width="300" ShowGridLines="True" Height="206" VerticalAlignment="Bottom">
</Grid> <Button x:Name="StartGame" BorderBrush="#FF3299CC" Content="启动游戏" Template="{StaticResource CornerButton}" Margin="10,0,10,10" Height="64" VerticalAlignment="Bottom" FontSize="16" Click="StartGame_Click"/>
<Grid HorizontalAlignment="Right" Width="300" ShowGridLines="True" Height="206" VerticalAlignment="Bottom"> </Grid>
<Button x:Name="StartGame" BorderBrush="#FF3299CC" Content="启动游戏" Template="{StaticResource CornerButton}" Margin="10,0,10,10" Height="64" VerticalAlignment="Bottom" FontSize="16" Click="StartGame_Click"/> </Grid>
</Grid> </Grid>
</Grid> <Button Template="{StaticResource CornerButton}" Width="30" HorizontalAlignment="Right" Content="r" Background="#FFE05A5A" Height="30" VerticalAlignment="Top" FontFamily="Webdings" Click="close_Click" Margin="0,0,0,0" d:IsLocked="True" />
</Grid> </Grid>
<Button Template="{StaticResource CornerButton}" Width="30" HorizontalAlignment="Right" Content="r" Background="#FFE05A5A" Height="30" VerticalAlignment="Top" FontFamily="Webdings" Click="close_Click" Margin="0,0,0,0" d:IsLocked="True" /> </Window>
</Grid>
</Window>

View File

@ -1,199 +1,238 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Data; using System.Windows.Data;
using System.Windows.Documents; using System.Windows.Documents;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using System.Windows.Navigation; using System.Windows.Navigation;
using System.Windows.Shapes; using System.Windows.Shapes;
using KMCCC.Authentication; using KMCCC.Authentication;
using KMCCC.Launcher; using KMCCC.Launcher;
using KMCCC.Tools; using KMCCC.Tools;
using KMCCC.Modules; using KMCCC.Modules;
using KMCCC.Modules.JVersion; using KMCCC.Modules.JVersion;
using CityCraft; using CityCraft;
using System.IO; using System.IO;
using System.Windows.Threading; using System.Windows.Threading;
using System.Windows.Media.Animation; using System.Windows.Media.Animation;
using LitJson;
namespace CTZLauncher using CTZLauncher.Modules.CTZServer;
{
/// <summary> namespace CTZLauncher
/// MainWindow.xaml 的交互逻辑 {
/// </summary> /// <summary>
public partial class MainWindow : Window /// MainWindow.xaml 的交互逻辑
{ /// </summary>
LauncherCore launcher = null; public partial class MainWindow : Window
int serverport = 25580; {
public MainWindow() LauncherCore launcher = null;
{ LaunchOptions option = new LaunchOptions();
InitializeComponent(); string serveraddress = "";
} int serverport = 25580;
private void Window_Initialized(object sender, EventArgs e) #region
{ public MainWindow()
if (!Directory.Exists(".minecraft")) {
{ InitializeComponent();
Directory.CreateDirectory(".minecraft"); }
}
launcher = LauncherCore.Create(".minecraft"); private void Window_Initialized(object sender, EventArgs e)
} {
if (!Directory.Exists(".minecraft"))
private void barclick_MouseDown(object sender, MouseButtonEventArgs e) {
{ Directory.CreateDirectory(".minecraft");
Label bar = (Label)sender; }
MessageBox.Show(bar.Name); launcher = LauncherCore.Create(".minecraft");
switch (bar.Name.Substring(4)) }
{ #endregion
case "l1":
break; #region
case "l2": private void barclick_MouseDown(object sender, MouseButtonEventArgs e)
break; {
case "l3": Label bar = (Label)sender;
break; MessageBox.Show(bar.Name);
case "l4": switch (bar.Name.Substring(4))
break; {
case "r1": case "l1":
break; break;
case "r2": case "l2":
break; break;
case "r3": case "l3":
break; break;
case "r4": case "l4":
break; break;
} case "r1":
} break;
case "r2":
private void Login_Click(object sender, RoutedEventArgs e) break;
{ case "r3":
if (username.Text.Length == 0 || password.Text.Length == 0) break;
{ case "r4":
MessageBox.Show("请输入账号密码!"); break;
return; }
} }
Login.IsEnabled = false;
CTZAuthenticator auth = new CTZAuthenticator(username.Text, password.Text, "citycraft.cn", serverport); private void Login_Click(object sender, RoutedEventArgs e)
if (auth.isLogin()) {
{ if (username.Text.Length == 0 || password.Text.Length == 0)
MessageBox.Show("当前玩家已登录服务器!"); {
} MessageBox.Show("请输入账号密码!");
else return;
{ }
if (!auth.Login()) Login.IsEnabled = false;
{ CTZAuthenticator auth = new CTZAuthenticator(username.Text, password.Text, serveraddress, serverport);
if (!auth.isRegistered()) if (auth.isLogin())
MessageBox.Show("该用户名未注册 请先注册!"); {
else MessageBox.Show("当前玩家已登录服务器!");
MessageBox.Show("登录失败 账号不存在 或 密码错误 !"); }
} else
else {
{ if (!auth.Login())
ServerWindow.Visibility = System.Windows.Visibility.Visible; {
RotateTransform rtf = new RotateTransform(); if (!auth.isRegistered())
ServerWindow.RenderTransform = rtf; MessageBox.Show("该用户名未注册 请先注册!");
LoginWindow.RenderTransform = rtf; else
DoubleAnimation dbAscending = new DoubleAnimation(0, 360, new Duration(TimeSpan.FromSeconds(0.75))); MessageBox.Show("登录失败 账号不存在 或 密码错误 !");
dbAscending.RepeatBehavior = new RepeatBehavior(1); }
rtf.BeginAnimation(RotateTransform.AngleProperty, dbAscending); else
} {
} ServerWindow.Visibility = System.Windows.Visibility.Visible;
Login.IsEnabled = true; RotateTransform rtf = new RotateTransform();
} ServerWindow.RenderTransform = rtf;
LoginWindow.RenderTransform = rtf;
/// <summary> DoubleAnimation dbAscending = new DoubleAnimation(0, 360, new Duration(TimeSpan.FromSeconds(0.75)));
/// 模仿C#的Application.Doevent函数。可以适当添加try catch 模块 dbAscending.RepeatBehavior = new RepeatBehavior(1);
/// </summary> rtf.BeginAnimation(RotateTransform.AngleProperty, dbAscending);
public void DoEvent() CTZServer areas = JsonMapper.ToObject<CTZServer>(auth.getServerList());
{ LoadAreas(areas);
DispatcherFrame frame = new DispatcherFrame(); }
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(ExitFrame), frame); }
Dispatcher.PushFrame(frame); Login.IsEnabled = true;
} }
public object ExitFrame(object f)
{ private void outline_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
((DispatcherFrame)f).Continue = false; {
return null; if (e.LeftButton == MouseButtonState.Pressed)
} this.DragMove();
}
private void outline_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{ private void close_Click(object sender, RoutedEventArgs e)
if (e.LeftButton == MouseButtonState.Pressed) {
this.DragMove(); this.Close();
} }
private void StartGame_Click(object sender, RoutedEventArgs e) private void maxmem_TextChanged(object sender, TextChangedEventArgs e)
{ {
Console.WriteLine("StartGame"); //屏蔽中文输入和非法字符粘贴输入
LaunchOptions option = new LaunchOptions(); TextBox textBox = sender as TextBox;
option.Mode = LaunchMode.MCLauncher; TextChange[] change = new TextChange[e.Changes.Count];
option.MaxMemory = 2048; e.Changes.CopyTo(change, 0);
option.Authenticator = new OfflineAuthenticator(username.Text); // offline
option.Version = launcher.GetVersion("1.8"); int offset = change[0].Offset;
launcher.JavaPath = SystemTools.FindJava().First(); if (change[0].AddedLength > 0)
launcher.GameLog += launcher_GameLog; {
launcher.Launch(option); double num = 0;
} if (!Double.TryParse(textBox.Text, out num))
{
void launcher_GameLog(LaunchHandle arg1, string log) textBox.Text = textBox.Text.Remove(offset, change[0].AddedLength);
{ textBox.Select(offset, 0);
Console.WriteLine(log); }
} }
}
private void close_Click(object sender, RoutedEventArgs e)
{ private void register_Click(object sender, RoutedEventArgs e)
this.Close(); {
} if (username.Text.Length == 0 || password.Text.Length == 0)
{
private void maxmem_TextChanged(object sender, TextChangedEventArgs e) MessageBox.Show("请输入账号密码!");
{ return;
//屏蔽中文输入和非法字符粘贴输入 }
TextBox textBox = sender as TextBox; CTZAuthenticator auth = new CTZAuthenticator(username.Text, password.Text, "citycraft.cn", serverport);
TextChange[] change = new TextChange[e.Changes.Count]; if (auth.isRegistered())
e.Changes.CopyTo(change, 0); {
MessageBox.Show("该用户名已注册 请更换用户名!");
int offset = change[0].Offset; return;
if (change[0].AddedLength > 0) }
{ if (auth.Register())
double num = 0; {
if (!Double.TryParse(textBox.Text, out num)) MessageBox.Show("注册成功!");
{ auth.Login();
textBox.Text = textBox.Text.Remove(offset, change[0].AddedLength); ServerWindow.Visibility = System.Windows.Visibility.Visible;
textBox.Select(offset, 0); }
} else
} MessageBox.Show("注册失败!");
} }
private void register_Click(object sender, RoutedEventArgs e) private void forget_Click(object sender, RoutedEventArgs e)
{ {
if (username.Text.Length == 0 || password.Text.Length == 0)
{ }
MessageBox.Show("请输入账号密码!"); #endregion
return;
} #region
CTZAuthenticator auth = new CTZAuthenticator(username.Text, password.Text, "citycraft.cn", serverport); private void LoadAreas(CTZServer areas)
if (auth.isRegistered()) {
{ for (int i = 1; i <= areas.Areas.Count; i++)
MessageBox.Show("该用户名已注册 请更换用户名!"); {
return; Area area = areas.Areas[i];
} RadioButton arearb = GameArea.FindName("a" + i) as RadioButton;
if (auth.Register()) arearb.Content = area.Name;
{ arearb.Visibility = Visibility.Visible;
MessageBox.Show("注册成功!"); arearb.Tag = area.Servers;
auth.Login(); }
ServerWindow.Visibility = System.Windows.Visibility.Visible; }
}
else private void LoadServers(List<Server> servers)
MessageBox.Show("注册失败!"); {
} for (int i = 1; i <= servers.Count; i++)
{
private void s(object sender, RoutedEventArgs e) Server server = servers[i];
{ RadioButton serverrb = GameArea.FindName("s" + i) as RadioButton;
serverrb.Content = server.Name;
} serverrb.Visibility = Visibility.Visible;
} serverrb.Tag = server;
} }
}
private void area_Checked(object sender, RoutedEventArgs e)
{
RadioButton rb = (RadioButton)sender;
LoadServers((List<Server>)rb.Tag);
}
private void server_Checked(object sender, RoutedEventArgs e)
{
RadioButton rb = (RadioButton)sender;
Server server = (Server)rb.Tag;
option.Server = new ServerInfo
{
Address = server.Address,
Port = server.Port
};
option.Version = launcher.GetVersion(server.Version);
}
private void StartGame_Click(object sender, RoutedEventArgs e)
{
Console.WriteLine("StartGame");
option.Mode = LaunchMode.MCLauncher;
option.MaxMemory = 2048;
option.Authenticator = new OfflineAuthenticator(username.Text); // offline
option.Version = launcher.GetVersion("1.8");
launcher.JavaPath = SystemTools.FindJava().First();
launcher.GameLog += launcher_GameLog;
launcher.Launch(option);
}
void launcher_GameLog(LaunchHandle arg1, string log)
{
Console.WriteLine(log);
}
#endregion
}
}

View File

@ -0,0 +1,87 @@
using LitJson;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CTZLauncher.Modules.CTZServer
{
/// <summary>
/// 实例化服务器信息
/// </summary>
public class CTZServer
{
/// <summary>
/// 大区列表
/// </summary>
[JsonPropertyName("areas")]
public List<Area> Areas { get; set; }
}
/// <summary>
/// 服务器大区信息
/// </summary>
public class Area
{
/// <summary>
/// 大区名称
/// </summary>
[JsonPropertyName("name")]
public string Name { get; set; }
/// <summary>
/// 大区服务器列表
/// </summary>
[JsonPropertyName("servers")]
public List<Server> Servers { get; set; }
}
/// <summary>
/// 服务器信息
/// </summary>
public class Server
{
/// <summary>
/// 服务器名称
/// </summary>
[JsonPropertyName("name")]
public string Name { get; set; }
/// <summary>
/// 服务器地址
/// </summary>
[JsonPropertyName("address")]
public string Address { get; set; }
/// <summary>
/// 服务器端口
/// </summary>
[JsonPropertyName("port")]
public ushort Port { get; set; }
/// <summary>
/// 服务器简介
/// </summary>
[JsonPropertyName("info")]
public string Info { get; set; }
/// <summary>
/// 客户端版本
/// </summary>
[JsonPropertyName("version")]
public string Version { get; set; }
/// <summary>
/// 客户端下载地址
/// </summary>
[JsonPropertyName("url")]
public string Url { get; set; }
/// <summary>
/// 获得服务器链接
/// </summary>
/// <returns>服务器链接</returns>
public override string ToString()
{
return string.Format("{0}:{1}", Address, Port);
}
}
}