예제 #1
0
        private void ListenWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            // setup http listener.
            if (!HttpListener.IsSupported)
            {
                e.Result = "HttpListener is not supported on your OS.";
                return;
            }

            HttpListener http = new HttpListener();

            try
            {
                http.Prefixes.Add($"http://localhost:{SERVER_PORT}/");
                http.Start();
            }
            catch (Exception exc)
            {
                e.Result = exc.Message;
                return;
            }

            // make a pseudo random generator.
            Random rnd = new Random();

            rnd.Next();

            BackgroundWorker self = sender as BackgroundWorker;
            int counter           = 1;

            List <IPAddress> blocked   = new List <IPAddress>();
            List <string>    allIPs    = new List <string>();
            List <int>       gennedIDs = new List <int>();

            while (true)
            {
                // obtain responses and stuff.
                HttpListenerContext  context  = http.GetContext();
                HttpListenerRequest  request  = context.Request;
                HttpListenerResponse response = context.Response;
                Stream output = response.OutputStream;
                Stream input  = request.InputStream;

                response.ContentType     = "application/x-www-form-urlencoded";
                response.ContentEncoding = Encoding.UTF8;
                response.StatusCode      = (int)HttpStatusCode.OK;

                // if blocked ip is trying again...
                bool cont = false;
                foreach (var endpoint in blocked)
                {
                    if (endpoint.Equals(request.RemoteEndPoint.Address))
                    {
                        // update the RNG so it gets stronger.
                        rnd.Next();

                        Console.WriteLine("Blocked IP trying again huh... " + endpoint.ToString());
                        output.WriteString("status=success&reason=ok");
                        output.Close();
                        cont = true;
                        break;
                    }
                }
                if (cont)
                {
                    continue;
                }

                switch (request.Url.AbsolutePath)
                {
                case "/register":
                {
                    // get values.
                    var    nvc          = HttpUtility.ParseQueryString(input.ReadToEnd());
                    string employeename = nvc["username"];
                    string ipport       = nvc["ipport"];
                    string iponly       = ipport.Substring(0, ipport.IndexOf(':'));

                    bool stop = false;
                    foreach (string ip in allIPs)
                    {
                        if (iponly == ip)
                        {
                            // oh.
                            output.WriteString("status=denied&id=0");
                            output.Close();
                            stop = true;
                            Console.WriteLine("Access denied for " + ipport);
                            break;
                        }
                    }
                    if (stop)
                    {
                        continue;
                    }

                    Console.WriteLine("Adding " + iponly);
                    allIPs.Add(iponly);

                    // generate a totally unique random emp id.
                    int id  = 0;
                    int bob = 100;
                    do
                    {
                        Console.WriteLine("Generating employee id...");
                        id = bob + rnd.Next(bob, int.MaxValue / bob);
                    }while (gennedIDs.IndexOf(id) != -1);

                    gennedIDs.Add(id);

                    // construct info struct
                    EmployeeInfo info = new EmployeeInfo(counter, id, employeename, ipport);

                    // return response
                    output.WriteString("status=success&id=" + id.ToString());

                    // send it to the ProgressChanged method.
                    self.ReportProgress(0, info);
                    counter++;

                    break;
                }

                case "/updatetime":
                {
                    // update the RNG so it gets stronger.
                    rnd.Next();

                    // lol.
                    Console.WriteLine("Updating time...");

                    // parse client.
                    string query = input.ReadToEnd();
                    var    nvc   = HttpUtility.ParseQueryString(query);
                    if (nvc["time"] == "ABUSE")         // abuse detection worked.
                    {
                        blocked.Add(request.RemoteEndPoint.Address);
                        Console.WriteLine("ABUSE DETECTED! " + request.RemoteEndPoint.ToString());
                    }
                    else
                    {
                        int _newtime = -1, _empid = -1;
                        if (!int.TryParse(nvc["time"], out _newtime))
                        {
                            output.WriteString("status=failure&reason=InvalidTime");
                            output.Close();
                            continue;
                        }
                        else if (!int.TryParse(nvc["employeeid"], out _empid))
                        {
                            output.WriteString("status=failure&reason=InvalidEmployeeId");
                            output.Close();
                            continue;
                        }

                        output.WriteString("status=success&reason=ok");

                        // construct update struct.
                        UpdateInfo uinfo = new UpdateInfo(_newtime, _empid);

                        // report to UI
                        self.ReportProgress(1, uinfo);
                    }

                    // we're done.
                    output.WriteString("status=success&reason=ok");
                    break;
                }

                case "/leaderboard":
                {
                    Leaderboard lbret = (Leaderboard)MainListView.Invoke((Func <Leaderboard>) delegate
                        {
                            Leaderboard lb = new Leaderboard
                            {
                                employees = new Employee[MainListView.Items.Count]
                            };

                            int i = 0;
                            foreach (ListViewItem lvi in MainListView.Items)
                            {
                                if (lvi.SubItems[2].Text == "-1")
                                {
                                    continue;
                                }

                                lb.employees[i] = new Employee
                                {
                                    id        = lvi.Text,
                                    best_time = lvi.SubItems[2].Text
                                };
                                i++;
                            }

                            return(lb);
                        });

                    string lbstring    = JsonConvert.SerializeObject(lbret);
                    byte[] lbrawstring = Encoding.UTF8.GetBytes(lbstring);

                    response.ContentType     = "application/json";
                    response.ContentLength64 = lbrawstring.LongLength;
                    output.WriteString(lbstring);
                    break;
                }

                default:
                {
                    Console.WriteLine("Unsupported method, ignoring...");
                    break;
                }
                }

                output.Close();
            }
        }