Advertisement
Guest User

Untitled

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