Пример #1
0
        /// <summary>
        /// Manual HTTPS request since we must directly use a TcpClient because of the proxy.
        /// This method connects to the server, enables SSL, do the request and read the response.
        /// </summary>
        /// <param name="headers">Request headers and optional body (POST)</param>
        /// <param name="host">Host to connect to</param>
        /// <param name="result">Request result</param>
        /// <returns>HTTP Status code</returns>

        private static int doHTTPSRequest(List <string> headers, string host, ref string result)
        {
            string postResult = null;
            int    statusCode = 520;

            AutoTimeout.Perform(() =>
            {
                TcpClient client = ProxyHandler.newTcpClient(host, 443, true);
                SslStream stream = new SslStream(client.GetStream());
                stream.AuthenticateAsClient(host);
                stream.Write(Encoding.ASCII.GetBytes(String.Join("\r\n", headers.ToArray())));
                System.IO.StreamReader sr = new System.IO.StreamReader(stream);
                string raw_result         = sr.ReadToEnd();
                if (raw_result.StartsWith("HTTP/1.1"))
                {
                    postResult = raw_result.Substring(raw_result.IndexOf("\r\n\r\n") + 4);
                    statusCode = Settings.str2int(raw_result.Split(' ')[1]);
                }
                else
                {
                    statusCode = 520;  //Web server is returning an unknown error
                }
            }, TimeSpan.FromSeconds(30));
            result = postResult;
            return(statusCode);
        }
        /// <summary>
        /// Send a http request to the server. Proxy is handled automatically
        /// </summary>
        /// <param name="method">Method in string representation</param>
        /// <param name="body">Optional request body</param>
        /// <returns></returns>
        private Response Send(string method, string body = "")
        {
            List <string> requestMessage = new List <string>()
            {
                string.Format("{0} {1} {2}", method.ToUpper(), path, httpVersion) // Request line
            };

            foreach (string key in Headers) // Headers
            {
                var value = Headers[key];
                requestMessage.Add(string.Format("{0}: {1}", key, value));
            }
            requestMessage.Add(""); // <CR><LF>
            if (body != "")
            {
                requestMessage.Add(body);
            }
            else
            {
                requestMessage.Add("");  // <CR><LF>
            }
            if (Settings.DebugMessages)
            {
                foreach (string l in requestMessage)
                {
                    ConsoleIO.WriteLine("< " + l);
                }
            }
            Response response = Response.Empty();

            AutoTimeout.Perform(() =>
            {
                TcpClient client = ProxyHandler.newTcpClient(host, port, true);
                Stream stream;
                if (isSecure)
                {
                    stream = new SslStream(client.GetStream());
                    ((SslStream)stream).AuthenticateAsClient(host);
                }
                else
                {
                    stream = client.GetStream();
                }
                string h    = string.Join("\r\n", requestMessage.ToArray());
                byte[] data = Encoding.ASCII.GetBytes(h);
                stream.Write(data, 0, data.Length);
                stream.Flush();
                StreamReader sr  = new StreamReader(stream);
                string rawResult = sr.ReadToEnd();
                response         = ParseResponse(rawResult);
                try
                {
                    sr.Close();
                    stream.Close();
                    client.Close();
                } catch { }
            },
                                TimeSpan.FromSeconds(30));
            return(response);
        }
        /// <summary>
        /// Retrieve information about a Minecraft server
        /// </summary>
        /// <param name="serverIP">Server IP to ping</param>
        /// <param name="serverPort">Server Port to ping</param>
        /// <param name="protocolversion">Will contain protocol version, if ping successful</param>
        /// <returns>TRUE if ping was successful</returns>
        public static bool GetServerInfo(string serverIP, ushort serverPort, ref int protocolversion, ref ForgeInfo forgeInfo)
        {
            bool      success            = false;
            int       protocolversionTmp = 0;
            ForgeInfo forgeInfoTmp       = null;

            if (AutoTimeout.Perform(() =>
            {
                try
                {
                    if (Protocol16Handler.doPing(serverIP, serverPort, ref protocolversionTmp) ||
                        Protocol18Handler.doPing(serverIP, serverPort, ref protocolversionTmp, ref forgeInfoTmp))
                    {
                        success = true;
                    }
                    else
                    {
                        Translations.WriteLineFormatted("error.unexpect_response");
                    }
                }
                catch (Exception e)
                {
                    ConsoleIO.WriteLineFormatted(String.Format("§8{0}: {1}", e.GetType().FullName, e.Message));
                }
            }, TimeSpan.FromSeconds(Settings.ResolveSrvRecordsShortTimeout ? 10 : 30)))
            {
                if (protocolversion != 0 && protocolversion != protocolversionTmp)
                {
                    Translations.WriteLineFormatted("error.version_different");
                }
                if (protocolversion == 0 && protocolversionTmp <= 1)
                {
                    Translations.WriteLineFormatted("error.no_version_report");
                }
                if (protocolversion == 0)
                {
                    protocolversion = protocolversionTmp;
                }
                forgeInfo = forgeInfoTmp;
                return(success);
            }
            else
            {
                Translations.WriteLineFormatted("error.connection_timeout");
                return(false);
            }
        }
        /// <summary>
        /// Retrieve information about a Minecraft server
        /// </summary>
        /// <param name="serverIP">Server IP to ping</param>
        /// <param name="serverPort">Server Port to ping</param>
        /// <param name="protocolversion">Will contain protocol version, if ping successful</param>
        /// <returns>TRUE if ping was successful</returns>
        public static bool GetServerInfo(string serverIP, ushort serverPort, ref int protocolversion, ref ForgeInfo forgeInfo)
        {
            bool      success            = false;
            int       protocolversionTmp = 0;
            ForgeInfo forgeInfoTmp       = null;

            if (AutoTimeout.Perform(() =>
            {
                try
                {
                    if (Protocol16Handler.doPing(serverIP, serverPort, ref protocolversionTmp) ||
                        Protocol18Handler.doPing(serverIP, serverPort, ref protocolversionTmp, ref forgeInfoTmp))
                    {
                        success = true;
                    }
                    else
                    {
                        ConsoleIO.WriteLineFormatted("§8Unexpected response from the server (is that a Minecraft server?)");
                    }
                }
                catch (Exception e)
                {
                    ConsoleIO.WriteLineFormatted(String.Format("§8{0}: {1}", e.GetType().FullName, e.Message));
                }
            }, TimeSpan.FromSeconds(Settings.ResolveSrvRecordsShortTimeout ? 10 : 30)))
            {
                if (protocolversion != 0 && protocolversion != protocolversionTmp)
                {
                    ConsoleIO.WriteLineFormatted("§8Server reports a different version than manually set. Login may not work.");
                }
                if (protocolversion == 0 && protocolversionTmp <= 1)
                {
                    ConsoleIO.WriteLineFormatted("§8Server does not report its protocol version, autodetection will not work.");
                }
                if (protocolversion == 0)
                {
                    protocolversion = protocolversionTmp;
                }
                forgeInfo = forgeInfoTmp;
                return(success);
            }
            else
            {
                ConsoleIO.WriteLineFormatted("§8A timeout occured while attempting to connect to this IP.");
                return(false);
            }
        }
        /// <summary>
        /// Retrieve information about a Minecraft server
        /// </summary>
        /// <param name="serverIP">Server IP to ping</param>
        /// <param name="serverPort">Server Port to ping</param>
        /// <param name="protocolversion">Will contain protocol version, if ping successful</param>
        /// <returns>TRUE if ping was successful</returns>
        public static bool GetServerInfo(string serverIP, ushort serverPort, ref int protocolversion, ref ForgeInfo forgeInfo)
        {
            bool      success            = false;
            int       protocolversionTmp = 0;
            ForgeInfo forgeInfoTmp       = null;

            if (AutoTimeout.Perform(() =>
            {
                try
                {
                    if (Protocol16Handler.doPing(serverIP, serverPort, ref protocolversionTmp) ||
                        Protocol18Handler.doPing(serverIP, serverPort, ref protocolversionTmp, ref forgeInfoTmp))
                    {
                        success = true;
                    }
                    else
                    {
                        ConsoleIO.WriteLineFormatted("§c[警告]§8无法连接至非Minecraft服务器之外的服务器!");
                    }
                }
                catch (Exception e)
                {
                    ConsoleIO.WriteLineFormatted(String.Format("§e[信息]§8{0}: {1}", e.GetType().FullName, e.Message));
                }
            }, TimeSpan.FromSeconds(Settings.ResolveSrvRecordsShortTimeout ? 10 : 30)))
            {
                if (protocolversion != 0 && protocolversion != protocolversionTmp)
                {
                    ConsoleIO.WriteLineFormatted("§e[信息]§8服务器发送了不同的版本,可能无法登入,请手动输入版本.");
                }
                if (protocolversion == 0 && protocolversionTmp <= 1)
                {
                    ConsoleIO.WriteLineFormatted("§e[信息]§8服务器未通知协议版本,可能会无法登入,请手动输入版本.");
                }
                if (protocolversion == 0)
                {
                    protocolversion = protocolversionTmp;
                }
                forgeInfo = forgeInfoTmp;
                return(success);
            }
            else
            {
                ConsoleIO.WriteLineFormatted("§c[错误]§8连接超时.");
                return(false);
            }
        }
        /// <summary>
        /// Perform a DNS lookup for a Minecraft Service using the specified domain name
        /// </summary>
        /// <param name="domain">Input domain name, updated with target host if any, else left untouched</param>
        /// <param name="port">Updated with target port if any, else left untouched</param>
        /// <returns>TRUE if a Minecraft Service was found.</returns>
        public static bool MinecraftServiceLookup(ref string domain, ref ushort port)
        {
            bool   foundService = false;
            string domainVal    = domain;
            ushort portVal      = port;

            if (!String.IsNullOrEmpty(domain) && domain.Any(c => char.IsLetter(c)))
            {
                AutoTimeout.Perform(() =>
                {
                    try
                    {
                        Translations.WriteLine("mcc.resolve", domainVal);
                        Heijden.DNS.Response response      = new Heijden.DNS.Resolver().Query("_minecraft._tcp." + domainVal, Heijden.DNS.QType.SRV);
                        Heijden.DNS.RecordSRV[] srvRecords = response.RecordsSRV;
                        if (srvRecords != null && srvRecords.Any())
                        {
                            //Order SRV records by priority and weight, then randomly
                            Heijden.DNS.RecordSRV result = srvRecords
                                                           .OrderBy(record => record.PRIORITY)
                                                           .ThenByDescending(record => record.WEIGHT)
                                                           .ThenBy(record => Guid.NewGuid())
                                                           .First();
                            string target = result.TARGET.Trim('.');
                            ConsoleIO.WriteLineFormatted(Translations.Get("mcc.found", target, result.PORT, domainVal));
                            domainVal    = target;
                            portVal      = result.PORT;
                            foundService = true;
                        }
                    }
                    catch (Exception e)
                    {
                        ConsoleIO.WriteLineFormatted(Translations.Get("mcc.not_found", domainVal, e.GetType().FullName, e.Message));
                    }
                }, TimeSpan.FromSeconds(Settings.ResolveSrvRecordsShortTimeout ? 10 : 30));
            }

            domain = domainVal;
            port   = portVal;
            return(foundService);
        }
Пример #7
0
        /// <summary>
        /// Manual HTTPS request since we must directly use a TcpClient because of the proxy.
        /// This method connects to the server, enables SSL, do the request and read the response.
        /// </summary>
        /// <param name="host">Host to connect to</param>
        /// <param name="endpoint">Endpoint for making the request</param>
        /// <param name="request">Request payload</param>
        /// <param name="result">Request result</param>
        /// <returns>HTTP Status code</returns>

        private static int doHTTPSPost(string host, string endpoint, string request, ref string result)
        {
            string postResult = null;
            int    statusCode = 520;

            AutoTimeout.Perform(() =>
            {
                TcpClient client = ProxyHandler.newTcpClient(host, 443);
                SslStream stream = new SslStream(client.GetStream());
                stream.AuthenticateAsClient(host);

                List <String> http_request = new List <string>();
                http_request.Add("POST " + endpoint + " HTTP/1.1");
                http_request.Add("Host: " + host);
                http_request.Add("User-Agent: MCC/" + Program.Version);
                http_request.Add("Content-Type: application/json");
                http_request.Add("Content-Length: " + Encoding.ASCII.GetBytes(request).Length);
                http_request.Add("Connection: close");
                http_request.Add("");
                http_request.Add(request);

                stream.Write(Encoding.ASCII.GetBytes(String.Join("\r\n", http_request.ToArray())));
                System.IO.StreamReader sr = new System.IO.StreamReader(stream);
                string raw_result         = sr.ReadToEnd();

                if (raw_result.StartsWith("HTTP/1.1"))
                {
                    postResult = raw_result.Substring(raw_result.IndexOf("\r\n\r\n") + 4);
                    statusCode = Settings.str2int(raw_result.Split(' ')[1]);
                }
                else
                {
                    statusCode = 520;  //Web server is returning an unknown error
                }
            }, 15000);
            result = postResult;
            return(statusCode);
        }
