mirror of
				https://github.com/KartKrewDev/RingRacers.git
				synced 2025-10-30 08:01:28 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1155 lines
		
	
	
	
		
			23 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1155 lines
		
	
	
	
		
			23 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/////////////////////////////
 | 
						|
//                         //
 | 
						|
//    Sonic Robo Blast 2   //
 | 
						|
// Official Win32 Launcher //
 | 
						|
//                         //
 | 
						|
//           By            //
 | 
						|
//        SSNTails         //
 | 
						|
//    ah518@tcnet.org      //
 | 
						|
//  (Sonic Team Junior)    //
 | 
						|
//  http://www.srb2.org    //
 | 
						|
//                         //
 | 
						|
/////////////////////////////
 | 
						|
//
 | 
						|
// This source code is released under
 | 
						|
// Public Domain. I hope it helps you
 | 
						|
// learn how to write exciting Win32
 | 
						|
// applications in C!
 | 
						|
//
 | 
						|
// However, you may not alter this
 | 
						|
// program and continue to call it
 | 
						|
// the "Official Sonic Robo Blast 2
 | 
						|
// Launcher".
 | 
						|
//
 | 
						|
// NOTE: Not all files in this project
 | 
						|
// are released under this license.
 | 
						|
// Any license mentioned in accompanying
 | 
						|
// source files overrides the license
 | 
						|
// mentioned here, sorry!
 | 
						|
//
 | 
						|
// SRB2Launcher.cpp : Defines the entry point for the application.
 | 
						|
//
 | 
						|
 | 
						|
#include "stdafx.h"
 | 
						|
#include <stdlib.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include "SRB2Launcher.h"
 | 
						|
 | 
						|
char TempString[256];
 | 
						|
 | 
						|
char Arguments[16384];
 | 
						|
 | 
						|
HWND mainHWND;
 | 
						|
HWND hostHWND;
 | 
						|
HWND joinHWND;
 | 
						|
HINSTANCE g_hInst;
 | 
						|
 | 
						|
HANDLE ServerlistThread = 0;
 | 
						|
 | 
						|
typedef struct
 | 
						|
{
 | 
						|
	char nospecialrings;
 | 
						|
	char suddendeath;
 | 
						|
	char scoringtype[16];
 | 
						|
	char matchboxes[16];
 | 
						|
	int respawnitemtime;
 | 
						|
	int timelimit;
 | 
						|
	int pointlimit;
 | 
						|
} matchsettings_t;
 | 
						|
 | 
						|
typedef struct
 | 
						|
{
 | 
						|
	char raceitemboxes[16];
 | 
						|
	int numlaps;
 | 
						|
} racesettings_t;
 | 
						|
 | 
						|
typedef struct
 | 
						|
{
 | 
						|
	char nospecialrings;
 | 
						|
	char matchboxes[16];
 | 
						|
	int respawnitemtime;
 | 
						|
	int timelimit;
 | 
						|
	int pointlimit;
 | 
						|
} tagsettings_t;
 | 
						|
 | 
						|
typedef struct
 | 
						|
{
 | 
						|
	char nospecialrings;
 | 
						|
	char matchboxes[16];
 | 
						|
	int respawnitemtime;
 | 
						|
	int timelimit;
 | 
						|
	int flagtime;
 | 
						|
	int pointlimit;
 | 
						|
} ctfsettings_t;
 | 
						|
 | 
						|
typedef struct
 | 
						|
{
 | 
						|
	char nofile;
 | 
						|
	char nodownload;
 | 
						|
} joinsettings_t;
 | 
						|
 | 
						|
typedef struct
 | 
						|
{
 | 
						|
	matchsettings_t match;
 | 
						|
	racesettings_t race;
 | 
						|
	tagsettings_t tag;
 | 
						|
	ctfsettings_t ctf;
 | 
						|
	char gametype[16];
 | 
						|
	char startmap[9];
 | 
						|
	int maxplayers;
 | 
						|
	char advancestage[16];
 | 
						|
	int inttime;
 | 
						|
	char forceskin;
 | 
						|
	char noautoaim;
 | 
						|
	char nosend;
 | 
						|
	char noadvertise;
 | 
						|
 | 
						|
	// Monitor Toggles...
 | 
						|
	char teleporters[8];
 | 
						|
	char superring[8];
 | 
						|
	char silverring[8];
 | 
						|
	char supersneakers[8];
 | 
						|
	char invincibility[8];
 | 
						|
	char jumpshield[8];
 | 
						|
	char watershield[8];
 | 
						|
	char ringshield[8];
 | 
						|
	char fireshield[8];
 | 
						|
	char bombshield[8];
 | 
						|
	char oneup[8];
 | 
						|
	char eggmanbox[8];
 | 
						|
} hostsettings_t;
 | 
						|
 | 
						|
typedef struct
 | 
						|
{
 | 
						|
	hostsettings_t host;
 | 
						|
	joinsettings_t join;
 | 
						|
	char EXEName[1024];
 | 
						|
	char ConfigFile[1024];
 | 
						|
	char ManualParameters[8192];
 | 
						|
	char PlayerName[24];
 | 
						|
	char PlayerColor[16];
 | 
						|
	char PlayerSkin[24];
 | 
						|
} settings_t;
 | 
						|
 | 
						|
// Whole structure is just dumped to a binary file when settings are saved.
 | 
						|
settings_t launchersettings;
 | 
						|
 | 
						|
#define APPTITLE "Official Sonic Robo Blast 2 Launcher"
 | 
						|
#define APPVERSION "v0.1"
 | 
						|
#define APPAUTHOR "SSNTails"
 | 
						|
#define APPCOMPANY "Sonic Team Junior"
 | 
						|
 | 
						|
LRESULT CALLBACK MainProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
 | 
						|
 | 
						|
//
 | 
						|
// RunSRB2
 | 
						|
//
 | 
						|
// Runs SRB2
 | 
						|
// returns true if successful
 | 
						|
//
 | 
						|
BOOL RunSRB2(void)
 | 
						|
{
 | 
						|
	SHELLEXECUTEINFO lpExecInfo;
 | 
						|
	BOOL result;
 | 
						|
	char EXEName[1024];
 | 
						|
 | 
						|
	memset(&lpExecInfo, 0, sizeof(SHELLEXECUTEINFO));
 | 
						|
 | 
						|
	lpExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
 | 
						|
 | 
						|
	SendMessage(GetDlgItem(mainHWND, IDC_EXENAME), WM_GETTEXT, sizeof(EXEName), (LPARAM)(LPCSTR)EXEName); 
 | 
						|
	lpExecInfo.lpFile = EXEName;
 | 
						|
	lpExecInfo.lpParameters = Arguments;
 | 
						|
	lpExecInfo.nShow = SW_SHOWNORMAL;
 | 
						|
	lpExecInfo.hwnd = mainHWND;
 | 
						|
	lpExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
 | 
						|
	lpExecInfo.lpVerb = "open";
 | 
						|
 | 
						|
	result = ShellExecuteEx(&lpExecInfo);
 | 
						|
 | 
						|
	if(!result)
 | 
						|
	{
 | 
						|
		MessageBox(mainHWND, "Error starting the game!", "Error", MB_OK|MB_APPLMODAL|MB_ICONERROR);
 | 
						|
		return false;
 | 
						|
	}
 | 
						|
 | 
						|
	return true;
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// ChooseEXEName
 | 
						|
//
 | 
						|
// Provides a common dialog box
 | 
						|
// for selecting the desired executable.
 | 
						|
//
 | 
						|
void ChooseEXEName(void)
 | 
						|
{
 | 
						|
	OPENFILENAME ofn;
 | 
						|
	char FileBuffer[256];
 | 
						|
 | 
						|
	ZeroMemory(&ofn, sizeof(ofn));
 | 
						|
	ofn.hwndOwner = NULL;
 | 
						|
	FileBuffer[0] = '\0';
 | 
						|
	ofn.lpstrFilter = "Executable Files\0*.exe\0All Files\0*.*\0\0";
 | 
						|
	ofn.lpstrInitialDir = NULL;
 | 
						|
	ofn.lpstrFile = FileBuffer;
 | 
						|
	ofn.lStructSize = sizeof(ofn);
 | 
						|
	ofn.nMaxFile = sizeof(FileBuffer);
 | 
						|
	ofn.nFilterIndex = 1;
 | 
						|
	ofn.lpstrFileTitle = NULL;
 | 
						|
	ofn.nMaxFileTitle = 0;
 | 
						|
	ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
 | 
						|
 | 
						|
	if(GetOpenFileName(&ofn))
 | 
						|
	{
 | 
						|
		SendMessage(GetDlgItem(mainHWND, IDC_EXENAME), WM_SETTEXT, 0, (LPARAM)(LPCSTR)FileBuffer);
 | 
						|
		strcpy(launchersettings.EXEName, FileBuffer);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// ChooseConfigName
 | 
						|
//
 | 
						|
// Provides a common dialog box
 | 
						|
// for selecting the desired cfg file.
 | 
						|
//
 | 
						|
void ChooseConfigName(void)
 | 
						|
{
 | 
						|
	OPENFILENAME ofn;
 | 
						|
	char FileBuffer[256];
 | 
						|
 | 
						|
	ZeroMemory(&ofn, sizeof(ofn));
 | 
						|
	ofn.hwndOwner = NULL;
 | 
						|
	FileBuffer[0] = '\0';
 | 
						|
	ofn.lpstrFilter = "Config Files\0*.cfg\0All Files\0*.*\0\0";
 | 
						|
	ofn.lpstrInitialDir = NULL;
 | 
						|
	ofn.lpstrFile = FileBuffer;
 | 
						|
	ofn.lStructSize = sizeof(ofn);
 | 
						|
	ofn.nMaxFile = sizeof(FileBuffer);
 | 
						|
	ofn.nFilterIndex = 1;
 | 
						|
	ofn.lpstrFileTitle = NULL;
 | 
						|
	ofn.nMaxFileTitle = 0;
 | 
						|
	ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
 | 
						|
 | 
						|
	if(GetOpenFileName(&ofn))
 | 
						|
	{
 | 
						|
		SendMessage(GetDlgItem(mainHWND, IDC_CONFIGFILE), WM_SETTEXT, 0, (LPARAM)(LPCSTR)FileBuffer);
 | 
						|
		strcpy(launchersettings.ConfigFile, FileBuffer);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// Add External File
 | 
						|
//
 | 
						|
// Provides a common dialog box
 | 
						|
// for adding an external file.
 | 
						|
//
 | 
						|
void AddExternalFile(void)
 | 
						|
{
 | 
						|
	OPENFILENAME ofn;
 | 
						|
	char FileBuffer[256];
 | 
						|
 | 
						|
	ZeroMemory(&ofn, sizeof(ofn));
 | 
						|
	ofn.hwndOwner = NULL;
 | 
						|
	FileBuffer[0] = '\0';
 | 
						|
	ofn.lpstrFilter = "WAD/SOC Files\0*.soc;*.wad\0All Files\0*.*\0\0";
 | 
						|
	ofn.lpstrInitialDir = NULL;
 | 
						|
	ofn.lpstrFile = FileBuffer;
 | 
						|
	ofn.lStructSize = sizeof(ofn);
 | 
						|
	ofn.nMaxFile = sizeof(FileBuffer);
 | 
						|
	ofn.nFilterIndex = 1;
 | 
						|
	ofn.lpstrFileTitle = NULL;
 | 
						|
	ofn.nMaxFileTitle = 0;
 | 
						|
	ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
 | 
						|
 | 
						|
	if(GetOpenFileName(&ofn) && SendMessage(GetDlgItem(mainHWND, IDC_EXTFILECOMBO), CB_FINDSTRING, -1, (LPARAM)(LPCSTR)FileBuffer) == CB_ERR)
 | 
						|
		SendMessage(GetDlgItem(mainHWND, IDC_EXTFILECOMBO), CB_ADDSTRING, 0, (LPARAM)(LPCSTR)FileBuffer);
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// CompileArguments
 | 
						|
//
 | 
						|
// Go through ALL of the settings
 | 
						|
// and put them into a parameter
 | 
						|
// string. Yikes!
 | 
						|
//
 | 
						|
void CompileArguments(void)
 | 
						|
{
 | 
						|
	HWND temp;
 | 
						|
	int numitems;
 | 
						|
	int i;
 | 
						|
 | 
						|
	// Clear out the arguments, if any existed.
 | 
						|
	memset(Arguments, 0, sizeof(Arguments));
 | 
						|
 | 
						|
 | 
						|
	// WAD/SOC Files Added
 | 
						|
	temp = GetDlgItem(mainHWND, IDC_EXTFILECOMBO);
 | 
						|
 | 
						|
	if ((numitems = SendMessage(temp, CB_GETCOUNT, 0, 0)) > 0)
 | 
						|
	{
 | 
						|
		char tempbuffer[1024];
 | 
						|
 | 
						|
		strcpy(Arguments, "-file ");
 | 
						|
 | 
						|
		for (i = 0; i < numitems; i++)
 | 
						|
		{
 | 
						|
			SendMessage(temp, CB_GETLBTEXT, i, (LPARAM)(LPCSTR)tempbuffer);
 | 
						|
			strcat(Arguments, tempbuffer);
 | 
						|
			strcat(Arguments, " ");
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// Manual Parameters
 | 
						|
	temp = GetDlgItem(mainHWND, IDC_PARAMETERS);
 | 
						|
 | 
						|
	if (SendMessage(temp, WM_GETTEXTLENGTH, 0, 0) > 0)
 | 
						|
	{
 | 
						|
		char tempbuffer[8192];
 | 
						|
 | 
						|
		SendMessage(temp, WM_GETTEXT, 8192, (LPARAM)(LPCSTR)tempbuffer);
 | 
						|
 | 
						|
		strcat(Arguments, tempbuffer);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// GetConfigVariable
 | 
						|
//
 | 
						|
// Pulls a value out of the chosen
 | 
						|
// config.cfg and places it into the
 | 
						|
// string supplied in 'dest'
 | 
						|
//
 | 
						|
BOOL GetConfigVariable(char* varname, char* dest)
 | 
						|
{
 | 
						|
	FILE* f;
 | 
						|
	int size = 0;
 | 
						|
	char* buffer;
 | 
						|
	char* posWeWant;
 | 
						|
	char* stringstart;
 | 
						|
	char varnamecpy[256];
 | 
						|
 | 
						|
	varnamecpy[0] = '\n';
 | 
						|
 | 
						|
	strncpy(varnamecpy+1, varname, 255);
 | 
						|
 | 
						|
	if(!(f = fopen(launchersettings.ConfigFile, "rb")))
 | 
						|
		return false; // Oops!
 | 
						|
 | 
						|
	// Get file size
 | 
						|
	while(!feof(f))
 | 
						|
	{
 | 
						|
		size++;
 | 
						|
		fgetc(f);
 | 
						|
	}
 | 
						|
 | 
						|
	fseek(f, 0, SEEK_SET);
 | 
						|
 | 
						|
	buffer = (char*)malloc(size);
 | 
						|
 | 
						|
	fread(buffer, size, 1, f);
 | 
						|
	fclose(f);
 | 
						|
 | 
						|
	posWeWant = strstr(buffer, varname);
 | 
						|
 | 
						|
	if(posWeWant == NULL)
 | 
						|
	{
 | 
						|
		free(buffer);
 | 
						|
		return false;
 | 
						|
	}
 | 
						|
 | 
						|
	posWeWant++;
 | 
						|
 | 
						|
	// We are now at the line we want.
 | 
						|
	// Get the variable from it
 | 
						|
 | 
						|
	while(*posWeWant != '\"') posWeWant++;
 | 
						|
 | 
						|
	posWeWant++;
 | 
						|
 | 
						|
	stringstart = posWeWant;
 | 
						|
 | 
						|
	while(*posWeWant != '\"') posWeWant++;
 | 
						|
 | 
						|
	*posWeWant = '\0';
 | 
						|
 | 
						|
	strcpy(dest, stringstart);
 | 
						|
 | 
						|
	free(buffer);
 | 
						|
 | 
						|
	// Phew!
 | 
						|
	return true;
 | 
						|
}
 | 
						|
 | 
						|
SOCKET ConnectSocket(char* IPAddress, int portnumber)
 | 
						|
{
 | 
						|
	DWORD dwDestAddr;
 | 
						|
	SOCKADDR_IN sockAddrDest;
 | 
						|
	SOCKET sockDest;
 | 
						|
 | 
						|
	// Create socket
 | 
						|
	sockDest = socket(AF_INET, SOCK_STREAM, 0);
 | 
						|
 | 
						|
	if(sockDest == SOCKET_ERROR)
 | 
						|
	{
 | 
						|
//		printf("Could not create socket: %d\n", WSAGetLastError());
 | 
						|
		return INVALID_SOCKET;
 | 
						|
	}
 | 
						|
 | 
						|
	// Convert address to in_addr (binary) format
 | 
						|
	dwDestAddr = inet_addr(IPAddress);
 | 
						|
 | 
						|
	if(dwDestAddr == INADDR_NONE)
 | 
						|
	{
 | 
						|
		// It's not a xxx.xxx.xxx.xxx IP, so resolve through DNS
 | 
						|
		struct hostent* pHE = gethostbyname(IPAddress);
 | 
						|
		if(pHE == 0)
 | 
						|
		{
 | 
						|
//			printf("Unable to resolve address.\n");
 | 
						|
			return INVALID_SOCKET;
 | 
						|
		}
 | 
						|
 | 
						|
		dwDestAddr = *((u_long*)pHE->h_addr_list[0]);
 | 
						|
	}
 | 
						|
 | 
						|
	// Initialize SOCKADDR_IN with IP address, port number and address family
 | 
						|
	memcpy(&sockAddrDest.sin_addr, &dwDestAddr, sizeof(DWORD));
 | 
						|
	
 | 
						|
	sockAddrDest.sin_port = htons(portnumber);
 | 
						|
	sockAddrDest.sin_family = AF_INET;
 | 
						|
 | 
						|
	// Attempt to connect to server
 | 
						|
	if(connect(sockDest, (LPSOCKADDR)&sockAddrDest, sizeof(sockAddrDest)) == SOCKET_ERROR)
 | 
						|
	{
 | 
						|
//		printf("Could not connect to server socket: %d\n", WSAGetLastError());
 | 
						|
		closesocket(sockDest);
 | 
						|
		return INVALID_SOCKET;
 | 
						|
	}
 | 
						|
	
 | 
						|
	return sockDest;
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// MS_Write():
 | 
						|
//
 | 
						|
static int MS_Write(msg_t *msg, SOCKET socket)
 | 
						|
{
 | 
						|
#ifdef NONET
 | 
						|
	msg = NULL;
 | 
						|
	return MS_WRITE_ERROR;
 | 
						|
#else
 | 
						|
	int len;
 | 
						|
 | 
						|
	if (msg->length < 0)
 | 
						|
		msg->length = (long)strlen(msg->buffer);
 | 
						|
	len = msg->length + HEADER_SIZE;
 | 
						|
 | 
						|
	msg->type = htonl(msg->type);
 | 
						|
	msg->length = htonl(msg->length);
 | 
						|
 | 
						|
	if (send(socket, (char *)msg, len, 0) != len)
 | 
						|
		return MS_WRITE_ERROR;
 | 
						|
	return 0;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// MS_Read():
 | 
						|
//
 | 
						|
static int MS_Read(msg_t *msg, SOCKET socket)
 | 
						|
{
 | 
						|
#ifdef NONET
 | 
						|
	msg = NULL;
 | 
						|
	return MS_READ_ERROR;
 | 
						|
#else
 | 
						|
	if (recv(socket, (char *)msg, HEADER_SIZE, 0) != HEADER_SIZE)
 | 
						|
		return MS_READ_ERROR;
 | 
						|
 | 
						|
	msg->type = ntohl(msg->type);
 | 
						|
	msg->length = ntohl(msg->length);
 | 
						|
 | 
						|
	if (!msg->length) // fix a bug in Windows 2000
 | 
						|
		return 0;
 | 
						|
 | 
						|
	if (recv(socket, (char *)msg->buffer, msg->length, 0) != msg->length)
 | 
						|
		return MS_READ_ERROR;
 | 
						|
	return 0;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
/** Gets a list of game servers from the master server.
 | 
						|
  */
 | 
						|
static inline int GetServersList(SOCKET socket)
 | 
						|
{
 | 
						|
	msg_t msg;
 | 
						|
	int count = 0;
 | 
						|
 | 
						|
	msg.type = GET_SERVER_MSG;
 | 
						|
	msg.length = 0;
 | 
						|
	if (MS_Write(&msg, socket) < 0)
 | 
						|
		return MS_WRITE_ERROR;
 | 
						|
 | 
						|
	while (MS_Read(&msg, socket) >= 0)
 | 
						|
	{
 | 
						|
		if (!msg.length)
 | 
						|
		{
 | 
						|
//			if (!count)
 | 
						|
//				printf("No server currently running.\n");
 | 
						|
			return MS_NO_ERROR;
 | 
						|
		}
 | 
						|
		count++;
 | 
						|
		printf(msg.buffer);
 | 
						|
	}
 | 
						|
 | 
						|
	return MS_READ_ERROR;
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// RunSocketStuff
 | 
						|
//
 | 
						|
// Thread that checks the masterserver for new games.
 | 
						|
void RunSocketStuff(HWND hListView)
 | 
						|
{
 | 
						|
	WSADATA wsaData;
 | 
						|
	SOCKET sock;
 | 
						|
	int i = 0;
 | 
						|
	char ServerAddressAndPort[256];
 | 
						|
	char Address[256];
 | 
						|
	char Port[8];
 | 
						|
 | 
						|
	if(!GetConfigVariable("masterserver", ServerAddressAndPort)) // srb2.servegame.org:28900
 | 
						|
	{
 | 
						|
		ServerlistThread = NULL;
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	strcpy(Address, ServerAddressAndPort);
 | 
						|
 | 
						|
	for(i = 0; i < (signed)strlen(Address); i++)
 | 
						|
	{
 | 
						|
		if(Address[i] == ':')
 | 
						|
		{
 | 
						|
			Address[i] = '\0';
 | 
						|
			break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	for(i = 0; i < (signed)strlen(ServerAddressAndPort); i++)
 | 
						|
	{
 | 
						|
		if(ServerAddressAndPort[i] == ':')
 | 
						|
		{
 | 
						|
			strcpy(Port, &ServerAddressAndPort[i+1]);
 | 
						|
			break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// Address now contains the hostname or IP
 | 
						|
	// Port now contains the port number
 | 
						|
 | 
						|
 | 
						|
	// Initialize WinSock
 | 
						|
	if(WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
 | 
						|
	{
 | 
						|
//		printf("Could not initialize sockets.\n");
 | 
						|
		ServerlistThread = NULL;
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	// Create socket and connect to server
 | 
						|
	sock = ConnectSocket(/*IPAddress*/0, /*PortNumber*/0);
 | 
						|
	if(sock == INVALID_SOCKET)
 | 
						|
	{
 | 
						|
//		printf("Socket Error: %d\n", WSAGetLastError());
 | 
						|
		ServerlistThread = NULL;
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	// We're connected!
 | 
						|
	// Now get information from server
 | 
						|
 | 
						|
 | 
						|
	// Add games to listview box.
 | 
						|
	ListView_DeleteAllItems(hListView);
 | 
						|
 | 
						|
/*
 | 
						|
	while (MoreServersStillExist)
 | 
						|
	{
 | 
						|
		GetTheNextServerInformation();
 | 
						|
		AddItemToList(hListView, servername, ping, players, gametype, level);
 | 
						|
	}
 | 
						|
*/
 | 
						|
 | 
						|
	// close socket
 | 
						|
	closesocket(sock);
 | 
						|
		
 | 
						|
	// Clean up WinSock
 | 
						|
	if(WSACleanup() == SOCKET_ERROR)
 | 
						|
	{
 | 
						|
//		printf("Could not cleanup sockets: %d\n", WSAGetLastError());
 | 
						|
		ServerlistThread = NULL;
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	printf("Winsock thread terminated successfully.\n");
 | 
						|
	ServerlistThread = NULL;
 | 
						|
 | 
						|
	return;
 | 
						|
}
 | 
						|
 | 
						|
BOOL GetGameList(HWND hListView)
 | 
						|
{
 | 
						|
	DWORD dwThreadID;
 | 
						|
	ServerlistThread = CreateThread(  NULL, // default security
 | 
						|
										 0, // default stack
 | 
						|
										 (LPTHREAD_START_ROUTINE)(void*)RunSocketStuff, // thread function 
 | 
						|
										 hListView, // arguments
 | 
						|
										 0, // default flags 
 | 
						|
										 &dwThreadID); // don't need this, but it makes it happy (and compatible with old Win32 OSes)
 | 
						|
 | 
						|
	if(ServerlistThread == NULL)
 | 
						|
		return false;
 | 
						|
 | 
						|
	return true;
 | 
						|
}
 | 
						|
 | 
						|
void RegisterDialogClass(char* name, WNDPROC callback)
 | 
						|
{
 | 
						|
	WNDCLASS wnd;
 | 
						|
 | 
						|
	wnd.style			= CS_HREDRAW | CS_VREDRAW;
 | 
						|
	wnd.cbWndExtra		= DLGWINDOWEXTRA;
 | 
						|
	wnd.cbClsExtra		= 0;
 | 
						|
	wnd.hCursor			= LoadCursor(NULL,MAKEINTRESOURCE(IDC_ARROW));
 | 
						|
	wnd.hIcon			= LoadIcon(NULL,MAKEINTRESOURCE(IDI_ICON1));
 | 
						|
	wnd.hInstance		= g_hInst;
 | 
						|
	wnd.lpfnWndProc		= callback;
 | 
						|
	wnd.lpszClassName	= name;
 | 
						|
	wnd.lpszMenuName	= NULL;
 | 
						|
	wnd.hbrBackground	= (HBRUSH)(COLOR_WINDOW);
 | 
						|
 | 
						|
	if(!RegisterClass(&wnd))
 | 
						|
	{
 | 
						|
		return;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
int APIENTRY WinMain(HINSTANCE hInstance,
 | 
						|
                     HINSTANCE hPrevInstance,
 | 
						|
                     LPSTR     lpCmdLine,
 | 
						|
                     int       nCmdShow)
 | 
						|
{
 | 
						|
	// Prevent multiples instances of this app.
 | 
						|
	CreateMutex(NULL, true, APPTITLE);
 | 
						|
 | 
						|
	if(GetLastError() == ERROR_ALREADY_EXISTS)
 | 
						|
		return 0;
 | 
						|
 | 
						|
	g_hInst = hInstance;
 | 
						|
 | 
						|
	RegisterDialogClass("SRB2Launcher", MainProc);
 | 
						|
 | 
						|
	DialogBox(g_hInst, (LPCSTR)IDD_MAIN, NULL, (DLGPROC)MainProc);
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// InitHostOptionsComboBoxes
 | 
						|
//
 | 
						|
// Does what it says.
 | 
						|
//
 | 
						|
void InitHostOptionsComboBoxes(HWND hwnd)
 | 
						|
{
 | 
						|
	HWND ctrl;
 | 
						|
 | 
						|
	ctrl = GetDlgItem(hwnd, IDC_MATCHBOXES);
 | 
						|
 | 
						|
	if(ctrl)
 | 
						|
	{
 | 
						|
		SendMessage(ctrl, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Normal (Default)");
 | 
						|
		SendMessage(ctrl, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Random");
 | 
						|
		SendMessage(ctrl, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Non-Random");
 | 
						|
		SendMessage(ctrl, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"None");
 | 
						|
	}
 | 
						|
 | 
						|
	ctrl = GetDlgItem(hwnd, IDC_RACEITEMBOXES);
 | 
						|
 | 
						|
	if(ctrl)
 | 
						|
	{
 | 
						|
		SendMessage(ctrl, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Normal (Default)");
 | 
						|
		SendMessage(ctrl, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Random");
 | 
						|
		SendMessage(ctrl, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Teleports");
 | 
						|
		SendMessage(ctrl, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"None");
 | 
						|
	}
 | 
						|
 | 
						|
	ctrl = GetDlgItem(hwnd, IDC_MATCH_SCORING);
 | 
						|
 | 
						|
	if(ctrl)
 | 
						|
	{
 | 
						|
		SendMessage(ctrl, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Normal (Default)");
 | 
						|
		SendMessage(ctrl, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Classic");
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
LRESULT CALLBACK MatchOptionsDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 | 
						|
{
 | 
						|
	switch(message)
 | 
						|
	{
 | 
						|
		case WM_INITDIALOG:
 | 
						|
			InitHostOptionsComboBoxes(hwnd);
 | 
						|
			break;
 | 
						|
	
 | 
						|
		case WM_DESTROY:
 | 
						|
			EndDialog(hwnd, LOWORD(wParam));
 | 
						|
			break;
 | 
						|
			
 | 
						|
		case WM_COMMAND:
 | 
						|
		{
 | 
						|
			switch(LOWORD(wParam))
 | 
						|
			{
 | 
						|
				case 2:
 | 
						|
					PostMessage(hwnd, WM_DESTROY, 0, 0);
 | 
						|
					break;
 | 
						|
			    default:
 | 
						|
					break;
 | 
						|
			}
 | 
						|
 | 
						|
			break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
LRESULT CALLBACK RaceOptionsDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 | 
						|
{
 | 
						|
	switch(message)
 | 
						|
	{
 | 
						|
		case WM_INITDIALOG:
 | 
						|
			InitHostOptionsComboBoxes(hwnd);
 | 
						|
			break;
 | 
						|
	
 | 
						|
		case WM_DESTROY:
 | 
						|
			EndDialog(hwnd, LOWORD(wParam));
 | 
						|
			break;
 | 
						|
			
 | 
						|
		case WM_COMMAND:
 | 
						|
		{
 | 
						|
			switch(LOWORD(wParam))
 | 
						|
			{
 | 
						|
				case 2:
 | 
						|
					PostMessage(hwnd, WM_DESTROY, 0, 0);
 | 
						|
					break;
 | 
						|
			    default:
 | 
						|
					break;
 | 
						|
			}
 | 
						|
 | 
						|
			break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
LRESULT CALLBACK TagOptionsDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 | 
						|
{
 | 
						|
	switch(message)
 | 
						|
	{
 | 
						|
		case WM_INITDIALOG:
 | 
						|
			InitHostOptionsComboBoxes(hwnd);
 | 
						|
			break;
 | 
						|
	
 | 
						|
		case WM_DESTROY:
 | 
						|
			EndDialog(hwnd, LOWORD(wParam));
 | 
						|
			break;
 | 
						|
			
 | 
						|
		case WM_COMMAND:
 | 
						|
		{
 | 
						|
			switch(LOWORD(wParam))
 | 
						|
			{
 | 
						|
				case 2:
 | 
						|
					PostMessage(hwnd, WM_DESTROY, 0, 0);
 | 
						|
					break;
 | 
						|
			    default:
 | 
						|
					break;
 | 
						|
			}
 | 
						|
 | 
						|
			break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
LRESULT CALLBACK CTFOptionsDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 | 
						|
{
 | 
						|
	switch(message)
 | 
						|
	{
 | 
						|
		case WM_INITDIALOG:
 | 
						|
			InitHostOptionsComboBoxes(hwnd);
 | 
						|
			break;
 | 
						|
	
 | 
						|
		case WM_DESTROY:
 | 
						|
			EndDialog(hwnd, LOWORD(wParam));
 | 
						|
			break;
 | 
						|
			
 | 
						|
		case WM_COMMAND:
 | 
						|
		{
 | 
						|
			switch(LOWORD(wParam))
 | 
						|
			{
 | 
						|
				case 2:
 | 
						|
					PostMessage(hwnd, WM_DESTROY, 0, 0);
 | 
						|
					break;
 | 
						|
			    default:
 | 
						|
					break;
 | 
						|
			}
 | 
						|
 | 
						|
			break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
LRESULT CALLBACK HostProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 | 
						|
{
 | 
						|
	HWND temp;
 | 
						|
 | 
						|
	switch(message)
 | 
						|
	{
 | 
						|
		case WM_INITDIALOG:
 | 
						|
			hostHWND = hwnd;
 | 
						|
 | 
						|
			temp = GetDlgItem(hwnd, IDC_ADVANCEMAP);
 | 
						|
			SendMessage(temp, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Off");
 | 
						|
			SendMessage(temp, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Next (Default)");
 | 
						|
			SendMessage(temp, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Random");
 | 
						|
 | 
						|
			temp = GetDlgItem(hwnd, IDC_GAMETYPE);
 | 
						|
			SendMessage(temp, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Coop");
 | 
						|
			SendMessage(temp, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Match");
 | 
						|
			SendMessage(temp, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Team Match");
 | 
						|
			SendMessage(temp, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Race");
 | 
						|
			SendMessage(temp, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Time-Only Race");
 | 
						|
			SendMessage(temp, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Tag");
 | 
						|
			SendMessage(temp, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"CTF");
 | 
						|
 | 
						|
			break;
 | 
						|
	
 | 
						|
	    case WM_CREATE:
 | 
						|
	    {
 | 
						|
	            
 | 
						|
	        break;
 | 
						|
	    }
 | 
						|
 | 
						|
		case WM_DESTROY:
 | 
						|
		{
 | 
						|
			hostHWND = NULL;
 | 
						|
			EndDialog(hwnd, LOWORD(wParam));
 | 
						|
			break;
 | 
						|
		}
 | 
						|
			
 | 
						|
		case WM_COMMAND:
 | 
						|
		{
 | 
						|
			switch(LOWORD(wParam))
 | 
						|
			{
 | 
						|
				case 2:
 | 
						|
					PostMessage(hwnd, WM_DESTROY, 0, 0);
 | 
						|
					break;
 | 
						|
				case IDC_OPTIONS:
 | 
						|
					{
 | 
						|
						int gametype;
 | 
						|
						int dialognum;
 | 
						|
						DLGPROC callbackfunc;
 | 
						|
 | 
						|
						// Grab the current gametype from the IDC_GAMETYPE
 | 
						|
						// combo box and then display the appropriate
 | 
						|
						// options dialog.
 | 
						|
						temp = GetDlgItem(hostHWND, IDC_GAMETYPE);
 | 
						|
						switch(SendMessage(temp, CB_GETCURSEL, 0, 0))
 | 
						|
						{
 | 
						|
							case 0:
 | 
						|
								gametype = 0;
 | 
						|
								break;
 | 
						|
							case 1:
 | 
						|
								gametype = 1;
 | 
						|
								break;
 | 
						|
							case 2:
 | 
						|
								gametype = 1;
 | 
						|
								break;
 | 
						|
							case 3:
 | 
						|
								gametype = 2;
 | 
						|
								break;
 | 
						|
							case 4:
 | 
						|
								gametype = 2;
 | 
						|
								break;
 | 
						|
							case 5:
 | 
						|
								gametype = 3;
 | 
						|
								break;
 | 
						|
							case 6:
 | 
						|
								gametype = 4;
 | 
						|
								break;
 | 
						|
						}
 | 
						|
 | 
						|
						switch(gametype)
 | 
						|
						{
 | 
						|
							case 1:
 | 
						|
								dialognum = IDD_MATCHOPTIONS;
 | 
						|
								callbackfunc = (DLGPROC)MatchOptionsDlgProc;
 | 
						|
								break;
 | 
						|
							case 2:
 | 
						|
								dialognum = IDD_RACEOPTIONS;
 | 
						|
								callbackfunc = (DLGPROC)RaceOptionsDlgProc;
 | 
						|
								break;
 | 
						|
							case 3:
 | 
						|
								dialognum = IDD_TAGOPTIONS;
 | 
						|
								callbackfunc = (DLGPROC)TagOptionsDlgProc;
 | 
						|
								break;
 | 
						|
							case 4:
 | 
						|
								dialognum = IDD_CTFOPTIONS;
 | 
						|
								callbackfunc = (DLGPROC)CTFOptionsDlgProc;
 | 
						|
								break;
 | 
						|
							case 0:
 | 
						|
							default: // ???
 | 
						|
								dialognum = 0;
 | 
						|
								callbackfunc = NULL;
 | 
						|
								MessageBox(hostHWND, "This gametype does not have any additional options.", "Not Available", MB_OK|MB_APPLMODAL);
 | 
						|
								break;
 | 
						|
						}
 | 
						|
 | 
						|
						if(dialognum)
 | 
						|
							DialogBox(g_hInst, (LPCSTR)dialognum, hostHWND, callbackfunc);
 | 
						|
					}
 | 
						|
					break;
 | 
						|
			    default:
 | 
						|
					break;
 | 
						|
			}
 | 
						|
 | 
						|
			break;
 | 
						|
		}
 | 
						|
 | 
						|
		case WM_PAINT:
 | 
						|
		{
 | 
						|
			break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// AddItemToList
 | 
						|
//
 | 
						|
// Adds a game to the list view.
 | 
						|
//
 | 
						|
void AddItemToList(HWND hListView, char* servername,
 | 
						|
				   char* ping, char* players,
 | 
						|
				   char* gametype, char* level)
 | 
						|
{
 | 
						|
	LVITEM			lvTest;
 | 
						|
 | 
						|
	lvTest.mask = LVIF_TEXT | LVIF_STATE;
 | 
						|
 | 
						|
	lvTest.pszText = servername;
 | 
						|
	lvTest.iIndent = 0;
 | 
						|
	lvTest.stateMask = 0;
 | 
						|
	lvTest.state = 0;
 | 
						|
 | 
						|
	lvTest.iSubItem = 0;
 | 
						|
	lvTest.iItem = ListView_InsertItem(hListView, &lvTest);
 | 
						|
 | 
						|
	ListView_SetItemText(hListView,lvTest.iItem,1,ping);
 | 
						|
 | 
						|
	ListView_SetItemText(hListView,lvTest.iItem,2,players);
 | 
						|
 | 
						|
	ListView_SetItemText(hListView,lvTest.iItem,3,gametype);
 | 
						|
 | 
						|
	ListView_SetItemText(hListView,lvTest.iItem,4,level);
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// InitJoinGameColumns
 | 
						|
//
 | 
						|
// Initializes the column headers on the listview control
 | 
						|
// on the Join Game page.
 | 
						|
//
 | 
						|
void InitJoinGameColumns(HWND hDlg)
 | 
						|
{
 | 
						|
	HWND hItemList;
 | 
						|
	LVCOLUMN		columns[10];
 | 
						|
	int i = 0;
 | 
						|
 | 
						|
	//Create the columns in the list control
 | 
						|
	hItemList = GetDlgItem(hDlg, IDC_GAMELIST);
 | 
						|
 | 
						|
	columns[i].mask = LVCF_TEXT | LVCF_WIDTH;
 | 
						|
	columns[i].pszText = "Server Name";
 | 
						|
	columns[i].cchTextMax = 256;
 | 
						|
	columns[i].cx = 120;
 | 
						|
	columns[i].fmt = LVCFMT_LEFT;
 | 
						|
	ListView_InsertColumn(hItemList, i, &columns[i]);
 | 
						|
 | 
						|
	i++;
 | 
						|
 | 
						|
	columns[i].mask = LVCF_TEXT | LVCF_WIDTH;
 | 
						|
	columns[i].pszText = "Ping";
 | 
						|
	columns[i].cchTextMax = 256;
 | 
						|
	columns[i].cx = 80;
 | 
						|
	columns[i].fmt = LVCFMT_LEFT;
 | 
						|
	ListView_InsertColumn(hItemList, i, &columns[i]);
 | 
						|
 | 
						|
	i++;
 | 
						|
 | 
						|
	columns[i].mask = LVCF_TEXT | LVCF_WIDTH;
 | 
						|
	columns[i].pszText = "Players";
 | 
						|
	columns[i].cchTextMax = 256;
 | 
						|
	columns[i].cx = 80;
 | 
						|
	columns[i].fmt = LVCFMT_LEFT;
 | 
						|
	ListView_InsertColumn(hItemList, i, &columns[i]);
 | 
						|
 | 
						|
	i++;
 | 
						|
 | 
						|
	columns[i].mask = LVCF_TEXT | LVCF_WIDTH;
 | 
						|
	columns[i].pszText = "Game Type";
 | 
						|
	columns[i].cchTextMax = 256;
 | 
						|
	columns[i].cx = 80;
 | 
						|
	columns[i].fmt = LVCFMT_LEFT;
 | 
						|
	ListView_InsertColumn(hItemList, i, &columns[i]);
 | 
						|
 | 
						|
	i++;
 | 
						|
 | 
						|
	columns[i].mask = LVCF_TEXT | LVCF_WIDTH;
 | 
						|
	columns[i].pszText = "Level";
 | 
						|
	columns[i].cchTextMax = 256;
 | 
						|
	columns[i].cx = 120;
 | 
						|
	columns[i].fmt = LVCFMT_LEFT;
 | 
						|
	ListView_InsertColumn(hItemList, i, &columns[i]);
 | 
						|
}
 | 
						|
 | 
						|
LRESULT CALLBACK JoinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 | 
						|
{
 | 
						|
	switch(message)
 | 
						|
	{
 | 
						|
		case WM_INITDIALOG:
 | 
						|
			joinHWND = hwnd;
 | 
						|
			InitJoinGameColumns(hwnd);
 | 
						|
			// Start server listing thread
 | 
						|
			// and grab game list.
 | 
						|
			GetGameList(GetDlgItem(hwnd, IDC_GAMELIST));
 | 
						|
			break;
 | 
						|
	
 | 
						|
		case WM_DESTROY:
 | 
						|
			joinHWND = NULL;
 | 
						|
			// Terminate server listing thread.
 | 
						|
			EndDialog(hwnd, LOWORD(wParam));
 | 
						|
			break;
 | 
						|
			
 | 
						|
		case WM_COMMAND:
 | 
						|
		{
 | 
						|
			switch(LOWORD(wParam))
 | 
						|
			{
 | 
						|
				case 2:
 | 
						|
					PostMessage(hwnd, WM_DESTROY, 0, 0);
 | 
						|
					break;
 | 
						|
				case IDC_SEARCHGAMES:
 | 
						|
					if(ServerlistThread == NULL)
 | 
						|
						GetGameList(GetDlgItem(hwnd, IDC_GAMELIST));
 | 
						|
					break;
 | 
						|
			    default:
 | 
						|
					break;
 | 
						|
			}
 | 
						|
 | 
						|
			break;
 | 
						|
		}
 | 
						|
 | 
						|
		case WM_PAINT:
 | 
						|
		{
 | 
						|
			break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
void InitializeDefaults(void)
 | 
						|
{
 | 
						|
	memset(&launchersettings, 0, sizeof(launchersettings));
 | 
						|
	strcpy(launchersettings.EXEName, "srb2win.exe");
 | 
						|
	strcpy(launchersettings.ConfigFile, "config.cfg");
 | 
						|
}
 | 
						|
 | 
						|
LRESULT CALLBACK MainProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 | 
						|
{
 | 
						|
	HWND temp;
 | 
						|
 | 
						|
	switch(message)
 | 
						|
	{
 | 
						|
		case WM_INITDIALOG:
 | 
						|
			mainHWND = hwnd;
 | 
						|
			InitializeDefaults();
 | 
						|
			SendMessage(GetDlgItem(hwnd, IDC_EXENAME), WM_SETTEXT, 0, (LPARAM)(LPCSTR)launchersettings.EXEName);
 | 
						|
			SendMessage(GetDlgItem(hwnd, IDC_CONFIGFILE), WM_SETTEXT, 0, (LPARAM)(LPCSTR)launchersettings.ConfigFile);
 | 
						|
			break;
 | 
						|
	
 | 
						|
	    case WM_CREATE:
 | 
						|
	    {
 | 
						|
	            
 | 
						|
	        break;
 | 
						|
	    }
 | 
						|
 | 
						|
		case WM_DESTROY:
 | 
						|
		{
 | 
						|
			PostQuitMessage(0);
 | 
						|
			break;
 | 
						|
		}
 | 
						|
			
 | 
						|
		case WM_COMMAND:
 | 
						|
		{
 | 
						|
			switch(LOWORD(wParam))
 | 
						|
			{
 | 
						|
				case 2:
 | 
						|
					PostMessage(hwnd, WM_DESTROY, 0, 0);
 | 
						|
					break;
 | 
						|
				case IDC_ABOUT: // The About button.
 | 
						|
					sprintf(TempString, "%s %s by %s - %s", APPTITLE, APPVERSION, APPAUTHOR, APPCOMPANY);
 | 
						|
					MessageBox(mainHWND, TempString, "About", MB_OK|MB_APPLMODAL);
 | 
						|
					break;
 | 
						|
				case IDC_FINDEXENAME:
 | 
						|
					ChooseEXEName();
 | 
						|
					break;
 | 
						|
				case IDC_FINDCONFIGNAME:
 | 
						|
					ChooseConfigName();
 | 
						|
					break;
 | 
						|
				case IDC_ADDFILE:
 | 
						|
					AddExternalFile();
 | 
						|
					break;
 | 
						|
				case IDC_REMOVEFILE:
 | 
						|
					temp = GetDlgItem(mainHWND, IDC_EXTFILECOMBO);
 | 
						|
					SendMessage(temp, CB_DELETESTRING, SendMessage(temp, CB_GETCURSEL, 0, 0), 0);
 | 
						|
					break;
 | 
						|
				case IDC_HOSTGAME:
 | 
						|
					DialogBox(g_hInst, (LPCSTR)IDD_HOSTGAME, mainHWND, (DLGPROC)HostProc);
 | 
						|
					break;
 | 
						|
				case IDC_JOINGAME:
 | 
						|
					DialogBox(g_hInst, (LPCSTR)IDD_JOINGAME, mainHWND, (DLGPROC)JoinProc);
 | 
						|
					break;
 | 
						|
				case IDC_GO:
 | 
						|
					CompileArguments();
 | 
						|
					RunSRB2();
 | 
						|
					break;
 | 
						|
			    default:
 | 
						|
					break;
 | 
						|
			}
 | 
						|
 | 
						|
			break;
 | 
						|
		}
 | 
						|
 | 
						|
		case WM_PAINT:
 | 
						|
		{
 | 
						|
			break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 |