Advertisement
Guest User

Untitled

a guest
May 26th, 2018
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.74 KB | None | 0 0
  1. #include <netdb.h>
  2. #include <iostream>
  3. #include <cstring>
  4. #include <unistd.h>
  5. #include <sys/time.h>
  6. #include <algorithm>
  7. #include <cmath>
  8. #include <fcntl.h>
  9.  
  10. #include "err.h"
  11. #include "server.h"
  12. #include "constans.h"
  13. #include "helper.h"
  14.  
  15. std::string get_string_from_datagram(unsigned char *datagram, uint8_t from, uint8_t to)
  16. {
  17.     std::string result_string = "";
  18.     for (int i = from; i <= to; ++i)
  19.         result_string += datagram[i];
  20.     return result_string;
  21. }
  22.  
  23. // datagram size 100, zal: >= 13, < 100, sprawdzic dla == 100 (>=100 tez) czy if bedzie dzialal (Wyslac dlugie imie)
  24. bool parse_datagram(unsigned char *datagram, uint32_t len, uint64_t &session_id, int8_t &turn_direction, uint32_t &next_expected_event_no, std::string &player_name)
  25. {
  26.     unsigned char session_id_str[8];
  27.     for (size_t i = 0; i < 8; ++i)
  28.         session_id_str[i] = datagram[i];
  29.  
  30.     unsigned char turn_direction_str[1];
  31.     turn_direction_str[0] = datagram[8];
  32.  
  33.     unsigned char next_expected_event_no_str[4];
  34.     for (size_t i = 9; i < 13; ++i)
  35.         next_expected_event_no_str[i-9] = datagram[i];
  36.  
  37.     session_id = read_8_byte_number(session_id_str);
  38.     turn_direction = read_1_byte_number(turn_direction_str);
  39.     next_expected_event_no = read_4_byte_number(next_expected_event_no_str);
  40.     player_name = get_string_from_datagram(datagram, 13, len-1);
  41.  
  42.     if (player_name.size() > 64)
  43.         return false;
  44.  
  45.     for (size_t i = 0; i < player_name.size(); ++i)
  46.         if (player_name[i] < 33 || player_name[i] > 126)
  47.             return false;
  48.  
  49.     return true;
  50. }
  51.  
  52. Datagram::Datagram(unsigned char *buffer, size_t len)
  53. {
  54.     this->correct_datagram = parse_datagram(buffer, len, this->session_id, this->turn_direction, this->next_expected_event_no, this->player_name);
  55. }
  56.  
  57. Event::Event(uint32_t event_type)
  58. {
  59.     this->event_type = event_type;
  60.     this->event_data = "";
  61. }
  62.  
  63. void Event::create_event_new_game(uint32_t maxx, uint32_t maxy, std::vector<std::string> &players_name)
  64. {
  65.     this->event_data += make_message_from_n_byte(maxx, 4);
  66.     this->event_data += make_message_from_n_byte(maxy, 4);
  67.     for (std::string str: players_name)
  68.         this->event_data += str + '\0';
  69. }
  70.  
  71. void Event::create_event_pixel(uint8_t player_number, uint32_t x, uint32_t y)
  72. {
  73.     this->event_data += make_message_from_n_byte(player_number, 1);
  74.     this->event_data += make_message_from_n_byte(x, 4);
  75.     this->event_data += make_message_from_n_byte(y, 4);
  76. }
  77.  
  78. void Event::create_event_player_eliminated(uint8_t player_number)
  79. {
  80.     this->event_data += make_message_from_n_byte(player_number, 1);
  81. }
  82.  
  83. std::string Event::to_string(uint32_t event_number)
  84. {
  85.     std::string result = "";
  86.     result += make_message_from_n_byte(event_number, 4);
  87.     result += make_message_from_n_byte(this->event_type, 1);
  88.     result += this->event_data;
  89.     uint32_t crc = calculate_crc32(result);
  90.     result = make_message_from_n_byte(result.size(), 4) + result;
  91.     result += make_message_from_n_byte(crc, 4);
  92.     return result;
  93. }
  94.  
  95. Client::Client(Server *server, struct sockaddr_in client_address, uint64_t session_id, std::string client_name, int8_t turn_direction, uint32_t next_expected_event_no)
  96. {
  97.     this->server = server;
  98.     this->client_address = client_address;
  99.     this->session_id = session_id;
  100.     this->client_name = client_name;
  101.     this->alive = false;
  102.     this->head_x = ((server->get_random())%server->map_width) + 0.5;
  103.     this->head_y = ((server->get_random())%server->map_height) + 0.5;
  104.     this->direction = (server->get_random())%360;
  105.     this->turn_direction = turn_direction;
  106.     this->next_expected_event_no = next_expected_event_no;
  107. }
  108.  
  109. bool cmp(Client &client1, Client &client2)
  110. {
  111.     return client1.client_name < client2.client_name;
  112. }
  113.  
  114. Game::Game(Server *server)
  115. {
  116.     this->game_id = server->get_random();
  117.     this->server = server;
  118.     this->is_game_active = false;
  119. }
  120.  
  121. bool Game::check_is_game_over()
  122. {
  123.     uint32_t active_clients = 0;
  124.     for (size_t i = 0; i < server->clients.size(); ++i)
  125.         if (this->server->clients[i].alive)
  126.             ++active_clients;
  127.     return active_clients <= 0;
  128. }
  129.  
  130. void Server::make_socket()
  131. {
  132.     this->sock = socket(AF_INET, SOCK_DGRAM, 0); // creating IPv4 UDP socket
  133.     if (this->sock < 0)
  134.         syserr("socket");
  135.  
  136.     this->server_address.sin_family = AF_INET; // IPv4
  137.     this->server_address.sin_addr.s_addr = htonl(INADDR_ANY);
  138.     this->server_address.sin_port = htons(this->server_port);
  139.  
  140.     if (bind(this->sock, (struct sockaddr *) &(this->server_address),
  141.             (socklen_t) sizeof(server_address)) < 0)
  142.         syserr("bind");
  143.  
  144.     fcntl(sock, F_SETFL, O_NONBLOCK);
  145. }
  146.  
  147. // Konwertuje ciag znakow na liczbe jezeli owa jest liczba
  148. // mniejsza od 2^20, w.p.p zwraca 2^30
  149. uint64_t get_int(char *buffer)
  150. {
  151.     uint64_t result = 1<<30;
  152.     int len = strlen(buffer);
  153.     if (len >= 7)
  154.         return result;
  155.     for (int i = 0; i < len; ++i)
  156.         if (buffer[i] < '0' || buffer[i] > '9')
  157.             return result;
  158.     result = (uint64_t)atoi(buffer);
  159.     return result;
  160. }
  161.  
  162. bool check_port(uint32_t port)
  163. {
  164.     if (port < MIN_PORT_VALUE || port > MAX_PORT_VALUE)
  165.         return false;
  166.     return true;
  167. }
  168.  
  169. Server::Server(int argc, char *argv[])
  170. {
  171.     this->map_width = DEFAULT_MAP_WIDTH;
  172.     this->map_height = DEFAULT_MAP_HEIGHT;
  173.     this->server_port = atoi(DEFAULT_SERVER_PORT);
  174.     this->game_speed = DEFAULT_GAME_SPEED;
  175.     this->turn_speed = DEFAULT_TURN_SPEED;
  176.     this->seed = time(NULL);
  177.     this->get_random_first_call = true;
  178.     this->game_is_active = false;
  179.     this->last_time = this->get_time();
  180.  
  181.     int opt;
  182.     while ((opt = getopt(argc, argv, "W:H:p:s:t:r:")) != -1) {
  183.         uint32_t num = get_int(optarg);
  184.         if (num == (1<<30))
  185.             syserr("Wrong call parameter(s)");
  186.         switch (opt) {
  187.             case 'W':
  188.                 this->map_width = num;
  189.                 break;
  190.             case 'H':
  191.                 this->map_height = num;
  192.                 break;
  193.             case 'p':
  194.                 if (!check_port(num))
  195.                     syserr("Wrong port parameter");
  196.                 this->server_port = num;
  197.                 break;
  198.             case 's':
  199.                 this->game_speed = num;
  200.                 break;
  201.             case 't':
  202.                 this->turn_speed = num;
  203.                 break;
  204.             case 'r':
  205.                 this->seed = num;
  206.                 break;
  207.             default: /* '?' */
  208.                 syserr("Usage: %s [-W n] [-H n] [-p n] [-s n] [-t n] [-r n]", argv[0]);
  209.         }
  210.     }
  211.     this->time_period = 1000/(this->game_speed);
  212. }
  213.  
  214. uint64_t Server::get_random()
  215. {
  216.     static uint32_t r = 0;
  217.     if (this->get_random_first_call) {
  218.         this->get_random_first_call = false;
  219.         return r = this->seed;
  220.     }
  221.     return r = ((uint64_t)r * 279470273) % 4294967291;
  222. }
  223.  
  224. ssize_t Server::receive_datagram_from_client(unsigned char *datagram, int len, struct sockaddr_in &srvr_address, ssize_t &rcv_len)
  225. {
  226.     int flags = 0;
  227.     socklen_t rcva_len;
  228.  
  229.     memset(datagram, 0, sizeof(datagram));
  230.     rcva_len = (socklen_t) sizeof(srvr_address);
  231.     rcv_len = recvfrom(this->sock, datagram, len, flags,
  232.         (struct sockaddr *) &srvr_address, &rcva_len);
  233.     return rcv_len;
  234.     //if (rcv_len < 0)
  235.     //    syserr("error on datagram from client socket");
  236. }
  237.  
  238. void Server::send_datagram_to_client(struct sockaddr_in *client_address, unsigned char *datagram, int len)
  239. {
  240.     int sflags = 0;
  241.     socklen_t snda_len;
  242.     ssize_t snd_len;
  243.  
  244.     snda_len = (socklen_t) sizeof(*client_address);
  245.     std::cout<<"len = "<<len<<"\n";
  246.     snd_len = sendto(this->sock, datagram, (size_t) len, sflags,
  247.             (struct sockaddr *) client_address, snda_len);
  248.     std::cout<<"snd_len "<<snd_len<<", len = "<<len<<"\n";
  249.     if (snd_len != len)
  250.         syserr("error on sending datagram to client socket");
  251. }
  252.  
  253. void Server::read_datagrams()
  254. {
  255.     unsigned char buffer[SERVER_BUFFER_SIZE];
  256.     struct sockaddr_in client_address;
  257.     ssize_t len = 0;
  258.  
  259.     while (len > -1) {
  260.         len = this->receive_datagram_from_client(buffer, (size_t)sizeof(buffer), client_address, len);
  261.         Datagram datagram(buffer, len);
  262.         if (!datagram.correct_datagram)
  263.             continue;
  264.         int ind = this->find_index_of_client(client_address, datagram.session_id);
  265.         if (ind == -1) {
  266.             Client client(this, client_address, datagram.session_id, datagram.player_name, datagram.turn_direction, datagram.next_expected_event_no);
  267.             this->add_client(client);
  268.             ind = this->find_index_of_client(client_address, datagram.session_id);
  269.         }
  270.         else {
  271.             this->clients[ind].turn_direction = datagram.turn_direction;
  272.             this->clients[ind].next_expected_event_no = datagram.next_expected_event_no;
  273.         }
  274.         this->send_events_to_client(ind);
  275.     }
  276. }
  277.  
  278. int Server::client_index_from_alives(int ind)
  279. {
  280.     int result = 0;
  281.     for (int i = 0; i < ind; ++i)
  282.         if (this->clients[i].alive)
  283.             ++result;
  284.     return result;
  285. }
  286.  
  287. bool Server::check_collision(int x, int y)
  288. {
  289.     if (x < 0 || y < 0 || x >= this->map_width || y >= this->map_height)
  290.         return true;
  291.     if (this->game->occupied_pixels.find(std::make_pair(x, y)) != this->game->occupied_pixels.end())
  292.         return true;
  293.     return false;
  294. }
  295.  
  296. void Server::send_event(int event_id)
  297. {
  298.     unsigned char message[MESSAGE_FROM_SERVER_MAX_SIZE];
  299.     std::string game_id_str = make_message_from_n_byte(this->game->game_id, 4);
  300.     int cur_ptr, client_id;
  301.     for (client_id = 0; client_id < this->clients.size(); ++client_id) {
  302.         for (cur_ptr = 0; cur_ptr < 4; ++cur_ptr)
  303.             message[cur_ptr] = game_id_str[cur_ptr];
  304.         std::string event_str = this->events[event_id].to_string(event_id);
  305.         for (int j = 0; j < event_str.size(); ++j)
  306.             message[cur_ptr++] = event_str[j];
  307.         std::cout<<"Wysylam event o len = "<<cur_ptr<<"\n";
  308.         this->send_datagram_to_client(&this->clients[client_id].client_address, message, cur_ptr);
  309.     }
  310. }
  311.  
  312. void Server::process_client(int ind)
  313. {
  314.     this->clients[ind].direction += this->clients[ind].direction * this->clients[ind].turn_direction;
  315.     this->clients[ind].direction = ((this->clients[ind].direction%360) + 360)%360;
  316.     int last_x = (int)this->clients[ind].head_x;
  317.     int last_y = (int)this->clients[ind].head_y;
  318.     this->clients[ind].head_x += sin((-1)*this->clients[ind].head_x/(2*PI));
  319.     this->clients[ind].head_y += cos((-1)*this->clients[ind].head_y/(2*PI));
  320.     int new_x = (int)this->clients[ind].head_x;
  321.     int new_y = (int)this->clients[ind].head_y;
  322.    
  323.     if (new_x == last_x && new_y == last_y)
  324.         return;
  325.     if (check_collision(new_x, new_y)) {
  326.         this->clients[ind].alive = false;
  327.         Event event(2);
  328.         event.create_event_player_eliminated(client_index_from_alives(ind));
  329.         this->events.push_back(event);
  330.         send_event(this->events.size()-1);
  331.         return;
  332.     }
  333.    
  334.     this->game->occupied_pixels.insert(std::make_pair(new_x, new_y));
  335.     Event event(1);
  336.     event.create_event_pixel(client_index_from_alives(ind), new_x, new_y);
  337.     this->events.push_back(event);
  338.     send_event(this->events.size()-1);
  339. }
  340.  
  341. void Server::process_clients()
  342. {
  343.     this->last_time = this->get_time();
  344.     for (size_t i = 0; i < this->clients.size(); ++i)
  345.         if (this->clients[i].alive)
  346.             process_client(i);
  347. }
  348.  
  349. void Server::send_events_to_client(int ind)
  350. {
  351.     int from = this->clients[ind].next_expected_event_no;
  352.     int to = this->events.size();
  353.     for (int i = from; i < to; ++i) {
  354.         unsigned char message[MESSAGE_FROM_SERVER_MAX_SIZE];
  355.         std::string game_id_str = make_message_from_n_byte(this->game->game_id, 4);
  356.         int cur_ptr;
  357.         for (cur_ptr = 0; cur_ptr < 4; ++cur_ptr)
  358.             message[cur_ptr] = game_id_str[cur_ptr];
  359.         while (i < to && cur_ptr + this->events[i].to_string(i).size() < MESSAGE_FROM_SERVER_MAX_SIZE) {
  360.             std::string event_str = this->events[i].to_string(i);
  361.             for (int j = 0; j < event_str.size(); ++j)
  362.                 message[cur_ptr++] = event_str[j];
  363.             ++i;
  364.         }
  365.         --i;
  366.         std::cout<<"Wysylam do "<<ind<<" wiadomosc:\n";
  367.         for (int j = 0; j < cur_ptr; ++j)
  368.             std::cout<<message[j];
  369.         std::cout<<"\n";
  370.         this->send_datagram_to_client(&this->clients[ind].client_address, message, cur_ptr);
  371.         std::cout<<"poszlo\n";
  372.     }
  373. }
  374.  
  375. void Server::add_client(Client client)
  376. {
  377.     this->clients.push_back(client);
  378.     sort(this->clients.begin(), this->clients.end(), cmp);
  379. }
  380.  
  381. uint64_t Server::get_time()
  382. {
  383.     struct timeval tp;
  384.     gettimeofday(&tp, NULL);
  385.     return (uint64_t)tp.tv_sec*1000 + tp.tv_usec/1000;
  386. }
  387.  
  388. int Server::find_index_of_client(struct sockaddr_in client_address, uint64_t session_id)
  389. {
  390.     for (size_t i = 0; i < (this->clients.size()); ++i) {
  391.         Client client = this->clients[i];
  392.         if (client.session_id == session_id && memcmp(&client.client_address, &client_address, sizeof(client_address)) == 0)
  393.             return i;
  394.     }
  395.     return -1;
  396. }
  397.  
  398. bool Server::can_start_new_game()
  399. {
  400.     size_t ready_clients = 0;
  401.     static bool flag = false;
  402.     for (size_t i = 0; i < this->clients.size(); ++i) {
  403.         if (!flag && this->clients.size() >= 2)
  404.             std::cout<<"name: "<<this->clients[i].client_name<<", direct = "<<(int)this->clients[i].turn_direction<<"\n";
  405.         if (this->clients[i].client_name.size() > 0 && this->clients[i].turn_direction == 0)
  406.             return false;
  407.         else if (this->clients[i].client_name.size() > 0)
  408.             ++ready_clients;
  409.     }
  410.     if (this->clients.size() >= 2)
  411.         flag = true;
  412.     return ready_clients >= 2;
  413. }
  414.  
  415. void Server::start_new_game()
  416. {
  417.     std::vector<std::string> players_name;
  418.  
  419.     this->game_is_active = true;
  420.     this->game = new Game(this);
  421.    
  422.     for (size_t i = 0; i < this->clients.size(); ++i)
  423.         if (this->clients[i].client_name.size() > 0) {
  424.             this->clients[i].alive = true;
  425.             players_name.push_back(this->clients[i].client_name);
  426.         }
  427.  
  428.     Event event(0);
  429.     event.create_event_new_game(this->map_width, this->map_height, players_name);
  430.     this->events.push_back(event);
  431.     send_event(this->events.size()-1);
  432. }
  433.  
  434. bool Server::time_to_next_round_elapsed()
  435. {
  436.     return this->game_is_active && ((this->get_time() - this->last_time) > this->time_period);
  437. }
  438.  
  439. void Server::close_socket()
  440. {
  441.     if (close(this->sock) == -1)
  442.         syserr("close");
  443. }
  444.  
  445. void Server::game_over()
  446. {
  447.     delete this->game;
  448.     this->game_is_active = false;
  449.     Event event(3);
  450.     this->events.push_back(event);
  451.     send_event(this->events.size()-1);
  452. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement