fork download
  1. // SDL_net Client | r3dux.org | 14/01/2011
  2.  
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <fstream>
  6. #include <iostream>
  7. #include <sstream>
  8.  
  9. //Allegro include files
  10. #include <allegro5/allegro.h>
  11. #include <allegro5/allegro_font.h>
  12. #include <allegro5/allegro_ttf.h>
  13.  
  14. //SDL include files
  15. #include "SDL.h"
  16. #include "SDL_net.h"
  17.  
  18. const unsigned short PORT = 1337; // The port we are connecting to
  19. const unsigned short BUFFER_SIZE = 512; // Size of our message buffer (i.e. maximum length of characters in a message)
  20.  
  21. ALLEGRO_DISPLAY *display;
  22. ALLEGRO_EVENT_QUEUE *event_queue;
  23. ALLEGRO_TIMER *timer;
  24. ALLEGRO_FONT *font;
  25.  
  26. IPaddress serverIP;
  27. Uint8 * dotQuad;
  28.  
  29. int lastFromServer = 0;//message duplicate containter/flag
  30. int FPS = 60;//display frames per second
  31. std::string text = "";
  32. bool redraw = false;
  33.  
  34. int main(int argc, char **argv)
  35. {
  36. const char *host; // Where we store the host name
  37.  
  38. int status = 0; int status_before = 0;
  39. std::ofstream file("log.txt");
  40. file << "Program initialized" << std::endl;
  41. TCPsocket clientSocket; // The socket to use
  42. std::string serverName; serverName = "localhost"; // The server name
  43. std::string cpp_cl_0 = "";//line of chat we can show other clients
  44.  
  45. std::string userInput = ""; // A string to hold our user input
  46. int inputLength = 0; // The length of our string in characters
  47. char buffer[BUFFER_SIZE]; // Array of character's we'll use to transmit our message. We get input into the userInput string for ease of use, then just copy it to this character array and send it.
  48. std::string FPScount_string = "none";
  49. std::stringstream myString;
  50.  
  51. if (!al_init()) {
  52. file << "Allegro could not be initialized" << std::endl;
  53. return -1;
  54. }
  55.  
  56. al_set_window_title(display, "Client");
  57.  
  58. // create ourself a display
  59. display = al_create_display(640, 480);
  60. if (!display)
  61. {
  62. al_destroy_display(display);
  63. file << "Display could not be created" << std::endl;
  64. return -1;
  65. }
  66.  
  67. event_queue = al_create_event_queue();
  68. if (!event_queue) {
  69. al_destroy_event_queue(event_queue);
  70. file << "Event queue could not be created!" << std::endl;
  71. return -1;
  72. }
  73.  
  74. timer = al_create_timer(1.0 / FPS);
  75. if (!timer) {
  76. al_destroy_timer(timer);
  77. file << "Timer could not be created!" << std::endl;
  78. return -1;
  79. }
  80.  
  81. // Initialise SDL_net
  82. if (SDLNet_Init() < 0)
  83. {
  84. file << "Failed to intialise SDN_net " << std::endl;
  85. return -1;
  86. }
  87.  
  88. al_install_keyboard();
  89. al_init_font_addon();
  90. al_init_ttf_addon();
  91.  
  92. font = al_load_font("data/fonts/bookosb.ttf", 0, 24);
  93.  
  94. al_register_event_source(event_queue, al_get_display_event_source(display));
  95. al_register_event_source(event_queue, al_get_timer_event_source(timer));
  96. al_register_event_source(event_queue, al_get_keyboard_event_source());
  97.  
  98. al_start_timer(timer);
  99.  
  100. // Create the socket set with enough space to store our desired number of connections (i.e. sockets)
  101. SDLNet_SocketSet socketSet = SDLNet_AllocSocketSet(1);
  102. if (socketSet == NULL)
  103. {
  104. file << "Failed to allocate the socket set." << std::endl;
  105. exit(-1); // Quit!
  106. }
  107. else
  108. {
  109. file << "Successfully allocated socket set." << std::endl;
  110. }
  111.  
  112.  
  113. // Try to resolve the host. If successful, this places the connection details in the serverIP object
  114. int hostResolved = SDLNet_ResolveHost(&serverIP, serverName.c_str(), PORT);
  115.  
  116. if (hostResolved == -1)
  117. {
  118. file << "Failed to resolve the server hostname: " << "\nContinuing..." << std::endl;
  119. }
  120. else // If we successfully resolved the host then output the details
  121. {
  122. // Get our IP address in proper dot-quad format by breaking up the 32-bit unsigned host address and splitting it into an array of four 8-bit unsigned numbers...
  123. dotQuad = (Uint8*)&serverIP.host;
  124.  
  125. //... and then outputting them cast to integers. Then read the last 16 bits of the serverIP object to get the port number
  126. file << "Successfully resolved host to IP: " << (unsigned short)dotQuad[0] << "." << (unsigned short)dotQuad[1] << "." << (unsigned short)dotQuad[2] << "." << (unsigned short)dotQuad[3] << ":" << PORT << std::endl;
  127. }
  128.  
  129. // Try to resolve the IP of the server, just for kicks
  130. if ((host = SDLNet_ResolveIP(&serverIP)) == NULL)
  131. {
  132. file << "Failed to resolve the server IP address." << std::endl;
  133. }
  134. else
  135. {
  136. file << "Successfully resolved IP to host: " << host << std::endl;
  137. }
  138.  
  139. // Flag to keep track of when to disconnect and when to shutdown.
  140. bool shutdownClient = false;//bool shutdownClient = true;
  141. bool clientConnected = false;
  142.  
  143. clientSocket = SDLNet_TCP_Open(&serverIP);
  144. if (!clientSocket)
  145. {
  146. file << "Failed to open socket to server: " << SDLNet_GetError() << std::endl;
  147. text = "Server seems to be down";
  148.  
  149. }
  150. else // If we successfully opened a connection then check for the server response to our connection
  151. {
  152. file << "Connection okay, about to read connection status from the server..." << std::endl;
  153.  
  154. // Add our socket to the socket set for polling
  155. SDLNet_TCP_AddSocket(socketSet, clientSocket);
  156.  
  157. // Wait for up to five seconds for a response from the server
  158. // Note: If we don't check the socket set and WAIT for the response, we'll be checking before the server can respond, and it'll look as if the server sent us nothing back
  159. int activeSockets = SDLNet_CheckSockets(socketSet, 5000);
  160.  
  161. file << "There are " << activeSockets << " socket(s) with data on them at the moment." << std::endl;
  162.  
  163. // Check if we got a response from the server
  164. int gotServerResponse = SDLNet_SocketReady(clientSocket);
  165.  
  166. if (gotServerResponse != 0)
  167. {
  168. file << "Got a response from the server... " << std::endl;
  169. int serverResponseByteCount = SDLNet_TCP_Recv(clientSocket, buffer, BUFFER_SIZE);
  170.  
  171. file << "Got the following from server: " << buffer << "(" << serverResponseByteCount << " bytes)" << std::endl;
  172.  
  173. // We got an okay from the server, so we can join!
  174. if (strcmp(buffer, "OK") == 0)
  175. {
  176. // So set the flag to say we're not quitting out just yet
  177. clientConnected = true; shutdownClient = false;
  178. file << "Joining server now..." << std::endl << std::endl;
  179. text = "Now connected";
  180. }
  181. else
  182. {
  183. file << "Server is full... Terminating connection." << std::endl;
  184. text = "Server reports FULL";
  185. }
  186. }
  187. else
  188. {
  189. file << "No response from server..." << std::endl;
  190. text = "Server failed to respond";
  191. }
  192.  
  193. } // End of if we managed to open a connection to the server condition
  194.  
  195. bool wrotePrompt = false; // Whether or not we've already written the prompt
  196. bool sendMessage = false; // Whether or not it's time to send the message (flips to true when the user presses return)
  197.  
  198. // While it's not time to shutdown the client...
  199. do
  200. {
  201. //SDL_Delay(500);
  202.  
  203. if (sendMessage == true)
  204. {
  205. file << "the message to be sent is>" << userInput << std::endl;
  206. if (clientConnected == true)
  207. {
  208. // Copy our user's string into our char array called "buffer"
  209. strcpy_s(buffer, userInput.c_str());
  210.  
  211. // Calculate the length of our input and then add 1 (for the terminating character) to get the total number of characters we need to send
  212. inputLength = strlen(buffer) + 1;
  213.  
  214. // Send the message to the server
  215. if (SDLNet_TCP_Send(clientSocket, (void *)buffer, inputLength) < inputLength)
  216. {
  217. file << "Failed to send message: " << std::endl;
  218. // exit(-1);
  219. }
  220. else
  221. {
  222. file << "Message sent successfully." << std::endl;
  223.  
  224. //quit=tell server to disconnect me
  225. if (sendMessage == true && (userInput == "quit"))
  226. {
  227. text = "Server disconnecting";
  228. }
  229. //exit=tell server I'm shutting down
  230. if (sendMessage == true && (userInput == "exit"))
  231. {
  232. text = "Shutting down";
  233. shutdownClient = true;
  234. }
  235. //shutdown=tell server to shut it's self down
  236. if (sendMessage == true && (userInput == "shutdown"))
  237. {
  238. text = "Server shut down sent";
  239. }
  240. }//end of failed to send message
  241. }//end of clientConnected == true
  242. //reset for the next message
  243. sendMessage = false;
  244. userInput = "";
  245. } // End of if message needs sent
  246.  
  247. // Check our socket set for activity. Don't wait if there's nothing on the socket just continue
  248. int socketActive = SDLNet_CheckSockets(socketSet, 0);
  249.  
  250. //cout << "Sockets with data on them at the moment: " << activeSockets << endl;
  251.  
  252. if (socketActive != 0)
  253. {
  254. // Check if we got a response from the server
  255. int messageFromServer = SDLNet_SocketReady(clientSocket);
  256.  
  257. if (messageFromServer != 0)//removed lastfromserver
  258. {
  259. file << "Got a response from the server... " << std::endl;
  260. int serverResponseByteCount = SDLNet_TCP_Recv(clientSocket, buffer, BUFFER_SIZE);
  261.  
  262. file << "Received: " << buffer << std::endl;// "(" << serverResponseByteCount << " bytes)" << endl;
  263.  
  264. if (strcmp(buffer, "shutdown") == 0)
  265. {
  266. std::cout << "Server is going down. Disconnecting..." << std::endl;
  267. text = "Server has gone down";
  268. shutdownClient = true;
  269. }
  270. }
  271. else
  272. {
  273. file << "No response from server..." << std::endl;
  274. text = "Server reports it is down";
  275. }
  276. lastFromServer = messageFromServer;//message duplicate checking
  277. } // End of if socket has activity check
  278. myString.str("");//most awesome way to clear a stringstream
  279. myString << FPS;//int to stringstream
  280. FPScount_string = myString.str();//stringstream to string
  281.  
  282. //check for events (currently keyboard events handled)
  283. ALLEGRO_EVENT ev;
  284. al_wait_for_event(event_queue, &ev);
  285.  
  286. if (ev.type == ALLEGRO_EVENT_TIMER) {
  287. redraw = true;
  288. }
  289. else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
  290. shutdownClient = true; // If we must quit, then do so
  291. }
  292. // Has a key been pressed down?
  293. else if (ev.type == ALLEGRO_EVENT_KEY_DOWN)
  294. {
  295. if (ev.keyboard.keycode == ALLEGRO_KEY_ENTER)
  296. {
  297. if (userInput.length() > 0) { sendMessage = true; }
  298. }//send the message
  299. }
  300.  
  301. if (ev.type == ALLEGRO_EVENT_KEY_CHAR) { //Add to the message
  302. status = ev.keyboard.unichar; // Get the keypress
  303.  
  304. file << "the key pressed was " << status << " " << (char)status << std::endl;
  305.  
  306. if (status == 8) {
  307. if (userInput.length() > 0) {
  308. userInput.erase(userInput.length() - 1);
  309. }
  310. }
  311. else if (status >= 65 && status <= 122) {
  312. userInput += (char)status;
  313. }
  314. }
  315. else {
  316. status = -1;
  317. }
  318.  
  319. if (redraw && al_is_event_queue_empty(event_queue)) {
  320. al_clear_to_color(al_map_rgb(0, 0, 0));
  321.  
  322. al_draw_text(font, al_map_rgb(255, 255, 255), 20, 20, 0, "Hello");
  323. //al_draw_text(font, al_map_rgb(255, 255, 255), 20, 20, 0, userInput.c_str());
  324. //al_draw_text(font, al_map_rgb(255, 255, 255), 20, 20, 0, text.c_str());
  325.  
  326. al_flip_display();
  327. }
  328.  
  329. }while (shutdownClient == false); // End of main while loop
  330.  
  331. file << "Client shutting down" << std::endl;
  332. // Close our socket, cleanup SDL_net, reset the terminal mode and finish!
  333. SDLNet_TCP_Close(clientSocket);
  334.  
  335. SDLNet_Quit();
  336.  
  337. al_destroy_font(font);
  338. al_destroy_display(display);
  339. al_destroy_event_queue(event_queue);
  340. al_destroy_timer(timer);
  341.  
  342. return 0;
  343. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:10:30: fatal error: allegro5/allegro.h: No such file or directory
compilation terminated.
stdout
Standard output is empty