#include "AdeptHeaders.hpp" #include "GameSpy.h" #include #include "buildnum/buildnum.h" #pragma comment(lib, "wsock32") #ifndef NEW_GAMESPY /****** goasample.c GameSpy Developer SDK Sample App Copyright 1999 GameSpy Industries, Inc Suite E-204 2900 Bristol Street Costa Mesa, CA 92626 (714)549-7689 Fax(714)549-0757 ****** This source file includes a "sample" game shell which demonstrates how to use the GameSpy Developer SDK (goautil.h) Please see the GameSpy Developer SDK documentation for more information ******/ #define FixSZString(s) ((s)[sizeof(s)-1]) = 0 namespace GameSpyOld { bool bGameSpy; }; /******** INCLUDES ********/ #include "nonport.h" #include "goautil.h" #include #include #include #include /******** DEFINES ********/ #define GAME_VERSION CURRENT_BUILD_FULL_STRING #define GAME_NAME GAMESPY_MASTER_ENGINENAME #define MAX_PLAYERS 32 #ifdef _WIN32_WCE void RetailOutputA(CHAR *tszErr, ...); #define printf RetailOutputA #endif /******** TYPDEFS ********/ //representative of a game player structure typedef struct { char pname[80]; char pteam[80]; int id; } player_t; //representative of a game data structure typedef struct { player_t players[MAX_PLAYERS]; char gamename[50]; char mapname[20]; char hostname[120]; char gamemode[200]; char gametype[30]; GUID guid; int locationid; int numplayers; int maxplayers; int fraglimit; int timelimit; int teamplay; int rankingson; int hostport; int flags; } gamedata_t; /******** GLOBAL VARS ********/ //just to give us bogus data char *constnames[MAX_PLAYERS]={"Joe Player","L33t 0n3","Raptor","Gr81","Flubber","Sarge","Void","runaway","Ph3ar","wh00t","gr1nder","Mace","stacy","lamby","Thrush"}; gamedata_t gamedata; /************* basic_callback sends a (sample) response to the basic query includes the following keys: \gamename\ \gamever\ \location\ *************/ static void basic_callback(char *outbuf, int maxlen, void *userdata) { sprintf(outbuf, "\\%s\\%s\\%s\\%s\\%s\\%d", GAMESPY_KEY_GAME_NAME, gamedata.gamename, GAMESPY_KEY_PRODUCT_VERSION, GAME_VERSION, GAMESPY_KEY_LOCATION, gamedata.locationid); // printf("Basic callback, sent: %s\n",outbuf); } /************ info_callback Sends a (sample) response to the info query including the following keys: \hostname\ \hostport\ \mapname\ \gametype\ \numplayers\ \maxplayers\ \gamemode\ ************/ static void info_callback(char *outbuf, int maxlen, void *userdata) { char keyvalue[200]; sprintf(keyvalue,"\\%s\\%s", GAMESPY_KEY_HOSTNAME, gamedata.hostname);strcat(outbuf, keyvalue); sprintf(keyvalue,"\\%s\\%d", GAMESPY_KEY_HOSTPORT, gamedata.hostport);strcat(outbuf, keyvalue); sprintf(keyvalue,"\\%s\\%s", GAMESPY_KEY_MAP_TYPE, gamedata.mapname);strcat(outbuf, keyvalue); sprintf(keyvalue,"\\%s\\%s", GAMESPY_KEY_GAME_TYPE, gamedata.gametype);strcat(outbuf, keyvalue); sprintf(keyvalue,"\\%s\\%d", GAMESPY_KEY_NUM_PLAYERS, gamedata.numplayers);strcat(outbuf, keyvalue); sprintf(keyvalue,"\\%s\\%d", GAMESPY_KEY_MAX_PLAYERS, gamedata.maxplayers);strcat(outbuf, keyvalue); sprintf(keyvalue,"\\%s\\%s", GAMESPY_KEY_GAMEMODE, gamedata.gamemode);strcat(outbuf, keyvalue); sprintf(keyvalue,"\\%s\\%d", GAMESPY_KEY_FLAGS, gamedata.flags);strcat(outbuf, keyvalue); sprintf(keyvalue,"\\%s\\{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", GAMESPY_KEY_INSTANCE, gamedata.guid.Data1, gamedata.guid.Data2, gamedata.guid.Data3, gamedata.guid.Data4[0], gamedata.guid.Data4[1], gamedata.guid.Data4[2], gamedata.guid.Data4[3], gamedata.guid.Data4[4], gamedata.guid.Data4[5], gamedata.guid.Data4[6], gamedata.guid.Data4[7]);strcat(outbuf, keyvalue); // printf("Info callback, sent: %s\n",outbuf); } /*************** rules_callback Sends a response to the rules query. You may need to add custom fields for your game in here. Some are provided as an example The following rules are included: \timelimit\ \fraglimit\ \teamplay\ \rankedserver\ ****************/ static void rules_callback(char *outbuf, int maxlen, void *userdata) { // char keyvalue[80]; // sprintf(keyvalue,"\\%s\\%d", GAMESPY_KEY_TIMELIMIT, gamedata.timelimit);strcat(outbuf, keyvalue); // sprintf(keyvalue,"\\%s\\%d", GAMESPY_KEY_FRAGLIMIT, gamedata.fraglimit);strcat(outbuf, keyvalue); // sprintf(keyvalue,"\\%s\\%d", GAMESPY_KEY_TEAMPLAY, gamedata.teamplay);strcat(outbuf, keyvalue); // //sample custom key/value // sprintf(keyvalue,"\\%s\\%d", GAMESPY_KEY_RANKEDSERVER, gamedata.rankingson);strcat(outbuf, keyvalue); // printf("Rules callback, sent: %s\n",outbuf); } /*************** players_callback sends the players and their information. Note that \ characters are not stripped out of player names. If your game allows players or team names with the \ character, you will need to strip or change it here. The following keys are included for each player: \player_N\ \frags_N\ \deaths_N\ \skill_N\ \ping_N\ \team_N\ ***************/ static void players_callback(char *outbuf, int maxlen, void *userdata) { char keyvalue[160]; int i; for (i = 0; i < gamedata.numplayers ; i++) { sprintf(keyvalue, "\\player_%d\\%s\\team_%d\\%s", i, gamedata.players[i].pname, i, gamedata.players[i].pteam); strcat(outbuf, keyvalue); } //printf("Players callback, sent: %s\n",outbuf); } /////*********** ////init_game ////Initialize the sample data structures with bogus data ////************/ ////static void init_game(void) ////{ //// int i; //// int team; //// //// srand( current_time() ); //// gamedata.numplayers = rand() % 15; //// gamedata.maxplayers = MAX_PLAYERS; //// for (i = 0 ; i < gamedata.numplayers ; i++) //// { //// strcpy(gamedata.players[i].pname, constnames[i]); //// gamedata.players[i].pfrags = rand() % 32; //// gamedata.players[i].pdeaths = rand() % 32; //// gamedata.players[i].pskill = rand() % 1000; //// gamedata.players[i].pping = rand() % 500; //// team = rand() % 3; //// if (team == 0) //// strcpy(gamedata.players[i].pteam,"Red"); //// else if (team == 1) //// strcpy(gamedata.players[i].pteam,"Blue"); //// else if (team == 2) //// strcpy(gamedata.players[i].pteam,""); //// } //// strcpy(gamedata.mapname,"gmtmap1"); //// strcpy(gamedata.gametype,"arena"); //// strcpy(gamedata.hostname,"GameMaster Arena Server"); //// strcpy(gamedata.gamemode,"openplaying"); //// gamedata.fraglimit = 0; //// gamedata.timelimit = 40; //// gamedata.teamplay = 1; //// gamedata.locationid = 1; //// gamedata.rankingson = 1; //// gamedata.hostport = 25000; ////} /******* DoGameStuff Simulate whatever else a game server does ********/ void DoGameStuff(void) { msleep(10); } /////******************* //// main ////Simulates a main program loop ////First, initializes the GOA items, then enters a main loop ////*****************/ ////int main_1(int argc, char* argv[]) ////{ //// //set the callback functions //// goa_basic_callback = basic_callback; //// goa_info_callback = info_callback; //// goa_rules_callback = rules_callback; //// goa_players_callback = players_callback; //// //set the secret key, in a semi-obfuscated manner //// ////#if 0 //// goa_secret_key[0] = 'H'; //// goa_secret_key[1] = 'A'; //// goa_secret_key[2] = '6'; //// goa_secret_key[3] = 'z'; //// goa_secret_key[4] = 'k'; //// goa_secret_key[5] = 'S'; //// goa_secret_key[6] = '\0'; ////#endif //// init_game(); //// //// //call goa_init with the query port number and gamename, default IP address, and no user data //// if (goa_init(27950,GAME_NAME, "localhost", NULL) != 0) //// { //// fprintf(stderr,"Error starting query sockets\n"); //// return -1; //// } //// //// while (kbhit()) //// _getch(); //// //// printf("Press any key to quit\n"); //// while (!kbhit()) //// { //// DoGameStuff(); //// //check for / process incoming queries //// goa_process_queries(); //// //// } //// _getch(); //// //// //let gamemaster know we are shutting down //// strcpy(gamedata.gamemode,"exiting"); //// goa_send_statechanged(); //// goa_shutdown(); //// //// return 0; //// ////} //======================================================================== //======================================================================== bool GameSpyOld::BeginAdvertisingOnGameSpy(const char * GameName, const char *PlayerName, int MaxPlayers, const char *Password, const GUID &guidInstance, bool Secure, DWORD dwFlags) { EndAdvertisingOnGameSpy(); gosASSERT(GameName != NULL); #ifdef _DEBUG if (!GameName) GameName = "testgame"; #endif strcpy(goa_secret_key, GetKeyName()); //set the callback functions goa_basic_callback = basic_callback; goa_info_callback = info_callback; goa_rules_callback = rules_callback; goa_players_callback = players_callback; //init_game(); strncpy(gamedata.players[0].pname, PlayerName, sizeof(gamedata.players[0].pname)); strncpy(gamedata.gamename, GameName, sizeof(gamedata.gamename)); //strncpy(gamedata.gametype, Environment.applicationName, sizeof(gamedata.gametype)); FixSZString(gamedata.players[0].pname); FixSZString(gamedata.gamename); //FixSZString(gamedata.gametype); //strncpy(gamedata.mapname, "map", sizeof(gamedata.mapname)); //strncpy(gamedata.hostname, GameName, sizeof(gamedata.hostname)); gamedata.numplayers = 1; gamedata.maxplayers = MaxPlayers; gamedata.guid = guidInstance; gamedata.flags = dwFlags; //call goa_init with the query port number and gamename, default IP address, and no user data if (goa_init(GetQueryPort(), GAMESPY_MASTER_ENGINENAME, "localhost", NULL) != 0) { return false; } bGameSpy = true; return true; } //======================================================================== //======================================================================== void GameSpyOld::SetKey(const char *szKey, const char *szValue) { if (!strcmp(szKey, GAMELIST_KEY_MAP_TYPE)) { strcpy(gamedata.mapname, szValue); } if (!strcmp(szKey, GAMELIST_KEY_GAME_TYPE)) { strcpy(gamedata.gametype, szValue); } goa_send_statechanged(); } //======================================================================== //======================================================================== void GameSpyOld::EndAdvertisingOnGameSpy(void) { if (bGameSpy) { goa_send_statechanged(); goa_shutdown(); bGameSpy = false; } return; } //======================================================================== //======================================================================== bool GameSpyOld::AddPlayer(int id, const char *szName, const char *szTeam, int reserved) { if (gamedata.numplayers == MAX_PLAYERS) return false; if (szName) { strncpy(gamedata.players[gamedata.numplayers].pname, szName, sizeof(gamedata.players[gamedata.numplayers].pname)); gamedata.players[gamedata.numplayers].pname[sizeof(gamedata.players[gamedata.numplayers].pname)-1]=0; } else gamedata.players[gamedata.numplayers].pname[0]=0; if (szTeam) { strncpy(gamedata.players[gamedata.numplayers].pteam, szTeam, sizeof(gamedata.players[gamedata.numplayers].pteam)); gamedata.players[gamedata.numplayers].pteam[sizeof(gamedata.players[gamedata.numplayers].pteam)-1]=0; } else gamedata.players[gamedata.numplayers].pteam[0]=0; gamedata.players[gamedata.numplayers].id = id; gamedata.numplayers++; goa_send_statechanged(); return true; } //======================================================================== //======================================================================== bool GameSpyOld::RemovePlayer(int id, const char *szName, const char *szTeam, int reserved) { int i; for (i=0 ; i