initial commit
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
build/
|
||||||
|
.vs/
|
||||||
|
.vscode/
|
||||||
41
CMakeLists.txt
Normal file
41
CMakeLists.txt
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.0)
|
||||||
|
project(DarkRP2D_DEDICATED_SERVER)
|
||||||
|
set (CMAKE_CXX_STANDARD 11)
|
||||||
|
include(ExternalProject)
|
||||||
|
|
||||||
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
|
set(CMAKE_BUILD_TYPE RELEASE)
|
||||||
|
add_definitions(-DNDEBUG)
|
||||||
|
endif(NOT CMAKE_BUILD_TYPE)
|
||||||
|
|
||||||
|
MESSAGE( STATUS "PROJECT_SOURCE_DIR: " ${PROJECT_SOURCE_DIR} )
|
||||||
|
MESSAGE( STATUS "DarkRP2D_DEDICATED_SERVER_SOURCE_DIR: " ${DarkRP2D_DEDICATED_SERVER_SOURCE_DIR} )
|
||||||
|
|
||||||
|
set(DarkRP2D_EXTERNAL_DIR ${DarkRP2D_DEDICATED_SERVER_SOURCE_DIR}/../external)
|
||||||
|
set(SDL2_net_DIR ${DarkRP2D_EXTERNAL_DIR}/SDL2_net-2.0.1)
|
||||||
|
set(SDL2_DIR ${DarkRP2D_EXTERNAL_DIR}/SDL2-2.0.8)
|
||||||
|
|
||||||
|
#Libs
|
||||||
|
|
||||||
|
find_package(SDL2 REQUIRED CONFIG)
|
||||||
|
include_directories(${SDL2_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
find_package(SDL2_net REQUIRED CONFIG)
|
||||||
|
include_directories(${SDL2_NET_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
MESSAGE( STATUS "SDL2 Lib: " ${SDL2_LIBRARIES} )
|
||||||
|
MESSAGE( STATUS "SDL2_NET Lib: " ${SDL2_NET_LIBRARIES} )
|
||||||
|
|
||||||
|
file(GLOB_RECURSE DarkRP2D_DEDICATED_SERVER_SOURCE_FILES ${DarkRP2D_DEDICATED_SERVER_SOURCE_DIR}/src/*.cpp)
|
||||||
|
|
||||||
|
add_executable(DarkRP2DDServer ${DarkRP2D_DEDICATED_SERVER_SOURCE_FILES})
|
||||||
|
|
||||||
|
target_link_libraries(DarkRP2DDServer ${SDL2_LIBRARIES}
|
||||||
|
${SDL2_NET_LIBRARIES} )
|
||||||
|
|
||||||
|
add_custom_target(CopyBinaries
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${SDL2_DLL} ${CMAKE_BINARY_DIR}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${SDL2_NET_DLL} ${CMAKE_BINARY_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
add_dependencies(DarkRP2DDServer CopyBinaries)
|
||||||
9
src/Constants.h
Normal file
9
src/Constants.h
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace constants {
|
||||||
|
|
||||||
|
const int CLIENT_PORT = 9999;
|
||||||
|
const int MAX_CLIENTS = 128;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
85
src/DarkRP2DDedicatedServer.cpp
Normal file
85
src/DarkRP2DDedicatedServer.cpp
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <SDL_net.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
TCPsocket sd, csd; /* Socket descriptor, Client socket descriptor */
|
||||||
|
IPaddress ip, *remoteIP;
|
||||||
|
int quit, quit2;
|
||||||
|
char buffer[512];
|
||||||
|
|
||||||
|
std::cout << "Starting DarkRP2D Server..." << std::endl;
|
||||||
|
|
||||||
|
if (SDLNet_Init() < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "SDLNet_Init: %s\n", SDLNet_GetError());
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Resolving the host using NULL make network interface to listen */
|
||||||
|
if (SDLNet_ResolveHost(&ip, NULL, 9999) < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "SDLNet_ResolveHost: %s\n", SDLNet_GetError());
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open a connection with the IP provided (listen on the host's port) */
|
||||||
|
if (!(sd = SDLNet_TCP_Open(&ip)))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "SDLNet_TCP_Open: %s\n", SDLNet_GetError());
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "DarkRP2D Server started." << std::endl;
|
||||||
|
std::cout << "Waiting for a Connection!" << std::endl;
|
||||||
|
|
||||||
|
/* Wait for a connection, send data and term */ quit = 0;
|
||||||
|
while (!quit)
|
||||||
|
{ /* This check the sd if there is a pending connection. * If there is one, accept that, and open a new socket for communicating */
|
||||||
|
if ((csd = SDLNet_TCP_Accept(sd)))
|
||||||
|
{ /* Now we can communicate with the client using csd socket * sd will remain opened waiting other connections */
|
||||||
|
|
||||||
|
/* Get the remote address */
|
||||||
|
if ((remoteIP = SDLNet_TCP_GetPeerAddress(csd))) /* Print the address, converting in the host format */
|
||||||
|
printf("Host connected: %x %d\n", SDLNet_Read32(&remoteIP->host), SDLNet_Read16(&remoteIP->port));
|
||||||
|
else
|
||||||
|
fprintf(stderr, "SDLNet_TCP_GetPeerAddress: %s\n", SDLNet_GetError());
|
||||||
|
|
||||||
|
quit2 = 0;
|
||||||
|
while (!quit2)
|
||||||
|
{
|
||||||
|
if (SDLNet_TCP_Recv(csd, buffer, 512) > 0)
|
||||||
|
{
|
||||||
|
printf("Client say: %s\n", buffer);
|
||||||
|
|
||||||
|
if (strcmp(buffer, "exit") == 0) /* Terminate this connection */
|
||||||
|
{
|
||||||
|
quit2 = 1;
|
||||||
|
printf("Terminate connection\n");
|
||||||
|
}
|
||||||
|
if (strcmp(buffer, "quit") == 0) /* Quit the program */
|
||||||
|
{
|
||||||
|
quit2 = 1;
|
||||||
|
quit = 1;
|
||||||
|
printf("Quit program\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the client socket */ SDLNet_TCP_Close(csd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << "Server is closing..." << std::endl;
|
||||||
|
SDLNet_TCP_Close(sd);
|
||||||
|
SDLNet_Quit();
|
||||||
|
std::cout << "Server closed!" << std::endl;
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
22
src/Protocoll.h
Normal file
22
src/Protocoll.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define CONNECTION_REQUEST 0x01
|
||||||
|
#define CONNECTION_ACCEPTED 0x02
|
||||||
|
#define CONNECTION_DENIED 0x03
|
||||||
|
|
||||||
|
struct ConnectionRequest {
|
||||||
|
ConnectionRequest() : type(CONNECTION_REQUEST) {}
|
||||||
|
char type = CONNECTION_REQUEST;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ConnectionAccepted {
|
||||||
|
ConnectionAccepted() : type(CONNECTION_ACCEPTED) {}
|
||||||
|
char type;
|
||||||
|
int index;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ConnectionDenied {
|
||||||
|
ConnectionDenied() : type(CONNECTION_DENIED) {}
|
||||||
|
char type;
|
||||||
|
};
|
||||||
|
|
||||||
164
src/Server.cpp
Normal file
164
src/Server.cpp
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
#include "Server.h"
|
||||||
|
#include "Protocoll.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
Server::Server(int port) : m_maxClients(constants::MAX_CLIENTS), m_clientConnected{0}
|
||||||
|
{
|
||||||
|
udpSocket = SDLNet_UDP_Open(port);
|
||||||
|
|
||||||
|
if (udpSocket == nullptr)
|
||||||
|
{
|
||||||
|
std::cout << "\tSDLNet_UDP_Open failed : " << SDLNet_GetError() << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << "Server was started and is listening on port: " << port << std::endl;
|
||||||
|
|
||||||
|
//Creating ConnectionAccepted packet!
|
||||||
|
// Allocate udp packet with 512 byte size
|
||||||
|
connectionAccepted = SDLNet_AllocPacket(512);
|
||||||
|
|
||||||
|
if (connectionAccepted == nullptr)
|
||||||
|
{
|
||||||
|
std::cout << "\tSDLNet_AllocPacket failed : " << SDLNet_GetError() << std::endl;
|
||||||
|
}
|
||||||
|
ConnectionAccepted conAcc = ConnectionAccepted();
|
||||||
|
memcpy(connectionAccepted->data, &conAcc, sizeof(ConnectionAccepted));
|
||||||
|
connectionAccepted->len = sizeof(ConnectionAccepted);
|
||||||
|
|
||||||
|
connectionDenied = SDLNet_AllocPacket(512);
|
||||||
|
|
||||||
|
if (connectionDenied == nullptr)
|
||||||
|
{
|
||||||
|
std::cout << "\tSDLNet_AllocPacket failed : " << SDLNet_GetError() << std::endl;
|
||||||
|
}
|
||||||
|
ConnectionDenied conDen = ConnectionDenied();
|
||||||
|
memcpy(connectionDenied->data, &conDen, sizeof(ConnectionDenied));
|
||||||
|
connectionDenied->len = sizeof(ConnectionDenied);
|
||||||
|
|
||||||
|
//Creating receiver packet!
|
||||||
|
receivedPacket = SDLNet_AllocPacket(512);
|
||||||
|
|
||||||
|
if (receivedPacket == nullptr)
|
||||||
|
{
|
||||||
|
std::cout << "\tSDLNet_AllocPacket failed : " << SDLNet_GetError() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Server::FindFreeClientIndex() const
|
||||||
|
{
|
||||||
|
for (int i = 0; i < m_maxClients; ++i)
|
||||||
|
{
|
||||||
|
if (!m_clientConnected[i])
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Server::FindExistingClientIndex(const IPaddress &ip) const
|
||||||
|
{
|
||||||
|
for (int i = 0; i < m_maxClients; ++i)
|
||||||
|
{
|
||||||
|
if (m_clientConnected[i] && m_clients[i].host == ip.host && m_clients[i].port == ip.port)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Server::IsClientConnected(int clientIndex) const
|
||||||
|
{
|
||||||
|
return m_clientConnected[clientIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
const IPaddress &Server::GetClientAddress(int clientIndex) const
|
||||||
|
{
|
||||||
|
return m_clients[clientIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::update(unsigned int delta)
|
||||||
|
{
|
||||||
|
//Receive packages
|
||||||
|
if (SDLNet_UDP_Recv(udpSocket, receivedPacket))
|
||||||
|
{
|
||||||
|
switch (*(receivedPacket->data))
|
||||||
|
{
|
||||||
|
case CONNECTION_REQUEST:
|
||||||
|
std::cout << "Connection request package received\n";
|
||||||
|
int freeIndex;
|
||||||
|
if ((freeIndex = this->FindFreeClientIndex()) == -1)
|
||||||
|
{
|
||||||
|
std::cout << "Connection denied because server full" << std::endl;
|
||||||
|
//Send Connection denied
|
||||||
|
this->sendConnectionDenied(receivedPacket->address);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
std::cout << "Free index found: " << freeIndex << std::endl;
|
||||||
|
int indexOfExistingClient;
|
||||||
|
if ((indexOfExistingClient = FindExistingClientIndex(receivedPacket->address)) == -1)
|
||||||
|
{
|
||||||
|
std::cout << "Client doesent exist create new" << std::endl;
|
||||||
|
m_clients[freeIndex] = receivedPacket->address;
|
||||||
|
m_clientConnected[freeIndex] = true;
|
||||||
|
//Send connection accepted with index
|
||||||
|
this->sendConnectionAccepted(receivedPacket->address, freeIndex);
|
||||||
|
m_numConnectedClients++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Client exist sending accepted" << std::endl;
|
||||||
|
//Send connection accepted with index
|
||||||
|
this->sendConnectionAccepted(receivedPacket->address, indexOfExistingClient);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Wait 10 sec
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
std::this_thread::sleep_for(1s);
|
||||||
|
|
||||||
|
//Send data
|
||||||
|
/*for(auto &value: clients) {
|
||||||
|
value.send(this->udpSocket,*helloWorldPacket);
|
||||||
|
}
|
||||||
|
std::cout << "Data was send!!" << std::endl;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Server::sendPacket(UDPpacket &packet)
|
||||||
|
{
|
||||||
|
// Send
|
||||||
|
// SDLNet_UDP_Send returns number of packets sent. 0 means error
|
||||||
|
if (SDLNet_UDP_Send(this->udpSocket, -1, &packet) == 0)
|
||||||
|
{
|
||||||
|
std::cout << "\tSDLNet_UDP_Send failed : " << SDLNet_GetError() << "\n"
|
||||||
|
<< "==========================================================================================================\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Server::sendConnectionDenied(IPaddress dest)
|
||||||
|
{
|
||||||
|
this->connectionDenied->address.host = dest.host;
|
||||||
|
this->connectionDenied->address.port = dest.port;
|
||||||
|
return this->sendPacket(*connectionDenied);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Server::sendConnectionAccepted(IPaddress dest, int index)
|
||||||
|
{
|
||||||
|
this->connectionAccepted->address.host = dest.host;
|
||||||
|
this->connectionAccepted->address.port = dest.port;
|
||||||
|
((ConnectionAccepted *) connectionAccepted->data)->index = index;
|
||||||
|
return this->sendPacket(*connectionAccepted);
|
||||||
|
}
|
||||||
|
|
||||||
|
Server::~Server()
|
||||||
|
{
|
||||||
|
SDLNet_FreePacket(receivedPacket);
|
||||||
|
SDLNet_FreePacket(connectionAccepted);
|
||||||
|
SDLNet_UDP_Close(udpSocket);
|
||||||
|
}
|
||||||
36
src/Server.h
Normal file
36
src/Server.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <SDL_net.h>
|
||||||
|
#include "Constants.h"
|
||||||
|
|
||||||
|
class Server {
|
||||||
|
public:
|
||||||
|
Server(int port);
|
||||||
|
~Server();
|
||||||
|
|
||||||
|
int FindFreeClientIndex() const;
|
||||||
|
int FindExistingClientIndex( const IPaddress &ip ) const;
|
||||||
|
bool IsClientConnected( int clientIndex ) const;
|
||||||
|
const IPaddress & GetClientAddress( int clientIndex ) const;
|
||||||
|
|
||||||
|
void update(unsigned int delta);
|
||||||
|
|
||||||
|
void gameTick();
|
||||||
|
|
||||||
|
private:
|
||||||
|
UDPsocket udpSocket;
|
||||||
|
|
||||||
|
UDPpacket *connectionDenied;
|
||||||
|
UDPpacket *connectionAccepted;
|
||||||
|
UDPpacket *receivedPacket;
|
||||||
|
|
||||||
|
int m_maxClients;
|
||||||
|
int m_numConnectedClients;
|
||||||
|
bool m_clientConnected[constants::MAX_CLIENTS];
|
||||||
|
IPaddress m_clients[constants::MAX_CLIENTS];
|
||||||
|
|
||||||
|
bool sendPacket(UDPpacket &packet);
|
||||||
|
|
||||||
|
bool sendConnectionDenied(IPaddress dest);
|
||||||
|
bool sendConnectionAccepted(IPaddress dest, int index);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user