mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-08 01:39:36 +00:00
1
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "CompletionEvent.h"
|
||||
#include "winlite.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: creates an event
|
||||
//-----------------------------------------------------------------------------
|
||||
EventHandle_t Event_CreateEvent()
|
||||
{
|
||||
return (EventHandle_t)::CreateEvent(NULL, false, false, NULL);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets the current thread to wait for either the event to be signalled, or the timeout to occur
|
||||
//-----------------------------------------------------------------------------
|
||||
void Event_WaitForEvent(EventHandle_t event, unsigned long timeoutMilliseconds)
|
||||
{
|
||||
::WaitForSingleObject((HANDLE)event, timeoutMilliseconds);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: signals an event to Activate
|
||||
// Releases one thread waiting on the event.
|
||||
// If the event has no threads waiting on it, the next thread to wait on it will be let right through
|
||||
//-----------------------------------------------------------------------------
|
||||
void Event_SignalEvent(EventHandle_t event)
|
||||
{
|
||||
::SetEvent((HANDLE)event);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Wraps windows WaitForSingleEvent() calls
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef COMPLETIONEVENT_H
|
||||
#define COMPLETIONEVENT_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// handle to an event
|
||||
typedef unsigned long EventHandle_t;
|
||||
|
||||
// creates an event
|
||||
EventHandle_t Event_CreateEvent();
|
||||
|
||||
// sets the current thread to wait for either the event to be signalled, or the timeout to occur
|
||||
void Event_WaitForEvent(EventHandle_t event, unsigned long timeoutMilliseconds);
|
||||
|
||||
// set the timeout to this for it to never time out
|
||||
#define TIMEOUT_INFINITE 0xFFFFFFFF
|
||||
|
||||
// signals an event to Activate
|
||||
// Releases one thread waiting on the event.
|
||||
// If the event has no threads waiting on it, the next thread to wait on it will be let right through
|
||||
void Event_SignalEvent(EventHandle_t event);
|
||||
|
||||
|
||||
#endif // COMPLETIONEVENT_H
|
||||
@@ -0,0 +1,30 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef DEBUGCONSOLE_INTERFACE_H
|
||||
#define DEBUGCONSOLE_INTERFACE_H
|
||||
#pragma once
|
||||
|
||||
#include "interface.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Debugging console interface
|
||||
//-----------------------------------------------------------------------------
|
||||
class IDebugConsole : public IBaseInterface
|
||||
{
|
||||
public:
|
||||
virtual void Initialize( const char *consoleName, int logLevel ) = 0;
|
||||
virtual void Print( int severity, PRINTF_FORMAT_STRING const char *msgDescriptor, ... ) = 0;
|
||||
|
||||
// gets a line of command input
|
||||
// returns true if anything returned, false otherwise
|
||||
virtual bool GetInput(char *buffer, int bufferSize) = 0;
|
||||
};
|
||||
|
||||
#define DEBUGCONSOLE_INTERFACE_VERSION "DebugConsole001"
|
||||
|
||||
#endif // DEBUGCONSOLE_INTERFACE_H
|
||||
@@ -0,0 +1,22 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef DEBUGTIMER_H
|
||||
#define DEBUGTIMER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// resets the timer
|
||||
void Timer_Start();
|
||||
|
||||
// returns the time since Timer_Start() was called, in seconds
|
||||
double Timer_End();
|
||||
|
||||
|
||||
|
||||
#endif // DEBUGTIMER_H
|
||||
@@ -0,0 +1,69 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef IGAMELIST_H
|
||||
#define IGAMELIST_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
struct serveritem_t;
|
||||
#include "FindSteamServers.h"
|
||||
|
||||
#define EMPTY_SERVER_NAME "0.0.0.0:0"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Interface to accessing a game list
|
||||
//-----------------------------------------------------------------------------
|
||||
class IGameList
|
||||
{
|
||||
public:
|
||||
|
||||
enum InterfaceItem_e
|
||||
{
|
||||
FILTERS,
|
||||
GETNEWLIST,
|
||||
ADDSERVER,
|
||||
ADDCURRENTSERVER,
|
||||
};
|
||||
|
||||
// returns true if the game list supports the specified ui elements
|
||||
virtual bool SupportsItem(InterfaceItem_e item) = 0;
|
||||
|
||||
// starts the servers refreshing
|
||||
virtual void StartRefresh() = 0;
|
||||
|
||||
// gets a new server list
|
||||
virtual void GetNewServerList() = 0;
|
||||
|
||||
// stops current refresh/GetNewServerList()
|
||||
virtual void StopRefresh() = 0;
|
||||
|
||||
// returns true if the list is currently refreshing servers
|
||||
virtual bool IsRefreshing() = 0;
|
||||
|
||||
// gets information about specified server
|
||||
virtual serveritem_t &GetServer(unsigned int serverID) = 0;
|
||||
|
||||
// adds a new server to list
|
||||
virtual void AddNewServer(serveritem_t &server) = 0;
|
||||
|
||||
// marks that server list has been fully received
|
||||
virtual void ListReceived(bool moreAvailable, const char *lastUniqueIP, ESteamServerType serverType) = 0;
|
||||
|
||||
// called when Connect button is pressed
|
||||
virtual void OnBeginConnect() = 0;
|
||||
|
||||
// reapplies filters
|
||||
virtual void ApplyFilters() = 0;
|
||||
|
||||
// invalid server index
|
||||
virtual int GetInvalidServerListID() = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif // IGAMELIST_H
|
||||
@@ -0,0 +1,34 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef ISERVERREFRESHRESPONSE_H
|
||||
#define ISERVERREFRESHRESPONSE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
struct serveritem_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Callback interface for server updates
|
||||
//-----------------------------------------------------------------------------
|
||||
class IServerRefreshResponse
|
||||
{
|
||||
public:
|
||||
// called when the server has successfully responded
|
||||
virtual void ServerResponded(serveritem_t &server) = 0;
|
||||
|
||||
// called when a server response has timed out
|
||||
virtual void ServerFailedToRespond(serveritem_t &server) = 0;
|
||||
|
||||
// called when the current refresh list is complete
|
||||
virtual void RefreshComplete() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // ISERVERREFRESHRESPONSE_H
|
||||
@@ -0,0 +1,65 @@
|
||||
//========= Public Domain Code ================================================
|
||||
//
|
||||
// Purpose: Header file for the C++ ICE encryption class.
|
||||
// Taken from public domain code, as written by Matthew Kwan - July 1996
|
||||
// http://www.darkside.com.au/ice/
|
||||
//=============================================================================
|
||||
|
||||
#ifndef _IceKey_H
|
||||
#define _IceKey_H
|
||||
|
||||
/*
|
||||
The IceKey class is used for encrypting and decrypting 64-bit blocks of data
|
||||
with the ICE (Information Concealment Engine) encryption algorithm.
|
||||
|
||||
The constructor creates a new IceKey object that can be used to encrypt and decrypt data.
|
||||
The level of encryption determines the size of the key, and hence its speed.
|
||||
Level 0 uses the Thin-ICE variant, which is an 8-round cipher taking an 8-byte key.
|
||||
This is the fastest option, and is generally considered to be at least as secure as DES,
|
||||
although it is not yet certain whether it is as secure as its key size.
|
||||
|
||||
For levels n greater than zero, a 16n-round cipher is used, taking 8n-byte keys.
|
||||
Although not as fast as level 0, these are very very secure.
|
||||
|
||||
Before an IceKey can be used to encrypt data, its key schedule must be set with the set() member function.
|
||||
The length of the key required is determined by the level, as described above.
|
||||
|
||||
The member functions encrypt() and decrypt() encrypt and decrypt respectively data
|
||||
in blocks of eight chracters, using the specified key.
|
||||
|
||||
Two functions keySize() and blockSize() are provided
|
||||
which return the key and block size respectively, measured in bytes.
|
||||
The key size is determined by the level, while the block size is always 8.
|
||||
|
||||
The destructor zeroes out and frees up all memory associated with the key.
|
||||
*/
|
||||
|
||||
class IceSubkey;
|
||||
|
||||
class IceKey {
|
||||
public:
|
||||
IceKey (int n);
|
||||
~IceKey ();
|
||||
|
||||
void set (const unsigned char *key);
|
||||
|
||||
void encrypt (const unsigned char *plaintext,
|
||||
unsigned char *ciphertext) const;
|
||||
|
||||
void decrypt (const unsigned char *ciphertext,
|
||||
unsigned char *plaintext) const;
|
||||
|
||||
int keySize () const;
|
||||
|
||||
int blockSize () const;
|
||||
|
||||
private:
|
||||
void scheduleBuild (unsigned short *k, int n,
|
||||
const int *keyrot);
|
||||
|
||||
int _size;
|
||||
int _rounds;
|
||||
IceSubkey *_keysched;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,393 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//========= Public Domain Code ================================================
|
||||
//
|
||||
// Purpose: C++ implementation of the ICE encryption algorithm.
|
||||
// Taken from public domain code, as written by Matthew Kwan - July 1996
|
||||
// http://www.darkside.com.au/ice/
|
||||
//=============================================================================
|
||||
|
||||
#include "mathlib/IceKey.H"
|
||||
|
||||
#pragma warning(disable: 4244)
|
||||
|
||||
|
||||
/* Structure of a single round subkey */
|
||||
class IceSubkey {
|
||||
public:
|
||||
unsigned long val[3];
|
||||
};
|
||||
|
||||
|
||||
/* The S-boxes */
|
||||
static unsigned long ice_sbox[4][1024];
|
||||
static int ice_sboxes_initialised = 0;
|
||||
|
||||
|
||||
/* Modulo values for the S-boxes */
|
||||
static const int ice_smod[4][4] = {
|
||||
{333, 313, 505, 369},
|
||||
{379, 375, 319, 391},
|
||||
{361, 445, 451, 397},
|
||||
{397, 425, 395, 505}};
|
||||
|
||||
/* XOR values for the S-boxes */
|
||||
static const int ice_sxor[4][4] = {
|
||||
{0x83, 0x85, 0x9b, 0xcd},
|
||||
{0xcc, 0xa7, 0xad, 0x41},
|
||||
{0x4b, 0x2e, 0xd4, 0x33},
|
||||
{0xea, 0xcb, 0x2e, 0x04}};
|
||||
|
||||
/* Permutation values for the P-box */
|
||||
static const unsigned long ice_pbox[32] = {
|
||||
0x00000001, 0x00000080, 0x00000400, 0x00002000,
|
||||
0x00080000, 0x00200000, 0x01000000, 0x40000000,
|
||||
0x00000008, 0x00000020, 0x00000100, 0x00004000,
|
||||
0x00010000, 0x00800000, 0x04000000, 0x20000000,
|
||||
0x00000004, 0x00000010, 0x00000200, 0x00008000,
|
||||
0x00020000, 0x00400000, 0x08000000, 0x10000000,
|
||||
0x00000002, 0x00000040, 0x00000800, 0x00001000,
|
||||
0x00040000, 0x00100000, 0x02000000, 0x80000000};
|
||||
|
||||
/* The key rotation schedule */
|
||||
static const int ice_keyrot[16] = {
|
||||
0, 1, 2, 3, 2, 1, 3, 0,
|
||||
1, 3, 2, 0, 3, 1, 0, 2};
|
||||
|
||||
|
||||
/*
|
||||
* 8-bit Galois Field multiplication of a by b, modulo m.
|
||||
* Just like arithmetic multiplication, except that additions and
|
||||
* subtractions are replaced by XOR.
|
||||
*/
|
||||
|
||||
static unsigned int
|
||||
gf_mult (
|
||||
register unsigned int a,
|
||||
register unsigned int b,
|
||||
register unsigned int m
|
||||
) {
|
||||
register unsigned int res = 0;
|
||||
|
||||
while (b) {
|
||||
if (b & 1)
|
||||
res ^= a;
|
||||
|
||||
a <<= 1;
|
||||
b >>= 1;
|
||||
|
||||
if (a >= 256)
|
||||
a ^= m;
|
||||
}
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Galois Field exponentiation.
|
||||
* Raise the base to the power of 7, modulo m.
|
||||
*/
|
||||
|
||||
static unsigned long
|
||||
gf_exp7 (
|
||||
register unsigned int b,
|
||||
unsigned int m
|
||||
) {
|
||||
register unsigned int x;
|
||||
|
||||
if (b == 0)
|
||||
return (0);
|
||||
|
||||
x = gf_mult (b, b, m);
|
||||
x = gf_mult (b, x, m);
|
||||
x = gf_mult (x, x, m);
|
||||
return (gf_mult (b, x, m));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Carry out the ICE 32-bit P-box permutation.
|
||||
*/
|
||||
|
||||
static unsigned long
|
||||
ice_perm32 (
|
||||
register unsigned long x
|
||||
) {
|
||||
register unsigned long res = 0;
|
||||
register const unsigned long *pbox = ice_pbox;
|
||||
|
||||
while (x) {
|
||||
if (x & 1)
|
||||
res |= *pbox;
|
||||
pbox++;
|
||||
x >>= 1;
|
||||
}
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialise the ICE S-boxes.
|
||||
* This only has to be done once.
|
||||
*/
|
||||
|
||||
static void
|
||||
ice_sboxes_init (void)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i=0; i<1024; i++) {
|
||||
int col = (i >> 1) & 0xff;
|
||||
int row = (i & 0x1) | ((i & 0x200) >> 8);
|
||||
unsigned long x;
|
||||
|
||||
x = gf_exp7 (col ^ ice_sxor[0][row], ice_smod[0][row]) << 24;
|
||||
ice_sbox[0][i] = ice_perm32 (x);
|
||||
|
||||
x = gf_exp7 (col ^ ice_sxor[1][row], ice_smod[1][row]) << 16;
|
||||
ice_sbox[1][i] = ice_perm32 (x);
|
||||
|
||||
x = gf_exp7 (col ^ ice_sxor[2][row], ice_smod[2][row]) << 8;
|
||||
ice_sbox[2][i] = ice_perm32 (x);
|
||||
|
||||
x = gf_exp7 (col ^ ice_sxor[3][row], ice_smod[3][row]);
|
||||
ice_sbox[3][i] = ice_perm32 (x);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create a new ICE key.
|
||||
*/
|
||||
|
||||
IceKey::IceKey (int n)
|
||||
{
|
||||
if (!ice_sboxes_initialised) {
|
||||
ice_sboxes_init ();
|
||||
ice_sboxes_initialised = 1;
|
||||
}
|
||||
|
||||
if (n < 1) {
|
||||
_size = 1;
|
||||
_rounds = 8;
|
||||
} else {
|
||||
_size = n;
|
||||
_rounds = n * 16;
|
||||
}
|
||||
|
||||
_keysched = new IceSubkey[_rounds];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Destroy an ICE key.
|
||||
*/
|
||||
|
||||
IceKey::~IceKey ()
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i=0; i<_rounds; i++)
|
||||
for (j=0; j<3; j++)
|
||||
_keysched[i].val[j] = 0;
|
||||
|
||||
_rounds = _size = 0;
|
||||
|
||||
delete[] _keysched;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The single round ICE f function.
|
||||
*/
|
||||
|
||||
static unsigned long
|
||||
ice_f (
|
||||
register unsigned long p,
|
||||
const IceSubkey *sk
|
||||
) {
|
||||
unsigned long tl, tr; /* Expanded 40-bit values */
|
||||
unsigned long al, ar; /* Salted expanded 40-bit values */
|
||||
|
||||
/* Left half expansion */
|
||||
tl = ((p >> 16) & 0x3ff) | (((p >> 14) | (p << 18)) & 0xffc00);
|
||||
|
||||
/* Right half expansion */
|
||||
tr = (p & 0x3ff) | ((p << 2) & 0xffc00);
|
||||
|
||||
/* Perform the salt permutation */
|
||||
// al = (tr & sk->val[2]) | (tl & ~sk->val[2]);
|
||||
// ar = (tl & sk->val[2]) | (tr & ~sk->val[2]);
|
||||
al = sk->val[2] & (tl ^ tr);
|
||||
ar = al ^ tr;
|
||||
al ^= tl;
|
||||
|
||||
al ^= sk->val[0]; /* XOR with the subkey */
|
||||
ar ^= sk->val[1];
|
||||
|
||||
/* S-box lookup and permutation */
|
||||
return (ice_sbox[0][al >> 10] | ice_sbox[1][al & 0x3ff]
|
||||
| ice_sbox[2][ar >> 10] | ice_sbox[3][ar & 0x3ff]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Encrypt a block of 8 bytes of data with the given ICE key.
|
||||
*/
|
||||
|
||||
void
|
||||
IceKey::encrypt (
|
||||
const unsigned char *ptext,
|
||||
unsigned char *ctext
|
||||
) const
|
||||
{
|
||||
register int i;
|
||||
register unsigned long l, r;
|
||||
|
||||
l = (((unsigned long) ptext[0]) << 24)
|
||||
| (((unsigned long) ptext[1]) << 16)
|
||||
| (((unsigned long) ptext[2]) << 8) | ptext[3];
|
||||
r = (((unsigned long) ptext[4]) << 24)
|
||||
| (((unsigned long) ptext[5]) << 16)
|
||||
| (((unsigned long) ptext[6]) << 8) | ptext[7];
|
||||
|
||||
for (i = 0; i < _rounds; i += 2) {
|
||||
l ^= ice_f (r, &_keysched[i]);
|
||||
r ^= ice_f (l, &_keysched[i + 1]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
ctext[3 - i] = r & 0xff;
|
||||
ctext[7 - i] = l & 0xff;
|
||||
|
||||
r >>= 8;
|
||||
l >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Decrypt a block of 8 bytes of data with the given ICE key.
|
||||
*/
|
||||
|
||||
void
|
||||
IceKey::decrypt (
|
||||
const unsigned char *ctext,
|
||||
unsigned char *ptext
|
||||
) const
|
||||
{
|
||||
register int i;
|
||||
register unsigned long l, r;
|
||||
|
||||
l = (((unsigned long) ctext[0]) << 24)
|
||||
| (((unsigned long) ctext[1]) << 16)
|
||||
| (((unsigned long) ctext[2]) << 8) | ctext[3];
|
||||
r = (((unsigned long) ctext[4]) << 24)
|
||||
| (((unsigned long) ctext[5]) << 16)
|
||||
| (((unsigned long) ctext[6]) << 8) | ctext[7];
|
||||
|
||||
for (i = _rounds - 1; i > 0; i -= 2) {
|
||||
l ^= ice_f (r, &_keysched[i]);
|
||||
r ^= ice_f (l, &_keysched[i - 1]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
ptext[3 - i] = r & 0xff;
|
||||
ptext[7 - i] = l & 0xff;
|
||||
|
||||
r >>= 8;
|
||||
l >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set 8 rounds [n, n+7] of the key schedule of an ICE key.
|
||||
*/
|
||||
|
||||
void
|
||||
IceKey::scheduleBuild (
|
||||
unsigned short *kb,
|
||||
int n,
|
||||
const int *keyrot
|
||||
) {
|
||||
int i;
|
||||
|
||||
for (i=0; i<8; i++) {
|
||||
register int j;
|
||||
register int kr = keyrot[i];
|
||||
IceSubkey *isk = &_keysched[n + i];
|
||||
|
||||
for (j=0; j<3; j++)
|
||||
isk->val[j] = 0;
|
||||
|
||||
for (j=0; j<15; j++) {
|
||||
register int k;
|
||||
unsigned long *curr_sk = &isk->val[j % 3];
|
||||
|
||||
for (k=0; k<4; k++) {
|
||||
unsigned short *curr_kb = &kb[(kr + k) & 3];
|
||||
register int bit = *curr_kb & 1;
|
||||
|
||||
*curr_sk = (*curr_sk << 1) | bit;
|
||||
*curr_kb = (*curr_kb >> 1) | ((bit ^ 1) << 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set the key schedule of an ICE key.
|
||||
*/
|
||||
|
||||
void
|
||||
IceKey::set (
|
||||
const unsigned char *key
|
||||
) {
|
||||
int i;
|
||||
|
||||
if (_rounds == 8) {
|
||||
unsigned short kb[4];
|
||||
|
||||
for (i=0; i<4; i++)
|
||||
kb[3 - i] = (key[i*2] << 8) | key[i*2 + 1];
|
||||
|
||||
scheduleBuild (kb, 0, ice_keyrot);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i<_size; i++) {
|
||||
int j;
|
||||
unsigned short kb[4];
|
||||
|
||||
for (j=0; j<4; j++)
|
||||
kb[3 - j] = (key[i*8 + j*2] << 8) | key[i*8 + j*2 + 1];
|
||||
|
||||
scheduleBuild (kb, i*8, ice_keyrot);
|
||||
scheduleBuild (kb, _rounds - 8 - i*8, &ice_keyrot[8]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the key size, in bytes.
|
||||
*/
|
||||
|
||||
int
|
||||
IceKey::keySize () const
|
||||
{
|
||||
return (_size * 8);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the block size, in bytes.
|
||||
*/
|
||||
|
||||
int
|
||||
IceKey::blockSize () const
|
||||
{
|
||||
return (8);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef MASTERMSGHANDLER_H
|
||||
#define MASTERMSGHANDLER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "Socket.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Socket handler for lan broadcast pings
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMasterMsgHandler : public CMsgHandler
|
||||
{
|
||||
public:
|
||||
CMasterMsgHandler( IGameList *baseobject, HANDLERTYPE type, void *typeinfo = NULL );
|
||||
|
||||
virtual bool Process( netadr_t *from, CMsgBuffer *msg );
|
||||
|
||||
private:
|
||||
IGameList *m_pGameList;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // MASTERMSGHANDLER_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,162 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
#if !defined( SOCKET_H )
|
||||
#define SOCKET_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "netadr.h"
|
||||
#include "MsgBuffer.h"
|
||||
#include "utlvector.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
class CMsgBuffer;
|
||||
class CSocket;
|
||||
class IGameList;
|
||||
|
||||
// Use this to pick apart the network stream, must be packed
|
||||
#pragma pack(1)
|
||||
typedef struct
|
||||
{
|
||||
int netID;
|
||||
int sequenceNumber;
|
||||
char packetID;
|
||||
} SPLITPACKET;
|
||||
#pragma pack()
|
||||
|
||||
#define MAX_PACKETS 16 // 4 bits for the packet count, so only
|
||||
#define MAX_RETRIES 2 // the number of fragments from other packets to drop before we declare the outstanding
|
||||
// fragment lost :)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Instances a message handler for incoming messages.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMsgHandler
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
MAX_HANDLER_STRING = 64
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MSGHANDLER_ALL = 0,
|
||||
MSGHANDLER_BYTECODE,
|
||||
MSGHANDLER_STRING
|
||||
} HANDLERTYPE;
|
||||
|
||||
// Construction
|
||||
CMsgHandler( HANDLERTYPE type, void *typeinfo = 0 );
|
||||
virtual ~CMsgHandler( void );
|
||||
|
||||
// Message received, process it
|
||||
virtual bool Process( netadr_t *from, CMsgBuffer *msg ) = 0;
|
||||
|
||||
// For linking togethr handler chains
|
||||
virtual CMsgHandler *GetNext( void ) const;
|
||||
virtual void SetNext( CMsgHandler *next );
|
||||
|
||||
// Access/set associated socket
|
||||
virtual CSocket *GetSocket( void ) const;
|
||||
virtual void SetSocket( CSocket *socket );
|
||||
|
||||
private:
|
||||
// Internal message received, crack type info and check it before calling process
|
||||
bool ProcessMessage( netadr_t *from, CMsgBuffer *msg );
|
||||
|
||||
// Opaque pointer to underlying recipient class
|
||||
IGameList *m_pBaseObject;
|
||||
|
||||
// Next handler in chain
|
||||
HANDLERTYPE m_Type;
|
||||
unsigned char m_ByteCode;
|
||||
char m_szString[ MAX_HANDLER_STRING ];
|
||||
|
||||
// Next handler in chain
|
||||
CMsgHandler *m_pNext;
|
||||
// Associated socket
|
||||
CSocket *m_pSocket;
|
||||
|
||||
friend CSocket;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Creates a non-blocking, broadcast capable, UDP socket. If port is
|
||||
// specified, binds it to listen on that port, otherwise, chooses a random port.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CSocket
|
||||
{
|
||||
public:
|
||||
// Construction/destruction
|
||||
CSocket( const char *socketname, int port = -1 );
|
||||
virtual ~CSocket( void );
|
||||
|
||||
// Adds the message hander to the head of the sockets handler chain
|
||||
virtual void AddMessageHandler( CMsgHandler *handler );
|
||||
// Removes the specified message handler
|
||||
virtual void RemoveMessageHandler( CMsgHandler *handler );
|
||||
|
||||
// Send the message to the recipient, if msg == NULL, use the internal message buffer
|
||||
virtual int SendMessage( netadr_t *to, CMsgBuffer *msg = NULL );
|
||||
// Broadcast the message on the specified port, if msg == NULL use the internal message buffer
|
||||
virtual int Broadcast( int port, CMsgBuffer *msg = NULL );
|
||||
// Get access to the internal message buffer
|
||||
virtual CMsgBuffer *GetSendBuffer( void );
|
||||
// Called once per frame to check for new data
|
||||
virtual void Frame( void );
|
||||
// Check whether the socket was created and set up properly
|
||||
virtual bool IsValid( void ) const;
|
||||
// Get the address this socket is bound to
|
||||
virtual const netadr_t *GetAddress( void );
|
||||
|
||||
// Allow creating object to store a 32 bit value and retrieve it
|
||||
virtual void SetUserData( unsigned int userData );
|
||||
virtual unsigned int GetUserData(void ) const;
|
||||
|
||||
// Allow other objects to get the raw socket interger
|
||||
virtual int GetSocketNumber( void ) const;
|
||||
// Called when FD_ISSET noted that the socket has incoming data
|
||||
virtual bool ReceiveData( void );
|
||||
// Called to get current time
|
||||
static float GetClock( void );
|
||||
|
||||
private:
|
||||
const char *m_pSocketName;
|
||||
// Socket listen address
|
||||
bool m_bValid;
|
||||
// Socket IP address
|
||||
netadr_t m_Address;
|
||||
// Has the IP address been resolved
|
||||
bool m_bResolved;
|
||||
// Internal message buffers
|
||||
CUtlVector<CMsgBuffer> m_MsgBuffers;
|
||||
CMsgBuffer m_SendBuffer;
|
||||
// critical section for accessing buffers
|
||||
void *m_pBufferCS;
|
||||
// One or more listeners for the incoming message
|
||||
CMsgHandler *m_pMessageHandlers;
|
||||
// Winsock socket number
|
||||
int m_Socket;
|
||||
// User 32 bit value
|
||||
unsigned int m_nUserData;
|
||||
// Socket to which non Broadcast SendMessage was directed. The socket will wait for a response
|
||||
// from that exact address
|
||||
netadr_t m_ToAddress;
|
||||
// Set to true if the send was a Broadcast, and therefore from != to address is okay
|
||||
bool m_bBroadcastSend;
|
||||
|
||||
int m_iTotalPackets; // total number of packets in a fragment
|
||||
int m_iCurrentPackets; // current packet count
|
||||
int m_iSeqNo; // the sequence number of the packet
|
||||
int m_iRetries;
|
||||
CMsgBuffer m_CurPacket[MAX_PACKETS]; // store for the packet
|
||||
};
|
||||
|
||||
#endif // SOCKET_H
|
||||
@@ -0,0 +1,22 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef TRACKERMESSAGEFLAGS_H
|
||||
#define TRACKERMESSAGEFLAGS_H
|
||||
#pragma once
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: the set of flags that can modify a message
|
||||
//-----------------------------------------------------------------------------
|
||||
enum TrackerMessageFlags_e
|
||||
{
|
||||
MESSAGEFLAG_SYSTEM = 1<<2, // message is from the tracker system
|
||||
MESSAGEFLAG_MARKETING = 1<<3, // message is from the tracker system
|
||||
};
|
||||
|
||||
|
||||
#endif // TRACKERMESSAGEFLAGS_H
|
||||
@@ -0,0 +1,161 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Holds all the protocol bits and defines used in tracker networking
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef TRACKERPROTOCOL_H
|
||||
#define TRACKERPROTOCOL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// failed return versions of the messages are the TMSG_FAIL_OFFSET + 10000
|
||||
#define TMSG_FAIL_OFFSET 10000
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: List of all the tracker messages used
|
||||
// msgID's are 32bits big
|
||||
//-----------------------------------------------------------------------------
|
||||
enum TrackerMsgID_t
|
||||
{
|
||||
// generic messages
|
||||
TMSG_NONE = 0, // no message id
|
||||
TMSG_ACK = 1, // packet acknowledgement
|
||||
|
||||
// server -> Client messages
|
||||
TSVC_BASE = 1000,
|
||||
|
||||
TSVC_CHALLENGE,
|
||||
TSVC_LOGINOK,
|
||||
TSVC_LOGINFAIL,
|
||||
TSVC_DISCONNECT,
|
||||
TSVC_FRIENDS,
|
||||
TSVC_FRIENDUPDATE,
|
||||
TSVC_HEARTBEAT,
|
||||
TSVC_PINGACK, // acknowledgement of TCLS_PING packet
|
||||
TSVC_FRIENDINFO,
|
||||
TSVC_USERVALID,
|
||||
TSVC_FRIENDSFOUND,
|
||||
TSVC_NOFRIENDS,
|
||||
TSVC_MESSAGE, // message passed through from another client
|
||||
TSVC_GAMEINFO, // information about a friends' game
|
||||
TSVC_AUTHREQUEST, // a user requesting auth from the receiving user
|
||||
TSVC_CONNECTIONKEEPALIVE, // information that an attemption connect is taking time, and the user should wait
|
||||
TSVC_ROUTEMESSAGEFAILED, // chat message failed to be routed through the servers
|
||||
TSVC_REDIRECTLOGIN, // tells the client to redirect their login attempt to a different server
|
||||
|
||||
// Client -> server messages
|
||||
TCLS_BASE = 2000,
|
||||
|
||||
TCLS_LOGIN, // login message
|
||||
TCLS_RESPONSE, // response to login challenge
|
||||
TCLS_PING,
|
||||
TCLS_FRIENDSEARCH,
|
||||
TCLS_HEARTBEAT,
|
||||
TCLS_AUTHUSER,
|
||||
TCLS_REQAUTH,
|
||||
TCLS_FRIENDINFO, // friend info request
|
||||
TCLS_SETINFO,
|
||||
TCLS_ROUTETOFRIEND, // generic reroute of a message to a friend
|
||||
|
||||
// Client -> Client messages
|
||||
TCL_BASE = 3000,
|
||||
TCL_MESSAGE, // chat text message
|
||||
TCL_USERBLOCK, // soon to be obselete
|
||||
TCL_ADDEDTOCHAT,
|
||||
TCL_CHATADDUSER,
|
||||
TCL_CHATUSERLEAVE,
|
||||
TCL_TYPINGMESSAGE,
|
||||
TCL_FRIENDNETMESSAGE,
|
||||
|
||||
// server -> server messages
|
||||
TSV_BASE = 4000,
|
||||
|
||||
TSV_WHOISPRIMARY,
|
||||
TSV_PRIMARYSRV,
|
||||
TSV_REQUESTINFO,
|
||||
TSV_TOPOLOGYINFO,
|
||||
TSV_REQUESTTOPOLOGYINFO,
|
||||
TSV_SERVERPING,
|
||||
TSV_MONITORINFO,
|
||||
TSV_LOCKUSERRANGE,
|
||||
TSV_UNLOCKUSERRANGE,
|
||||
TSV_REDIRECTTOUSER,
|
||||
TSV_FORCEDISCONNECTUSER,
|
||||
TSV_USERCHECKMESSAGES,
|
||||
TSV_USERAUTHREQUEST,
|
||||
TSV_USERSTATUSCHANGED,
|
||||
TSV_USERRELOADFRIENDSLIST,
|
||||
TSV_REGISTERSERVERINNETWORK,
|
||||
TSV_SERVERSHUTTINGDOWN,
|
||||
TSV_UPDATEACTIVEUSERRANGESTATUS,
|
||||
|
||||
// game server -> Client
|
||||
TCLG_BASE = 5000,
|
||||
|
||||
// common msg failed ID's
|
||||
TSVC_HEARTBEAT_FAIL = TSVC_HEARTBEAT + TMSG_FAIL_OFFSET,
|
||||
|
||||
TCLS_HEARTBEAT_FAIL = TCLS_HEARTBEAT + TMSG_FAIL_OFFSET,
|
||||
|
||||
TCL_MESSAGE_FAIL = TCL_MESSAGE + TMSG_FAIL_OFFSET,
|
||||
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: List of reasons explaining to user why they have been disconnected
|
||||
// from the friends network
|
||||
//-----------------------------------------------------------------------------
|
||||
enum TrackerLogoffReason_t
|
||||
{
|
||||
TRACKER_LOGOFF_NOREASON,
|
||||
|
||||
// server reasons for disconnecting user
|
||||
TRACKER_LOGOFF_LOGGEDINELSEWHERE, // user has logged into friends at a different location
|
||||
TRACKER_LOGOFF_SERVERWORK, // server needs to do work (like lock the user range)
|
||||
TRACKER_LOGOFF_SERVERSHUTDOWN, // server has been shutdown
|
||||
TRACKER_LOGOFF_TIMEDOUT, // user hasn't heartbeat'd to server recently enough
|
||||
TRACKER_LOGOFF_REQUESTED, // user has requested to logoff
|
||||
TRACKER_LOGOFF_FIREWALL, // users' firewall won't allow enough packets through
|
||||
TRACKER_LOGOFF_NOTCONNECTED, // user sent server a packet that implied they think they're logged in but they're not
|
||||
TRACKER_LOGOFF_INVALIDSTEAMTICKET, // users steam ticket is invalid
|
||||
|
||||
// client reasons for being disconnected
|
||||
TRACKER_LOGOFF_JOINEDGAME, // user has logged off because they joined a game
|
||||
TRACKER_LOGOFF_CONNECTIONTIMEOUT, // user connection has timed out
|
||||
TRACKER_LOGOFF_SERVERMESSAGEFAIL, // a message to the server was not successfully transmitted
|
||||
|
||||
TRACKER_LOGOFF_TOOMANYATTEMPTS, // too many login attempts have been performed
|
||||
TRACKER_LOGOFF_OFFLINE, // steam is in offline mode so don't try to connect
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: List of all the reasons a login attempt may fail
|
||||
//-----------------------------------------------------------------------------
|
||||
enum TrackerLoginFailReason_t
|
||||
{
|
||||
TRACKER_LOGINFAIL_NOREASON = 0,
|
||||
TRACKER_LOGINFAIL_NOSUCHUSER = -2,
|
||||
TRACKER_LOGINFAIL_ALREADLOGGEDIN = -3,
|
||||
TRACKER_LOGINFAIL_INVALIDSTEAMTICKET = -4,
|
||||
TRACKER_LOGINFAIL_BUILDOUTOFDATE = -5,
|
||||
TRACKER_LOGINFAIL_PLATFORMOUTOFDATE = -6,
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Holds basic status for a friend
|
||||
//-----------------------------------------------------------------------------
|
||||
struct FriendStatus_t
|
||||
{
|
||||
unsigned int friendID;
|
||||
int status;
|
||||
unsigned int sessionID;
|
||||
unsigned int ip;
|
||||
unsigned int port;
|
||||
unsigned int serverID;
|
||||
};
|
||||
|
||||
#endif // TRACKERPROTOCOL_H
|
||||
@@ -0,0 +1,332 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "UtlMsgBuffer.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: bitfields for use in variable descriptors
|
||||
//-----------------------------------------------------------------------------
|
||||
enum
|
||||
{
|
||||
PACKBIT_CONTROLBIT = 0x01, // this must always be set
|
||||
PACKBIT_INTNAME = 0x02, // if this is set then it's an int named variable, instead of a string
|
||||
PACKBIT_BINARYDATA = 0x04, // signifies the data in this variable is binary, it's not a string
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CUtlMsgBuffer::CUtlMsgBuffer(unsigned short msgID, int initialSize) : m_Memory(0, initialSize)
|
||||
{
|
||||
m_iMsgID = msgID;
|
||||
m_iWritePos = 0;
|
||||
m_iReadPos = 0;
|
||||
m_iNextVarPos = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor, takes initial data
|
||||
//-----------------------------------------------------------------------------
|
||||
CUtlMsgBuffer::CUtlMsgBuffer(unsigned short msgID, void const *data, int dataSize) : m_Memory(0, dataSize)
|
||||
{
|
||||
m_iMsgID = msgID;
|
||||
m_iWritePos = (short)dataSize;
|
||||
m_iReadPos = 0;
|
||||
m_iNextVarPos = 0;
|
||||
|
||||
memcpy(Base(), data, dataSize);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CUtlMsgBuffer::~CUtlMsgBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Copy
|
||||
//-----------------------------------------------------------------------------
|
||||
CUtlMsgBuffer &CUtlMsgBuffer::Copy(const CUtlMsgBuffer &rhs)
|
||||
{
|
||||
m_iWritePos = rhs.m_iWritePos;
|
||||
m_iReadPos = rhs.m_iReadPos;
|
||||
m_iNextVarPos = rhs.m_iNextVarPos;
|
||||
|
||||
m_Memory.EnsureCapacity(rhs.m_Memory.NumAllocated());
|
||||
if ( rhs.m_Memory.NumAllocated() > 0 )
|
||||
{
|
||||
memcpy(Base(), rhs.Base(), rhs.m_Memory.NumAllocated());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Writes string data to the message
|
||||
// Input : *name - name of the variable
|
||||
// *data - pointer to the string data to write
|
||||
//-----------------------------------------------------------------------------
|
||||
void CUtlMsgBuffer::WriteString(const char *name, const char *data)
|
||||
{
|
||||
// write out the variable type
|
||||
unsigned char vtype = PACKBIT_CONTROLBIT; // stringname var, string data
|
||||
Write(&vtype, 1);
|
||||
|
||||
// write out the variable name
|
||||
Write(name, strlen(name) + 1);
|
||||
|
||||
// write out the size of the data
|
||||
unsigned short size = (unsigned short)(strlen(data) + 1);
|
||||
Write(&size, 2);
|
||||
|
||||
// write out the data itself
|
||||
Write(data, size);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Writes out a named block of data
|
||||
//-----------------------------------------------------------------------------
|
||||
void CUtlMsgBuffer::WriteBlob(const char *name, const void *data, int dataSize)
|
||||
{
|
||||
// write out the variable type
|
||||
unsigned char vtype = PACKBIT_CONTROLBIT | PACKBIT_BINARYDATA; // stringname var, binary data
|
||||
Write(&vtype, 1);
|
||||
|
||||
// write out the variable name
|
||||
Write(name, strlen(name) + 1);
|
||||
|
||||
// write out the size of the data
|
||||
unsigned short size = (unsigned short)dataSize;
|
||||
Write(&size, 2);
|
||||
|
||||
// write out the data itself
|
||||
Write(data, dataSize);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Writes out another UtlMsgBuffer as an element of this one
|
||||
//-----------------------------------------------------------------------------
|
||||
void CUtlMsgBuffer::WriteBuffer(const char *name, const CUtlMsgBuffer *buffer)
|
||||
{
|
||||
// write out the variable type
|
||||
unsigned char vtype = PACKBIT_CONTROLBIT | PACKBIT_BINARYDATA; // stringname var, binary data
|
||||
Write(&vtype, 1);
|
||||
|
||||
// write out the variable name
|
||||
Write(name, strlen(name) + 1);
|
||||
|
||||
// write out the size of the data
|
||||
unsigned short size = (unsigned short) buffer->DataSize();
|
||||
Write(&size, 2);
|
||||
|
||||
// write out the data itself
|
||||
Write(buffer->Base(), size);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Reads from the buffer, increments read position
|
||||
// returns false if past end of buffer
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CUtlMsgBuffer::Read(void *buffer, int readAmount)
|
||||
{
|
||||
if (m_iReadPos + readAmount >= m_iWritePos)
|
||||
return false;
|
||||
|
||||
memcpy(buffer, &m_Memory[m_iReadPos], readAmount);
|
||||
m_iReadPos += readAmount;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Reads characterse from the buffer until a null is hit
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CUtlMsgBuffer::ReadUntilNull(void *buffer, int bufferSize)
|
||||
{
|
||||
int nullPos = m_iReadPos;
|
||||
|
||||
// look through the buffer for the null terminator
|
||||
while (nullPos < m_Memory.NumAllocated() && m_Memory[nullPos] != 0)
|
||||
{
|
||||
nullPos++;
|
||||
}
|
||||
|
||||
if (nullPos >= m_Memory.NumAllocated())
|
||||
{
|
||||
// never found a null terminator
|
||||
((char *)buffer)[0] = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// copy from the null terminator
|
||||
int copySize = nullPos - m_iReadPos;
|
||||
if (copySize > bufferSize)
|
||||
{
|
||||
copySize = bufferSize - 1;
|
||||
}
|
||||
|
||||
// copy out the data and return
|
||||
memcpy(buffer, &m_Memory[m_iReadPos], copySize);
|
||||
((char *)buffer)[copySize] = 0;
|
||||
m_iReadPos += (copySize+1);
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Writes to the buffer, incrementing the write position
|
||||
// assumes enough space has already been allocated for the write
|
||||
//-----------------------------------------------------------------------------
|
||||
void CUtlMsgBuffer::Write(void const *data, int size)
|
||||
{
|
||||
// make sure it will fit
|
||||
m_Memory.EnsureCapacity(m_iWritePos + size);
|
||||
|
||||
// normal write
|
||||
memcpy(&m_Memory[m_iWritePos], data, size);
|
||||
|
||||
// increment write position
|
||||
m_iWritePos += size;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Reads in a named variable length data blob
|
||||
// returns number of bytes read, 0 on failure
|
||||
//-----------------------------------------------------------------------------
|
||||
int CUtlMsgBuffer::ReadBlob(const char *name, void *data, int dataBufferSize)
|
||||
{
|
||||
int dataSize = 0;
|
||||
char *readData = (char *)FindVar(name, dataSize);
|
||||
if (!readData)
|
||||
{
|
||||
memset(data, 0, dataBufferSize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ensure against buffer overflow
|
||||
if (dataSize > dataBufferSize)
|
||||
dataSize = dataBufferSize;
|
||||
|
||||
// copy out data
|
||||
memcpy(data, readData, dataSize);
|
||||
return dataSize;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Reads a blob of binary data into it's own buffer
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CUtlMsgBuffer::ReadBuffer(const char *name, CUtlMsgBuffer &buffer)
|
||||
{
|
||||
int dataSize = 0;
|
||||
char *readData = (char *)FindVar(name, dataSize);
|
||||
if (!readData)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer.m_Memory.EnsureCapacity(dataSize);
|
||||
memcpy(&buffer.m_Memory[0], readData, dataSize);
|
||||
buffer.m_iReadPos = 0;
|
||||
buffer.m_iWritePos = (short)dataSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: reads out the next variable available in the buffer
|
||||
// fills out parameters with var details and data
|
||||
// returns false if no more vars available
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CUtlMsgBuffer::ReadNextVar(char varname[32], bool &stringData, void *data, int &dataSize)
|
||||
{
|
||||
// read the type
|
||||
unsigned char vtype = 1;
|
||||
if (!Read(&vtype, 1))
|
||||
return false;
|
||||
|
||||
// check for null-termination type
|
||||
if (vtype == 0)
|
||||
return false;
|
||||
|
||||
stringData = !(vtype & PACKBIT_BINARYDATA);
|
||||
|
||||
// read the variable name
|
||||
if (!ReadUntilNull(varname, 31))
|
||||
return false;
|
||||
|
||||
// read the data size
|
||||
unsigned short size = 0;
|
||||
if (!Read(&size, 2))
|
||||
return false;
|
||||
|
||||
// ensure against buffer overflows
|
||||
if (dataSize > size)
|
||||
dataSize = size;
|
||||
|
||||
// copy data
|
||||
memcpy(data, &m_Memory[m_iReadPos], dataSize);
|
||||
|
||||
// store of the next position, since that is probably where the next read needs to occur
|
||||
m_iReadPos += size;
|
||||
m_iNextVarPos = m_iReadPos;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets the read/write position to be at the specified variable
|
||||
// returns pointer to buffer position on success, NULL if not found
|
||||
//-----------------------------------------------------------------------------
|
||||
void *CUtlMsgBuffer::FindVar(const char *name, int &dataSize)
|
||||
{
|
||||
// reset to where we Think the next var will be read from
|
||||
m_iReadPos = m_iNextVarPos;
|
||||
int loopCount = 2;
|
||||
|
||||
// loop through looking for the specified variable
|
||||
while (loopCount--)
|
||||
{
|
||||
unsigned char vtype = 1;
|
||||
while (Read(&vtype, 1))
|
||||
{
|
||||
// check for null-termination type
|
||||
if (vtype == 0)
|
||||
break;
|
||||
|
||||
// read the variable name
|
||||
char varname[32];
|
||||
if (!ReadUntilNull(varname, 31))
|
||||
break;
|
||||
|
||||
// read the data size
|
||||
unsigned short size = 0;
|
||||
if (!Read(&size, 2))
|
||||
break;
|
||||
|
||||
// is this our variable?
|
||||
if (!stricmp(varname, name))
|
||||
{
|
||||
dataSize = size;
|
||||
void *data = &m_Memory[m_iReadPos];
|
||||
|
||||
// store of the next position, since that is probably where the next read needs to occur
|
||||
m_iReadPos += size;
|
||||
m_iNextVarPos = m_iReadPos;
|
||||
return data;
|
||||
}
|
||||
|
||||
// skip over the data block to the next variable
|
||||
m_iReadPos += size;
|
||||
if (m_iReadPos >= m_iWritePos)
|
||||
break;
|
||||
}
|
||||
|
||||
// we haven't found the data yet, Start again
|
||||
m_iReadPos = 0;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Generic named data buffer, declaration and implementation
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef UTLMSGBUFFER_H
|
||||
#define UTLMSGBUFFER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "UtlMemory.h"
|
||||
|
||||
#pragma warning(disable: 4244) // warning C4244: '=' : conversion from 'int' to 'short', possible loss of data
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Generic named data buffer
|
||||
//-----------------------------------------------------------------------------
|
||||
class CUtlMsgBuffer
|
||||
{
|
||||
public:
|
||||
CUtlMsgBuffer(unsigned short msgID, int initialSize);
|
||||
CUtlMsgBuffer(unsigned short msgID, void const *data, int dataSize);
|
||||
~CUtlMsgBuffer();
|
||||
|
||||
unsigned short GetMsgID() const { return m_iMsgID; }
|
||||
void SetMsgID(unsigned short msgID) { m_iMsgID = msgID; }
|
||||
|
||||
// read functions
|
||||
bool ReadInt(const char *name, int &data);
|
||||
bool ReadUInt(const char *name, unsigned int &data);
|
||||
bool ReadString(const char *name, char *data, int dataBufferSize);
|
||||
bool ReadBuffer(const char *name, CUtlMsgBuffer &buffer);
|
||||
// returns number of bytes read, 0 on failure
|
||||
int ReadBlob(const char *name, void *data, int dataBufferSize);
|
||||
|
||||
// reads out the next variable available in the buffer
|
||||
// fills out parameters with var details and data
|
||||
// returns false if no more vars available
|
||||
bool ReadNextVar(char name[32], bool &stringData, void *data, int &dataSize);
|
||||
|
||||
// write functions
|
||||
void WriteInt(const char *name, int data);
|
||||
void WriteUInt(const char *name, unsigned int data);
|
||||
void WriteString(const char *name, const char *data);
|
||||
void WriteBlob(const char *name, const void *data, int dataSize);
|
||||
void WriteBuffer(const char *name, const CUtlMsgBuffer *buffer);
|
||||
|
||||
// returns a pointer to the data buffer, and its size, of the specified variable
|
||||
void *FindVar(const char *name, int &dataSizeOut);
|
||||
|
||||
// pads the buffer to the specified boundary (in bytes)
|
||||
void PadBuffer(int boundary);
|
||||
|
||||
// makes sure the message has this much space allocated
|
||||
void EnsureCapacity(int dataSize);
|
||||
|
||||
// returns the number of bytes used by the message
|
||||
int DataSize() const;
|
||||
|
||||
// returns a pointer to the base data
|
||||
void *Base();
|
||||
|
||||
// returns a const pointer to the base data
|
||||
const void *Base() const;
|
||||
|
||||
// advances the write pointer - used when you write directly into the buffer
|
||||
void SetWritePos(int size);
|
||||
|
||||
CUtlMsgBuffer& Copy(const CUtlMsgBuffer &rhs);
|
||||
|
||||
// copy constructor
|
||||
CUtlMsgBuffer(const CUtlMsgBuffer &rhs)
|
||||
{
|
||||
m_iMsgID = rhs.m_iMsgID;
|
||||
m_iWritePos = rhs.m_iWritePos;
|
||||
m_iReadPos = rhs.m_iReadPos;
|
||||
m_iNextVarPos = rhs.m_iNextVarPos;
|
||||
|
||||
m_Memory.EnsureCapacity(rhs.m_Memory.NumAllocated());
|
||||
if ( rhs.m_Memory.NumAllocated() > 0 )
|
||||
{
|
||||
memcpy(Base(), rhs.Base(), rhs.m_Memory.NumAllocated());
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool Read(void *buffer, int readAmount);
|
||||
bool ReadUntilNull(void *buffer, int bufferSize);
|
||||
void Write(void const *data, int size);
|
||||
|
||||
CUtlMemory<char> m_Memory;
|
||||
|
||||
unsigned short m_iMsgID;
|
||||
short m_iWritePos; // position in buffer we are currently writing to
|
||||
short m_iReadPos; // current reading position
|
||||
short m_iNextVarPos; // a guess at which variable is most likely to be read next
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the number of bytes used by the message
|
||||
//-----------------------------------------------------------------------------
|
||||
inline int CUtlMsgBuffer::DataSize() const
|
||||
{
|
||||
// return the highest read/write mark
|
||||
if (m_iWritePos > m_iReadPos)
|
||||
return m_iWritePos;
|
||||
|
||||
return m_iReadPos;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns a pointer to the base data
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void *CUtlMsgBuffer::Base()
|
||||
{
|
||||
return &m_Memory[0];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns a pointer to the base data
|
||||
//-----------------------------------------------------------------------------
|
||||
inline const void *CUtlMsgBuffer::Base() const
|
||||
{
|
||||
return &m_Memory[0];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: ensures capacity
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void CUtlMsgBuffer::EnsureCapacity(int dataSize)
|
||||
{
|
||||
m_Memory.EnsureCapacity(dataSize);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: pads the buffer to the specified boundary (in bytes)
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void CUtlMsgBuffer::PadBuffer(int boundary)
|
||||
{
|
||||
// pad the buffer to be the right size for encryption
|
||||
int pad = (boundary - (DataSize() % boundary));
|
||||
Write("\0\0\0\0\0\0\0\0\0\0\0\0", pad);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Reads in a named 4-byte int, returns true on sucess, false on failure
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool CUtlMsgBuffer::ReadInt(const char *name, int &data)
|
||||
{
|
||||
return (ReadBlob(name, &data, 4) == 4);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Reads in a named 4-byte unsigned int, returns true on sucess, false on failure
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool CUtlMsgBuffer::ReadUInt(const char *name, unsigned int &data)
|
||||
{
|
||||
return (ReadBlob(name, &data, 4) == 4);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Reads in a named variable length character string
|
||||
// returns true on sucess, false on failure
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool CUtlMsgBuffer::ReadString(const char *name, char *data, int dataBufferSize)
|
||||
{
|
||||
return (ReadBlob(name, data, dataBufferSize) > 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Writes out an integer to the message
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void CUtlMsgBuffer::WriteInt(const char *name, int data)
|
||||
{
|
||||
WriteBlob(name, &data, 4);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Writes out an unsigned integer to the message
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void CUtlMsgBuffer::WriteUInt(const char *name, unsigned int data)
|
||||
{
|
||||
WriteBlob(name, &data, 4);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void CUtlMsgBuffer::SetWritePos(int size)
|
||||
{
|
||||
m_iWritePos = size;
|
||||
}
|
||||
|
||||
|
||||
#endif // UTLMSGBUFFER_H
|
||||
@@ -0,0 +1,42 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
#if !defined( INETAPI_H )
|
||||
#define INETAPI_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "netadr.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Internal winsock helpers for launcher
|
||||
//-----------------------------------------------------------------------------
|
||||
class INetAPI
|
||||
{
|
||||
public:
|
||||
// Convert a netadr_t to sockaddr
|
||||
virtual void NetAdrToSockAddr( netadr_t *a, struct sockaddr *s ) = 0;
|
||||
// Convert a sockaddr to netadr_t
|
||||
virtual void SockAddrToNetAdr( struct sockaddr *s, netadr_t *a ) = 0;
|
||||
|
||||
// Convert a netadr_t to a string
|
||||
virtual char *AdrToString( netadr_t *a ) = 0;
|
||||
// Convert a string address to a netadr_t, doing DNS if needed
|
||||
virtual bool StringToAdr( const char *s, netadr_t *a ) = 0;
|
||||
// Look up IP address for socket
|
||||
virtual void GetSocketAddress( int socket, netadr_t *a ) = 0;
|
||||
|
||||
virtual bool CompareAdr( netadr_t *a, netadr_t *b ) =0;
|
||||
|
||||
// return the IP of the local host
|
||||
virtual void GetLocalIP(netadr_t *a)=0;
|
||||
|
||||
};
|
||||
|
||||
extern INetAPI *net;
|
||||
|
||||
#endif // INETAPI_H
|
||||
@@ -0,0 +1,421 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "msgbuffer.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include <tier0/memdbgon.h>
|
||||
|
||||
#pragma warning(disable: 4244) // warning C4244: '=' : conversion from 'int' to 'unsigned char', possible loss of data
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Allocate message buffer
|
||||
// Input : *buffername -
|
||||
// *ef -
|
||||
//-----------------------------------------------------------------------------
|
||||
CMsgBuffer::CMsgBuffer( const char *buffername, void (*ef)( const char *fmt, ... ) /*= NULL*/ )
|
||||
{
|
||||
m_pszBufferName = buffername;
|
||||
m_pfnErrorFunc = ef;
|
||||
m_bAllowOverflow = false; // if false, Error
|
||||
m_bOverFlowed = false; // set to true if the buffer size failed
|
||||
m_nMaxSize = NET_MAXMESSAGE;
|
||||
m_nPushedCount = 0;
|
||||
m_bPushed = false;
|
||||
m_nReadCount = 0;
|
||||
m_bBadRead = false;
|
||||
|
||||
Clear();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CMsgBuffer::~CMsgBuffer( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Temporarily remember the read position so we can reset it
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::Push( void )
|
||||
{
|
||||
// ??? Allow multiple pushes without matching pops ???
|
||||
assert( !m_bPushed );
|
||||
|
||||
m_nPushedCount = m_nReadCount;
|
||||
m_bPushed = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::Pop( void )
|
||||
{
|
||||
assert( m_bPushed );
|
||||
|
||||
m_nReadCount = m_nPushedCount;
|
||||
m_bPushed = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : allowed -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::SetOverflow( bool allowed )
|
||||
{
|
||||
m_bAllowOverflow = allowed;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMsgBuffer::GetMaxSize( void )
|
||||
{
|
||||
return m_nMaxSize;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : void *
|
||||
//-----------------------------------------------------------------------------
|
||||
void * CMsgBuffer::GetData( void )
|
||||
{
|
||||
return m_rgData;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMsgBuffer::GetCurSize( void )
|
||||
{
|
||||
return m_nCurSize;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMsgBuffer::GetReadCount( void )
|
||||
{
|
||||
return m_nReadCount;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::SetTime(float time)
|
||||
{
|
||||
m_fRecvTime = time;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
float CMsgBuffer::GetTime()
|
||||
{
|
||||
return m_fRecvTime;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::SetNetAddress(netadr_t &adr)
|
||||
{
|
||||
m_NetAddr = adr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
netadr_t &CMsgBuffer::GetNetAddress()
|
||||
{
|
||||
return m_NetAddr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::WriteByte( int c )
|
||||
{
|
||||
unsigned char *buf;
|
||||
buf = (unsigned char *)GetSpace( 1 );
|
||||
buf[0] = c;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : c -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::WriteShort ( int c )
|
||||
{
|
||||
unsigned char *buf;
|
||||
buf = (unsigned char *)GetSpace( 2 );
|
||||
buf[0] = c&0xff;
|
||||
buf[1] = c>>8;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : c -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::WriteLong (int c)
|
||||
{
|
||||
unsigned char *buf;
|
||||
|
||||
buf = (unsigned char *)GetSpace( 4 );
|
||||
buf[0] = c&0xff;
|
||||
buf[1] = (c>>8)&0xff;
|
||||
buf[2] = (c>>16)&0xff;
|
||||
buf[3] = c>>24;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : f -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::WriteFloat (float f)
|
||||
{
|
||||
union
|
||||
{
|
||||
float f;
|
||||
int l;
|
||||
} dat;
|
||||
|
||||
dat.f = f;
|
||||
Write( &dat.l, 4 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *s -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::WriteString (const char *s)
|
||||
{
|
||||
if ( !s )
|
||||
{
|
||||
Write ("", 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Write ( s, strlen( s ) + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : iSize -
|
||||
// *buf -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::WriteBuf( int iSize, void *buf )
|
||||
{
|
||||
if ( !buf )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Write( buf, iSize );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::BeginReading (void)
|
||||
{
|
||||
m_nReadCount = 0;
|
||||
m_bBadRead = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int CMsgBuffer::ReadByte
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMsgBuffer::ReadByte (void)
|
||||
{
|
||||
int c;
|
||||
|
||||
if ( m_nReadCount + 1 > m_nCurSize )
|
||||
{
|
||||
m_bBadRead = true;
|
||||
return -1;
|
||||
}
|
||||
|
||||
c = ( unsigned char )m_rgData[ m_nReadCount ];
|
||||
m_nReadCount++;
|
||||
return c;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int CMsgBuffer::ReadShort
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMsgBuffer::ReadShort (void)
|
||||
{
|
||||
int c;
|
||||
|
||||
if ( m_nReadCount + 2 > m_nCurSize )
|
||||
{
|
||||
m_bBadRead = true;
|
||||
return -1;
|
||||
}
|
||||
|
||||
c = (short)(m_rgData[m_nReadCount] + (m_rgData[m_nReadCount+1]<<8));
|
||||
m_nReadCount += 2;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int CMsgBuffer::ReadLong
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMsgBuffer::ReadLong (void)
|
||||
{
|
||||
int c;
|
||||
|
||||
if (m_nReadCount+4 > m_nCurSize)
|
||||
{
|
||||
m_bBadRead = true;
|
||||
return -1;
|
||||
}
|
||||
|
||||
c = m_rgData[m_nReadCount]
|
||||
+ (m_rgData[m_nReadCount+1]<<8)
|
||||
+ (m_rgData[m_nReadCount+2]<<16)
|
||||
+ (m_rgData[m_nReadCount+3]<<24);
|
||||
|
||||
m_nReadCount += 4;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : float CMsgBuffer::ReadFloat
|
||||
//-----------------------------------------------------------------------------
|
||||
float CMsgBuffer::ReadFloat (void)
|
||||
{
|
||||
union
|
||||
{
|
||||
unsigned char b[4];
|
||||
float f;
|
||||
} dat;
|
||||
|
||||
dat.b[0] = m_rgData[m_nReadCount];
|
||||
dat.b[1] = m_rgData[m_nReadCount+1];
|
||||
dat.b[2] = m_rgData[m_nReadCount+2];
|
||||
dat.b[3] = m_rgData[m_nReadCount+3];
|
||||
m_nReadCount += 4;
|
||||
return dat.f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : iSize -
|
||||
// *pbuf -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMsgBuffer::ReadBuf( int iSize, void *pbuf )
|
||||
{
|
||||
if (m_nReadCount + iSize > m_nCurSize)
|
||||
{
|
||||
m_bBadRead = true;
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy( pbuf, &m_rgData[m_nReadCount], iSize );
|
||||
m_nReadCount += iSize;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : char *
|
||||
//-----------------------------------------------------------------------------
|
||||
char *CMsgBuffer::ReadString (void)
|
||||
{
|
||||
static char string[ NET_MAXMESSAGE ];
|
||||
int l,c;
|
||||
|
||||
l = 0;
|
||||
do
|
||||
{
|
||||
c = (char)ReadByte();
|
||||
if ( c == -1 || c == 0 )
|
||||
break;
|
||||
string[l] = c;
|
||||
l++;
|
||||
} while ( l < sizeof(string)-1 );
|
||||
|
||||
string[ l ] = 0;
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::Clear( void )
|
||||
{
|
||||
m_nCurSize = 0;
|
||||
m_bOverFlowed = false;
|
||||
m_nReadCount = 0;
|
||||
m_bBadRead = false;
|
||||
memset( m_rgData, 0, sizeof( m_rgData ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : length -
|
||||
//-----------------------------------------------------------------------------
|
||||
void *CMsgBuffer::GetSpace( int length )
|
||||
{
|
||||
void *d;
|
||||
|
||||
if (m_nCurSize + length > m_nMaxSize)
|
||||
{
|
||||
if ( !m_bAllowOverflow )
|
||||
{
|
||||
if ( m_pfnErrorFunc )
|
||||
{
|
||||
( *m_pfnErrorFunc )( "CMsgBuffer(%s), no room for %i bytes, %i / %i already in use\n",
|
||||
m_pszBufferName, length, m_nCurSize, m_nMaxSize );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (length > m_nMaxSize)
|
||||
{
|
||||
if ( m_pfnErrorFunc )
|
||||
{
|
||||
( *m_pfnErrorFunc )( "CMsgBuffer(%s), no room for %i bytes, %i is max\n",
|
||||
m_pszBufferName, length, m_nMaxSize );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m_bOverFlowed = true;
|
||||
Clear();
|
||||
}
|
||||
|
||||
d = m_rgData + m_nCurSize;
|
||||
m_nCurSize += length;
|
||||
return d;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *m_rgData -
|
||||
// length -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMsgBuffer::Write(const void *m_rgData, int length)
|
||||
{
|
||||
memcpy( GetSpace(length), m_rgData, length );
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
#if !defined( MSGBUFFER_H )
|
||||
#define MSGBUFFER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "netadr.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Generic byte level message buffer with read/write support
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMsgBuffer
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
NET_MAXMESSAGE = 8192
|
||||
};
|
||||
|
||||
// Buffers must be named
|
||||
CMsgBuffer( const char *buffername = "unnamed", void (*ef)( PRINTF_FORMAT_STRING const char *fmt, ... ) = 0 );
|
||||
virtual ~CMsgBuffer( void );
|
||||
|
||||
// Reset the buffer for writing
|
||||
void Clear( void );
|
||||
// Get current # of bytes
|
||||
int GetCurSize( void );
|
||||
// Get max # of bytes
|
||||
int GetMaxSize( void );
|
||||
// Get pointer to raw data
|
||||
void *GetData( void );
|
||||
// Set/unset the allow overflow flag
|
||||
void SetOverflow( bool allowed );
|
||||
// Start reading from buffer
|
||||
void BeginReading( void );
|
||||
// Get current read byte
|
||||
int GetReadCount( void );
|
||||
|
||||
// Push read count ( to peek at data )
|
||||
void Push( void );
|
||||
void Pop( void );
|
||||
|
||||
// Writing functions
|
||||
void WriteByte(int c);
|
||||
void WriteShort(int c);
|
||||
void WriteLong(int c);
|
||||
void WriteFloat(float f);
|
||||
void WriteString(const char *s);
|
||||
void WriteBuf( int iSize, void *buf );
|
||||
|
||||
// Reading functions
|
||||
int ReadByte( void );
|
||||
int ReadShort( void );
|
||||
int ReadLong( void );
|
||||
float ReadFloat( void );
|
||||
char *ReadString( void );
|
||||
int ReadBuf( int iSize, void *pbuf );
|
||||
|
||||
// setting and storing time received
|
||||
void SetTime(float time);
|
||||
float GetTime();
|
||||
|
||||
// net address received from
|
||||
void SetNetAddress(netadr_t &adr);
|
||||
netadr_t &GetNetAddress();
|
||||
|
||||
private:
|
||||
// Ensures sufficient space to append an object of length
|
||||
void *GetSpace( int length );
|
||||
// Copy buffer in at current writing point
|
||||
void Write( const void *data, int length );
|
||||
|
||||
private:
|
||||
// Name of buffer in case of debugging/errors
|
||||
const char *m_pszBufferName;
|
||||
// Optional error callback
|
||||
void ( *m_pfnErrorFunc )( PRINTF_FORMAT_STRING const char *fmt, ... );
|
||||
|
||||
// Current read pointer
|
||||
int m_nReadCount;
|
||||
// Push/pop read state
|
||||
int m_nPushedCount;
|
||||
bool m_bPushed;
|
||||
// Did we hit the end of the read buffer?
|
||||
bool m_bBadRead;
|
||||
// Max size of buffer
|
||||
int m_nMaxSize;
|
||||
// Current bytes written
|
||||
int m_nCurSize;
|
||||
// if false, call m_pfnErrorFunc
|
||||
bool m_bAllowOverflow;
|
||||
// set to true when buffer hits end
|
||||
bool m_bOverFlowed;
|
||||
// Internal storage
|
||||
unsigned char m_rgData[ NET_MAXMESSAGE ];
|
||||
// time received
|
||||
float m_fRecvTime;
|
||||
// address received from
|
||||
netadr_t m_NetAddr;
|
||||
};
|
||||
|
||||
#endif // !MSGBUFFER_H
|
||||
@@ -0,0 +1,277 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#if defined( WIN32 )
|
||||
#if !defined( _X360 )
|
||||
#include "winsock.h"
|
||||
#else
|
||||
#include "winsockx.h"
|
||||
#endif
|
||||
#elif defined( POSIX )
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
#include "inetapi.h"
|
||||
|
||||
#if defined( _X360 )
|
||||
#include "xbox/xbox_win32stubs.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include <tier0/memdbgon.h>
|
||||
#pragma warning(disable: 4706) // warning C4706: assignment within conditional expression
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Implements INetAPI
|
||||
//-----------------------------------------------------------------------------
|
||||
class CNetAPI : public INetAPI
|
||||
{
|
||||
public:
|
||||
virtual void NetAdrToSockAddr( netadr_t *a, struct sockaddr *s );
|
||||
virtual void SockAddrToNetAdr( struct sockaddr *s, netadr_t *a );
|
||||
|
||||
virtual char *AdrToString( netadr_t *a );
|
||||
virtual bool StringToAdr( const char *s, netadr_t *a );
|
||||
|
||||
virtual void GetSocketAddress( int socket, netadr_t *a );
|
||||
|
||||
virtual bool CompareAdr( netadr_t *a, netadr_t *b );
|
||||
|
||||
virtual void GetLocalIP(netadr_t *a);
|
||||
};
|
||||
|
||||
// Expose interface
|
||||
static CNetAPI g_NetAPI;
|
||||
INetAPI *net = ( INetAPI * )&g_NetAPI;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *a -
|
||||
// *s -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CNetAPI::NetAdrToSockAddr (netadr_t *a, struct sockaddr *s)
|
||||
{
|
||||
memset (s, 0, sizeof(*s));
|
||||
|
||||
if (a->type == NA_BROADCAST)
|
||||
{
|
||||
((struct sockaddr_in *)s)->sin_family = AF_INET;
|
||||
((struct sockaddr_in *)s)->sin_port = a->port;
|
||||
((struct sockaddr_in *)s)->sin_addr.s_addr = INADDR_BROADCAST;
|
||||
}
|
||||
else if (a->type == NA_IP)
|
||||
{
|
||||
((struct sockaddr_in *)s)->sin_family = AF_INET;
|
||||
((struct sockaddr_in *)s)->sin_addr.s_addr = *(int *)&a->ip;
|
||||
((struct sockaddr_in *)s)->sin_port = a->port;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *s -
|
||||
// *a -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CNetAPI::SockAddrToNetAdr( struct sockaddr *s, netadr_t *a )
|
||||
{
|
||||
if (s->sa_family == AF_INET)
|
||||
{
|
||||
a->type = NA_IP;
|
||||
*(int *)&a->ip = ((struct sockaddr_in *)s)->sin_addr.s_addr;
|
||||
a->port = ((struct sockaddr_in *)s)->sin_port;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *a -
|
||||
// Output : char
|
||||
//-----------------------------------------------------------------------------
|
||||
char *CNetAPI::AdrToString( netadr_t *a )
|
||||
{
|
||||
static char s[64];
|
||||
|
||||
memset(s, 0, 64);
|
||||
|
||||
if ( a )
|
||||
{
|
||||
if ( a->type == NA_LOOPBACK )
|
||||
{
|
||||
sprintf (s, "loopback");
|
||||
}
|
||||
else if ( a->type == NA_IP )
|
||||
{
|
||||
sprintf(s, "%i.%i.%i.%i:%i", a->ip[0], a->ip[1], a->ip[2], a->ip[3], ntohs( a->port ) );
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *s -
|
||||
// *sadr -
|
||||
// Output : static bool
|
||||
//-----------------------------------------------------------------------------
|
||||
static bool StringToSockaddr( const char *s, struct sockaddr *sadr )
|
||||
{
|
||||
struct hostent *h;
|
||||
char *colon;
|
||||
char copy[128];
|
||||
struct sockaddr_in *p;
|
||||
|
||||
memset (sadr, 0, sizeof(*sadr));
|
||||
|
||||
p = ( struct sockaddr_in * )sadr;
|
||||
p->sin_family = AF_INET;
|
||||
p->sin_port = 0;
|
||||
|
||||
strcpy (copy, s);
|
||||
|
||||
// strip off a trailing :port if present
|
||||
for ( colon = copy ; *colon ; colon++ )
|
||||
{
|
||||
if (*colon == ':')
|
||||
{
|
||||
// terminate
|
||||
*colon = 0;
|
||||
// Start at next character
|
||||
p->sin_port = htons( ( short )atoi( colon + 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Numeric IP, no DNS
|
||||
if ( copy[0] >= '0' && copy[0] <= '9' && strstr( copy, "." ) )
|
||||
{
|
||||
*(int *)&p->sin_addr = inet_addr( copy );
|
||||
}
|
||||
else
|
||||
{
|
||||
// DNS it
|
||||
if ( !( h = gethostbyname( copy ) ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Use first result
|
||||
*(int *)&p->sin_addr = *(int *)h->h_addr_list[0];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *s -
|
||||
// *a -
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetAPI::StringToAdr( const char *s, netadr_t *a )
|
||||
{
|
||||
struct sockaddr sadr;
|
||||
|
||||
if ( !strcmp ( s, "localhost" ) )
|
||||
{
|
||||
memset ( a, 0, sizeof( *a ) );
|
||||
a->type = NA_LOOPBACK;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( !StringToSockaddr (s, &sadr) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SockAddrToNetAdr( &sadr, a );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Lookup the IP address for the specified IP socket
|
||||
// Input : socket -
|
||||
// *a -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CNetAPI::GetSocketAddress( int socket, netadr_t *a )
|
||||
{
|
||||
char buff[512];
|
||||
struct sockaddr_in address;
|
||||
int namelen;
|
||||
// int net_error = 0;
|
||||
|
||||
memset( a, 0, sizeof( *a ) );
|
||||
gethostname(buff, 512);
|
||||
// Ensure that it doesn't overrun the buffer
|
||||
buff[512-1] = 0;
|
||||
|
||||
StringToAdr(buff, a );
|
||||
|
||||
namelen = sizeof(address);
|
||||
if ( getsockname( socket, (struct sockaddr *)&address, (int *)&namelen) == 0 )
|
||||
{
|
||||
a->port = address.sin_port;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Full IP address compare
|
||||
// Input : *a -
|
||||
// *b -
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNetAPI::CompareAdr( netadr_t *a, netadr_t *b )
|
||||
{
|
||||
if ( a->type != b->type )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( a->type == NA_LOOPBACK )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( a->type == NA_IP &&
|
||||
a->ip[0] == b->ip[0] &&
|
||||
a->ip[1] == b->ip[1] &&
|
||||
a->ip[2] == b->ip[2] &&
|
||||
a->ip[3] == b->ip[3] &&
|
||||
a->port == b->port )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Full IP address compare
|
||||
// Input : *a -
|
||||
// *b -
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void CNetAPI::GetLocalIP(netadr_t *a)
|
||||
{
|
||||
char s[64];
|
||||
|
||||
if(!::gethostname(s,64))
|
||||
{
|
||||
struct hostent *localip = ::gethostbyname(s);
|
||||
if(localip)
|
||||
{
|
||||
a->type=NA_IP;
|
||||
a->port=0;
|
||||
memcpy(a->ip,localip->h_addr_list[0],4);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef SERVER_H
|
||||
#define SERVER_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Data describing a single server
|
||||
//-----------------------------------------------------------------------------
|
||||
struct serveritem_t
|
||||
{
|
||||
serveritem_t()
|
||||
{
|
||||
pings[0] = 0;
|
||||
pings[1] = 0;
|
||||
pings[2] = 0;
|
||||
}
|
||||
|
||||
unsigned char ip[4];
|
||||
int port;
|
||||
int received;
|
||||
float time;
|
||||
int ping; // current ping time, derived from pings[]
|
||||
int pings[3]; // last 3 ping times
|
||||
bool hadSuccessfulResponse; // server has responded successfully in the past
|
||||
bool doNotRefresh; // server is marked as not responding and should no longer be refreshed
|
||||
char gameDir[32]; // current game directory
|
||||
char map[32]; // current map
|
||||
char gameDescription[64]; // game description
|
||||
char name[64]; // server name
|
||||
int players;
|
||||
int maxPlayers;
|
||||
int botPlayers;
|
||||
bool proxy;
|
||||
bool password;
|
||||
unsigned int serverID;
|
||||
int listEntryID;
|
||||
char rconPassword[64]; // the rcon password for this server
|
||||
bool loadedFromFile; // true if this entry was loaded from file rather than comming from the master
|
||||
};
|
||||
|
||||
|
||||
#endif // SERVER_H
|
||||
@@ -0,0 +1,70 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "util.h"
|
||||
#include <string.h>
|
||||
|
||||
#define NUM_BUFFERS 4
|
||||
#define MAX_INFO_TOKEN_LENGTH 512
|
||||
const char *CUtil::InfoGetValue( const char *s, const char *key )
|
||||
{
|
||||
char pkey[MAX_INFO_TOKEN_LENGTH];
|
||||
// Use multiple buffers so compares
|
||||
// work without stomping on each other
|
||||
static char value[NUM_BUFFERS][MAX_INFO_TOKEN_LENGTH];
|
||||
static int valueindex;
|
||||
char *o;
|
||||
|
||||
valueindex = (valueindex + 1) % NUM_BUFFERS;
|
||||
|
||||
if (*s == '\\')
|
||||
s++;
|
||||
while (1)
|
||||
{
|
||||
o = pkey;
|
||||
while (*s != '\\')
|
||||
{
|
||||
if (!*s)
|
||||
return "";
|
||||
*o++ = *s++;
|
||||
}
|
||||
*o = 0;
|
||||
s++;
|
||||
|
||||
o = value[valueindex];
|
||||
|
||||
while (*s != '\\' && *s)
|
||||
{
|
||||
if (!*s)
|
||||
return "";
|
||||
*o++ = *s++;
|
||||
}
|
||||
*o = 0;
|
||||
|
||||
if (!strcmp (key, pkey) )
|
||||
return value[valueindex];
|
||||
|
||||
if (!*s)
|
||||
return "";
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This function is supposed to localise the strings, but for now just return internal value
|
||||
// Input : *stringName -
|
||||
// Output : const char
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CUtil::GetString(const char *stringName)
|
||||
{
|
||||
return stringName;
|
||||
}
|
||||
|
||||
static CUtil g_Util;
|
||||
CUtil *util = &g_Util;
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Utility function for the server browser
|
||||
//-----------------------------------------------------------------------------
|
||||
class CUtil
|
||||
{
|
||||
public:
|
||||
const char *InfoGetValue(const char *s, const char *key);
|
||||
const char *GetString(const char *stringName);
|
||||
|
||||
};
|
||||
|
||||
extern CUtil *util;
|
||||
|
||||
|
||||
|
||||
#endif // UTIL_H
|
||||
Reference in New Issue
Block a user