Пример #8
0
        /// <summary>
        /// Retrieve information about a Minecraft server
        /// </summary>
        /// <param name="serverIP">Server IP to ping</param>
        /// <param name="serverPort">Server Port to ping</param>
        /// <param name="protocolversion">Will contain protocol version, if ping successful</param>
        /// <returns>TRUE if ping was successful</returns>
        public static bool GetServerInfo(string serverIP, ushort serverPort, ref int protocolversion, ref ForgeInfo forgeInfo)
        {
            bool      success            = false;
            int       protocolversionTmp = 0;
            ForgeInfo forgeInfoTmp       = null;

            if (AutoTimeout.Perform(() =>
            {
                try
                {
                    if (Protocol16Handler.doPing(serverIP, serverPort, ref protocolversionTmp) ||
                        Protocol18Handler.doPing(serverIP, serverPort, ref protocolversionTmp, ref forgeInfoTmp))
                    {
                        success = true;
                    }
                    else
                    {
                        ConsoleIO.WriteLineFormatted("§8Unexpected response from the server (is that a Minecraft server?)");
                    }
                }
                catch (Exception e)
                {
                    //ConsoleIO.WriteLineFormatted("ProtocolHandler:82");
                    //ConsoleIO.WriteLineFormatted(String.Format("§8{0}: {1}", e.GetType().FullName, e.Message));
                }
            }, TimeSpan.FromSeconds(Settings.ResolveSrvRecordsShortTimeout ? 10 : 30)))
            {
                protocolversion = protocolversionTmp;
                forgeInfo       = forgeInfoTmp;
                return(success);
            }
            else
            {
                //ConsoleIO.WriteLineFormatted("§8A timeout occured while attempting to connect to this IP.");
                return(false);
            }
        }
