2023-07-27 22:43:51 +02:00
|
|
|
/************
|
|
|
|
GameSpy Open Architecture
|
|
|
|
Portable C Engine
|
|
|
|
*************/
|
|
|
|
/******
|
|
|
|
goaceng.h
|
|
|
|
GameSpy C Engine SDK
|
|
|
|
|
|
|
|
Copyright 1999 GameSpy Industries, Inc
|
|
|
|
|
|
|
|
Suite E-204
|
|
|
|
2900 Bristol Street
|
|
|
|
Costa Mesa, CA 92626
|
|
|
|
(714)549-7689
|
|
|
|
Fax(714)549-0757
|
|
|
|
|
|
|
|
******
|
|
|
|
|
|
|
|
Please see the GameSpy C Engine SDK documentation for more
|
|
|
|
information
|
|
|
|
|
|
|
|
Updated 3/16/00 - DDW
|
|
|
|
Added ServerListRemoveServer (to remove a server from the serverlist)
|
|
|
|
Updated ServerListAuxUpdate to update the existing server if its already in the list
|
|
|
|
instead of adding a duplicate
|
|
|
|
Note that these functions change the indexes of servers in the list. You should never
|
|
|
|
rely on the indexes staying constant (they change if you use the sort functions too).
|
|
|
|
|
|
|
|
Updated 3/18/00 - DDW
|
|
|
|
Added Dreamcast CE support (needs to recreate sockets for each query)
|
|
|
|
|
|
|
|
Updated 4/17/00 - DDW
|
|
|
|
Added compressed server lists and advanced filtering
|
|
|
|
|
|
|
|
Updated 5/16/00 - DDW
|
|
|
|
Do a select() in ServerListReadList to keep from blocking if the list is slow
|
|
|
|
|
|
|
|
Updated 5/25/00 - DDW
|
|
|
|
Extensive changes to minimize memory usage and increse flexibility
|
|
|
|
-Server IPs are now stored internally as unsigned longs
|
|
|
|
-Server key names are stored in a single shared list to minimize memory usage
|
|
|
|
-Hashtable and DArray allocations optimized
|
|
|
|
-You can now specify the query type using ServerListUpdate2 and ServerListAuxUpdate
|
|
|
|
-ServerListAuxUpdate is now the official way to do multi-pass updates and manual updates
|
|
|
|
Updated 6/13/99 - DDW
|
|
|
|
More memory optimizations (keys/values share same list)
|
|
|
|
Fixed alignment compiler problem for MWERKS on Dreamcast
|
|
|
|
Remove server list select on ACCESS stack (doesn't seem to work)
|
|
|
|
******/
|
|
|
|
//todo: max results and ordering
|
|
|
|
|
|
|
|
#ifndef _GOACENG_H
|
|
|
|
#define _GOACENG_H
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2023-08-30 21:53:40 +02:00
|
|
|
#define ENGINE_VERSION "3.0"
|
2023-07-27 22:43:51 +02:00
|
|
|
#define SERVER_TIMEOUT 3000
|
|
|
|
/* GServerList and GServer are the abstracted serverlist and server data types.
|
|
|
|
All access to their internal data structures is done via the functions below */
|
|
|
|
typedef struct GServerListImplementation *GServerList;
|
|
|
|
typedef struct GServerImplementation *GServer;
|
|
|
|
|
|
|
|
/* A simple error type that we can use for return values to certain functions */
|
|
|
|
typedef int GError; //we will define some error return values
|
|
|
|
|
|
|
|
typedef int gbool; //a simple boolean type
|
|
|
|
|
|
|
|
/* Various Server List States
|
|
|
|
idle - no processing or querying underway, ready to being updates
|
|
|
|
listreq - a server list request has been or is being sent
|
|
|
|
listxfer - we are transfering the server list
|
|
|
|
lanlist - we are waiting for replies from servers on the LAN
|
2025-04-23 00:18:09 +02:00
|
|
|
querying - the servers on the list are being queried
|
|
|
|
connecting (added in OPM) - socket is currently connecting to the master server
|
|
|
|
*/
|
2025-04-27 22:14:08 +02:00
|
|
|
typedef enum {sl_idle, sl_listxfer, sl_lanlist, sl_querying} GServerListState;
|
2023-07-27 22:43:51 +02:00
|
|
|
|
|
|
|
/* Comparision types for the ServerListSort function
|
|
|
|
int - assume the values are int and do an integer compare
|
|
|
|
float - assume the values are float and do a flot compare
|
|
|
|
strcase - assume the values are strings and do a case sensitive compare
|
|
|
|
stricase - assume the values are strings and do a case insensitive compare */
|
|
|
|
typedef enum {cm_int, cm_float, cm_strcase, cm_stricase} GCompareMode;
|
|
|
|
|
|
|
|
|
2025-02-22 22:13:23 +01:00
|
|
|
typedef enum {qt_basic, qt_info, qt_rules, qt_players, qt_info_rules, qt_status, qt_grouprooms, qt_masterinfo} GQueryType;
|
2023-07-27 22:43:51 +02:00
|
|
|
|
|
|
|
/* Messages that are passed to the ListCallBackFn */
|
|
|
|
#define LIST_STATECHANGED 1 // ServerListState changed, no parameters
|
|
|
|
#define LIST_PROGRESS 2 // New Server updated, param1 = GServer (server updated), param2 = percent done
|
|
|
|
|
|
|
|
//Single callback function into the client app for status / progress messages
|
|
|
|
typedef void (*ListCallBackFn)(GServerList serverlist, int msg, void *instance, void *param1, void *param2);
|
|
|
|
|
|
|
|
// Callback function used for enumerating the keys/values for a server
|
|
|
|
typedef void (*KeyEnumFn)(char *key, char *value, void *instance);
|
|
|
|
|
|
|
|
|
|
|
|
/* Callback parameter types (e.g. window handle, thread window, event, function etc) */
|
|
|
|
#define GCALLBACK_FUNCTION 1 //only currently supported callback type
|
|
|
|
|
|
|
|
#define GE_NOERROR 0
|
|
|
|
#define GE_NOSOCKET 1
|
|
|
|
#define GE_NODNS 2
|
|
|
|
#define GE_NOCONNECT 3
|
|
|
|
#define GE_BUSY 4
|
|
|
|
#define GE_DATAERROR 5
|
|
|
|
|
|
|
|
/*********
|
|
|
|
Server List Functions
|
|
|
|
**********/
|
|
|
|
|
|
|
|
/* ServerListNew
|
|
|
|
----------------
|
|
|
|
Creates and returns a new (empty) GServerList.
|
|
|
|
gamename - game to ask the master for servers
|
|
|
|
enginename - the engine name that matches your seckey
|
|
|
|
seckey - secret key used for talking to the master
|
|
|
|
maxconcupdates - max number of concurent updates (10-15 for modem users, 20-30 for high-bandwidth)
|
|
|
|
CallBackFn - The function or handle used for progress updates
|
|
|
|
CallBackFnType - The type of the CallBackFn parameter (from the #define list above)
|
|
|
|
instance - user-defined instance data (e.g. structure or object pointer) */
|
2023-07-28 21:44:43 +02:00
|
|
|
GServerList ServerListNew(const char *gamename, const char *enginename, const char *seckey, int maxconcupdates, void *CallBackFn, int CallBackFnType, void *instance);
|
2023-07-27 22:43:51 +02:00
|
|
|
|
|
|
|
/* ServerListFree
|
|
|
|
-----------------
|
|
|
|
Free a GServerList and all internal sturctures and servers */
|
|
|
|
void ServerListFree(GServerList serverlist);
|
|
|
|
|
|
|
|
/* ServerListUpdate
|
|
|
|
-------------------
|
|
|
|
Start updating a GServerList from the master server.
|
|
|
|
Can only be called when the list is in the sl_idle state, will return an error otherwise.
|
|
|
|
The server list will be retrieved from the master, then each server in the list will be
|
|
|
|
added and updated.
|
|
|
|
If async = false, the function will not return until the entire list has been processed, or
|
|
|
|
ServerListHalt has been called (from another thread or from the progress callback)
|
|
|
|
If async = true, the function will return immediately, but you must call ServerListThink
|
|
|
|
every ~10ms for list processing and querying to occur. */
|
|
|
|
GError ServerListUpdate(GServerList serverlist, gbool async);
|
|
|
|
|
|
|
|
|
|
|
|
/* ServerListUpdate2
|
|
|
|
-------------------------
|
|
|
|
Identical to ServerListUpdate, except that the server list is filtered
|
|
|
|
on the server side by the filter, and you can specify the type of query to perform.
|
|
|
|
If you want to specify the type of query, but no filter, simply pass NULL for filter.
|
|
|
|
Filter is a SQL-style boolean statement such as:
|
|
|
|
"gametype='ctf'"
|
|
|
|
"numplayers > 1 and numplayers < 8"
|
|
|
|
"gamestate='openplaying'"
|
|
|
|
The filter can be arbitrarily complex and supports all standard SQL
|
|
|
|
groupings and boolean operations. The following fields are available
|
|
|
|
for filtering:
|
|
|
|
hostport
|
|
|
|
gamever
|
|
|
|
location
|
|
|
|
hostname
|
|
|
|
mapname
|
|
|
|
gametype
|
|
|
|
gamemode
|
|
|
|
numplayers
|
|
|
|
maxplayers*/
|
|
|
|
GError ServerListUpdate2(GServerList serverlist, gbool async, char *filter, GQueryType querytype);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ServerListLANUpdate
|
|
|
|
-------------------
|
|
|
|
Search for servers on the local LAN and start updating them. This will search over a
|
|
|
|
range of ports for any servers within broadcast range.
|
|
|
|
Can only be called when the list is in the sl_idle state, will return an error otherwise.
|
|
|
|
A query will be sent out on each port between start and end (inclusive) on intervals of delta
|
|
|
|
(e.g. 10,20,2 would search 10,12,14,16,18,20)
|
|
|
|
If async = false, the function will not return until the entire list has been processed, or
|
|
|
|
ServerListHalt has been called (from another thread or from the progress callback)
|
|
|
|
If async = true, the function will return immediately, but you must call ServerListThink
|
|
|
|
every ~10ms for list processing and querying to occur. */ //TODO: add filter
|
|
|
|
GError ServerListLANUpdate(GServerList serverlist, gbool async, int startsearchport, int endsearchport, int searchdelta);
|
|
|
|
|
|
|
|
/* ServerListAuxUpdate
|
|
|
|
-------------------
|
|
|
|
Adds an "auxilliary" server -- this is a way to either update a server manually or
|
|
|
|
get additional/updated information from a server already in the list.
|
|
|
|
If there is an update currently in progress (not sl_idle), the aux server will
|
|
|
|
be processed along with the current batch. If the state is idle, this function behaves
|
|
|
|
like ServerListUpdate() and starts the engine.
|
|
|
|
If async = false, the function will not return until the server has been processed, or
|
|
|
|
ServerListHalt has been called (from another thread or from the progress callback)
|
|
|
|
If async = true, the function will return immediately, but you must call ServerListThink
|
|
|
|
every ~10ms for list processing and querying to occur. Note that async has no effect
|
|
|
|
if an update is in progress. */
|
2023-07-27 23:00:27 +02:00
|
|
|
GError ServerListAuxUpdate(GServerList serverlist, const char *ip, int port, gbool async, GQueryType querytype);
|
2023-07-27 22:43:51 +02:00
|
|
|
|
|
|
|
/* ServerListRemoveServer
|
|
|
|
-------------------------
|
|
|
|
Removes a single server from the list. Frees the memory associated with the GServer.
|
|
|
|
Do not reference the GServer object after calling this function. Note that this changes
|
|
|
|
the indexes of the servers in the list. You should never store the indexes of the servers
|
|
|
|
in the list, just their GServer objects */
|
|
|
|
void ServerListRemoveServer(GServerList serverlist, char *ip, int port);
|
|
|
|
|
|
|
|
/* ServerListThink
|
|
|
|
------------------
|
|
|
|
For use with Async Updates. This needs to be called every ~10ms for list processing and
|
|
|
|
updating to occur during async server list updates */
|
|
|
|
GError ServerListThink(GServerList serverlist);
|
|
|
|
|
|
|
|
/* ServerListHalt
|
|
|
|
-----------------
|
|
|
|
Halts the current updates batch */
|
|
|
|
GError ServerListHalt(GServerList serverlist);
|
|
|
|
|
|
|
|
/* ServerListClear
|
|
|
|
------------------
|
|
|
|
Clear and free all of the servers from the server list.
|
|
|
|
List must be in the sl_idle state */
|
|
|
|
GError ServerListClear(GServerList serverlist);
|
|
|
|
|
|
|
|
/* ServerListState
|
|
|
|
------------------
|
|
|
|
Returns the current state of the server list */
|
|
|
|
GServerListState ServerListState(GServerList serverlist);
|
|
|
|
|
|
|
|
/* ServerListErrorDesc
|
|
|
|
----------------------
|
|
|
|
Returns a static string description of the specified error */
|
|
|
|
char *ServerListErrorDesc(GServerList serverlist, GError error);
|
|
|
|
|
|
|
|
/* ServerListGetServer
|
|
|
|
----------------------
|
|
|
|
Returns the server at the specified index, or NULL if the index is out of bounds */
|
|
|
|
GServer ServerListGetServer(GServerList serverlist, int index);
|
|
|
|
|
|
|
|
/* ServerListCount
|
|
|
|
------------------
|
|
|
|
Returns the number of servers on the specified list. Indexing is 0 based, so
|
|
|
|
the actual server indexes are 0 <= valid index < Count */
|
|
|
|
int ServerListCount(GServerList serverlist);
|
|
|
|
|
|
|
|
/* ServerListSort
|
|
|
|
-----------------
|
|
|
|
Sort the server list in either ascending or descending order using the
|
|
|
|
specified comparemode.
|
|
|
|
sortkey can be a normal server key, or "ping" or "hostaddr" */
|
|
|
|
void ServerListSort(GServerList serverlist, gbool ascending, char *sortkey, GCompareMode comparemode);
|
|
|
|
|
|
|
|
|
|
|
|
/**************
|
|
|
|
ServerFunctions
|
|
|
|
***************/
|
|
|
|
|
|
|
|
/* ServerGetPing
|
|
|
|
----------------
|
|
|
|
Returns the ping for the specified server.
|
|
|
|
A ping of 9999 indicates that the server has not been queried or did not respond */
|
|
|
|
int ServerGetPing(GServer server);
|
|
|
|
|
|
|
|
/* ServerGetAddress
|
|
|
|
-------------------
|
|
|
|
Returns the string, dotted IP address for the specified server */
|
|
|
|
char *ServerGetAddress(GServer server);
|
|
|
|
|
|
|
|
/* ServerGetInetAddress
|
|
|
|
-------------------
|
|
|
|
Returns the network-ordered IP address for the specified server */
|
|
|
|
unsigned int ServerGetInetAddress(GServer server);
|
|
|
|
|
|
|
|
|
|
|
|
/* ServerGetPort
|
|
|
|
----------------
|
|
|
|
Returns the "query" port for the specified server. If the game uses a seperate
|
|
|
|
"game" port, it can be retrieved via: ServerGetIntValue(server,"hostport",0) */
|
|
|
|
int ServerGetQueryPort(GServer server);
|
|
|
|
|
|
|
|
/* ServerGet[]Value
|
|
|
|
------------------
|
|
|
|
Returns the value for the specified key. If the key does not exist for the
|
|
|
|
given server, the default value is returned */
|
|
|
|
char *ServerGetStringValue(GServer server, char *key, char *sdefault);
|
|
|
|
int ServerGetIntValue(GServer server, char *key, int idefault);
|
|
|
|
double ServerGetFloatValue(GServer server, char *key, double fdefault);
|
|
|
|
|
|
|
|
|
|
|
|
/* ServerGetPlayer[]Value
|
|
|
|
------------------
|
|
|
|
Returns the value for the specified key on the specified player. If the key does not exist for the
|
|
|
|
given server, the default value is returned */
|
|
|
|
char *ServerGetPlayerStringValue(GServer server, int playernum, char *key, char *sdefault);
|
|
|
|
int ServerGetPlayerIntValue(GServer server, int playernum, char *key, int idefault);
|
|
|
|
double ServerGetPlayerFloatValue(GServer server, int playernum, char *key, double fdefault);
|
|
|
|
|
|
|
|
/* ServerEnumKeys
|
|
|
|
-----------------
|
|
|
|
Enumerates the keys/values for a given server by calling KeyEnumFn with each
|
|
|
|
key/value. The user-defined instance data will be passed to the KeyFn callback */
|
|
|
|
void ServerEnumKeys(GServer server, KeyEnumFn KeyFn, void *instance);
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif //_GOACENG_H
|