mirror of
https://github.com/tribufu/node-gamedig
synced 2026-05-06 15:17:36 +00:00
Add a ton of reference
This commit is contained in:
parent
473d9544b1
commit
09d9b87ad6
22 changed files with 5115 additions and 4 deletions
2
reference/cryengine/gamedignote.txt
Normal file
2
reference/cryengine/gamedignote.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
I was under the impression all the crysis games used gamespy?
|
||||
If anyone notices a problem, this is reference for some old cryengine protocol.
|
||||
|
|
@ -1,7 +1,3 @@
|
|||
I was under the impression all the farcry games used ASE?
|
||||
If anyone notices a problem, this is reference for some old cryengine protocol:
|
||||
|
||||
|
||||
<?php
|
||||
/**
|
||||
* This file is part of GameQ.
|
||||
|
|
|
|||
326
reference/cryengine/qstat.txt
Normal file
326
reference/cryengine/qstat.txt
Normal file
|
|
@ -0,0 +1,326 @@
|
|||
LICENSE: The Artistic License 2.0
|
||||
|
||||
/*
|
||||
* qstat.h
|
||||
* by Steve Jankowski
|
||||
* steve@qstat.org
|
||||
* http://www.qstat.org
|
||||
*
|
||||
* Copyright 1996,1997,1998,1999,2000,2001,2002 by Steve Jankowski
|
||||
*/
|
||||
|
||||
{
|
||||
/* CRYSIS PROTOCOL */
|
||||
CRYSIS_PROTOCOL_SERVER, /* id */
|
||||
"CRYSIS", /* type_prefix */
|
||||
"crysis", /* type_string */
|
||||
"-crysis", /* type_option */
|
||||
"Crysis", /* game_name */
|
||||
0, /* master */
|
||||
0, /* default_port */
|
||||
0, /* port_offset */
|
||||
TF_TCP_CONNECT|TF_QUERY_ARG_REQUIRED|TF_QUERY_ARG, /* flags */
|
||||
"gamerules", /* game_rule */
|
||||
"CRYSISPROTOCOL", /* template_var */
|
||||
NULL, /* status_packet */
|
||||
0, /* status_len */
|
||||
NULL, /* player_packet */
|
||||
0, /* player_len */
|
||||
NULL, /* rule_packet */
|
||||
0, /* rule_len */
|
||||
NULL, /* master_packet */
|
||||
0, /* master_len */
|
||||
NULL, /* master_protocol */
|
||||
NULL, /* master_query */
|
||||
NULL, /* display_player_func */
|
||||
display_server_rules, /* display_rule_func */
|
||||
NULL, /* display_raw_player_func */
|
||||
raw_display_server_rules, /* display_raw_rule_func */
|
||||
xml_display_player_info, /* display_xml_player_func */
|
||||
xml_display_server_rules, /* display_xml_rule_func */
|
||||
send_crysis_request_packet, /* status_query_func */
|
||||
NULL, /* rule_query_func */
|
||||
NULL, /* player_query_func */
|
||||
deal_with_crysis_packet, /* packet_func */
|
||||
},
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* qstat 2.8
|
||||
* by Steve Jankowski
|
||||
*
|
||||
* Crysis query protocol
|
||||
* Copyright 2012 Steven Hartland
|
||||
*
|
||||
* Licensed under the Artistic License, see LICENSE.txt for license terms
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifndef _WIN32
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#else
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "utils.h"
|
||||
#include "qstat.h"
|
||||
#include "md5.h"
|
||||
#include "packet_manip.h"
|
||||
|
||||
char *decode_crysis_val( char *val )
|
||||
{
|
||||
// Very basic html conversion
|
||||
val = str_replace( val, """, "\"" );
|
||||
return str_replace( val, "&", "&" );
|
||||
}
|
||||
|
||||
query_status_t send_crysis_request_packet( struct qserver *server )
|
||||
{
|
||||
char cmd[256], buf[1024], *password, *md5;
|
||||
debug( 2, "challenge: %ld", server->challenge );
|
||||
switch ( server->challenge )
|
||||
{
|
||||
case 0:
|
||||
// Not seen a challenge yet, request it
|
||||
server->challenge++;
|
||||
sprintf( cmd, "challenge" );
|
||||
break;
|
||||
|
||||
case 1:
|
||||
server->challenge++;
|
||||
password = get_param_value( server, "password", "" );
|
||||
sprintf( cmd, "%s:%s", server->challenge_string, password );
|
||||
md5 = md5_hex( cmd, strlen( cmd ) );
|
||||
sprintf( cmd, "authenticate %s", md5 );
|
||||
free( md5 );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// NOTE: we currently don't support player info
|
||||
server->challenge++;
|
||||
server->flags |= TF_STATUS_QUERY;
|
||||
server->n_servers = 3;
|
||||
sprintf( cmd, "status" );
|
||||
break;
|
||||
|
||||
case 3:
|
||||
return DONE_FORCE;
|
||||
}
|
||||
|
||||
server->saved_data.pkt_max = -1;
|
||||
sprintf(buf, "POST /RPC2 HTTP/1.1\015\012Keep-Alive: 300\015\012User-Agent: qstat %s\015\012Content-Length: %d\015\012Content-Type: text/xml\015\012\015\012<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodCall><methodName>%s</methodName><params /></methodCall>", VERSION, (int)(98 + strlen(cmd)), cmd);
|
||||
|
||||
return send_packet( server, buf, strlen( buf ) );
|
||||
}
|
||||
|
||||
query_status_t valid_crysis_response( struct qserver *server, char *rawpkt, int pktlen )
|
||||
{
|
||||
char *s;
|
||||
int len;
|
||||
int cnt = packet_count( server );
|
||||
if ( 0 == cnt && 0 != strncmp( "HTTP/1.1 200 OK", rawpkt, 15 ) )
|
||||
{
|
||||
// not valid response
|
||||
return REQ_ERROR;
|
||||
}
|
||||
|
||||
s = strnstr(rawpkt, "Content-Length: ", pktlen );
|
||||
if ( NULL == s )
|
||||
{
|
||||
// not valid response
|
||||
return INPROGRESS;
|
||||
}
|
||||
s += 16;
|
||||
if ( 1 != sscanf( s, "%d", &len ) )
|
||||
{
|
||||
return INPROGRESS;
|
||||
}
|
||||
|
||||
s = strnstr(rawpkt, "\015\012\015\012", pktlen );
|
||||
if ( NULL == s )
|
||||
{
|
||||
return INPROGRESS;
|
||||
}
|
||||
|
||||
s += 4;
|
||||
if ( pktlen != ( s - rawpkt + len ) )
|
||||
{
|
||||
return INPROGRESS;
|
||||
}
|
||||
|
||||
return DONE_FORCE;
|
||||
}
|
||||
|
||||
char* crysis_response( struct qserver *server, char *rawpkt, int pktlen )
|
||||
{
|
||||
char *s, *e;
|
||||
int len = pktlen;
|
||||
|
||||
s = strnstr(rawpkt, "<methodResponse><params><param><value><string>", len );
|
||||
if ( NULL == s )
|
||||
{
|
||||
// not valid response
|
||||
return NULL;
|
||||
}
|
||||
s += 46;
|
||||
len += rawpkt - s;
|
||||
e = strnstr(s, "</string></value>", len );
|
||||
if ( NULL == e )
|
||||
{
|
||||
// not valid response
|
||||
return NULL;
|
||||
}
|
||||
*e = '\0';
|
||||
|
||||
return strdup( s );
|
||||
}
|
||||
|
||||
query_status_t deal_with_crysis_packet( struct qserver *server, char *rawpkt, int pktlen )
|
||||
{
|
||||
char *s, *val, *line;
|
||||
query_status_t state = INPROGRESS;
|
||||
debug( 2, "processing..." );
|
||||
|
||||
if ( ! server->combined )
|
||||
{
|
||||
state = valid_crysis_response( server, rawpkt, pktlen );
|
||||
server->retry1 = n_retries;
|
||||
if ( 0 == server->n_requests )
|
||||
{
|
||||
server->ping_total = time_delta( &packet_recv_time, &server->packet_time1 );
|
||||
server->n_requests++;
|
||||
}
|
||||
|
||||
switch ( state )
|
||||
{
|
||||
case INPROGRESS:
|
||||
{
|
||||
// response fragment recieved
|
||||
int pkt_id;
|
||||
int pkt_max;
|
||||
|
||||
// We're expecting more to come
|
||||
debug( 5, "fragment recieved..." );
|
||||
pkt_id = packet_count( server );
|
||||
pkt_max = pkt_id++;
|
||||
if ( ! add_packet( server, 0, pkt_id, pkt_max, pktlen, rawpkt, 1 ) )
|
||||
{
|
||||
// fatal error e.g. out of memory
|
||||
return MEM_ERROR;
|
||||
}
|
||||
|
||||
// combine_packets will call us recursively
|
||||
return combine_packets( server );
|
||||
}
|
||||
case DONE_FORCE:
|
||||
break; // single packet response fall through
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
if ( DONE_FORCE != state )
|
||||
{
|
||||
state = valid_crysis_response( server, rawpkt, pktlen );
|
||||
switch ( state )
|
||||
{
|
||||
case DONE_FORCE:
|
||||
break; // actually process
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
debug( 3, "packet: challenge = %ld", server->challenge );
|
||||
switch ( server->challenge )
|
||||
{
|
||||
case 1:
|
||||
s = crysis_response( server, rawpkt, pktlen );
|
||||
if ( NULL != s )
|
||||
{
|
||||
server->challenge_string = s;
|
||||
return send_crysis_request_packet( server );
|
||||
}
|
||||
return REQ_ERROR;
|
||||
case 2:
|
||||
s = crysis_response( server, rawpkt, pktlen );
|
||||
if ( NULL == s )
|
||||
{
|
||||
return REQ_ERROR;
|
||||
}
|
||||
if ( 0 != strncmp( s, "authorized", 10 ) )
|
||||
{
|
||||
free( s );
|
||||
return REQ_ERROR;
|
||||
}
|
||||
free( s );
|
||||
return send_crysis_request_packet( server );
|
||||
case 3:
|
||||
s = crysis_response( server, rawpkt, pktlen );
|
||||
if ( NULL == s )
|
||||
{
|
||||
return REQ_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// Correct ping
|
||||
// Not quite right but gives a good estimate
|
||||
server->ping_total = ( server->ping_total * server->n_requests ) / 2;
|
||||
|
||||
debug( 3, "processing response..." );
|
||||
|
||||
s = decode_crysis_val( s );
|
||||
line = strtok( s, "\012" );
|
||||
|
||||
// NOTE: id=XXX and msg=XXX will be processed by the mod following the one they where the response of
|
||||
while ( NULL != line )
|
||||
{
|
||||
debug( 4, "LINE: %s\n", line );
|
||||
val = strstr( line, ":" );
|
||||
if ( NULL != val )
|
||||
{
|
||||
*val = '\0';
|
||||
val+=2;
|
||||
debug( 4, "var: %s, val: %s", line, val );
|
||||
if ( 0 == strcmp( "name", line ) )
|
||||
{
|
||||
server->server_name = strdup( val );
|
||||
}
|
||||
else if ( 0 == strcmp( "level", line ) )
|
||||
{
|
||||
server->map_name = strdup( val );
|
||||
}
|
||||
else if ( 0 == strcmp( "players", line ) )
|
||||
{
|
||||
if ( 2 == sscanf( val, "%d/%d", &server->num_players, &server->max_players) )
|
||||
{
|
||||
}
|
||||
}
|
||||
else if (
|
||||
0 == strcmp( "version", line ) ||
|
||||
0 == strcmp( "gamerules", line ) ||
|
||||
0 == strcmp( "time remaining", line )
|
||||
)
|
||||
{
|
||||
add_rule( server, line, val, NO_FLAGS );
|
||||
}
|
||||
}
|
||||
|
||||
line = strtok( NULL, "\012" );
|
||||
}
|
||||
|
||||
gettimeofday( &server->packet_time1, NULL );
|
||||
|
||||
return DONE_FORCE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue