Skip to content

Commit

Permalink
Improved NetworkManager integration #4 [ci skip]
Browse files Browse the repository at this point in the history
  • Loading branch information
gbaudic committed Feb 21, 2019
1 parent 03593ec commit 19dfa36
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 31 deletions.
15 changes: 15 additions & 0 deletions src/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ using namespace std;
Context* Context::currentContext = nullptr;
Context* Context::lastContext = nullptr;
gcn::Container* Context::parent = nullptr;
NetworkManager Context::network;

Context::Context(ContextName type) :
name(type)
Expand Down Expand Up @@ -61,6 +62,20 @@ void Context::leave() {
parent->remove(&top);
}

void Context::receive() {
// Get messages from network manager
vector<UDPpacket *> data = network.receive();

// Unpack and feed context, one by one
for(UDPpacket *p : data) {
processMessage(NetworkManager::getCode(p), NetworkManager::getMessage(p));
}
}

void Context::send(const Uint8 code, const std::string & message) {
network.send(code, message);
}

/**
* Create and replace the current Context in the application
* Closely related to the Factory design pattern
Expand Down
5 changes: 5 additions & 0 deletions src/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <string>
#include <SDL2/SDL.h>
#include <guisan.hpp>
#include "network.hpp"

/**
* Enum to tell the different states for the software
Expand Down Expand Up @@ -42,6 +43,7 @@ class Context {

virtual void enter();
virtual void leave();
void receive();
virtual void processMessage(const Uint8 code, const std::string &message) {
// Left empty because some derived classes will not need this
};
Expand All @@ -53,6 +55,7 @@ class Context {
void addWidget(gcn::Widget *widget, int x = 0, int y = 0);
void addCenteredWidget(gcn::Widget *widget);
void setNextContext(const ContextName newContext);
void send(const Uint8 code, const std::string & message);

private:
static gcn::Container *parent;
Expand All @@ -62,6 +65,8 @@ class Context {

static Context* currentContext;
static Context* lastContext;

static NetworkManager network;
};

#endif // !_H_CONTEXT_
Expand Down
57 changes: 30 additions & 27 deletions src/network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ NetworkManager::NetworkManager() {
}

NetworkManager::~NetworkManager() {
for(UDPpacket *p : packets) {
SDLNet_FreePacket(p);
}
packets.clear();

SDLNet_UDP_Close(clientSock);

SDLNet_Quit();
Expand All @@ -42,53 +47,51 @@ void NetworkManager::send(Uint8 code, const string & message) {
SDLNet_FreePacket(packet);
}

void NetworkManager::receive(Context* currentContext) {
vector<UDPpacket*> & NetworkManager::receive() {
// Cleanly remove the previously allocated packets, if any
for(UDPpacket *p : packets) {
SDLNet_FreePacket(p);
}
packets.clear();

UDPpacket *packet = SDLNet_AllocPacket(1024);

int nbRecv = SDLNet_UDP_Recv(clientSock, packet);
while(nbRecv == 1) {
if(packet->len > 1) {
Uint8 code = packet->data[0];
string data((char*)packet->data+1);

// Based on the code, do something with the packet...
}
packets.push_back(packet);

packet = SDLNet_AllocPacket(1024);
nbRecv = SDLNet_UDP_Recv(clientSock, packet);
}

SDLNet_FreePacket(packet);
SDLNet_FreePacket(packet); // the last allocated one is empty

return packets;
}

/**
* Save server info for future use once chosen by the user
* \param ip server IPv4, in machine byte order
* \param port server port, in machine byte order
*/
void NetworkManager::setServerInfo(Uint32 ip, Uint16 port) {
void NetworkManager::setServerInfo(Uint32 ip) {
SDLNet_Write32(ip, &serverInfo.host);
SDLNet_Write16(port, &serverInfo.port);
SDLNet_Write16(SERVER_PORT, &serverInfo.port);
}

Uint8 NetworkManager::getCode(UDPpacket *p) {
return p->data[0];
}

string NetworkManager::getMessage(UDPpacket *p) {
string message(reinterpret_cast<char*>(p->data+1));
return message;
}

/**
* Send the broadcast message to try to find a server on the local network
* \param ip server address (IPv4), defaults to broadcast if none supplied
*/
void NetworkManager::findServer(Uint32 ip) {
string msg = "HELLO";
IPaddress broadcast;
SDLNet_Write32(ip, &broadcast.host);
SDLNet_Write16(SERVER_PORT, &broadcast.port);

int size = static_cast<int>(msg.size()) + 1 + 1;
UDPpacket *packet = SDLNet_AllocPacket(size);

packet->len = size;
packet->address = broadcast;
packet->data[0] = HELLO_MSG;
strncpy((char*)packet->data + 1, msg.c_str(), 6);

SDLNet_UDP_Send(clientSock, -1, packet);

SDLNet_FreePacket(packet);
setServerInfo(ip);
send(HELLO_MSG, "HELLO");
}
12 changes: 9 additions & 3 deletions src/network.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
*/

#include <string>
#include <vector>
#include <SDL2/SDL.h>
#include <SDL2/SDL_net.h>
#include "context.hpp"

#ifndef _H_NETWORK_
#define _H_NETWORK_
Expand All @@ -20,14 +20,20 @@ class NetworkManager final {
~NetworkManager();
void send(Uint8 code, const std::string & message);
void findServer(Uint32 ip = INADDR_BROADCAST);
void setServerInfo(Uint32 ip, Uint16 port);
void receive(Context* currentContext);
void setServerInfo(Uint32 ip);
std::vector<UDPpacket*> & receive();

static Uint8 getCode(UDPpacket *p);
static std::string getMessage(UDPpacket *p);

private:
const Uint16 SERVER_PORT = 6545;

UDPsocket clientSock; //! to send data
UDPsocket serverSock; //! only useful if also a server
IPaddress serverInfo;

std::vector<UDPpacket*> packets;
};

#endif //! _H_NETWORK_
11 changes: 10 additions & 1 deletion src/views/serverlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ input_ip("IP", "Enter server address")
w_login.setActionEventId("login");
w_login.addActionListener(this);
w_login.setVisible(false);
input_ip.setVisible(false);
input_ip.setActionEventId("connect");
input_ip.addActionListener(this);
btn_manualIP.setWidth(btn_rescan.getWidth());

string imgPath = RESOURCE_PREFIX + "/menu/lb_serverlist.png";
Expand Down Expand Up @@ -155,7 +158,13 @@ void ServerList::sendRequest(Uint32 ip) {
lastChangeTime = SDL_GetTicks();
}

void ServerList::login(Uint32 ip, const std::string & login, const std::string & password) {
void ServerList::login(Uint32 ip, const string & login, const string & password) {
// Set IP in NetworkManager

string message = login + '\3' + password; // yup, in clear

// Send it
send(LOGIN_MSG, message);

state = State::LOGIN;
lastChangeTime = SDL_GetTicks();
Expand Down

0 comments on commit 19dfa36

Please sign in to comment.