mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 13:47:58 +03:00
Use the original gqueryreporting from GameSpy SDK
Potentially more stable and thoroughly tested
This commit is contained in:
parent
aa7639485e
commit
ffc35fb5ab
4 changed files with 860 additions and 496 deletions
|
@ -79,10 +79,6 @@ static const char* GS_GAME_VERSION_DEMO[] =
|
||||||
|
|
||||||
static const unsigned int GAMESPY_DEFAULT_PORT = 12300;
|
static const unsigned int GAMESPY_DEFAULT_PORT = 12300;
|
||||||
|
|
||||||
void qr_send_statechanged(qr_t qrec);
|
|
||||||
void qr_shutdown(qr_t qrec);
|
|
||||||
void qr_process_queries(qr_t qrec);
|
|
||||||
|
|
||||||
int qr_init(
|
int qr_init(
|
||||||
qr_t *qrec,
|
qr_t *qrec,
|
||||||
const char *ip,
|
const char *ip,
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -20,47 +20,180 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
===========================================================================
|
===========================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/******
|
||||||
|
gqueryreporting.h
|
||||||
|
GameSpy Query & Reporting SDK
|
||||||
|
|
||||||
|
Copyright 2000 GameSpy Industries, Inc
|
||||||
|
|
||||||
|
18002 Skypark Circle
|
||||||
|
Irvine, CA 92614
|
||||||
|
(949)798-4200
|
||||||
|
Fax(949)798-4299
|
||||||
|
******
|
||||||
|
|
||||||
|
Please see the GameSpy Query & Reporting SDK documentation for more
|
||||||
|
information
|
||||||
|
|
||||||
|
******/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/gsPlatformSocket.h"
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MAX_KEYVALUES_LENGTH 1400
|
/********
|
||||||
|
ERROR CONSTANTS
|
||||||
|
---------------
|
||||||
|
These constants are returned from qr_init to signal an error condition
|
||||||
|
***************/
|
||||||
|
|
||||||
static const unsigned int MIN_HEARTBEAT_TIME = 30000; // wait at least 30 seconds before new heartbeat can be sent
|
#define E_GOA_WSOCKERROR 1
|
||||||
static const unsigned int MAX_HEARTBEAT_TIME = 300000; // 5 minutes
|
#define E_GOA_BINDERROR 2
|
||||||
|
#define E_GOA_DNSERROR 3
|
||||||
|
#define E_GOA_CONNERROR 4
|
||||||
|
/*********
|
||||||
|
NUM_PORTS_TO_TRY
|
||||||
|
----------------
|
||||||
|
This value is the maximum number of ports that will be scanned to
|
||||||
|
find an open query port, starting from the value passed to qr_init
|
||||||
|
as the base port. Generally there is no reason to modify this value.
|
||||||
|
***********/
|
||||||
|
#define NUM_PORTS_TO_TRY 100
|
||||||
|
|
||||||
typedef void (*qr_querycallback_t)(char *outbuf, int maxlen, void *userdata);
|
/* The hostname of the master server.
|
||||||
|
If the app resolves the hostname, an
|
||||||
|
IP can be stored here before calling
|
||||||
|
qr_init */
|
||||||
|
extern char qr_hostname[64];
|
||||||
|
|
||||||
|
/********
|
||||||
|
qr_querycallback_t
|
||||||
|
-------------------
|
||||||
|
This is the prototype for the callback functions your game needs to
|
||||||
|
implement for each of the four basic query types. The callback works the
|
||||||
|
same for each query type.
|
||||||
|
|
||||||
|
[outbuf] is a pre-allocated buffer for you to place the query reply. It's size is
|
||||||
|
[maxlen] (default is 1400). If you need larger, you can adjust the
|
||||||
|
defines in gqueryreporting.c
|
||||||
|
[userdata] is the pointer that was passed into qr_init. You can use this for an
|
||||||
|
object or structure pointer if needed.
|
||||||
|
|
||||||
|
Simply fill outbuf with the correct data for the query type (consult the sample
|
||||||
|
apps and the GameSpy Developer Spec).
|
||||||
|
outbuf should be a NULL terminated ANSI string.
|
||||||
|
********/
|
||||||
|
typedef void (*qr_querycallback_t)(char *outbuf, int maxlen, void *userdata);
|
||||||
typedef void (*qr_custom_handler_t)(const char *query, struct sockaddr *sender);
|
typedef void (*qr_custom_handler_t)(const char *query, struct sockaddr *sender);
|
||||||
|
|
||||||
typedef enum query_e {
|
/***********
|
||||||
qtunknown,
|
qr_t
|
||||||
qtbasic,
|
----
|
||||||
qtinfo,
|
This abstract type is used to instantiate multiple instances of the
|
||||||
qtrules,
|
Query & Reporting SDK (for example, if you are running multiple servers
|
||||||
qtplayers,
|
in the same process).
|
||||||
qtstatus,
|
For most games, you can ignore this value and pass NULL in to all functions
|
||||||
qtpackets,
|
that require it. A single global instance will be used, similar to how the
|
||||||
qtecho,
|
original Developer SDK worked
|
||||||
qtsecure
|
************/
|
||||||
} query_t;
|
typedef struct qr_implementation_s *qr_t;
|
||||||
|
|
||||||
typedef struct qr_implementation_s {
|
|
||||||
void *querysock;
|
|
||||||
void *hbsock;
|
|
||||||
char gamename[64];
|
|
||||||
char secret_key[128];
|
|
||||||
qr_querycallback_t qr_basic_callback;
|
|
||||||
qr_querycallback_t qr_info_callback;
|
|
||||||
qr_querycallback_t qr_rules_callback;
|
|
||||||
qr_querycallback_t qr_players_callback;
|
|
||||||
long unsigned int lastheartbeat;
|
|
||||||
int queryid;
|
|
||||||
int packetnumber;
|
|
||||||
int qport;
|
|
||||||
char no_query;
|
|
||||||
struct sockaddr_in master_saddr;
|
|
||||||
qr_custom_handler_t qr_custom_handler;
|
|
||||||
void *udata;
|
|
||||||
} qr_implementation_t, *qr_t;
|
|
||||||
|
|
||||||
|
/************
|
||||||
|
QR_INIT
|
||||||
|
--------
|
||||||
|
This creates/binds the sockets needed for heartbeats and queries/replies.
|
||||||
|
[qrec] if not null, will be filled with the qr_t instance for this server.
|
||||||
|
If you are not using more than one instance of the Query & Reporting SDK you
|
||||||
|
can pass in NULL for this value.
|
||||||
|
[ip] is an optional parameter that determines which dotted IP address to bind to on
|
||||||
|
a multi-homed machine. You can pass NULL to bind to all IP addresses.
|
||||||
|
[baseport] is the port to accept queries on. If baseport is not available, the
|
||||||
|
Query and Reporting SDK will scan for an available port in the range of
|
||||||
|
baseport -> baseport + NUM_PORTS_TO_TRY
|
||||||
|
Optionally, you can pass in 0 to have a port chosen automatically
|
||||||
|
(makes it harder for debugging/testing).
|
||||||
|
[gamename] is the unique gamename that you were given
|
||||||
|
[secretkey] is your unique secret key
|
||||||
|
[qr_*_callback] are your data callback functions, this cannot be NULL
|
||||||
|
[userdata] is an optional, implementation specific parameter that will be
|
||||||
|
passed to all callback functions. Use it to store an object or structure
|
||||||
|
pointer if needed.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
0 is successful, otherwise one of the E_GOA constants above.
|
||||||
|
************/
|
||||||
|
int qr_init(/*[out]*/qr_t *qrec, const char *ip, int baseport, const char *gamename, const char *secret_key,
|
||||||
|
qr_querycallback_t qr_basic_callback,
|
||||||
|
qr_querycallback_t qr_info_callback,
|
||||||
|
qr_querycallback_t qr_rules_callback,
|
||||||
|
qr_querycallback_t qr_players_callback,
|
||||||
|
void *userdata);
|
||||||
|
|
||||||
|
|
||||||
|
/*******************
|
||||||
|
QR_PROCESS_QUERIES
|
||||||
|
-------------------
|
||||||
|
This function should be called somewhere in your main program loop to
|
||||||
|
process any pending server queries and send a heartbeat if 5 minutes has
|
||||||
|
elapsed.
|
||||||
|
|
||||||
|
Query replies are very latency sensative, so you should make sure this
|
||||||
|
function is called at least every 100ms while your game is in progress.
|
||||||
|
The function has very low overhead and should not cause any performance
|
||||||
|
problems.
|
||||||
|
Unless you are using multiple instances of the SDK, you should pass NULl
|
||||||
|
for qrec.
|
||||||
|
The no_heartbeat version will not send any heartbeats to the master - use
|
||||||
|
this if you only want to advertise your server on the LAN.
|
||||||
|
********************/
|
||||||
|
void qr_process_queries(qr_t qrec);
|
||||||
|
void qr_process_queries_no_heartbeat(qr_t qrec);
|
||||||
|
|
||||||
|
/*****************
|
||||||
|
QR_SEND_STATECHANGED
|
||||||
|
--------------------
|
||||||
|
This function forces a \statechanged\ heartbeat to be sent immediately.
|
||||||
|
Use it any time you have changed the gamestate of your game to signal the
|
||||||
|
master to update your status.
|
||||||
|
Also use it before your game exits by changing the gamestate to "exiting"
|
||||||
|
and sending a statechanged heartbeat. This will insure that your game
|
||||||
|
is removed from the list promptly.
|
||||||
|
Unless you are using multiple instances of the SDK, you should pass NULl
|
||||||
|
for qrec.
|
||||||
|
*******************/
|
||||||
|
void qr_send_statechanged(qr_t qrec);
|
||||||
|
|
||||||
|
/*****************
|
||||||
|
QR_SHUTDOWN
|
||||||
|
------------
|
||||||
|
This function closes the sockets created in qr_init and takes care of
|
||||||
|
any misc. cleanup. You should try to call it when before exiting the server
|
||||||
|
if qr_init was called.
|
||||||
|
If you pass in a qrec that was returned from qr_init, all resources associated
|
||||||
|
with that qrec will be freed. If you passed NULL into qr_int, you can pass
|
||||||
|
NULL in here as well.
|
||||||
|
******************/
|
||||||
|
void qr_shutdown(qr_t qrec);
|
||||||
|
|
||||||
|
void qr_check_queries(qr_t qrec);
|
||||||
|
|
||||||
|
/********
|
||||||
|
DEFINES
|
||||||
|
********/
|
||||||
|
#define MASTER_PORT 27900
|
||||||
|
#define MASTER_ADDR MASTER_SERVER_HOST
|
||||||
|
#define FIRST_HB_TIME 30000 /* 30 sec */
|
||||||
|
#define HB_TIME 300000 /* 5 minutes */
|
||||||
|
#define MAX_FIRST_COUNT 10 /* 10 tries = 5 minutes */
|
||||||
|
#define MAX_DATA_SIZE 1400
|
||||||
|
#define INBUF_LEN 256
|
||||||
|
#define BUF_SIZE 1400
|
||||||
#define MASTER_SERVER_HOST "master.333networks.com"
|
#define MASTER_SERVER_HOST "master.333networks.com"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -267,7 +267,7 @@ void SV_MasterHeartbeat( void ) {
|
||||||
|
|
||||||
if (svs.time >= svs.nextHeartbeatTime)
|
if (svs.time >= svs.nextHeartbeatTime)
|
||||||
{
|
{
|
||||||
svs.nextHeartbeatTime = svs.time + MAX_HEARTBEAT_TIME;
|
svs.nextHeartbeatTime = svs.time + HB_TIME;
|
||||||
SV_GamespyHeartbeat();
|
SV_GamespyHeartbeat();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue