/* called once per select() loop */ void periodicHandler() { vector<int> clientIDs = server.getClientIDs(); static time_t next = time(NULL)+1; time_t current = time(NULL); messageDelay(); if (gameStarted) { if (current >= next) { snakeState.UpdateBoardState(); ostringstream ss; ostringstream score1; ostringstream score2; ss << "GB:" << snakeState.GetBoardState(); score1 << "1:" << player1 + " score: " << snakeState.GetPlayerScore(0); score2 << "2:" << player2 + " score: " << snakeState.GetPlayerScore(1); for (int i = 0; i < clientIDs.size(); i++){ server.wsSend(clientIDs[i], ss.str()); server.wsSend(clientIDs[i], score1.str()); server.wsSend(clientIDs[i], score2.str()); } next = time(NULL) + 1; } } }
/* called when a client connects */ void openHandler(int clientID) { vector<int> clientIDs = server.getClientIDs(); server.wsSend(clientID, "Welcome!"); ostringstream game_width; ostringstream game_height; ostringstream game_board; game_width << "GW:" << snakeState.GetBoardWidth(); game_height << "GH:" << snakeState.GetBoardHeight(); game_board << "GB:" << snakeState.GetBoardState(); server.wsSend(clientID, game_width.str()); server.wsSend(clientID, game_height.str()); server.wsSend(clientID, game_board.str()); if (clientIDs.size() == 2) { gameStarted = true; snakeState.StartNewGame(); return; } else if (clientIDs.size() > 2) server.wsClose(clientID); else gameStarted = false; }
/* called when a client connects */ void openHandler(int clientID){ ostringstream os; os << "Stranger " << clientID << " has joined."; vector<int> clientIDs = server.getClientIDs(); for (int i = 0; i < clientIDs.size(); i++){ if (clientIDs[i] != clientID) server.wsSend(clientIDs[i], os.str()); } server.wsSend(clientID, "Welcome!"); }
void ProcessMessages() { time_t t1 = time(NULL); int index = 0; if (message_to_process[0].find("AVGL") != std::string::npos) { index = message_to_process[0].find("AVGL"); } else { if (message_to_process[0].find("COMMAND") != std::string::npos) { index = message_to_process[0].find("COMMAND"); InterpretCommand(0, message_to_process[0].substr(index)); } else if (message_to_process[0].find("NewPlayer") != std::string::npos) { index = message_to_process[0].find("NewPlayer"); InterpretCommand(0, message_to_process[0].substr(index)); } time_t t2 = time(NULL); stringstream ss; ss << "t0:" << message_to_process[0].substr(4, message_to_process[0].length() - (message_to_process[0].length() - index + 5)) << ";t1:" << time_received[0] << ";t2:" << t2; server.wsSend(0, ss.str()); delay_time1 = time(NULL) + (rand() % 2); } index = 0; if (message_to_process[1].find("AVGL") != std::string::npos) { index = message_to_process[1].find("AVGL"); int delay = convertToInt(message_to_process[1].substr(index + 5)); } else { if (message_to_process[1].find("COMMAND") != std::string::npos) { index = message_to_process[1].find("COMMAND"); InterpretCommand(1, message_to_process[1].substr(index)); } else if (message_to_process[1].find("NewPlayer") != std::string::npos) { index = message_to_process[1].find("NewPlayer"); InterpretCommand(1, message_to_process[1].substr(index)); } time_t t2 = time(NULL); stringstream ss; ss << "t0:" << message_to_process[1].substr(4, message_to_process[1].length() - (message_to_process[1].length() - index + 5)) << ";t1:" << time_received[1] << ";t2:" << t2; server.wsSend(1, ss.str()); delay_time2 = time(NULL) + (rand() % 2); } }
/* called when a client connects */ void openHandler(int clientID){ score1 = 0; score2 = 0; server.wsSend(clientID, "Welcome!"); }
void messageDelay() { time_t t1 = time(NULL); if (message_queue.size() > 0 && t1 >= delay_time) { std::string message = message_queue.front(); int clientID = message[0] - '0'; int index = 0; if (message.find("COMMAND") != std::string::npos) { index = message.find("COMMAND"); InterpretCommand(clientID, message.substr(index)); } else if (message.find("NewPlayer") != std::string::npos){ index = message.find("NewPlayer"); InterpretCommand(clientID, message.substr(index)); } time_t t2 = time(NULL); stringstream ss; ss << "t0:" << message.substr(4, message.length() - (message.length() - index + 2)) << ";t1:" << t1 << ";t2:" << t2; server.wsSend(clientID, ss.str()); delay_time = time(NULL) + (rand() % 10); message_queue.pop(); } }
/* called when a client disconnects */ void closeHandler(int clientID){ ostringstream os; os << "Stranger " << clientID << " has leaved."; vector<int> clientIDs = server.getClientIDs(); for (int i = 0; i < clientIDs.size(); i++){ if (clientIDs[i] != clientID) server.wsSend(clientIDs[i], os.str()); } }
/* called when a client sends a message to the server */ void messageHandler(int clientID, string message){ ostringstream os; os << "Stranger " << clientID << " says: " << message; vector<int> clientIDs = server.getClientIDs(); for (int i = 0; i < clientIDs.size(); i++){ if (clientIDs[i] != clientID) server.wsSend(clientIDs[i], os.str()); } }
/* called when a client sends a message to the server */ void messageHandler(int clientID, string message){ bool scored = false; bool named = false; ostringstream os; ostringstream os2; if (message.find("Player1:")==0) { if(message.length()>8) player1 = message.substr(8); named = true; } if (message.find("Player2:")==0) { if (message.length()>8) player2 = message.substr(8); named = true; } if(!named){ if (message == "1: addScore") { score1++; scored = true; } else if (message == "2: addScore") { score2++; scored = true; } if(scored){ os << ("1:" + player1 + " Score: ")<<score1; os2 << ("2:" + player2 + " Score: " )<< score2; } vector<int> clientIDs = server.getClientIDs(); for (int i = 0; i < clientIDs.size(); i++) { server.wsSend(clientIDs[i], os.str()); server.wsSend(clientIDs[i], os2.str()); } } }
/* called when a client disconnects */ void closeHandler(int clientID){ ostringstream os; os << "Stranger " << clientID << " has leaved."; vector<int> clientIDs = server.getClientIDs(); for (int i = 0; i < clientIDs.size(); i++){ server.wsSend(clientIDs[i], "Disconnected"); server.wsClose(clientIDs[i]); } ReceiveQueue.clear(); SendQueue.clear(); }
/* called once per select() loop */ void periodicHandler(){ if (clientSnakes.size() == 2){ std::chrono::steady_clock::time_point other = std::chrono::steady_clock::now(); if (!ReceiveQueue.empty()){ //use iterators so that we can edit queue during iteration. for (auto msg = ReceiveQueue.begin(); msg != ReceiveQueue.end();){ for (auto vect = msg->second.begin(); vect != msg->second.end();){ if (std::chrono::duration_cast<std::chrono::milliseconds>(other - msg->first).count() > vect->latencyVal){ messageHandler(vect->clientID, vect->message); //removes message from queue vect = msg->second.erase(vect); } else{ ++vect; } } if (msg->second.empty()){ msg = ReceiveQueue.erase(msg); } else{ ++msg; } } } std::chrono::steady_clock::time_point other1 = std::chrono::steady_clock::now(); if (!SendQueue.empty()){ for (auto key = SendQueue.begin(); key != SendQueue.end();){ for (auto vec = key->second.begin(); vec != key->second.end();){ if (std::chrono::duration_cast<std::chrono::milliseconds>(other1 - key->first).count() > vec->latencyVal){ if (vec->message == "latency"){ vec->message = "latency;" + std::to_string(serverDelayStart); } server.wsSend(vec->clientID, vec->message); vec = key->second.erase(vec); } else{ ++vec; } } if (key->second.empty()){ key = SendQueue.erase(key); } else{ ++key; } } } } }
/* called once per select() loop */ void periodicHandler(){ static time_t next = time(NULL) + 10; time_t current = time(NULL); if (current >= next){ ostringstream os; string timestring = ctime(¤t); timestring = timestring.substr(0, timestring.size() - 1); os << timestring; vector<int> clientIDs = server.getClientIDs(); for (int i = 0; i < clientIDs.size(); i++) server.wsSend(clientIDs[i], os.str()); next = time(NULL) + 10; } }
/* called when a client disconnects */ void closeHandler(int clientID) { vector<int> clientIDs = server.getClientIDs(); if (clientIDs.size() <= 2) gameStarted = false; ostringstream os; std::string player_name; if (clientID == 0) player_name = player1; else player_name = player2; os << player_name << " has left."; for (int i = 0; i < clientIDs.size(); i++) { if (clientIDs[i] != clientID) server.wsSend(clientIDs[i], os.str()); } }
void closeHandler(int clientID){ // If game is ongoing, kill it and send out // an error to whomever is still connected: if (game_p != NULL && game_p->isActive()) { json errorMsg; errorMsg["MESSAGE_TYPE"] = "ERROR"; errorMsg["ERROR_MSG"] = "Other player disconnected"; // Send the message to whomever is connected vector<int> clientIDs = server.getClientIDs(); for (int i = 0; i < clientIDs.size(); i++) { server.wsSend(clientIDs[i], errorMsg.dump()); // Don't buffer } // Close all open connections (must be done separately) clientIDs = server.getClientIDs(); for (int i = 0; i < clientIDs.size(); i++) { server.wsClose(i); } resetGame(); } }
/* called when a client connects */ void openHandler(int clientID){ ostringstream os; vector<int> clientIDs = server.getClientIDs(); std::cout << "in openhandler " << clientIDs.size() << std::endl; if (clientIDs.size() > 3){ server.wsClose(clientID); cout << "Connection rejected: Only two connection allowed at a time."; } else if (clientIDs.size() == 2) { std::cout << "size is 2" << std::endl; os << "Stranger " << clientID << " has joined."; for (int i = 0; i < clientIDs.size(); i++){ clientSnakes[clientIDs[i]].ID = clientID; server.wsSend(clientIDs[i], "Welcome!"); //SendQueue[std::chrono::steady_clock::now()].push_back(createMessage(clientIDs[i], "Welcome!")); } gameStartState(); } }
/* called when a client connects */ void openHandler(int clientID) { vector<int> clientIDs = server.getClientIDs(); server.wsSend(clientID, "Welcome!"); ostringstream game_width; ostringstream game_height; ostringstream game_board; ostringstream ssMove; ostringstream playerID; game_width << "GW:" << snakeState.GetBoardWidth(); game_height << "GH:" << snakeState.GetBoardHeight(); game_board << "GB:" << snakeState.GetBoardState(); ssMove << "MOVE:" << snakeState.GetPlayerDirection(0) << snakeState.GetPlayerDirection(1); playerID << "ID:" << clientID; server.wsSend(clientID, playerID.str()); server.wsSend(clientID, game_width.str()); server.wsSend(clientID, game_height.str()); server.wsSend(clientID, game_board.str()); server.wsSend(clientID, ssMove.str()); if (clientIDs.size() == 2) { gameStarted = true; message_to_process[0] = ""; message_to_process[1] = ""; emptyQueue(); last_move[0] = 'D'; last_move[1] = 'A'; snakeState.StartNewGame(); return; } else if (clientIDs.size() > 2) server.wsClose(clientID); else gameStarted = false; }
/* called once per select() loop */ void periodicHandler() { vector<int> clientIDs = server.getClientIDs(); if (last_score1 != snakeState.GetPlayerScore(0) || last_score2 != snakeState.GetPlayerScore(1) || last_move[0] != snakeState.GetPlayerDirection(0) || last_move[1] != snakeState.GetPlayerDirection(1)) { if (last_score1 != snakeState.GetPlayerScore(0) || last_score2 != snakeState.GetPlayerScore(1)) { snakeState.SetPlayerInput(0, 'D'); snakeState.SetPlayerInput(1, 'A'); } emptyQueue(); message_to_process[0] = ""; message_to_process[1] = ""; last_score1 = snakeState.GetPlayerScore(0); last_score2 = snakeState.GetPlayerScore(1); last_move[0] = snakeState.GetPlayerDirection(0); last_move[1] = snakeState.GetPlayerDirection(1); snakeState.UpdateBoardState(); } messageDelay(); LARGE_INTEGER li; if (!QueryPerformanceFrequency(&li)) cout << "QueryPerformanceFrequency failed!\n"; static double freq = double(li.QuadPart) / 1000.0; QueryPerformanceCounter(&li); __int64 current = li.QuadPart; static __int64 interval = (double)500 * freq; // 500 ms static __int64 next = current + interval; if (gameStarted) { if (current >= next) { if (message_to_process[0] != "" && message_to_process[1] != "") { ProcessMessages(); message_to_process[0] = ""; message_to_process[1] = ""; ostringstream ss; ostringstream score1; ostringstream score2; ostringstream ssMove; ss << "GB:" << snakeState.GetBoardState(); score1 << "1:" << player1 + " score: " << snakeState.GetPlayerScore(0); score2 << "2:" << player2 + " score: " << snakeState.GetPlayerScore(1); ssMove << "MOVE:" << snakeState.GetPlayerDirection(0) << snakeState.GetPlayerDirection(1); for (int i = 0; i < clientIDs.size(); i++) { server.wsSend(clientIDs[i], ss.str()); server.wsSend(clientIDs[i], score1.str()); server.wsSend(clientIDs[i], score2.str()); server.wsSend(clientIDs[i], ssMove.str()); } snakeState.UpdateBoardState(); next = current + interval; } } } }
void periodicHandler(){ // Poll the incoming & outgoing message buffers. std::pair <int, std::string> message_pair; if (send_buffer.isMessageReady()) { message_pair = send_buffer.getMessage(); if (message_pair.first != -1) { json time_check = json::parse(message_pair.second); if (time_check["MESSAGE_TYPE"] == "TIME_STAMP_REPLY") { time_check["T3"] = chrono::system_clock::now().time_since_epoch() / chrono::milliseconds(1); message_pair.second = time_check.dump(); } server.wsSend(message_pair.first, message_pair.second); } } if (receive_buffer.isMessageReady()) { message_pair = receive_buffer.getMessage(); if (message_pair.first != -1) { read_message(message_pair.first, message_pair.second); } } // If the game is active, update the game state. // We want this to occur no sooner than UPDATE_CYCLE_LENGTH_MS. // WARNING: This sets the pace of the game, so Milestone 4 client features that // perform movement prediction MUST use the same clock speed. if (game_p != NULL && game_p->isActive()) { unsigned long long currentTime = chrono::system_clock::now().time_since_epoch() / chrono::milliseconds(1); if (currentTime - lastUpdateTime >= UPDATE_CYCLE_LENGTH_MS) { // Update the game json msg = game_p->update(); // Broadcast the update to all clients vector<int> clientIDs = server.getClientIDs(); for (int i = 0; i < clientIDs.size(); i++) { send_message(clientIDs[i], msg); } // Update the clock lastUpdateTime = chrono::system_clock::now().time_since_epoch() / chrono::milliseconds(1); } } // If there is a game object but the status is INACTIVE, // update the clients and then DESTROY the game object. if (game_p != NULL && !game_p->isActive()) { json msg = game_p->update(); resetGame(); // Broadcast the final update to all clients // and then disconnect clients cout << "GAME OVER BROADCASTING FINAL UPDATE" << endl; vector<int> clientIDs = server.getClientIDs(); for (int i = 0; i < clientIDs.size(); i++) { server.wsSend(clientIDs[i], msg.dump()); // Don't buffer } for (int i = 0; i < clientIDs.size(); i++) { server.wsClose(i); } } }