diff --git a/testClient/CMakeLists.txt b/testClient/CMakeLists.txt new file mode 100644 index 0000000..8bee1e2 --- /dev/null +++ b/testClient/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.0) +project(DarkRP2D_TEST_CLIENT) +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_TEST_CLIENT_SOURCE_DIR: " ${DarkRP2D_TEST_CLIENT_SOURCE_DIR} ) + +set(DarkRP2D_EXTERNAL_DIR ${DarkRP2D_TEST_CLIENT_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_TEST_CLIENT_SOURCE_FILES ${DarkRP2D_TEST_CLIENT_SOURCE_DIR}/src/*.cpp) + +add_executable(DarkRP2DTestClient ${DarkRP2D_TEST_CLIENT_SOURCE_FILES}) + +target_link_libraries(DarkRP2DTestClient ${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(DarkRP2DTestClient CopyBinaries) \ No newline at end of file diff --git a/testClient/src/Client.cpp b/testClient/src/Client.cpp new file mode 100644 index 0000000..79211ea --- /dev/null +++ b/testClient/src/Client.cpp @@ -0,0 +1,87 @@ +#include "Client.h" +#include "Constants.h" +#include "Protocoll.h" + +#include +#include + +Client::Client(std::string _serverIP, int port) : connected(new Connected(this)), + connecting(new Connecting(this)), + disconnected(new Disconnected(this)) +{ + + udpSocket = SDLNet_UDP_Open(constants::CLIENT_PORT); + + if (udpSocket == nullptr) + { + std::cout << "\tSDLNet_UDP_Open failed : " << SDLNet_GetError() << std::endl; + } + + // Set IP and port number with correct endianess + if (SDLNet_ResolveHost(&serverIP, _serverIP.c_str(), port) == -1) + { + std::cout << "\tSDLNet_ResolveHost failed : " << SDLNet_GetError() << std::endl; + } + + connectionRequest = SDLNet_AllocPacket(512); + + if (connectionRequest == nullptr) + { + std::cout << "\tSDLNet_AllocPacket failed : " << SDLNet_GetError() << std::endl; + } + ConnectionRequest conReq = ConnectionRequest(); + memcpy(connectionRequest->data, &conReq, sizeof(ConnectionRequest)); + connectionRequest->len = sizeof(ConnectionRequest); + + receivedPacket = SDLNet_AllocPacket(512); + + if (receivedPacket == nullptr) + { + std::cout << "\tSDLNet_AllocPacket failed : " << SDLNet_GetError() << std::endl; + } + + this->setClientState(connecting); +} + +void Client::setClientState(ClientState *state) +{ + std::cout << "State changed!" << std::endl; + currentState = state; +} + +void Client::update(unsigned int delta) +{ + currentState->update(delta); + using namespace std::chrono_literals; + std::this_thread::sleep_for(2s); +} + +bool Client::sendConnectionRequest(IPaddress dest) +{ + connectionRequest->address.host = dest.host; + connectionRequest->address.port = dest.port; + return this->sendPacket(*connectionRequest); +} + +bool Client::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; +} + +Client::~Client() +{ + delete connected; + delete connecting; + delete disconnected; + SDLNet_FreePacket(connectionRequest); + SDLNet_FreePacket(receivedPacket); + SDLNet_UDP_Close(udpSocket); +} \ No newline at end of file diff --git a/testClient/src/Client.h b/testClient/src/Client.h new file mode 100644 index 0000000..08351d1 --- /dev/null +++ b/testClient/src/Client.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include + +class Client; + +#include "ClientStates.h" + + +class Client { + public: + Client(std::string serverIP, int port); + ~Client(); + + Client(const Client&) = delete; + + void setClientState(ClientState *state); + + void update(unsigned int delta); + + + bool sendConnectionRequest(IPaddress dest); + bool sendPacket(UDPpacket &packet); + + UDPsocket udpSocket; + IPaddress serverIP; + + UDPpacket *connectionRequest; + UDPpacket *receivedPacket; + + ClientState *currentState; + + Connected *connected; + Connecting *connecting; + Disconnected *disconnected; +}; \ No newline at end of file diff --git a/testClient/src/ClientStates.cpp b/testClient/src/ClientStates.cpp new file mode 100644 index 0000000..1fdc541 --- /dev/null +++ b/testClient/src/ClientStates.cpp @@ -0,0 +1,40 @@ +#include "ClientStates.h" + +#include "Protocoll.h" + +#include + +void Connecting::update(unsigned int delta) +{ + std::cout << "Connecting.. (Sending Request)" << std::endl; + m_client->sendConnectionRequest(m_client->serverIP); + if (SDLNet_UDP_Recv(m_client->udpSocket, m_client->receivedPacket)) + { + std::cout << "Something received.." << std::endl; + switch (*(m_client->receivedPacket->data)) + { + case CONNECTION_ACCEPTED: + { + int index = ((ConnectionAccepted *)(m_client->receivedPacket->data))->index; + std::cout << "Server accepted Connection! My Index ist: " << index << std::endl; + m_client->setClientState(m_client->connected); + } + break; + case CONNECTION_DENIED: + std::cout << "Server denied Connection!" << std::endl; + m_client->setClientState(m_client->disconnected); + default: + break; + } + } +} + +void Connected::update(unsigned int delta) +{ + std::cout << "I AM IN CONNECTED STATE!" << std::endl; +} + +void Disconnected::update(unsigned int delta) +{ + std::cout << "I AM IN DISCONNECTED STATE!" << std::endl; +} \ No newline at end of file diff --git a/testClient/src/ClientStates.h b/testClient/src/ClientStates.h new file mode 100644 index 0000000..9a4bb9e --- /dev/null +++ b/testClient/src/ClientStates.h @@ -0,0 +1,47 @@ +#pragma once + +class ClientState; + +class Connecting; +class Connected; +class Disconnected; + +#include "Client.h" + +class ClientState +{ + public: + virtual void update(unsigned int delta) = 0; +}; + +class Connecting : public ClientState { + public: + Connecting(Client *client) : m_client(client) {} + + virtual void update(unsigned int delta) override; + + private: + Client *m_client; +}; + +class Connected : public ClientState +{ + public: + Connected(Client *client) : m_client(client) {} + + virtual void update(unsigned int delta) override; + + private: + Client *m_client; +}; + +class Disconnected : public ClientState +{ + public: + Disconnected(Client *client) : m_client(client) {} + + virtual void update(unsigned int delta) override; + + private: + Client *m_client; +}; diff --git a/testClient/src/Constants.h b/testClient/src/Constants.h new file mode 100644 index 0000000..b8bf19e --- /dev/null +++ b/testClient/src/Constants.h @@ -0,0 +1,8 @@ +#pragma once + +namespace constants { + + const int CLIENT_PORT = 9999; + +} + diff --git a/testClient/src/Protocoll.h b/testClient/src/Protocoll.h new file mode 100644 index 0000000..dc4befe --- /dev/null +++ b/testClient/src/Protocoll.h @@ -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; +}; + diff --git a/testClient/src/TestClient.cpp b/testClient/src/TestClient.cpp new file mode 100644 index 0000000..3868fd0 --- /dev/null +++ b/testClient/src/TestClient.cpp @@ -0,0 +1,33 @@ +#include +#include + +#include "Client.h" + +int main(int argc, char *argv[]) +{ + std::cout << "Starting DarkRP2D Client..." << std::endl; + + if (SDLNet_Init() < 0) + { + fprintf(stderr, "SDLNet_Init: %s\n", SDLNet_GetError()); + exit(EXIT_FAILURE); + } + + bool clientQuit = false; + { + Client client("127.0.0.1",12000); + unsigned int lastTime = SDL_GetTicks(), currentTime, elapsedTime; + while (!clientQuit) + { + currentTime = SDL_GetTicks(); + elapsedTime = currentTime - lastTime; + lastTime = currentTime; + client.update(elapsedTime); + } + } + + SDLNet_Quit(); + std::cout << "Client closed!" << std::endl; + + return EXIT_SUCCESS; +} \ No newline at end of file