Advertisement
Guest User

Untitled

a guest
Jul 28th, 2017
461
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.21 KB | None | 0 0
  1. //By: Tim
  2. //Date: 2-24-11
  3. //Purpose: Basic Minecraft Login / Update Server.
  4. //  Listens on port 8124 for incoming GET requests
  5. //  Listens on port 8123 for incoming LOGIN requests
  6. //  and sends the requested files, if they are in the
  7. //  shared folder
  8. //To DO:
  9. //  A GUI? :-o
  10.  
  11. /************\
  12. |  Includes  |
  13. \************/
  14. //standard library
  15. #include <stdlib.h>
  16. //print to console
  17. #include <iostream>
  18. //allow us to sleep (pause execution)
  19. #include <Windows.h>
  20. //allow us to multi-thread
  21. #include <process.h>
  22. //allow us to networkz
  23. #include <WinSock.h>
  24. //gives us strings for yarn and stuff
  25. #include <string>
  26. //allows us to read from files
  27. #include <fstream>
  28. //allows us to determine size of file
  29. #include <sys/stat.h>
  30.  
  31. //don't have to say std:: before every god damn line
  32. using namespace std;
  33.  
  34. /*************\
  35. |  Functions  |
  36. \*************/
  37. //used to accept clients + give out updated files
  38. void update_handle(void *params);
  39. //used to spoof the acceptence of login requests
  40. void login_handle(void *params);
  41. //sets up the socket, listens
  42. int webserver(int PORT);
  43. //sends files to the client
  44. bool sendfile(int sockfd, string file_name);
  45. //listens for login requests from minecraft
  46. void threaded_listen(void *port);
  47.  
  48. //SIZE = the size of sockaddr_in
  49. #define SIZE sizeof(struct sockaddr_in)
  50.  
  51. int main()
  52. {
  53.     _beginthread(threaded_listen, 0, (void *)8123);
  54.     webserver(8124);
  55.     system("pause");
  56.     return 0;
  57. }
  58.  
  59. void threaded_listen(void *port)
  60. {
  61.     //start another listen server, but on a different port and in a different thread
  62.     webserver((int)port);
  63. }
  64.  
  65. bool sendfile(int sockfd, string file_name)
  66. {
  67.     //allows us to read from file
  68.     ifstream fin;
  69.     //stores the size of the file in some odd format
  70.     struct stat fsize;
  71.     //buffer
  72.     char buff[65536];
  73.     //number of bytes read from the file
  74.     int num_read = 1;
  75.     //total number of bytes read from the file
  76.     int total_read = 0;
  77.     //number of bytes sent to the client
  78.     int num_sent = 0;
  79.     //HTTP response to the client
  80.     string output;
  81.     //character array storing the size of the file
  82.     char *file_size = (char*) malloc(sizeof(char));
  83.  
  84.     //attempt to open the file in binary format
  85.     fin.open(file_name.c_str(), ios::binary);
  86.  
  87.     //did we open it?
  88.     if (!fin.is_open())
  89.     {
  90.         cout << "couldn't open file" << endl;
  91.         return false;
  92.     }
  93.     else
  94.     {
  95.         //grab the size of the file
  96.         stat(file_name.c_str(), &fsize);
  97.         //format it
  98.         _itoa(fsize.st_size, file_size, 10);
  99.         //build our HTTP response to the client
  100.         output = "HTTP/1.1 200 OK\r\n";
  101.         output += "x-amz-id-2: 57cxuiXKkSb32YEYIfZWMSyBA1STz/Dp/6NqjKhjWqJmHTTNtYFzAk9qdIrIzyhV\r\n";
  102.         output += "x-amz-request-id: 8FB790874B07CF65\r\n";
  103.         output += "Date: Tuesday, 25-Nov-97 01:00:00 EST\r\n";
  104.         output += "Last-Modified: 25-Nov-97 01:00:00 EST\r\n";
  105.  
  106.         //whatever this stupid etag junk is, it's unique to each file (MD5, perhaps?)
  107.         if (file_name == "shared\\lwjgl.jar")
  108.             output += "ETag: \"7a07c4285fa9a6b204ba59f011f1cd77\"\r\n";
  109.         else if (file_name == "shared\\jinput.jar")
  110.             output += "ETag: \"a7835a73a130656aba23e34147a55367\"\r\n";
  111.         else if (file_name == "shared\\lwjgl_util.jar")
  112.             output += "ETag: \"f00470751cfc093ba760ca3cf10a512c\"\r\n";
  113.         else if (file_name == "shared\\windows_natives.jar.lzma")
  114.             output += "ETag: \"e3361fe429a3709e96cadec4b56a904f\"\r\n";
  115.         else if (file_name == "shared\\minecraft.jar")
  116.             output += "ETag: \"4203826f35e1036f089919032c3d19d1\"\r\n";
  117.  
  118.         output += "Accept-Ranges: bytes\r\n";
  119.         output += "Content-type: application/x-java-archive\r\n";
  120.         output += "Content-Length: " + (string)file_size + "\r\n";
  121.         output += "Server: test\r\n\r\n";
  122.         //send it
  123.         send(sockfd, output.c_str(), output.length(), 0);
  124.  
  125.         //make sure we're at position 0
  126.         fin.seekg(0);
  127.  
  128.         //while we have read something
  129.         while(num_read > 0)
  130.         {
  131.             //attempt to read the next 1024 bytes, check how many we actually got
  132.             //and update the counts
  133.             fin.read(buff, 65536);
  134.             num_read = fin.gcount();
  135.             total_read += num_read;
  136.  
  137.             //if the number we have read so far is less than the total
  138.             //and we just read something
  139.             if (total_read <= fsize.st_size && num_read > 0)
  140.             {
  141.                 //attempt to send the data to our client
  142.                 num_sent = send(sockfd, buff, num_read, 0);
  143.  
  144.                 //did it send?
  145.                 if (num_sent <= 0)
  146.                 {
  147.                     //failed, let's wait a bit and try again
  148.                     cout << "error sending data, trying again" << endl;
  149.                     Sleep(5);
  150.                     num_sent = send(sockfd, buff, num_read, 0);
  151.                     if (num_sent <= 0)
  152.                     {
  153.                         cout << "errored sending data again, quitting" << endl;
  154.                         fin.close();
  155.                         return false;
  156.                     }
  157.                 }
  158.             }
  159.         }
  160.     }
  161.  
  162.     //we sent!
  163.     fin.close();
  164.     return true;
  165. }
  166.  
  167. int webserver(int PORT)
  168. {
  169.     //Socket to listen for connections on
  170.     struct sockaddr_in server;
  171.     //not used
  172.     struct sockaddr_in client;
  173.     //File descriptor for the listen socket
  174.     int sockfd;
  175.     //Status code in case we get an error
  176.     int status;
  177.     //File descriptor for the socket on which we accept clients
  178.     int newfd;
  179.     //Error code.
  180.     int errno;
  181.     //Error code.
  182.     int iResult;
  183.  
  184.     //prepare for sockets
  185.     WSADATA wsaData;
  186.     iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
  187.  
  188.     //Set up listen socket and client socket
  189.     server.sin_family = AF_INET;
  190.     server.sin_port = htons(PORT);
  191.     server.sin_addr.s_addr = INADDR_ANY;
  192.  
  193.     client.sin_family = AF_INET;
  194.     client.sin_port = htons(PORT);
  195.  
  196.     //Create the socket
  197.     sockfd = socket(AF_INET, SOCK_STREAM, 0);
  198.     if (sockfd < 0)
  199.     {
  200.         cout << "Error creating listen socket." << endl;
  201.         return 1;
  202.     }
  203.  
  204.     //Bind the socket
  205.     status = bind(sockfd, (struct sockaddr *)&server, SIZE);
  206.     if (status < 0)
  207.     {
  208.         cout << "Could not bind listen socket." << endl;
  209.         return 1;
  210.     }
  211.  
  212.     //Listen for connection requests
  213.     status = listen(sockfd, 1);
  214.     if (status < 0)
  215.     {
  216.         cout << "Could not listen." << endl;
  217.         return 1;
  218.     }
  219.  
  220.     //Everything went right
  221.     cout << "Listening on port " << PORT << endl;
  222.  
  223.     int len = SIZE;
  224.  
  225.     //forever
  226.     while(1)
  227.     {
  228.         newfd = accept(sockfd, (struct sockaddr*)&client, &len);
  229.         if (newfd < 0)
  230.         {
  231.             //whoooooops something went wrong
  232.             cout << "Could not accept request" << endl;
  233.         }
  234.         else
  235.         {
  236.             //did it! print the file descriptor just for the lolz, then enter the new thread
  237.             cout << "passing FD of " << newfd << endl;
  238.             if (PORT == 8124)
  239.                 _beginthread(update_handle, 0, (void *)newfd);
  240.             else
  241.                 _beginthread(login_handle, 0, (void *)newfd);
  242.         }
  243.  
  244.     }
  245. }
  246.  
  247. void update_handle(void * params)
  248. {
  249.     //incoming file descriptor
  250.     int newfd;
  251.     //number of bytes read
  252.     int num_read = 1;
  253.     //number of bytes sent
  254.     int num_sent = 0;
  255.     //size of the buffer
  256.     char buff[15000];
  257.     //actual data storage
  258.     string data;
  259.     //set the file descriptor
  260.     newfd = (int)params;
  261.  
  262.     //while we haven't gotten a disconnect
  263.     while(num_read > 0)
  264.     {
  265.         //recieve data
  266.         num_read = recv(newfd, buff, 14999, 0);
  267.         //terminate the data
  268.         buff[num_read] = '\0';
  269.         //if we got anything, print it
  270.         data = buff;
  271.        
  272.         //spot to parse data
  273.         //minecraft insists on doing a HEAD before a GET - probably to check
  274.         //if there's an updated version or not.  Too god damn bad, notch.
  275.         if (data.find("HEAD") != string::npos && data[5] == '/')
  276.             send(newfd, "HTTP/1.0 501 Not Implemented\r\nServer: test\r\n\r\n", 46,0);
  277.         else if (data.find("GET") != string::npos && data[4] == '/')
  278.         {
  279.             //what do they want?
  280.             if (data.find("lwjgl.jar") != string::npos)
  281.                 sendfile(newfd, "shared\\lwjgl.jar");
  282.             else if (data.find("jinput.jar") != string::npos)
  283.                 sendfile(newfd, "shared\\jinput.jar");
  284.             else if (data.find("lwjgl_util.jar") != string::npos)
  285.                 sendfile(newfd, "shared\\lwjgl_util.jar");
  286.             else if (data.find("windows_natives.jar") != string::npos)
  287.                 sendfile(newfd, "shared\\windows_natives.jar.lzma");
  288.             else if (data.find("user") != string::npos)
  289.                 sendfile(newfd, "shared\\minecraft.jar");
  290.         }
  291.     }
  292.     //they left us :(
  293.     cout << "client disconnected" << endl;
  294.     //end the thread, yo
  295.     _endthread();
  296. }
  297.  
  298. void login_handle(void * params)
  299. {
  300.     //incoming file descriptor
  301.     int newfd;
  302.     //number of bytes read
  303.     int num_read = 1;
  304.     //number of bytes sent
  305.     int num_sent = 0;
  306.     //size of the buffer
  307.     char buff[15000];
  308.     //actual data storage
  309.     string data;
  310.     //set the file descriptor
  311.     newfd = (int)params;
  312.     //username the user wants
  313.     string uname = "noob";
  314.     //login OK response
  315.     string Okay;
  316.  
  317.     //while we haven't gotten a disconnect
  318.     while(num_read > 0)
  319.     {
  320.         num_read = recv(newfd, buff, 14999, 0);
  321.         //terminate the data
  322.         buff[num_read] = '\0';
  323.         //if we got anything, print it
  324.         data = buff;
  325.  
  326.         cout << data << endl;
  327.         //did it send a login request?
  328.         if (data.find("user") != string::npos)
  329.         {
  330.             //steal the username they tried to login with and use it as the accepted username
  331.             uname = data.substr(data.find("user") + 5);
  332.             uname = uname.substr(0, uname.find("password") - 1);
  333.  
  334.             cout << "caught login request from " << uname << endl;
  335.  
  336.             //lol
  337.             if (uname == "wrycu" || uname == "Wrycu")
  338.                 uname = "noob";
  339.  
  340.             //build the reply
  341.             Okay = "1295383684000:2699b4c0c738f69cfd066f538502f374:" + uname + ":11111111111";
  342.             //attempt to send it
  343.             num_sent = send(newfd, Okay.c_str(), Okay.length(), 0);
  344.             //if it sent, close the socket and end the thread
  345.             if (num_sent > 0)
  346.                 closesocket(newfd);
  347.                 _endthread();
  348.         }
  349.     }
  350. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement