Ported auto-discover LAN connect to win32

This commit is contained in:
Mark Vejvoda
2010-04-01 07:46:14 +00:00
parent 215fbdb33f
commit 6c92f188b6
13 changed files with 642 additions and 28 deletions

View File

@@ -225,6 +225,10 @@ void MainWindow::eventClose(){
program= NULL; program= NULL;
} }
void MainWindow::setProgram(Program *program) {
this->program= program;
}
// ===================================================== // =====================================================
// Main // Main
// ===================================================== // =====================================================
@@ -252,7 +256,7 @@ int glestMain(int argc, char** argv){
SystemFlags::debugLogFile = debugLogFile.c_str(); SystemFlags::debugLogFile = debugLogFile.c_str();
NetworkInterface::setDisplayMessageFunction(ExceptionHandler::DisplayMessage); NetworkInterface::setDisplayMessageFunction(ExceptionHandler::DisplayMessage);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//showCursor(config.getBool("Windowed")); //showCursor(config.getBool("Windowed"));

View File

@@ -36,7 +36,7 @@ public:
MainWindow(Program *program); MainWindow(Program *program);
~MainWindow(); ~MainWindow();
void setProgram(Program *program) {this->program= program;} void setProgram(Program *program);
virtual void eventMouseDown(int x, int y, MouseButton mouseButton); virtual void eventMouseDown(int x, int y, MouseButton mouseButton);
virtual void eventMouseUp(int x, int y, MouseButton mouseButton); virtual void eventMouseUp(int x, int y, MouseButton mouseButton);

View File

@@ -223,12 +223,14 @@ void Program::resize(SizeState sizeState){
// ==================== misc ==================== // ==================== misc ====================
void Program::setState(ProgramState *programState) void Program::setState(ProgramState *programState, bool cleanupOldState)
{ {
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] START\n",__FILE__,__FUNCTION__); //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] START\n",__FILE__,__FUNCTION__);
delete this->programState; if(cleanupOldState == true) {
delete this->programState;
}
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] %d\n",__FILE__,__FUNCTION__,__LINE__); //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] %d\n",__FILE__,__FUNCTION__,__LINE__);
@@ -259,7 +261,7 @@ void Program::exit() {
// ==================== PRIVATE ==================== // ==================== PRIVATE ====================
void Program::init(WindowGl *window, bool initSound){ void Program::init(WindowGl *window, bool initSound, bool toggleFullScreen){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@@ -269,7 +271,9 @@ void Program::init(WindowGl *window, bool initSound){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//set video mode //set video mode
setDisplaySettings(); if(toggleFullScreen == false) {
setDisplaySettings();
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@@ -331,7 +335,7 @@ void Program::init(WindowGl *window, bool initSound){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//sound //sound
if(initSound == true) { if(initSound == true && toggleFullScreen == false) {
SoundRenderer &soundRenderer= SoundRenderer::getInstance(); SoundRenderer &soundRenderer= SoundRenderer::getInstance();
soundRenderer.init(window); soundRenderer.init(window);
} }

View File

@@ -128,12 +128,14 @@ public:
void showMessage(const char *msg); void showMessage(const char *msg);
//misc //misc
void setState(ProgramState *programState); void setState(ProgramState *programState,bool cleanupOldState=true);
ProgramState * getState() { return programState;} ProgramState * getState() { return programState;}
WindowGl * getWindow() { return window; }
void init(WindowGl *window, bool initSound=true, bool toggleFullScreen=false);
void exit(); void exit();
private: private:
void init(WindowGl *window, bool initSound=true);
void setDisplaySettings(); void setDisplaySettings();
void restoreDisplaySettings(); void restoreDisplaySettings();
}; };

View File

@@ -356,11 +356,19 @@ void MenuStateJoinGame::keyDown(char key){
else if(key== 'A') { else if(key== 'A') {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
string bestIPMatch = "";
std::vector<string> serverList = clientInterface->discoverServers(); std::vector<string> serverList = clientInterface->discoverServers();
if(serverList.size() > 0) { if(serverList.size() > 0) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] serverList[0] = [%s]\n",__FILE__,__FUNCTION__,__LINE__,serverList[0].c_str()); std::vector<std::string> localIPList = Socket::getLocalIPAddressList();
for(int idx = 0; idx < serverList.size(); idx++) {
bestIPMatch = serverList[idx];
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] bestIPMatch = [%s] localIPList[0] = [%s]\n",__FILE__,__FUNCTION__,__LINE__,bestIPMatch.c_str(),localIPList[0].c_str());
if(strncmp(localIPList[0].c_str(),serverList[idx].c_str(),4) == 0) {
break;
}
}
labelServerIp.setText(serverList[0]); labelServerIp.setText(bestIPMatch);
connectToServer(); connectToServer();
} }
} }

View File

@@ -112,7 +112,8 @@ private:
static MouseState mouseState; static MouseState mouseState;
static Vec2i mousePos; static Vec2i mousePos;
static bool isKeyPressedDown; static bool isKeyPressedDown;
static bool isFullScreen;
static void setLastMouseEvent(unsigned int lastMouseEvent) {Window::lastMouseEvent = lastMouseEvent;} static void setLastMouseEvent(unsigned int lastMouseEvent) {Window::lastMouseEvent = lastMouseEvent;}
static unsigned int getLastMouseEvent() {return Window::lastMouseEvent;} static unsigned int getLastMouseEvent() {return Window::lastMouseEvent;}
@@ -129,8 +130,10 @@ public:
static bool handleEvent(); static bool handleEvent();
static void revertMousePos(); static void revertMousePos();
static bool isKeyDown() { return isKeyPressedDown; } static bool isKeyDown() { return isKeyPressedDown; }
static void setupGraphicsScreen(int depthBits=-1, int stencilBits=-1);
static const bool getIsFullScreen() { return isFullScreen; }
static void setIsFullScreen(bool value) { isFullScreen = value; }
Window(); Window();
virtual ~Window(); virtual ~Window();

View File

@@ -17,6 +17,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <stdexcept> #include <stdexcept>
#include <list>
#include "types.h" #include "types.h"
#include "checksum.h" #include "checksum.h"
@@ -25,6 +26,7 @@
using std::string; using std::string;
using std::vector; using std::vector;
using std::exception; using std::exception;
using std::list;
using Shared::Platform::int64; using Shared::Platform::int64;
using Shared::Util::Checksum; using Shared::Util::Checksum;
@@ -78,6 +80,20 @@ private:
int64 queryCounter(int multiplier) const; int64 queryCounter(int multiplier) const;
}; };
// =====================================================
// class ModeInfo
// =====================================================
class ModeInfo {
public:
int width;
int height;
int depth;
ModeInfo(int width, int height, int depth);
string getString() const;
};
// ===================================================== // =====================================================
// class PlatformExceptionHandler // class PlatformExceptionHandler
// ===================================================== // =====================================================
@@ -113,6 +129,7 @@ string extractDirectoryPathFromFile(string filename);
string extractExtension(const string& filename); string extractExtension(const string& filename);
void getFullscreenVideoInfo(int &colorBits,int &screenWidth,int &screenHeight); void getFullscreenVideoInfo(int &colorBits,int &screenWidth,int &screenHeight);
void getFullscreenVideoModes(list<ModeInfo> *modeinfos);
bool changeVideoMode(int resH, int resW, int colorBits, int refreshFrequency); bool changeVideoMode(int resH, int resW, int colorBits, int refreshFrequency);
void restoreVideoMode(bool exitingApp=false); void restoreVideoMode(bool exitingApp=false);

View File

@@ -15,6 +15,8 @@
#include <string> #include <string>
#include <winsock.h> #include <winsock.h>
#include <map> #include <map>
#include <vector>
#include "thread.h"
using std::string; using std::string;
@@ -54,14 +56,16 @@ private:
protected: protected:
static SocketManager socketManager; static SocketManager socketManager;
SOCKET sock; SOCKET sock;
static int broadcast_portno;
public: public:
Socket(SOCKET sock); Socket(SOCKET sock);
Socket(); Socket();
~Socket(); virtual ~Socket();
static bool enableDebugText; static int getBroadCastPort() { return broadcast_portno; }
static bool enableNetworkDebugInfo; static void setBroadCastPort(int value) { broadcast_portno = value; }
static std::vector<std::string> getLocalIPAddressList();
// Int lookup is socket fd while bool result is whether or not that socket was signalled for reading // Int lookup is socket fd while bool result is whether or not that socket was signalled for reading
static bool hasDataToRead(std::map<int,bool> &socketTriggeredList); static bool hasDataToRead(std::map<int,bool> &socketTriggeredList);
@@ -96,6 +100,27 @@ protected:
class ClientSocket: public Socket{ class ClientSocket: public Socket{
public: public:
void connect(const Ip &ip, int port); void connect(const Ip &ip, int port);
static std::vector<string> discoverServers();
};
class BroadCastSocketThread : public Thread
{
private:
Mutex mutexRunning;
Mutex mutexQuit;
bool quit;
bool running;
void setRunningStatus(bool value);
void setQuitStatus(bool value);
public:
BroadCastSocketThread();
virtual void execute();
void signalQuit();
bool getQuitStatus();
bool getRunningStatus();
}; };
// ===================================================== // =====================================================
@@ -105,13 +130,19 @@ public:
class ServerSocket: public Socket{ class ServerSocket: public Socket{
public: public:
ServerSocket();
virtual ~ServerSocket();
void bind(int port); void bind(int port);
void listen(int connectionQueueSize= SOMAXCONN); void listen(int connectionQueueSize= SOMAXCONN);
Socket *accept(); Socket *accept();
void stopBroadCastThread();
protected: protected:
void broadcast_thread(); BroadCastSocketThread *broadCastThread;
void startBroadCastThread();
}; };
}}//end namespace }}//end namespace

View File

@@ -87,7 +87,8 @@ std::vector<std::string> Socket::getLocalIPAddressList() {
int ipIdx = 0; int ipIdx = 0;
while (myhostent->h_addr_list[ipIdx] != 0) { while (myhostent->h_addr_list[ipIdx] != 0) {
sprintf(myhostaddr, "%s",inet_ntoa(*(struct in_addr *)myhostent->h_addr_list[ipIdx])); sprintf(myhostaddr, "%s",inet_ntoa(*(struct in_addr *)myhostent->h_addr_list[ipIdx]));
printf("%s\n",myhostaddr); //printf("%s\n",myhostaddr);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] myhostaddr = [%s]\n",__FILE__,__FUNCTION__,__LINE__,myhostaddr);
if(strlen(myhostaddr) > 0 && strncmp(myhostaddr,"127.",4) != 0) { if(strlen(myhostaddr) > 0 && strncmp(myhostaddr,"127.",4) != 0) {
ipList.push_back(myhostaddr); ipList.push_back(myhostaddr);
@@ -1035,7 +1036,10 @@ void BroadCastSocketThread::execute() {
try { try {
// Send this machine's host name and address in hostname:n.n.n.n format // Send this machine's host name and address in hostname:n.n.n.n format
sprintf(buff,"%s:%s",myhostname,ipList[0].c_str()); strcat(buff,myhostname);
for(int idx = 0; idx < ipList.size() ++idx) {
sprintf(buff,"%s:%s",buf,ipList[idx].c_str());
}
time_t elapsed = 0; time_t elapsed = 0;
for( pn = 1; ; pn++ ) for( pn = 1; ; pn++ )

View File

@@ -21,6 +21,7 @@
#include "sdl_private.h" #include "sdl_private.h"
#include "noimpl.h" #include "noimpl.h"
#include "util.h" #include "util.h"
#include "window.h"
#include "leak_dumper.h" #include "leak_dumper.h"
@@ -37,18 +38,18 @@ void PlatformContextGl::init(int colorBits, int depthBits, int stencilBits) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); Window::setupGraphicsScreen(depthBits, stencilBits);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 1);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 1);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 1);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, stencilBits);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, depthBits);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
int flags = SDL_OPENGL; int flags = SDL_OPENGL;
if(Private::shouldBeFullscreen) if(Private::shouldBeFullscreen) {
flags |= SDL_FULLSCREEN; flags |= SDL_FULLSCREEN;
Window::setIsFullScreen(true);
}
else {
Window::setIsFullScreen(false);
}
int resW = Private::ScreenWidth; int resW = Private::ScreenWidth;
int resH = Private::ScreenHeight; int resH = Private::ScreenHeight;

View File

@@ -15,9 +15,11 @@
#include "conversion.h" #include "conversion.h"
#include "platform_util.h" #include "platform_util.h"
#include "leak_dumper.h"
#include "sdl_private.h" #include "sdl_private.h"
#include "noimpl.h" #include "noimpl.h"
#include "util.h"
#include "SDL_syswm.h"
#include "leak_dumper.h"
using namespace Shared::Util; using namespace Shared::Util;
using namespace std; using namespace std;
@@ -37,6 +39,7 @@ unsigned int Window::lastMouseEvent = 0; /** for use in mouse hover calculations
Vec2i Window::mousePos; Vec2i Window::mousePos;
MouseState Window::mouseState; MouseState Window::mouseState;
bool Window::isKeyPressedDown = false; bool Window::isKeyPressedDown = false;
bool Window::isFullScreen = false;
// ========== PUBLIC ========== // ========== PUBLIC ==========
@@ -118,6 +121,7 @@ bool Window::handleEvent() {
/* handle ALT+Return */ /* handle ALT+Return */
if(event.key.keysym.sym == SDLK_RETURN if(event.key.keysym.sym == SDLK_RETURN
&& (event.key.keysym.mod & (KMOD_LALT | KMOD_RALT))) { && (event.key.keysym.mod & (KMOD_LALT | KMOD_RALT))) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d] SDLK_RETURN pressed.\n",__FILE__,__FUNCTION__,__LINE__);
toggleFullscreen(); toggleFullscreen();
} }
if(global_window) { if(global_window) {
@@ -206,8 +210,124 @@ void Window::destroy() {
SDL_PushEvent(&event); SDL_PushEvent(&event);
} }
void Window::setupGraphicsScreen(int depthBits, int stencilBits) {
static int newDepthBits = depthBits;
static int newStencilBits = stencilBits;
if(depthBits >= 0)
newDepthBits = depthBits;
if(stencilBits >= 0)
newStencilBits = stencilBits;
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 1);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 1);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 1);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, newStencilBits);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, newDepthBits);
}
static HWND GetSDLWindow()
{
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
if (SDL_GetWMInfo(&info) == -1)
return NULL;
return info.window;
}
void Window::toggleFullscreen() { void Window::toggleFullscreen() {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
Window::isFullScreen = !Window::isFullScreen;
#ifdef WIN32
/* -- Portable Fullscreen Toggling --
As of SDL 1.2.10, if width and height are both 0, SDL_SetVideoMode will use the
width and height of the current video mode (or the desktop mode, if no mode has been set).
Use 0 for Height, Width, and Color Depth to keep the current values. */
/*
//setupGraphicsScreen();
//SDL_Surface *surface = SDL_GetVideoSurface();
//int flags = surface->flags ^ SDL_FULLSCREEN;
//int flags = SDL_OPENGL;
//if(Window::isFullScreen) {
// flags |= SDL_FULLSCREEN;
//}
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
//SDL_SetVideoMode(0, 0, 0, flags);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
SDL_Surface *sf = SDL_GetVideoSurface();
SDL_Surface **surface = &sf;
uint32 *flags = NULL;
void *pixels = NULL;
SDL_Color *palette = NULL;
SDL_Rect clip;
int ncolors = 0;
Uint32 tmpflags = 0;
int w = 0;
int h = 0;
int bpp = 0;
if ( (!surface) || (!(*surface)) ) // don't bother if there's no surface.
return;
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
tmpflags = (*surface)->flags;
w = (*surface)->w;
h = (*surface)->h;
bpp = (*surface)->format->BitsPerPixel;
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n w = %d, h = %d, bpp = %d",__FILE__,__FUNCTION__,__LINE__,w,h,bpp);
if (flags == NULL) // use the surface's flags.
flags = &tmpflags;
//
if ( *flags & SDL_FULLSCREEN )
*flags &= ~SDL_FULLSCREEN;
//
else
*flags |= SDL_FULLSCREEN;
SDL_GetClipRect(*surface, &clip);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
*surface = SDL_SetVideoMode(w, h, bpp, (*flags));
if (*surface == NULL) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
*surface = SDL_SetVideoMode(w, h, bpp, tmpflags);
} // if
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
SDL_SetClipRect(*surface, &clip);
*/
HWND handle = GetSDLWindow();
if(Window::isFullScreen == true) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d] Window::isFullScreen == true [%d]\n",__FILE__,__FUNCTION__,__LINE__,handle);
ShowWindow(handle, SW_MAXIMIZE);
}
else {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d] Window::isFullScreen == false [%d]\n",__FILE__,__FUNCTION__,__LINE__,handle);
ShowWindow(handle, SW_RESTORE);
}
#else
SDL_WM_ToggleFullScreen(SDL_GetVideoSurface()); SDL_WM_ToggleFullScreen(SDL_GetVideoSurface());
#endif
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
} }
void Window::handleMouseDown(SDL_Event event) { void Window::handleMouseDown(SDL_Event event) {

View File

@@ -650,6 +650,48 @@ void getFullscreenVideoInfo(int &colorBits,int &screenWidth,int &screenHeight) {
} }
} }
void getFullscreenVideoModes(list<ModeInfo> *modeinfos) {
// Get the current video hardware information
//const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo();
//colorBits = vidInfo->vfmt->BitsPerPixel;
//screenWidth = vidInfo->current_w;
//screenHeight = vidInfo->current_h;
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
/* Get available fullscreen/hardware modes */
SDL_Rect**modes = SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE);
/* Check if there are any modes available */
if (modes == (SDL_Rect**)0) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] no hardware modes available.\n",__FILE__,__FUNCTION__,__LINE__);
const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo();
modeinfos->push_back(ModeInfo(vidInfo->current_w,vidInfo->current_h,vidInfo->vfmt->BitsPerPixel));
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] adding only current resolution: %d x %d.\n",__FILE__,__FUNCTION__,__LINE__,vidInfo->current_w,vidInfo->current_h);
}
/* Check if our resolution is restricted */
else if (modes == (SDL_Rect**)-1) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] all resolutions available.\n",__FILE__,__FUNCTION__,__LINE__);
const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo();
modeinfos->push_back(ModeInfo(vidInfo->current_w,vidInfo->current_h,vidInfo->vfmt->BitsPerPixel));
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] adding only current resolution: %d x %d.\n",__FILE__,__FUNCTION__,__LINE__,vidInfo->current_w,vidInfo->current_h);
}
else{
/* Print valid modes */
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] available Modes are:\n",__FILE__,__FUNCTION__,__LINE__);
int bestW = -1;
int bestH = -1;
for(int i=0; modes[i]; ++i) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"%d x %d\n",modes[i]->w, modes[i]->h,modes[i]->x);
modeinfos->push_back(ModeInfo(modes[i]->w,modes[i]->h,modes[i]->x));
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] adding resolution: %d x %d.\n",__FILE__,__FUNCTION__,__LINE__,modes[i]->w,modes[i]->h);
}
}
}
bool changeVideoMode(int resW, int resH, int colorBits, int ) { bool changeVideoMode(int resW, int resH, int colorBits, int ) {
Private::shouldBeFullscreen = true; Private::shouldBeFullscreen = true;
return true; return true;
@@ -710,4 +752,18 @@ bool isKeyDown(int virtualKey){
return (GetKeyState(virtualKey) & 0x8000) != 0; return (GetKeyState(virtualKey) & 0x8000) != 0;
} }
// =====================================
// ModeInfo
// =====================================
ModeInfo::ModeInfo(int w, int h, int d) {
width=w;
height=h;
depth=d;
}
string ModeInfo::getString() const{
return intToStr(width)+"x"+intToStr(height);
}
}}//end namespace }}//end namespace

View File

@@ -18,7 +18,7 @@
#include <strstream> #include <strstream>
#include <algorithm> #include <algorithm>
#include "util.h" #include "util.h"
#include "platform_util.h"
#include "leak_dumper.h" #include "leak_dumper.h"
#define socklen_t int #define socklen_t int
@@ -155,6 +155,8 @@ const char* WSAGetLastErrorMessage(const char* pcMessagePrefix,
namespace Shared{ namespace Platform{ namespace Shared{ namespace Platform{
int Socket::broadcast_portno = 61357;
// ===================================================== // =====================================================
// class Ip // class Ip
// ===================================================== // =====================================================
@@ -208,6 +210,32 @@ Socket::SocketManager::~SocketManager(){
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Winsock cleanup complete.\n"); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Winsock cleanup complete.\n");
} }
std::vector<std::string> Socket::getLocalIPAddressList() {
std::vector<std::string> ipList;
/* get my host name */
char myhostname[101]="";
gethostname(myhostname,100);
struct hostent* myhostent = gethostbyname(myhostname);
// get all host IP addresses (Except for loopback)
char myhostaddr[101] = "";
int ipIdx = 0;
while (myhostent->h_addr_list[ipIdx] != 0) {
sprintf(myhostaddr, "%s",inet_ntoa(*(struct in_addr *)myhostent->h_addr_list[ipIdx]));
//printf("%s\n",myhostaddr);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] myhostaddr = [%s]\n",__FILE__,__FUNCTION__,__LINE__,myhostaddr);
if(strlen(myhostaddr) > 0 && strncmp(myhostaddr,"127.",4) != 0) {
ipList.push_back(myhostaddr);
}
ipIdx++;
}
return ipList;
}
Socket::Socket(SOCKET sock){ Socket::Socket(SOCKET sock){
this->sock= sock; this->sock= sock;
} }
@@ -757,9 +785,132 @@ void ClientSocket::connect(const Ip &ip, int port)
} }
} }
//=======================================================================
// Function : discovery_response_thread
// in : none
// return : none
// Description: To be forked in its own thread to listen and respond to broadcasts from
// other servers
//
std::vector<string> ClientSocket::discoverServers() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
std::vector<string> foundServers;
short port; // The port for the broadcast.
struct sockaddr_in bcSender; // local socket address for the broadcast.
struct sockaddr_in bcaddr; // The broadcast address for the receiver.
int bcfd; // The file descriptor used for the broadcast.
bool one = true; // Parameter for "setscokopt".
char buff[10024]; // Buffers the data to be broadcasted.
socklen_t alen;
int nb; // The number of bytes read.
port = htons( Socket::getBroadCastPort() );
// Prepare to receive the broadcast.
bcfd = socket(AF_INET, SOCK_DGRAM, 0);
if( bcfd <= 0 ) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"socket failed: %d\n", WSAGetLastError());
//exit(-1);
}
else {
// Create the address we are receiving on.
memset( (char*)&bcaddr, 0, sizeof(bcaddr));
bcaddr.sin_family = AF_INET;
bcaddr.sin_addr.s_addr = htonl(INADDR_ANY);
bcaddr.sin_port = port;
int val = 1;
setsockopt(bcfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
if(bind( bcfd, (struct sockaddr *)&bcaddr, sizeof(bcaddr) ) < 0 ) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"bind failed: %d\n", WSAGetLastError());
}
else {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
// Keep getting packets forever.
for( time_t elapsed = time(NULL); difftime(time(NULL),elapsed) <= 3; )
{
alen = sizeof(struct sockaddr);
if( (nb = recvfrom(bcfd, buff, 10024, 0, (struct sockaddr *) &bcSender, &alen)) <= 0 )
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"recvfrom failed: %d\n", WSAGetLastError());
//exit(-1);
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"broadcast message received: [%s] from: [%s]\n", buff,inet_ntoa(bcSender.sin_addr) );
vector<string> tokens;
Tokenize(buff,tokens,":");
for(int idx = 1; idx < tokens.size(); idx++) {
foundServers.push_back(tokens[idx]);
}
break;
}
}
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
return foundServers;
}
// ===================================================== // =====================================================
// class ServerSocket // class ServerSocket
// ===================================================== // =====================================================
ServerSocket::ServerSocket() : Socket() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
broadCastThread = NULL;
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
ServerSocket::~ServerSocket() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
stopBroadCastThread();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void ServerSocket::stopBroadCastThread() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(broadCastThread != NULL) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
broadCastThread->signalQuit();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
for( time_t elapsed = time(NULL); difftime(time(NULL),elapsed) <= 5; ) {
if(broadCastThread->getRunningStatus() == false) {
break;
}
sleep(100);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
delete broadCastThread;
broadCastThread = NULL;
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void ServerSocket::startBroadCastThread() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
stopBroadCastThread();
broadCastThread = new BroadCastSocketThread();
broadCastThread->start();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void ServerSocket::bind(int port){ void ServerSocket::bind(int port){
//sockaddr structure //sockaddr structure
@@ -779,6 +930,8 @@ void ServerSocket::listen(int connectionQueueSize){
if(err==SOCKET_ERROR){ if(err==SOCKET_ERROR){
throwException("Error listening socket"); throwException("Error listening socket");
} }
broadCastThread = new BroadCastSocketThread();
broadCastThread->start();
} }
Socket *ServerSocket::accept(){ Socket *ServerSocket::accept(){
@@ -792,4 +945,215 @@ Socket *ServerSocket::accept(){
return new Socket(newSock); return new Socket(newSock);
} }
BroadCastSocketThread::BroadCastSocketThread() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
setQuitStatus(false);
setRunningStatus(false);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void BroadCastSocketThread::signalQuit() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
setQuitStatus(true);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void BroadCastSocketThread::setQuitStatus(bool value) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
mutexQuit.p();
quit = value;
mutexQuit.v();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
bool BroadCastSocketThread::getQuitStatus() {
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
bool retval = false;
mutexQuit.p();
retval = quit;
mutexQuit.v();
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
return retval;
}
bool BroadCastSocketThread::getRunningStatus() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
bool retval = false;
mutexRunning.p();
retval = running;
mutexRunning.v();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] running = %d\n",__FILE__,__FUNCTION__,__LINE__,retval);
return retval;
}
void BroadCastSocketThread::setRunningStatus(bool value) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] value = %d\n",__FILE__,__FUNCTION__,__LINE__,value);
mutexRunning.p();
running = value;
mutexRunning.v();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] running = %d\n",__FILE__,__FUNCTION__,__LINE__,value);
}
//=======================================================================
// Function : broadcast_thread
// in : none
// return : none
// Description: To be forked in its own thread to send out a broadcast to the local subnet
// the current broadcast message is <myhostname:my.ip.address.dotted>
//
void BroadCastSocketThread::execute() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
unsigned int tbcaddr; // The broadcast address.
short port; // The port for the broadcast.
struct sockaddr_in bcLocal; // local socket address for the broadcast.
struct sockaddr_in bcaddr; // The broadcast address for the receiver.
int bcfd; // The socket used for the broadcast.
bool one = true; // Parameter for "setscokopt".
int pn; // The number of the packet broadcasted.
char buff[1024]; // Buffers the data to be broadcasted.
char myhostname[100]; // hostname of local machine
//char subnetmask[100]; // Subnet mask to broadcast to
struct in_addr myaddr; // My host address in net format
struct hostent* myhostent;
char * ptr; // some transient vars
int len,i;
/* get my host name */
gethostname(myhostname,100);
myhostent = gethostbyname(myhostname);
// get only the first host IP address
std::vector<std::string> ipList = Socket::getLocalIPAddressList();
/*
strcpy(subnetmask, ipList[0].c_str());
ptr = &subnetmask[0];
len = strlen(ptr);
// substitute the address with class C subnet mask x.x.x.255
for(i=len;i>0;i--) {
if(ptr[i] == '.') {
strcpy(&ptr[i+1],"255");
break;
}
}
*/
// Convert the broadcast address from dot notation to a broadcast address.
//if( (tbcaddr = inet_addr( subnetmask )) == INADDR_NONE )
//{
// SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Badly formatted BC address: %d\n", WSAGetLastError());
//exit(-1);
//}
//else
{
port = htons( Socket::getBroadCastPort() );
// Create the broadcast socket
memset( &bcLocal, 0, sizeof( struct sockaddr_in));
bcLocal.sin_family = AF_INET;
bcLocal.sin_addr.s_addr = htonl( INADDR_BROADCAST );
bcLocal.sin_port = port; // We are letting the OS fill in the port number for the local machine.
bcfd = socket( AF_INET, SOCK_DGRAM, 0 );
// If there is an error, report it and terminate.
if( bcfd <= 0 ) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Unable to allocate broadcast socket.: %d\n", WSAGetLastError());
//exit(-1);
}
// Mark the socket for broadcast.
else if( setsockopt( bcfd, SOL_SOCKET, SO_BROADCAST, (const char *) &one, sizeof( int ) ) < 0 ) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Could not set socket to broadcast.: %d\n", WSAGetLastError());
//exit(-1);
}
// Bind the address to the broadcast socket.
else {
//int val = 1;
//setsockopt(bcfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
//if(::bind(bcfd, (struct sockaddr *) &bcLocal, sizeof(struct sockaddr_in)) < 0) {
// SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Could not bind address to BC socket.: %d\n", WSAGetLastError());
//exit(-1);
//}
//else
{
// Record the broadcast address of the receiver.
bcaddr.sin_family = AF_INET;
bcaddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);//tbcaddr;
bcaddr.sin_port = port;
setRunningStatus(true);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast thread is running\n");
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
try {
// Send this machine's host name and address in hostname:n.n.n.n format
sprintf(buff,"%s",myhostname);
for(int idx = 0; idx < ipList.size(); idx++) {
sprintf(buff,"%s:%s",buff,ipList[idx].c_str());
}
time_t elapsed = 0;
for( pn = 1; ; pn++ )
{
if(difftime(time(NULL),elapsed) >= 1) {
time_t elapsed = time(NULL);
// Broadcast the packet to the subnet
if( sendto( bcfd, buff, sizeof(buff) + 1, 0 , (struct sockaddr *)&bcaddr, sizeof(struct sockaddr_in) ) != sizeof(buff) + 1 )
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Sendto error: %d\n", WSAGetLastError());
//exit(-1);
}
else {
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcasting to [%s] the message: [%s]\n",subnetmask,buff);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcasting on port [%d] the message: [%s]\n",Socket::getBroadCastPort(),buff);
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
if(getQuitStatus() == true) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
break;
}
sleep( 100 ); // send out broadcast every 1 seconds
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
catch(const exception &ex) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
setRunningStatus(false);
}
catch(...) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] unknown error\n",__FILE__,__FUNCTION__,__LINE__);
setRunningStatus(false);
}
setRunningStatus(false);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast thread is exiting\n");
}
}
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
}}//end namespace }}//end namespace