2019-01-09 20:44:58 +01:00
|
|
|
/*
|
|
|
|
* =====================================================================================
|
|
|
|
*
|
|
|
|
* Filename: Server.cpp
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
*
|
|
|
|
* Created: 23/01/2018 14:48:07
|
|
|
|
*
|
|
|
|
* Author: Quentin Bazin, <quent42340@gmail.com>
|
|
|
|
*
|
|
|
|
* =====================================================================================
|
|
|
|
*/
|
|
|
|
#include "Server.hpp"
|
|
|
|
|
2019-01-11 23:54:33 +01:00
|
|
|
void Server::init(u16 port) {
|
|
|
|
if (m_udpSocket.bind(port) != sf::Socket::Done)
|
2019-01-09 20:44:58 +01:00
|
|
|
throw EXCEPTION("Network error: Bind failed");
|
|
|
|
|
|
|
|
m_udpSocket.setBlocking(false);
|
|
|
|
|
2019-01-11 23:54:33 +01:00
|
|
|
if (m_tcpListener.listen(port) != sf::Socket::Done)
|
2019-01-09 20:44:58 +01:00
|
|
|
throw EXCEPTION("Network error: Listen failed");
|
|
|
|
|
|
|
|
m_tcpListener.setBlocking(false);
|
|
|
|
|
|
|
|
m_selector.add(m_tcpListener);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Server::handleKeyState() {
|
|
|
|
sf::Packet packet;
|
|
|
|
sf::IpAddress senderAddress;
|
|
|
|
u16 senderPort;
|
|
|
|
while (m_udpSocket.receive(packet, senderAddress, senderPort) == sf::Socket::Status::Done) {
|
|
|
|
Network::Command command;
|
|
|
|
u32 timestamp;
|
|
|
|
u16 clientId;
|
|
|
|
packet >> command >> timestamp >> clientId;
|
|
|
|
|
2019-01-09 21:15:46 +01:00
|
|
|
// std::cout << "UDP Message of type '" << Network::commandToString(command) << "' received from: " << senderAddress << ":" << senderPort << std::endl;
|
2019-01-09 20:44:58 +01:00
|
|
|
|
|
|
|
if (command == Network::Command::KeyState) {
|
|
|
|
Client *client = m_info.getClient(clientId);
|
|
|
|
if (client && client->previousKeyTimestamp < timestamp) {
|
|
|
|
client->previousKeyTimestamp = timestamp;
|
|
|
|
|
|
|
|
while (!packet.endOfPacket()) {
|
|
|
|
u8 key;
|
|
|
|
bool isPressed;
|
|
|
|
packet >> key >> isPressed;
|
|
|
|
|
2019-01-09 21:15:46 +01:00
|
|
|
if (client->inputHandler.keysPressed().at(key) != isPressed)
|
|
|
|
DEBUG((int)key, "changed state to", isPressed ? "true" : "false");
|
|
|
|
|
2019-01-09 20:44:58 +01:00
|
|
|
client->inputHandler.setKeyPressed(key, isPressed);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Server::handleGameEvents() {
|
|
|
|
if (m_selector.wait(sf::milliseconds(10))) {
|
|
|
|
if (m_selector.isReady(m_tcpListener)) {
|
|
|
|
handleNewConnections();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
handleClientMessages();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Server::handleNewConnections() {
|
|
|
|
std::shared_ptr<sf::TcpSocket> clientSocket = std::make_shared<sf::TcpSocket>();
|
|
|
|
if (m_tcpListener.accept(*clientSocket) == sf::Socket::Done) {
|
|
|
|
sf::Packet packet;
|
|
|
|
clientSocket->receive(packet);
|
|
|
|
|
|
|
|
Network::Command command;
|
|
|
|
packet >> command;
|
|
|
|
if (command != Network::Command::ClientConnect)
|
|
|
|
throw EXCEPTION("Network error: Expected 'ClientConnect' packet.");
|
|
|
|
|
2019-01-17 01:28:24 +01:00
|
|
|
if (m_info.clients().size() < 5) {
|
2019-01-09 20:44:58 +01:00
|
|
|
std::string address;
|
|
|
|
u16 port;
|
|
|
|
packet >> address >> port;
|
|
|
|
|
|
|
|
Client &client = m_info.addClient(address, port, clientSocket);
|
|
|
|
m_selector.add(*client.tcpSocket);
|
|
|
|
|
|
|
|
sf::Packet outPacket;
|
|
|
|
outPacket << Network::Command::ClientOk << client.id;
|
|
|
|
client.tcpSocket->send(outPacket);
|
2019-01-12 18:53:25 +01:00
|
|
|
// client.tcpSocket->setBlocking(false);
|
2019-01-12 13:52:30 +01:00
|
|
|
|
|
|
|
if (m_connectionCallback)
|
|
|
|
m_connectionCallback(client);
|
2019-01-09 20:44:58 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
sf::Packet outPacket;
|
|
|
|
outPacket << Network::Command::ClientRefused;
|
|
|
|
clientSocket->send(outPacket);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2019-01-16 22:24:57 +01:00
|
|
|
std::cerr << "Warning: Connection accept failed." << std::endl;
|
2019-01-09 20:44:58 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Server::handleClientMessages() {
|
|
|
|
for (size_t i = 0 ; i < m_info.clients().size() ; ++i) {
|
|
|
|
Client &client = m_info.clients()[i];
|
|
|
|
if (m_selector.isReady(*client.tcpSocket)) {
|
|
|
|
sf::Packet packet;
|
|
|
|
if (client.tcpSocket->receive(packet) == sf::Socket::Done) {
|
|
|
|
Network::Command command;
|
|
|
|
packet >> command;
|
|
|
|
|
2019-01-16 22:24:57 +01:00
|
|
|
// DEBUG("TCP message received:", Network::commandToString(command));
|
|
|
|
|
2019-01-09 20:44:58 +01:00
|
|
|
if (command == Network::Command::ClientDisconnect) {
|
|
|
|
m_selector.remove(*client.tcpSocket);
|
|
|
|
m_info.removeClient(client.id);
|
|
|
|
|
|
|
|
if (m_info.clients().size() == 0) {
|
|
|
|
// m_tcpListener.close();
|
|
|
|
m_isRunning = false;
|
|
|
|
}
|
2019-01-18 01:59:26 +01:00
|
|
|
|
|
|
|
--i;
|
2019-01-09 20:44:58 +01:00
|
|
|
}
|
2019-01-16 22:24:57 +01:00
|
|
|
|
|
|
|
if (m_isRunning)
|
|
|
|
for (auto &it : m_commands)
|
|
|
|
if (command == it.first)
|
2019-01-18 01:59:26 +01:00
|
|
|
it.second(client, packet);
|
2019-01-09 20:44:58 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-16 22:24:57 +01:00
|
|
|
void Server::sendToAllClients(sf::Packet &packet) {
|
|
|
|
for (Client &client : m_info.clients()) {
|
|
|
|
client.tcpSocket->send(packet);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|