mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 13:47:58 +03:00
389 lines
13 KiB
C
389 lines
13 KiB
C
/******
|
|
gstats.h
|
|
GameSpy Stats/Tracking SDK
|
|
|
|
Copyright 1999-2007 GameSpy Industries, Inc
|
|
|
|
******
|
|
|
|
Please see the GameSpy Stats and Tracking SDK documentation for more info
|
|
|
|
08-23-00 - DDW
|
|
Fixed a problem that prevented opening/closing/re-opening of the connection within
|
|
a single session.
|
|
|
|
*****/
|
|
|
|
#ifndef _GSTATS_H_
|
|
#define _GSTATS_H_
|
|
|
|
|
|
/********
|
|
INCLUDES
|
|
********/
|
|
#include "../common/gsCommon.h"
|
|
#include "gbucket.h"
|
|
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#if defined(_WIN32)
|
|
// Warnings are generated because we store function ptrs into a void* array
|
|
#pragma warning(disable: 4152) // function to data ptr
|
|
#pragma warning(disable: 4055) // data to function ptr
|
|
#endif
|
|
|
|
|
|
/********
|
|
TYPEDEFS
|
|
********/
|
|
|
|
|
|
/* The abstracted "game" structure */
|
|
typedef struct statsgame_s *statsgame_t;
|
|
|
|
/* All of the operations you can do on a bucket */
|
|
typedef enum {bo_set, bo_add, bo_sub, bo_mult, bo_div, bo_concat, bo_avg} bucketop_t;
|
|
#define NUMOPS 7
|
|
|
|
/* The types of buckets (server info, team info, or player info) */
|
|
typedef enum {bl_server, bl_team, bl_player} bucketlevel_t;
|
|
|
|
/* Init states for async initialization */
|
|
typedef enum {init_none, init_failed, init_connecting, init_awaitchallenge, init_awaitsessionkey, init_complete} initstate_t;
|
|
|
|
/* Used by the bucket operation macros */
|
|
typedef void *(*BucketFunc)(bucketset_t set, char *name,void *value);
|
|
typedef int (*SetIntFunc)(statsgame_t game,char *name, BucketFunc func, int value, int index);
|
|
typedef double (*SetFloatFunc)(statsgame_t game,char *name, BucketFunc func, double value, int index);
|
|
typedef char *(*SetStringFunc)(statsgame_t game,char *name, BucketFunc func, char *value, int index);
|
|
extern BucketFunc bucketfuncs[NUMOPS];
|
|
extern void * bopfuncs[][3];
|
|
|
|
/********
|
|
DEFINES
|
|
********/
|
|
/* Error codes */
|
|
#define GE_NOERROR 0
|
|
#define GE_NOSOCKET 1 /* Unable to create a socket */
|
|
#define GE_NODNS 2 /* Unable to resolve a DNS name */
|
|
#define GE_NOCONNECT 3 /* Unable to connect to stats server, or connection lost */
|
|
#define GE_BUSY 4 /* Not used */
|
|
#define GE_DATAERROR 5 /* Bad data from the stats server */
|
|
#define GE_CONNECTING 6 /* Connect did no immediately complete. Call InitStatsThink() */
|
|
#define GE_TIMEDOUT 7 /* Connect attempt timed out */
|
|
|
|
/* Types of snapshots, update (any snapshot that is not final) or final */
|
|
#define SNAP_UPDATE 0
|
|
#define SNAP_FINAL 1
|
|
|
|
/* If you want to allow disk logging in case the stats server isn't available.
|
|
This has SERIOUS security repercussions, so please read the docs before turning this on */
|
|
#define ALLOW_DISK
|
|
|
|
#if defined(NOFILE)
|
|
#undef ALLOW_DISK
|
|
#endif /* make sure it's never defined on platforms with no disk! */
|
|
|
|
/********
|
|
VARS
|
|
********/
|
|
|
|
/* You need to fill these in with your game-specific info */
|
|
extern char gcd_secret_key[256];
|
|
extern char gcd_gamename[256];
|
|
|
|
/* The hostname of the stats server.
|
|
If the app resolves the hostname, an
|
|
IP can be stored here before calling
|
|
InitStatsConnection */
|
|
extern char StatsServerHostname[64];
|
|
|
|
|
|
/********
|
|
PROTOTYPES
|
|
********/
|
|
#ifndef GSI_UNICODE
|
|
#define GenerateAuth GenerateAuthA
|
|
#define SendGameSnapShot SendGameSnapShotA
|
|
#define NewPlayer NewPlayerA
|
|
#define NewTeam NewTeamA
|
|
#else
|
|
#define GenerateAuth GenerateAuthW
|
|
#define SendGameSnapShot SendGameSnapShotW
|
|
#define NewPlayer NewPlayerW
|
|
#define NewTeam NewTeamW
|
|
#endif
|
|
|
|
/********
|
|
InitStatsConnection
|
|
|
|
DESCRIPTION
|
|
Opens a connection to the stats server. Should be done before calling
|
|
NewGame or any of the bucket/snapshot functions. May block for 1-2 secs
|
|
while the connection is established so you will want to do this before
|
|
gameplay starts or in another thread.
|
|
|
|
PARAMETERS
|
|
gameport: integer port associated with your server (may be the same as
|
|
your developer spec query port). Used only to help players differentiate
|
|
between servers on the same machine (no queries are done on it). If not
|
|
appropriate for your game, pass in 0.
|
|
|
|
RETURNS
|
|
GE_NODNS: Unable to resolve stats server DNS
|
|
GE_NOSOCKET: Unable to create data socket
|
|
GE_NOCONNECT: Unable to connect to stats server
|
|
GE_DATAERROR: Unable to receive challenge from stats server, or bad challenge
|
|
GE_NOERROR: Connected to stats server and ready to send data
|
|
|
|
Note: You can still call ANY of the other Stats SDK functions, even if the
|
|
connection fails. If you have disk logging enabled, these calls will be logged
|
|
for future sending, otherwise they will be discarded.
|
|
*********/
|
|
int InitStatsConnection(int gameport);
|
|
int InitStatsAsync(int gameport, gsi_time theInitTimeout);
|
|
int InitStatsThink();
|
|
|
|
|
|
/********
|
|
StatsThink
|
|
|
|
DESCRIPTION
|
|
Eats up any incoming keep-alive messages that are sent by the stats server.
|
|
Returns any errors occur because of a socket problem or if the SDK was
|
|
not completely initialized.
|
|
|
|
RETURNS
|
|
1 if no errors occured during read, 0 on all other errors
|
|
********/
|
|
int StatsThink();
|
|
|
|
/********
|
|
IsStatsConnected
|
|
|
|
DESCRIPTION
|
|
Returns whether or not you are currently connected to the stats server. Even
|
|
if your initial connection was successful, you may lose connection later and
|
|
want to try to reconnnect
|
|
|
|
RETURNS
|
|
1 if connected, 0 otherwise
|
|
*********/
|
|
int IsStatsConnected();
|
|
|
|
/********
|
|
CloseStatsConnection
|
|
|
|
DESCRIPTION
|
|
Closes the connection to the stats server. You should do this when done
|
|
with the connection.
|
|
*********/
|
|
void CloseStatsConnection(void);
|
|
|
|
/********
|
|
GetChallenge
|
|
|
|
DESCRIPTION
|
|
Returns a string that should be sent to clients for authentication
|
|
(using GenerateAuth). You do not have to free the string when done.
|
|
This string will be constant for the entire length of the game and is
|
|
generated during the call to NewGame.
|
|
|
|
PARAMETERS
|
|
game: Game to return the challenge string for. If game is NULL, the last
|
|
game created with NewGame will be used.
|
|
|
|
RETURNS
|
|
A string to send to clients so they can authorize. If you game is NULL and
|
|
you haven't created a game with NewGame, it returns "NULLGAME".
|
|
*********/
|
|
char *GetChallenge(statsgame_t game);
|
|
|
|
/********
|
|
GenerateAuth
|
|
|
|
DESCRIPTION
|
|
Should be used on the CLIENT SIDE to generate an authentication reply
|
|
(auth_N) for a given challenge and password (CD Key or Profile password)
|
|
|
|
PARAMETERS
|
|
challenge: The challenge string sent by the server. On the server this
|
|
should be generated with GetChallenge
|
|
password: The CD Key (un-hashed) or profile password
|
|
response: The output authentication string
|
|
|
|
RETURNS
|
|
A pointer to response
|
|
*********/
|
|
char *GenerateAuth(const char *challenge, const gsi_char *password,/*[out]*/char response[33]);
|
|
|
|
/********
|
|
NewGame
|
|
|
|
DESCRIPTION
|
|
Creates a new game for logging and registers it with the stats server.
|
|
Creates all the game structures, including buckets if needed.
|
|
|
|
PARAMETERS
|
|
usebuckets: Set to 1 for bucket based logging, 0 if you are going to create
|
|
the snapshots yourself. See the SDK for more info.
|
|
|
|
RETURNS
|
|
A pointer to the new game. If you are not connected, and disk logging is
|
|
disabled, this will be NULL. You can still pass NULL to any function without
|
|
causing any errors.
|
|
Note: The last game created by NewGame is stored internally.
|
|
If you only create / use one game at a time, you can simply discard
|
|
the return value and pass NULL for game into all of the bucket and snapshot functions.
|
|
*********/
|
|
statsgame_t NewGame(int usebuckets);
|
|
|
|
/********
|
|
FreeGame
|
|
|
|
DESCRIPTION
|
|
Frees a game and its associated structures (including buckets). You should
|
|
send a final snapshot for the game (using SendGameSnapShot with SNAP_FINAL)
|
|
before freeing the game.
|
|
|
|
PARAMETERS
|
|
game: The game you want to free. If set to NULL, it will free the last
|
|
game created with NewGame.
|
|
*********/
|
|
void FreeGame(statsgame_t game);
|
|
|
|
/********
|
|
SendGameSnapShot
|
|
|
|
DESCRIPTION
|
|
Sends a snapshot of information about the current game. If bucket based
|
|
logging is enabled the snapshot will be generated from the buckets, otherwise
|
|
you should provide it in "snapshot".
|
|
|
|
PARAMETERS
|
|
game: The game to send a snapshot for. If set to NULL, the last game
|
|
created with NewGame will be used.
|
|
snapshot: The snapshot to send. If you are using buckets, this will not be
|
|
used, so you can pass in NULL
|
|
final: If this is SNAP_UPDATE, the game is marked as in progress, if it
|
|
is SNAP_FINAL, the game is marked as complete.
|
|
|
|
RETURNS
|
|
GE_DATAERROR: If game is NULL and the last game created by NewGame failed
|
|
(because the connection was lost and disk logging is disabled)
|
|
GE_NOCONNECT: If the connection is lost and disk logging is disabled
|
|
GE_NOERROR: The update was sent, or disk logging is enabled and the game was logged
|
|
*********/
|
|
int SendGameSnapShot(statsgame_t game, const gsi_char *snapshot, int final);
|
|
|
|
/******************************
|
|
BUCKET FUNCTION PROTOTYPES
|
|
These functions are only used for bucket-based logging
|
|
*******************************/
|
|
|
|
/********
|
|
Bucket_____Op
|
|
|
|
DESCRIPTION
|
|
Performs an operation on a bucket for a game. If the bucket doesn't exist already,
|
|
the call will set the bucket to whatever "value" is.
|
|
You can always create each bucket explicitly by using bo_set with whatever initial
|
|
value you want the bucket to have.
|
|
Valid operations include set, add, subtract, multiply, divide, concat, and average.
|
|
Each bucket type (int, float, or string) has its own operation function, always call
|
|
the same one for each bucket (i.e. don't create a bucket with BucketIntOp then try to
|
|
add a float with BucketFloatOp).
|
|
|
|
PARAMETERS
|
|
game: The game to send containing the bucket you want to operate on.
|
|
If set to NULL, the last game created with NewGame will be used.
|
|
name: The name of the bucket to update. Note that for player or team buckets, this name
|
|
does NOT include the "_" or "_t" (e.g. "score" for player score, not "score_N"). The underscore
|
|
and number will be added automatically.
|
|
operation: One of the bucketop_t enums defined above
|
|
value: Argument for the operation (bucket OP= value, e.g. bucket += value, bucket *= value)
|
|
bucketlevel: One of the bucketlevel_t enums defined above. Determines whether you are
|
|
referring to a server, player, or team bucket. Note that you can have seperate buckets of
|
|
each type with the same name (e.g. "score" player bucket for each player and "score" team
|
|
bucket for each team)
|
|
index: For player or team buckets, the game index of the player or team (as passed to NewPlayer or
|
|
NewTeam). This will be translated to the actual index internally.
|
|
Not used for server buckets (bl_server).
|
|
*********/
|
|
#define BucketIntOp(game, name, operation, value, bucketlevel, index) (((SetIntFunc)bopfuncs[bucketlevel][bt_int])(game,name,bucketfuncs[operation],value,index) )
|
|
#define BucketFloatOp(game, name, operation, value, bucketlevel, index) (((SetFloatFunc)bopfuncs[bucketlevel][bt_float])(game,name,bucketfuncs[operation],value,index) )
|
|
#define BucketStringOp(game, name, operation, value, bucketlevel, index) (((SetStringFunc)bopfuncs[bucketlevel][bt_string])(game,name,bucketfuncs[operation],value,index) )
|
|
|
|
/********
|
|
NewPlayer
|
|
|
|
DESCRIPTION
|
|
Adds a "player" to the game and assigns them an internal player number. Sets
|
|
their connect time to the number of seconds since NewGame was called.
|
|
|
|
PARAMETERS
|
|
game: The game to add the player to. If set to NULL, the last game created
|
|
with NewGame will be used.
|
|
pnum: Your internal reference for this player, use this value in any calls
|
|
to the Bucket___Op functions.
|
|
name: The name for this player. If you don't have one yet, set it to empty ("")
|
|
then call: BucketStringOp(game,"player",bo_set,realplayername, bl_player, pnum)
|
|
when you get a realplayername.
|
|
**********/
|
|
void NewPlayer(statsgame_t game,int pnum, gsi_char *name);
|
|
|
|
/********
|
|
RemovePlayer
|
|
|
|
DESCRIPTION
|
|
Removes a "player" from the game and sets their disconnect time to the
|
|
number of seconds since NewGame was called.
|
|
|
|
PARAMETERS
|
|
game: The game to remove the player from. If set to NULL, the last game created
|
|
with NewGame will be used.
|
|
pnum: Your internal reference for this player, use this value in any calls
|
|
to the Bucket___Op functions.
|
|
**********/
|
|
void RemovePlayer(statsgame_t game,int pnum);
|
|
|
|
/*********
|
|
NewTeam
|
|
RemoveTeam
|
|
|
|
DESCRIPTION
|
|
See the player functions above. These function the same, except for teams
|
|
**********/
|
|
void NewTeam(statsgame_t game,int tnum, gsi_char *name);
|
|
void RemoveTeam(statsgame_t game,int tnum);
|
|
|
|
/*********
|
|
GetPlayerIndex
|
|
GetTeamIndex
|
|
|
|
DESCRIPTION
|
|
Gets the gstats reference number for that player or team. For
|
|
example, if you start the game and players 0, 1, and 2 join, then player 1
|
|
leaves, and another player 1 joins, the new player 1 will be referenced
|
|
by gstats as 3. If player 3 joins, it will be referenced as player 4, and so on.
|
|
Normally this doesn't matter to you, but if you want to do a key name or key value
|
|
that references a player or team number (for example, setting a player's team number),
|
|
you need to use the translated values.
|
|
|
|
PARAMETERS
|
|
game: The game to retrieve the translated value for. If set to NULL,the last game created
|
|
with NewGame will be used.
|
|
pnum/tnum: Your internal player or team number (as sent to NewTeam/NewPlayer)
|
|
**********/
|
|
int GetPlayerIndex(statsgame_t game, int pnum);
|
|
int GetTeamIndex(statsgame_t game, int tnum);
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|