Пример #9
0
        /// <summary>
        /// Manual HTTPS request since we must directly use a TcpClient because of the proxy.
        /// This method connects to the server, enables SSL, do the request and read the response.
        /// </summary>
        /// <param name="headers">Request headers and optional body (POST)</param>
        /// <param name="host">Host to connect to</param>
        /// <param name="result">Request result</param>
        /// <returns>HTTP Status code</returns>
        private static int DoHTTPSRequest(List <string> headers, string host, ref string result)
        {
            string    postResult = null;
            int       statusCode = 520;
            Exception exception  = null;

            AutoTimeout.Perform(() =>
            {
                try
                {
                    if (Settings.DebugMessages)
                    {
                        ConsoleIO.WriteLineFormatted("§8Performing request to " + host);
                    }

                    TcpClient client = ProxyHandler.newTcpClient(host, 443, true);
                    SslStream stream = new SslStream(client.GetStream());
                    stream.AuthenticateAsClient(host);

                    if (Settings.DebugMessages)
                    {
                        foreach (string line in headers)
                        {
                            ConsoleIO.WriteLineFormatted("§8> " + line);
                        }
                    }

                    stream.Write(Encoding.ASCII.GetBytes(String.Join("\r\n", headers.ToArray())));
                    System.IO.StreamReader sr = new System.IO.StreamReader(stream);
                    string raw_result         = sr.ReadToEnd();

                    if (Settings.DebugMessages)
                    {
                        ConsoleIO.WriteLine("");
                        foreach (string line in raw_result.Split('\n'))
                        {
                            ConsoleIO.WriteLineFormatted("§8< " + line);
                        }
                    }

                    if (raw_result.StartsWith("HTTP/1.1"))
                    {
                        postResult = raw_result.Substring(raw_result.IndexOf("\r\n\r\n") + 4);
                        statusCode = Settings.str2int(raw_result.Split(' ')[1]);
                    }
                    else
                    {
                        statusCode = 520;  //Web server is returning an unknown error
                    }
                }
                catch (Exception e)
                {
                    if (!(e is System.Threading.ThreadAbortException))
                    {
                        exception = e;
                    }
                }
            }, TimeSpan.FromSeconds(30));
            result = postResult;
            if (exception != null)
            {
                throw exception;
            }
            return(statusCode);
        }
Пример #10
0
        /// <summary>
        /// Calculate a path from the start location to the destination location
        /// </summary>
        /// <remarks>
        /// Based on the A* pathfinding algorithm described on Wikipedia
        /// </remarks>
        /// <see href="https://en.wikipedia.org/wiki/A*_search_algorithm#Pseudocode"/>
        /// <param name="start">Start location</param>
        /// <param name="goal">Destination location</param>
        /// <param name="allowUnsafe">Allow possible but unsafe locations</param>
        /// <returns>A list of locations, or null if calculation failed</returns>
        public static Queue <Location> CalculatePath(World world, Location start, Location goal, bool allowUnsafe = false)
        {
            Queue <Location> result = null;

            AutoTimeout.Perform(() =>
            {
                HashSet <Location> ClosedSet = new HashSet <Location>();                           // The set of locations already evaluated.
                HashSet <Location> OpenSet   = new HashSet <Location>(new[] { start });            // The set of tentative nodes to be evaluated, initially containing the start node
                Dictionary <Location, Location> Came_From = new Dictionary <Location, Location>(); // The map of navigated nodes.

                Dictionary <Location, int> g_score = new Dictionary <Location, int>();             //:= map with default value of Infinity
                g_score[start] = 0;                                                                // Cost from start along best known path.
                // Estimated total cost from start to goal through y.
                Dictionary <Location, int> f_score = new Dictionary <Location, int>();             //:= map with default value of Infinity
                f_score[start] = (int)start.DistanceSquared(goal);                                 //heuristic_cost_estimate(start, goal)

                while (OpenSet.Count > 0)
                {
                    Location current = //the node in OpenSet having the lowest f_score[] value
                                       OpenSet.Select(location => f_score.ContainsKey(location)
                        ? new KeyValuePair <Location, int>(location, f_score[location])
                        : new KeyValuePair <Location, int>(location, int.MaxValue))
                                       .OrderBy(pair => pair.Value).First().Key;
                    if (current == goal)
                    { //reconstruct_path(Came_From, goal)
                        List <Location> total_path = new List <Location>(new[] { current });
                        while (Came_From.ContainsKey(current))
                        {
                            current = Came_From[current];
                            total_path.Add(current);
                        }
                        total_path.Reverse();
                        result = new Queue <Location>(total_path);
                    }
                    OpenSet.Remove(current);
                    ClosedSet.Add(current);
                    foreach (Location neighbor in GetAvailableMoves(world, current, allowUnsafe))
                    {
                        if (ClosedSet.Contains(neighbor))
                        {
                            continue;                                                                      // Ignore the neighbor which is already evaluated.
                        }
                        int tentative_g_score = g_score[current] + (int)current.DistanceSquared(neighbor); //dist_between(current,neighbor) // length of this path.
                        if (!OpenSet.Contains(neighbor))                                                   // Discover a new node
                        {
                            OpenSet.Add(neighbor);
                        }
                        else if (tentative_g_score >= g_score[neighbor])
                        {
                            continue;           // This is not a better path.
                        }
                        // This path is the best until now. Record it!
                        Came_From[neighbor] = current;
                        g_score[neighbor]   = tentative_g_score;
                        f_score[neighbor]   = g_score[neighbor] + (int)neighbor.DistanceSquared(goal); //heuristic_cost_estimate(neighbor, goal)
                    }
                }
            }, TimeSpan.FromSeconds(5));

            return(result);
        }