2019-01-09 20:44:58 +01:00
|
|
|
/*
|
|
|
|
* =====================================================================================
|
|
|
|
*
|
2020-02-08 18:34:26 +09:00
|
|
|
* OpenMiner
|
|
|
|
* Copyright (C) 2018-2020 Unarelith, Quentin Bazin <openminer@unarelith.net>
|
2019-01-09 20:44:58 +01:00
|
|
|
*
|
2020-02-08 18:34:26 +09:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
2019-01-09 20:44:58 +01:00
|
|
|
*
|
2020-02-08 18:34:26 +09:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
2019-01-09 20:44:58 +01:00
|
|
|
*
|
2020-02-08 18:34:26 +09:00
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
2019-01-09 20:44:58 +01:00
|
|
|
*
|
|
|
|
* =====================================================================================
|
|
|
|
*/
|
|
|
|
#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);
|
|
|
|
|
2020-01-25 16:38:45 +09:00
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|