mirror of
https://github.com/rlabrecque/SteamworksSDK.git
synced 2026-10-10 09:33:04 +08:00
v1.00
This commit is contained in:
+18
@@ -0,0 +1,18 @@
|
||||
This is the Steamworks SDK v1.0
|
||||
|
||||
================================================================
|
||||
|
||||
Copyright © 1996-2008, Valve Corporation, All rights reserved.
|
||||
|
||||
================================================================
|
||||
|
||||
|
||||
Welcome to the Steamworks SDK. For documentation please see our partner
|
||||
website at: http://partner.steamgames.com.
|
||||
|
||||
|
||||
Revision History:
|
||||
|
||||
v1.0:
|
||||
|
||||
- Initial Steamworks SDK release
|
||||
@@ -0,0 +1,16 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Base class for various game menu screens
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "BaseMenu.h"
|
||||
|
||||
// Static data
|
||||
HGAMEFONT g_hMenuFont = 0;
|
||||
uint64 g_ulLastReturnKeyTick = 0;
|
||||
uint64 g_ulLastKeyDownTick = 0;
|
||||
uint64 g_ulLastKeyUpTick = 0;
|
||||
@@ -0,0 +1,237 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Base class for various game menu screens
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef BASEMENU_H
|
||||
#define BASEMENU_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "GameEngine.h"
|
||||
#include "SpaceWar.h"
|
||||
#include "SpaceWarClient.h"
|
||||
|
||||
#define MENU_FONT_HEIGHT 24
|
||||
#define MENU_ITEM_PADDING 12
|
||||
|
||||
extern HGAMEFONT g_hMenuFont;
|
||||
extern uint64 g_ulLastReturnKeyTick;
|
||||
extern uint64 g_ulLastKeyDownTick;
|
||||
extern uint64 g_ulLastKeyUpTick;
|
||||
|
||||
template <class T> class CBaseMenu
|
||||
{
|
||||
public:
|
||||
// Typedef for menu items
|
||||
typedef std::pair<std::string, T> MenuItem_t;
|
||||
|
||||
// Constructor
|
||||
CBaseMenu( CGameEngine *pGameEngine )
|
||||
{
|
||||
m_pGameEngine = pGameEngine;
|
||||
|
||||
m_uSelectedItem = 0;
|
||||
m_bSelectionPushed = false;
|
||||
|
||||
if ( !g_hMenuFont )
|
||||
{
|
||||
g_hMenuFont = pGameEngine->HCreateFont( MENU_FONT_HEIGHT, FW_BOLD, false, "Arial" );
|
||||
if ( !g_hMenuFont )
|
||||
OutputDebugString( "Menu font was not created properly, text won't draw\n" );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Sets a heading for the menu
|
||||
void SetHeading( const char *pchHeading )
|
||||
{
|
||||
m_sHeading = pchHeading;
|
||||
}
|
||||
|
||||
// Clear all menu entries
|
||||
void ClearMenuItems()
|
||||
{
|
||||
m_VecMenuItems.clear();
|
||||
m_uSelectedItem = 0;
|
||||
}
|
||||
|
||||
// Add a menu item to the menu
|
||||
void AddMenuItem( MenuItem_t item )
|
||||
{
|
||||
m_VecMenuItems.push_back( item );
|
||||
}
|
||||
|
||||
void PushSelectedItem()
|
||||
{
|
||||
if ( m_VecMenuItems.size() )
|
||||
{
|
||||
m_bSelectionPushed = true;
|
||||
m_selection = m_VecMenuItems[m_uSelectedItem].second;
|
||||
}
|
||||
}
|
||||
|
||||
void PopSelectedItem()
|
||||
{
|
||||
if ( m_bSelectionPushed )
|
||||
{
|
||||
m_bSelectionPushed = false;
|
||||
|
||||
// find the item and set it as selected if it exists
|
||||
for ( unsigned int i = 0; i < m_VecMenuItems.size(); i++ )
|
||||
{
|
||||
if ( !memcmp( &m_VecMenuItems[i].second, &m_selection, sizeof( m_selection ) ) )
|
||||
{
|
||||
m_uSelectedItem = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Run a frame + render
|
||||
void RunFrame()
|
||||
{
|
||||
// Note: The below code uses globals that are shared across all menus to avoid double
|
||||
// key press registration, this is so that when you do something like hit return in the pause
|
||||
// menu to "go back to main menu" you don't end up immediately registering a return in the
|
||||
// main menu afterwards.
|
||||
|
||||
// check if the enter key is down, if it is take action
|
||||
if ( m_pGameEngine->BIsKeyDown( VK_RETURN ) )
|
||||
{
|
||||
uint64 ulCurrentTickCount = m_pGameEngine->GetGameTickCount();
|
||||
if ( ulCurrentTickCount - 150 > g_ulLastReturnKeyTick )
|
||||
{
|
||||
g_ulLastReturnKeyTick = ulCurrentTickCount;
|
||||
if ( m_uSelectedItem >= 0 && m_uSelectedItem < m_VecMenuItems.size() )
|
||||
{
|
||||
SpaceWarClient()->OnMenuSelection( m_VecMenuItems[m_uSelectedItem].second );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check if we need to change the selected menu item
|
||||
else if ( m_pGameEngine->BIsKeyDown( VK_DOWN ) )
|
||||
{
|
||||
uint64 ulCurrentTickCount = m_pGameEngine->GetGameTickCount();
|
||||
if ( ulCurrentTickCount - 150 > g_ulLastKeyDownTick )
|
||||
{
|
||||
g_ulLastKeyDownTick = ulCurrentTickCount;
|
||||
if ( m_uSelectedItem < m_VecMenuItems.size() - 1 )
|
||||
m_uSelectedItem++;
|
||||
}
|
||||
}
|
||||
else if ( m_pGameEngine->BIsKeyDown( VK_UP ) )
|
||||
{
|
||||
uint64 ulCurrentTickCount = m_pGameEngine->GetGameTickCount();
|
||||
if ( ulCurrentTickCount - 250 > g_ulLastKeyUpTick )
|
||||
{
|
||||
g_ulLastKeyUpTick = ulCurrentTickCount;
|
||||
if ( m_uSelectedItem > 0 )
|
||||
m_uSelectedItem--;
|
||||
}
|
||||
}
|
||||
|
||||
Render();
|
||||
}
|
||||
|
||||
// Render the menu
|
||||
virtual void Render()
|
||||
{
|
||||
const int32 iMaxMenuItems = 13;
|
||||
int32 iNumItems = (int32)m_VecMenuItems.size();
|
||||
uint32 uBoxHeight = min( iNumItems, iMaxMenuItems ) * ( MENU_FONT_HEIGHT + MENU_ITEM_PADDING );
|
||||
uint32 yPos = m_pGameEngine->GetViewportHeight()/2 - uBoxHeight/2;
|
||||
|
||||
RECT rect;
|
||||
rect.top = yPos;
|
||||
rect.bottom = yPos + MENU_FONT_HEIGHT + MENU_ITEM_PADDING;
|
||||
rect.left = 0;
|
||||
rect.right = m_pGameEngine->GetViewportWidth();
|
||||
char rgchBuffer[256];
|
||||
|
||||
if ( m_sHeading.length() )
|
||||
{
|
||||
DWORD dwColor = D3DCOLOR_ARGB( 255, 255, 128, 128 );
|
||||
RECT rect;
|
||||
rect.top = 10;
|
||||
rect.bottom = rect.top + MENU_FONT_HEIGHT + ( MENU_ITEM_PADDING * 2 );
|
||||
rect.left = 0;
|
||||
rect.right = m_pGameEngine->GetViewportWidth();
|
||||
m_pGameEngine->BDrawString( g_hMenuFont, rect, dwColor, DT_CENTER|DT_VCENTER, m_sHeading.c_str() );
|
||||
}
|
||||
|
||||
int32 iStartItem = 0;
|
||||
int32 iEndItem = iNumItems;
|
||||
if ( iNumItems > iMaxMenuItems )
|
||||
{
|
||||
iStartItem = max( (int32)m_uSelectedItem - iMaxMenuItems/2, 0 );
|
||||
iEndItem = min( iStartItem + iMaxMenuItems, iNumItems );
|
||||
}
|
||||
|
||||
if ( iStartItem > 0 )
|
||||
{
|
||||
// Draw ... Scroll Up ...
|
||||
DWORD dwColor = D3DCOLOR_ARGB( 255, 255, 255, 255 );
|
||||
m_pGameEngine->BDrawString( g_hMenuFont, rect, dwColor, DT_CENTER|DT_VCENTER, "... Scroll Up ..." );
|
||||
|
||||
rect.top = rect.bottom;
|
||||
rect.bottom += MENU_FONT_HEIGHT + MENU_ITEM_PADDING;
|
||||
}
|
||||
|
||||
for( int32 i=iStartItem; i<iEndItem; ++i )
|
||||
{
|
||||
// Empty strings can be used to space menus, they don't get drawn or selected
|
||||
if ( strlen( m_VecMenuItems[i].first.c_str() ) > 0 )
|
||||
{
|
||||
DWORD dwColor;
|
||||
if ( i == m_uSelectedItem )
|
||||
{
|
||||
dwColor = D3DCOLOR_ARGB( 255, 25, 200, 25 );
|
||||
_snprintf( rgchBuffer, sizeof( rgchBuffer), "{ %s }", m_VecMenuItems[i].first.c_str() );
|
||||
}
|
||||
else
|
||||
{
|
||||
dwColor = D3DCOLOR_ARGB( 255, 255, 255, 255 );
|
||||
_snprintf( rgchBuffer, sizeof( rgchBuffer), "%s", m_VecMenuItems[i].first.c_str() );
|
||||
}
|
||||
m_pGameEngine->BDrawString( g_hMenuFont, rect, dwColor, DT_CENTER|DT_VCENTER, rgchBuffer );
|
||||
}
|
||||
|
||||
rect.top = rect.bottom;
|
||||
rect.bottom += MENU_FONT_HEIGHT + MENU_ITEM_PADDING;
|
||||
}
|
||||
|
||||
if ( iNumItems > iEndItem )
|
||||
{
|
||||
// Draw ... Scroll Down ...
|
||||
DWORD dwColor = D3DCOLOR_ARGB( 255, 255, 255, 255 );
|
||||
m_pGameEngine->BDrawString( g_hMenuFont, rect, dwColor, DT_CENTER|DT_VCENTER, "... Scroll Down ..." );
|
||||
|
||||
rect.top = rect.bottom;
|
||||
rect.bottom += MENU_FONT_HEIGHT + MENU_ITEM_PADDING;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// Game engine instance
|
||||
CGameEngine *m_pGameEngine;
|
||||
|
||||
// Heading
|
||||
std::string m_sHeading;
|
||||
|
||||
// Vector of menu options
|
||||
std::vector< MenuItem_t > m_VecMenuItems;
|
||||
|
||||
// Currently selected item index
|
||||
uint32 m_uSelectedItem;
|
||||
|
||||
// pushed selection
|
||||
bool m_bSelectionPushed;
|
||||
T m_selection;
|
||||
};
|
||||
|
||||
#endif // MAINMENU_H
|
||||
@@ -0,0 +1 @@
|
||||
480
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,349 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Main class for the game engine
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef GAMEENGINE_H
|
||||
#define GAMEENGINE_H
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
// How big is the vertex buffer for batching lines in total?
|
||||
// NOTE: This must be a multiple of the batch size below!!! (crashes will occur if it isn't)
|
||||
#define LINE_BUFFER_TOTAL_SIZE 1000
|
||||
|
||||
// How many lines do we put in the buffer in between flushes?
|
||||
//
|
||||
// This should be enough smaller than the total size so that draw calls
|
||||
// can finish using the data before we wrap around and discard it.
|
||||
#define LINE_BUFFER_BATCH_SIZE 250
|
||||
|
||||
// How big is the vertex buffer for batching points in total?
|
||||
// NOTE: This must be a multiple of the batch size below!!! (crashes will occur if it isn't)
|
||||
#define POINT_BUFFER_TOTAL_SIZE 1800
|
||||
|
||||
// How many points do we put in the buffer in between flushes?
|
||||
//
|
||||
// This should be enough smaller than the total size so that draw calls
|
||||
// can finish using the data before we wrap around and discard it.
|
||||
#define POINT_BUFFER_BATCH_SIZE 600
|
||||
|
||||
// How big is the vertex buffer for batching quads in total?
|
||||
// NOTE: This must be a multiple of the batch size below!!! (crashes will occur if it isn't)
|
||||
#define QUAD_BUFFER_TOTAL_SIZE 1000
|
||||
|
||||
// How many quads do we put in the buffer in between flushes?
|
||||
//
|
||||
// This should be enough smaller than the total size so that draw calls
|
||||
// can finish using the data before we wrap around and discard it.
|
||||
#define QUAD_BUFFER_BATCH_SIZE 250
|
||||
|
||||
// Vertex struct for line batches
|
||||
struct LineVertex_t
|
||||
{
|
||||
float x, y, z, rhw;
|
||||
DWORD color;
|
||||
};
|
||||
|
||||
|
||||
// Vertex struct for point batches
|
||||
struct PointVertex_t
|
||||
{
|
||||
float x, y, z, rhw;
|
||||
DWORD color;
|
||||
};
|
||||
|
||||
// Vertex struct for textured quads
|
||||
struct TexturedQuadVertex_t
|
||||
{
|
||||
float x, y, z, rhw;
|
||||
DWORD color;
|
||||
float u, v; // texture coordinates
|
||||
};
|
||||
|
||||
// WndProc declaration
|
||||
LRESULT CALLBACK GameWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
|
||||
|
||||
// Typedef for font handles
|
||||
typedef int HGAMEFONT;
|
||||
|
||||
// Typedef for vertex buffer handles
|
||||
typedef int HGAMEVERTBUF;
|
||||
|
||||
// Typedef for texture handles
|
||||
typedef int HGAMETEXTURE;
|
||||
|
||||
class CGameEngine
|
||||
{
|
||||
public:
|
||||
|
||||
// Static methods for tracing mapping of game engine class instances to hwnds
|
||||
static CGameEngine * FindEngineInstanceForHWND( HWND hWnd );
|
||||
static void AddInstanceToHWNDMap( CGameEngine* pInstance, HWND hWnd );
|
||||
static void RemoveInstanceFromHWNDMap( HWND hWnd );
|
||||
|
||||
// Constructor
|
||||
CGameEngine( HINSTANCE hInstance, int nShowCommand, int32 nWindowWidth, int32 nWindowHeight );
|
||||
|
||||
// Destructor
|
||||
~CGameEngine() { Shutdown(); }
|
||||
|
||||
// Check if the game engine is initialized ok and ready for use
|
||||
bool BReadyForUse() { return m_bEngineReadyForUse; }
|
||||
|
||||
// Check if the engine is shutting down
|
||||
bool BShuttingDown() { return m_bShuttingDown; }
|
||||
|
||||
// Set the background color
|
||||
void SetBackgroundColor( short a, short r, short g, short b );
|
||||
|
||||
// Start a frame, clear(), beginscene(), etc
|
||||
bool StartFrame();
|
||||
|
||||
// Finish a frame, endscene(), present(), etc.
|
||||
void EndFrame();
|
||||
|
||||
// Shutdown the game engine
|
||||
void Shutdown();
|
||||
|
||||
// Pump messages from the OS
|
||||
void MessagePump();
|
||||
|
||||
// Accessors for game screen size
|
||||
int32 GetViewportWidth() { return m_nViewportWidth; }
|
||||
int32 GetViewportHeight() { return m_nViewportHeight; }
|
||||
|
||||
// Function for drawing text to the screen, dwFormat is a combination of flags like DT_LEFT, DT_VCENTER etc...
|
||||
bool BDrawString( HGAMEFONT hFont, RECT rect, DWORD dwColor, DWORD dwFormat, const char *pchText );
|
||||
|
||||
// Create a new font returning our internal handle value for it (0 means failure)
|
||||
HGAMEFONT HCreateFont( int nHeight, int nFontWeight, bool bItalic, char * pchFont );
|
||||
|
||||
// Create a new texture returning our internal handle value for it (0 means failure)
|
||||
HGAMETEXTURE HCreateTexture( byte *pRGBAData, uint32 uWidth, uint32 uHeight );
|
||||
|
||||
// Draw a line, the engine itself will manage batching these (although you can explicitly flush if you need to)
|
||||
bool BDrawLine( float xPos0, float yPos0, DWORD dwColor0, float xPos1, float yPos1, DWORD dwColor1 );
|
||||
|
||||
// Flush the line buffer
|
||||
bool BFlushLineBuffer();
|
||||
|
||||
// Draw a point, the engine itself will manage batching these (although you can explicitly flush if you need to)
|
||||
bool BDrawPoint( float xPos, float yPos, DWORD dwColor );
|
||||
|
||||
// Flush the point buffer
|
||||
bool BFlushPointBuffer();
|
||||
|
||||
// Draw a filled quad
|
||||
bool BDrawFilledQuad( float xPos0, float yPos0, float xPos1, float yPos1, DWORD dwColor );
|
||||
|
||||
// Draw a textured rectangle
|
||||
bool BDrawTexturedQuad( float xPos0, float yPos0, float xPos1, float yPos1,
|
||||
float u0, float v0, float u1, float v1, DWORD dwColor, HGAMETEXTURE hTexture );
|
||||
|
||||
// Flush any still cached quad buffers
|
||||
bool BFlushQuadBuffer();
|
||||
|
||||
// Track the state of keyboard input
|
||||
void RecordKeyDown( DWORD dwVK );
|
||||
void RecordKeyUp( DWORD dwVK );
|
||||
|
||||
// Get the current state of a key
|
||||
bool BIsKeyDown( DWORD dwVK );
|
||||
|
||||
// Get current tick count for the game engine
|
||||
uint64 GetGameTickCount() { return m_ulGameTickCount; }
|
||||
|
||||
// Get the tick count elapsed since the previous frame
|
||||
// bugbug - We use this time to compute things like thrust and acceleration in the game,
|
||||
// so it's important in doesn't jump ahead by large increments... Need a better
|
||||
// way to handle that.
|
||||
uint64 GetGameTicksFrameDelta() { return m_ulGameTickCount - m_ulPreviousGameTickCount; }
|
||||
|
||||
// Get the game engines hwnd
|
||||
HWND GetGameHWND() { return m_hWnd; }
|
||||
|
||||
// Check if the game engine hwnd currently has focus (and a working d3d device)
|
||||
bool BGameEngineHasFocus() { return ::GetForegroundWindow() == m_hWnd && !m_bDeviceLost; }
|
||||
|
||||
// Set the max FPS for the engine to run at (will sleep in EndFrame() to limit the rate)
|
||||
void SetMaxFPS( float flMaxFPS ) { m_flMaxFPS = flMaxFPS; }
|
||||
|
||||
private:
|
||||
// Creates the hwnd for the game
|
||||
bool BCreateGameWindow( int nShowCommand );
|
||||
|
||||
// Initializes D3D for the game
|
||||
bool BInitializeD3D9();
|
||||
|
||||
// Resets all the render, texture, and sampler states to our defaults
|
||||
void ResetRenderStates();
|
||||
|
||||
// Create a new vertex buffer returning our internal handle for it (0 means failure)
|
||||
HGAMEVERTBUF HCreateVertexBuffer( uint32 nSizeInBytes, DWORD dwUsage, DWORD dwFVF );
|
||||
|
||||
// Lock an entire vertex buffer with the specified flags
|
||||
bool BLockEntireVertexBuffer( HGAMEVERTBUF hVertBuf, void **ppVoid, DWORD dwFlags );
|
||||
|
||||
// Unlock a vertex buffer
|
||||
bool BUnlockVertexBuffer( HGAMEVERTBUF hVertBuf );
|
||||
|
||||
// Release a vertex buffer and free its resources
|
||||
bool BReleaseVertexBuffer( HGAMEVERTBUF hVertBuf );
|
||||
|
||||
// Set steam source
|
||||
bool BSetStreamSource( HGAMEVERTBUF hVertBuf, uint32 uOffset, uint32 uStride );
|
||||
|
||||
// Render primitives out of the current stream source
|
||||
bool BRenderPrimitive( D3DPRIMITIVETYPE primType, uint32 uStartVertex, uint32 uCount );
|
||||
|
||||
// Set vertex format
|
||||
bool BSetFVF( DWORD dwFormat );
|
||||
|
||||
// Handle losing the d3d device (ie, release resources)
|
||||
bool BHandleLostDevice();
|
||||
|
||||
// Handle reseting the d3d device (ie, acquire resources again)
|
||||
bool BHandleResetDevice();
|
||||
|
||||
|
||||
private:
|
||||
// Tracks whether the engine is ready for use
|
||||
bool m_bEngineReadyForUse;
|
||||
|
||||
// Tracks if we are shutting down
|
||||
bool m_bShuttingDown;
|
||||
|
||||
// Color we clear the background of the window to each frame
|
||||
DWORD m_dwBackgroundColor;
|
||||
|
||||
// HInstance for the application running the engine
|
||||
HINSTANCE m_hInstance;
|
||||
|
||||
// HWND for the engine instance
|
||||
HWND m_hWnd;
|
||||
|
||||
// IDirect3D9 interface
|
||||
IDirect3D9 *m_pD3D9Interface;
|
||||
|
||||
// IDirect3DDevice9 interface
|
||||
IDirect3DDevice9 *m_pD3D9Device;
|
||||
|
||||
// Size of the window to display the game in
|
||||
int32 m_nWindowWidth;
|
||||
int32 m_nWindowHeight;
|
||||
|
||||
// Size of actual d3d viewport (window size minus borders, title, etc)
|
||||
int32 m_nViewportWidth;
|
||||
int32 m_nViewportHeight;
|
||||
|
||||
// Next font handle value to give out
|
||||
HGAMEFONT m_nNextFontHandle;
|
||||
|
||||
// Map of font handles to font objects
|
||||
std::map<HGAMEFONT, ID3DXFont *> m_MapFontInstances;
|
||||
|
||||
// Next vertex buffer handle value to give out
|
||||
HGAMEVERTBUF m_nNextVertBufferHandle;
|
||||
|
||||
// Map of handles to vertex buffer objects
|
||||
struct VertBufData_t
|
||||
{
|
||||
bool m_bIsLocked;
|
||||
IDirect3DVertexBuffer9 * m_pBuffer;
|
||||
};
|
||||
std::map<HGAMEVERTBUF, VertBufData_t> m_MapVertexBuffers;
|
||||
|
||||
HGAMETEXTURE m_nNextTextureHandle;
|
||||
|
||||
// Map of handles to texture objects
|
||||
struct TextureData_t
|
||||
{
|
||||
byte *m_pRGBAData; // We keep a copy of the raw data so we can rebuild textures after a device is lost
|
||||
uint32 m_uWidth;
|
||||
uint32 m_uHeight;
|
||||
LPDIRECT3DTEXTURE9 m_pTexture;
|
||||
};
|
||||
std::map<HGAMETEXTURE, TextureData_t> m_MapTextures;
|
||||
|
||||
// Vertex buffer for textured quads
|
||||
HGAMEVERTBUF m_hQuadBuffer;
|
||||
|
||||
// Last texture used in drawing a batched quad
|
||||
HGAMETEXTURE m_hLastTexture;
|
||||
|
||||
// Pointer to quad vertex data
|
||||
TexturedQuadVertex_t *m_pQuadVertexes;
|
||||
|
||||
// How many quads are awaiting flushing
|
||||
DWORD m_dwQuadsToFlush;
|
||||
|
||||
// Where does the current batch begin
|
||||
DWORD m_dwQuadBufferBatchPos;
|
||||
|
||||
// White texture used when drawing filled quads
|
||||
HGAMETEXTURE m_hTextureWhite;
|
||||
|
||||
// Currently set FVF format
|
||||
DWORD m_dwCurrentFVF;
|
||||
|
||||
// Map of key state
|
||||
std::set<DWORD> m_SetKeysDown;
|
||||
|
||||
// Current game time in milliseconds
|
||||
uint64 m_ulGameTickCount;
|
||||
|
||||
// Game time at the start of the previous frame
|
||||
uint64 m_ulPreviousGameTickCount;
|
||||
|
||||
// Track whether this is the first frame
|
||||
bool m_bFirstFrame;
|
||||
|
||||
// Value to divide from QueryPerformanceCounter results to get milliseconds
|
||||
uint64 m_ulPerfCounterToMillisecondsDivisor;
|
||||
|
||||
// Last value from QueryPerformanceCounter
|
||||
uint64 m_ulLastQueryPerformanceCounterValue;
|
||||
|
||||
// Maximum FPS to run the engine at
|
||||
float m_flMaxFPS;
|
||||
|
||||
// Map of engine instances by HWND, used in wndproc to find engine instance for messages
|
||||
static std::map<HWND, CGameEngine *> m_MapEngineInstances;
|
||||
|
||||
// Internal vertex buffer for batching line drawing
|
||||
HGAMEVERTBUF m_hLineBuffer;
|
||||
|
||||
// Pointer to actual line buffer memory (valid only while locked)
|
||||
LineVertex_t *m_pLineVertexes;
|
||||
|
||||
// Track how many lines are awaiting flushing in our line buffer
|
||||
DWORD m_dwLinesToFlush;
|
||||
|
||||
// Track where the current batch starts in the vert buffer
|
||||
DWORD m_dwLineBufferBatchPos;
|
||||
|
||||
// Internal vertex buffer for batching point drawing
|
||||
HGAMEVERTBUF m_hPointBuffer;
|
||||
|
||||
// Pointer to actual point buffer memory (valid only while locked)
|
||||
PointVertex_t *m_pPointVertexes;
|
||||
|
||||
// Track how many points are awaiting flushing in our line buffer
|
||||
DWORD m_dwPointsToFlush;
|
||||
|
||||
// Track where the current batch starts in the vert buffer
|
||||
DWORD m_dwPointBufferBatchPos;
|
||||
|
||||
// Track if we have lost the d3d device
|
||||
bool m_bDeviceLost;
|
||||
|
||||
// Presentation parameters, saved in case of lost device needing reset
|
||||
D3DPRESENT_PARAMETERS m_d3dpp;
|
||||
|
||||
};
|
||||
|
||||
#endif // GAMEENGINE_H
|
||||
@@ -0,0 +1,315 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Class for handling finding & creating lobbies, getting their details,
|
||||
// and seeing other users in the current lobby
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Lobby.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Menu that shows a list of other users in a lobby
|
||||
//-----------------------------------------------------------------------------
|
||||
class CLobbyMenu : public CBaseMenu<LobbyMenuItem_t>
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
CLobbyMenu( CGameEngine *pGameEngine ) : CBaseMenu<LobbyMenuItem_t>( pGameEngine ) {}
|
||||
|
||||
void Rebuild( const CSteamID &steamIDLobby )
|
||||
{
|
||||
PushSelectedItem();
|
||||
ClearMenuItems();
|
||||
|
||||
// list of users in lobby
|
||||
// iterate all the users in the lobby and show their details
|
||||
int cLobbyMembers = SteamMatchmaking()->GetNumLobbyMembers( steamIDLobby );
|
||||
for ( int i = 0; i < cLobbyMembers; i++ )
|
||||
{
|
||||
CSteamID steamIDLobbyMember = SteamMatchmaking()->GetLobbyMemberByIndex( steamIDLobby, i ) ;
|
||||
|
||||
// we get the details of a user from the ISteamFriends interface
|
||||
const char *pchName = SteamFriends()->GetFriendPersonaName( steamIDLobbyMember );
|
||||
// we may not know the name of the other users in the lobby immediately; but we'll receive
|
||||
// a PersonaStateUpdate_t callback when they do, and we'll rebuild the list then
|
||||
if ( pchName && *pchName )
|
||||
{
|
||||
bool bReady = ( 1 == atoi( SteamMatchmaking()->GetLobbyMemberData( steamIDLobby, steamIDLobbyMember, "ready" ) ) );
|
||||
LobbyMenuItem_t menuItem = { steamIDLobbyMember };
|
||||
|
||||
char rgchMenuText[256];
|
||||
_snprintf( rgchMenuText, sizeof( rgchMenuText ), "%s %s", pchName, bReady ? "(READY)" : "" );
|
||||
AddMenuItem( MenuItem_t( std::string( rgchMenuText ), menuItem ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ready/not ready toggle
|
||||
{
|
||||
bool bReady = ( 1 == atoi( SteamMatchmaking()->GetLobbyMemberData( steamIDLobby, SteamUser()->GetSteamID(), "ready" ) ) );
|
||||
LobbyMenuItem_t menuItem = { CSteamID(), false, true };
|
||||
if ( bReady )
|
||||
AddMenuItem( CLobbyMenu::MenuItem_t( "Set myself as Not Ready", menuItem ) );
|
||||
else
|
||||
AddMenuItem( CLobbyMenu::MenuItem_t( "Set myself as Ready", menuItem ) );
|
||||
}
|
||||
|
||||
// bugbug taylor make it so we can find out who the lobby owner is
|
||||
bool bLobbyOwner = true;
|
||||
|
||||
// start game
|
||||
if ( bLobbyOwner )
|
||||
{
|
||||
LobbyMenuItem_t menuItem = { CSteamID(), true, false };
|
||||
AddMenuItem( CLobbyMenu::MenuItem_t( "Start game", menuItem ) );
|
||||
}
|
||||
|
||||
// exit lobby
|
||||
{
|
||||
LobbyMenuItem_t menuItem = { CSteamID(), false, false, true };
|
||||
AddMenuItem( CLobbyMenu::MenuItem_t( "Return to main menu", menuItem ) );
|
||||
}
|
||||
|
||||
// reset selection
|
||||
PopSelectedItem();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CLobby::CLobby( CGameEngine *pGameEngine ) :
|
||||
m_pGameEngine( pGameEngine ),
|
||||
m_CallbackPersonaStateChange( this, &CLobby::OnPersonaStateChange ),
|
||||
m_CallbackLobbyDataUpdate( this, &CLobby::OnLobbyDataUpdate ),
|
||||
m_CallbackChatDataUpdate( this, &CLobby::OnLobbyChatUpdate )
|
||||
{
|
||||
m_pMenu = new CLobbyMenu( pGameEngine );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CLobby::~CLobby()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sets the ID of the lobby to display
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLobby::SetLobbySteamID( const CSteamID &steamIDLobby )
|
||||
{
|
||||
m_steamIDLobby = steamIDLobby;
|
||||
m_pMenu->Rebuild( m_steamIDLobby );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Draws the lobby
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLobby::RunFrame()
|
||||
{
|
||||
m_pMenu->RunFrame();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handles a user in the lobby changing their name or details
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLobby::OnPersonaStateChange( PersonaStateChange_t *pCallback )
|
||||
{
|
||||
// callbacks are broadcast to all listeners, so we'll get this for every friend who changes state
|
||||
// so make sure the user is in the lobby before acting
|
||||
if ( !SteamFriends()->IsUserInSource( pCallback->m_ulSteamID, m_steamIDLobby ) )
|
||||
return;
|
||||
|
||||
// rebuild the menu
|
||||
m_pMenu->Rebuild( m_steamIDLobby );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handles lobby data changing
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLobby::OnLobbyDataUpdate( LobbyDataUpdate_t *pCallback )
|
||||
{
|
||||
// callbacks are broadcast to all listeners, so we'll get this for every lobby we're requesting
|
||||
if ( m_steamIDLobby != pCallback->m_ulSteamIDLobby )
|
||||
return;
|
||||
|
||||
// set the heading
|
||||
m_pMenu->SetHeading( SteamMatchmaking()->GetLobbyData( m_steamIDLobby, "name" ) );
|
||||
|
||||
// rebuild the menu
|
||||
m_pMenu->Rebuild( m_steamIDLobby );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handles users in the lobby joining or leaving
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLobby::OnLobbyChatUpdate( LobbyChatUpdate_t *pCallback )
|
||||
{
|
||||
// callbacks are broadcast to all listeners, so we'll get this for every lobby we're requesting
|
||||
if ( m_steamIDLobby != pCallback->m_ulSteamIDLobby )
|
||||
return;
|
||||
|
||||
// rebuild the menu
|
||||
m_pMenu->Rebuild( m_steamIDLobby );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Menu that shows a list of lobbies to choose from
|
||||
//-----------------------------------------------------------------------------
|
||||
class CLobbyBrowserMenu : public CBaseMenu<LobbyBrowserMenuItem_t>
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
CLobbyBrowserMenu( CGameEngine *pGameEngine ) : CBaseMenu<LobbyBrowserMenuItem_t>( pGameEngine ) {}
|
||||
|
||||
void Rebuild( std::list<Lobby_t> &listLobbies )
|
||||
{
|
||||
PushSelectedItem();
|
||||
ClearMenuItems();
|
||||
|
||||
LobbyBrowserMenuItem_t data;
|
||||
std::list<Lobby_t>::iterator iter;
|
||||
|
||||
for( iter = listLobbies.begin(); iter != listLobbies.end(); ++iter )
|
||||
{
|
||||
data.m_eStateToTransitionTo = k_EClientJoiningLobby;
|
||||
data.m_steamIDLobby = iter->m_steamIDLobby;
|
||||
if ( iter->m_rgchName[0] )
|
||||
{
|
||||
AddMenuItem( MenuItem_t( std::string( iter->m_rgchName ), data ) );
|
||||
}
|
||||
}
|
||||
|
||||
data.m_eStateToTransitionTo = k_EClientGameMenu;
|
||||
AddMenuItem( CLobbyBrowserMenu::MenuItem_t( "Return to main menu", data ) );
|
||||
|
||||
// reset selection
|
||||
PopSelectedItem();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
// just initializes base data
|
||||
//-----------------------------------------------------------------------------
|
||||
CLobbyBrowser::CLobbyBrowser( CGameEngine *pGameEngine ) :
|
||||
m_CallbackLobbyMatchList( this, &CLobbyBrowser::OnLobbyMatchListCallback ),
|
||||
m_CallbackLobbyDataUpdated( this, &CLobbyBrowser::OnLobbyDataUpdatedCallback )
|
||||
{
|
||||
m_pGameEngine = pGameEngine;
|
||||
m_pMenu = new CLobbyBrowserMenu( pGameEngine );
|
||||
m_pMenu->Rebuild( m_ListLobbies );
|
||||
m_pMenu->SetHeading( "Lobby browser" );
|
||||
m_bRequestingLobbies = false;
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CLobbyBrowser::~CLobbyBrowser()
|
||||
{
|
||||
delete m_pMenu;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Run a frame (to handle KB input and such as well as render)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLobbyBrowser::RunFrame()
|
||||
{
|
||||
m_pMenu->RunFrame();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Starts rebuilding the lobby list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLobbyBrowser::Refresh()
|
||||
{
|
||||
if ( !m_bRequestingLobbies )
|
||||
{
|
||||
m_bRequestingLobbies = true;
|
||||
// request all lobbies for this game
|
||||
SteamMatchmaking()->RequestLobbyList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Callback, on a list of lobbies being received from the Steam back-end
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLobbyBrowser::OnLobbyMatchListCallback( LobbyMatchList_t *pCallback )
|
||||
{
|
||||
m_ListLobbies.clear();
|
||||
m_bRequestingLobbies = false;
|
||||
|
||||
// lobbies are returned in order of closeness to the user, so add them to the list in that order
|
||||
for ( uint32 iLobby = 0; iLobby < pCallback->m_nLobbiesMatching; iLobby++ )
|
||||
{
|
||||
CSteamID steamIDLobby = SteamMatchmaking()->GetLobbyByIndex( iLobby );
|
||||
|
||||
// add the lobby to the list
|
||||
Lobby_t lobby;
|
||||
lobby.m_steamIDLobby = steamIDLobby;
|
||||
// pull the name from the lobby metadata
|
||||
const char *pchLobbyName = SteamMatchmaking()->GetLobbyData( steamIDLobby, "name" );
|
||||
if ( pchLobbyName && pchLobbyName[0] )
|
||||
{
|
||||
// set the lobby name
|
||||
_snprintf( lobby.m_rgchName, sizeof( lobby.m_rgchName ), "%s", pchLobbyName );
|
||||
}
|
||||
else
|
||||
{
|
||||
// we don't have info about the lobby yet, request it
|
||||
SteamMatchmaking()->RequestLobbyData( steamIDLobby );
|
||||
// results will be returned via LobbyDataUpdate_t callback
|
||||
_snprintf( lobby.m_rgchName, sizeof( lobby.m_rgchName ), "Lobby %d", steamIDLobby.GetAccountID() );
|
||||
}
|
||||
|
||||
m_ListLobbies.push_back( lobby );
|
||||
}
|
||||
|
||||
m_pMenu->Rebuild( m_ListLobbies );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Callback, on a list of lobbies being received from the Steam back-end
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLobbyBrowser::OnLobbyDataUpdatedCallback( LobbyDataUpdate_t *pCallback )
|
||||
{
|
||||
// find the lobby in our local list
|
||||
std::list<Lobby_t>::iterator iter;
|
||||
for( iter = m_ListLobbies.begin(); iter != m_ListLobbies.end(); ++iter )
|
||||
{
|
||||
// update the name of the lobby
|
||||
if ( iter->m_steamIDLobby == pCallback->m_ulSteamIDLobby )
|
||||
{
|
||||
// extract the display name from the lobby metadata
|
||||
const char *pchLobbyName = SteamMatchmaking()->GetLobbyData( iter->m_steamIDLobby, "name" );
|
||||
if ( pchLobbyName[0] )
|
||||
{
|
||||
_snprintf( iter->m_rgchName, sizeof( iter->m_rgchName ), "%s", pchLobbyName );
|
||||
// update the menu
|
||||
m_pMenu->Rebuild( m_ListLobbies );
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Class for handling finding & creating lobbies, getting their details,
|
||||
// and seeing other users in the current lobby
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef LOBBY_H
|
||||
#define LOBBY_H
|
||||
|
||||
#include "SpaceWar.h"
|
||||
#include "GameEngine.h"
|
||||
#include "steam/isteammatchmaking.h"
|
||||
#include "BaseMenu.h"
|
||||
#include <list>
|
||||
|
||||
class CSpaceWarClient;
|
||||
class CLobbyBrowserMenu;
|
||||
class CLobbyMenu;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Displays the other users in a lobby and allows the game to be started
|
||||
//-----------------------------------------------------------------------------
|
||||
class CLobby
|
||||
{
|
||||
public:
|
||||
CLobby( CGameEngine *pGameEngine );
|
||||
~CLobby();
|
||||
|
||||
// sets which lobby to display
|
||||
void SetLobbySteamID( const CSteamID &steamIDLobby );
|
||||
|
||||
// Run a frame (to handle KB input and such as well as render)
|
||||
void RunFrame();
|
||||
|
||||
private:
|
||||
CSteamID m_steamIDLobby;
|
||||
|
||||
// Pointer to engine instance (so we can draw stuff)
|
||||
CGameEngine *m_pGameEngine;
|
||||
|
||||
// Menu object
|
||||
CLobbyMenu *m_pMenu;
|
||||
|
||||
// user state change handler
|
||||
STEAM_CALLBACK( CLobby, OnPersonaStateChange, PersonaStateChange_t, m_CallbackPersonaStateChange );
|
||||
|
||||
// lobby state change handler
|
||||
STEAM_CALLBACK( CLobby, OnLobbyDataUpdate, LobbyDataUpdate_t, m_CallbackLobbyDataUpdate );
|
||||
STEAM_CALLBACK( CLobby, OnLobbyChatUpdate, LobbyChatUpdate_t, m_CallbackChatDataUpdate );
|
||||
};
|
||||
|
||||
|
||||
// an item in the list of lobbies we've found to display
|
||||
struct Lobby_t
|
||||
{
|
||||
CSteamID m_steamIDLobby;
|
||||
char m_rgchName[256];
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Displaying and allows selection from a list of lobbies
|
||||
//-----------------------------------------------------------------------------
|
||||
class CLobbyBrowser
|
||||
{
|
||||
public:
|
||||
CLobbyBrowser( CGameEngine *pGameEngine );
|
||||
~CLobbyBrowser();
|
||||
|
||||
// rebuild the list
|
||||
void Refresh();
|
||||
|
||||
// Run a frame (to handle KB input and such as well as render)
|
||||
void RunFrame();
|
||||
|
||||
private:
|
||||
// Pointer to engine instance (so we can draw stuff)
|
||||
CGameEngine *m_pGameEngine;
|
||||
|
||||
// Track whether we are in the middle of a refresh or not
|
||||
bool m_bRequestingLobbies;
|
||||
|
||||
// Menu object
|
||||
CLobbyBrowserMenu *m_pMenu;
|
||||
|
||||
STEAM_CALLBACK( CLobbyBrowser, OnLobbyMatchListCallback, LobbyMatchList_t, m_CallbackLobbyMatchList );
|
||||
STEAM_CALLBACK( CLobbyBrowser, OnLobbyDataUpdatedCallback, LobbyDataUpdate_t, m_CallbackLobbyDataUpdated );
|
||||
|
||||
std::list< Lobby_t > m_ListLobbies;
|
||||
};
|
||||
|
||||
|
||||
#endif //LOBBY_H
|
||||
@@ -0,0 +1,176 @@
|
||||
//====== Copyright © 1996-2008, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose: Main file for the SteamworksExample app
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "GameEngine.h"
|
||||
#include "SpaceWarClient.h"
|
||||
#include "steam/steam_api.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Wrapper around SteamAPI_WriteMiniDump which can be used directly
|
||||
// as a se translator
|
||||
//-----------------------------------------------------------------------------
|
||||
void MiniDumpFunction( unsigned int nExceptionCode, EXCEPTION_POINTERS *pException )
|
||||
{
|
||||
// You can build and set an arbitrary comment to embed in the minidump here,
|
||||
// maybe you want to put what level the user was playing, how many players on the server,
|
||||
// how much memory is free, etc...
|
||||
SteamAPI_SetMiniDumpComment( "Minidump comment: SteamworksExample.exe\n" );
|
||||
|
||||
// The 0 here is a build ID, we don't set it
|
||||
SteamAPI_WriteMiniDump( nExceptionCode, pException, 0 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: callback hook for debug text emitted from the Steam API
|
||||
//-----------------------------------------------------------------------------
|
||||
extern "C" void __cdecl SteamAPIDebugTextHook( int nSeverity, const char *pchDebugText )
|
||||
{
|
||||
// if you're running in the debugger, only warnings (nSeverity >= 1) will be sent
|
||||
// if you add -debug_steamapi to the command-line, a lot of extra informational messages will also be sent
|
||||
::OutputDebugString( pchDebugText );
|
||||
|
||||
if ( nSeverity >= 1 )
|
||||
{
|
||||
// place to set a breakpoint for catching API errors
|
||||
int x = 3;
|
||||
x;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Real main entry point for the program
|
||||
//-----------------------------------------------------------------------------
|
||||
int APIENTRY RealMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow)
|
||||
{
|
||||
// Initialize SteamAPI, if this fails we bail out since we depend on Steam for lots of stuff.
|
||||
// You don't necessarily have to though if you write your code to check whether all the Steam
|
||||
// interfaces are NULL before using them and provide alternate paths when they are unavailable.
|
||||
//
|
||||
// This will also load the in-game steam overlay dll into your process. That dll is normally
|
||||
// injected by steam when it launches games, but by calling this you cause it to always load,
|
||||
// even when not launched via steam.
|
||||
if ( !SteamAPI_Init() )
|
||||
{
|
||||
OutputDebugString( "SteamAPI_Init() failed\n" );
|
||||
::MessageBox( NULL, "Steam must be running to play this game (SteamAPI_Init() failed).\n", "Fatal Error", MB_OK );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// set our debug handler
|
||||
SteamClient()->SetWarningMessageHook( &SteamAPIDebugTextHook );
|
||||
|
||||
|
||||
// Look for the +connect ipaddress:port parameter in the command line,
|
||||
// Steam will pass this when a user has used the Steam Server browser to find
|
||||
// a server for our game and is trying to join it.
|
||||
const char* pchConnectParam = "+connect";
|
||||
char *pchCmdLine = ::GetCommandLine();
|
||||
char *pchConnect = strstr( pchCmdLine, pchConnectParam );
|
||||
char *pchServerAddress = NULL;
|
||||
if ( pchConnect && strlen( pchCmdLine ) > (pchConnect - pchCmdLine) + strlen( pchConnectParam ) + 1 )
|
||||
{
|
||||
// Address should be right after the +connect, +1 on the end to skip the space
|
||||
pchServerAddress = pchCmdLine + ( pchConnect - pchCmdLine ) + strlen( pchConnectParam ) + 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Construct a new instance of the game engine
|
||||
// bugbug jmccaskey - make screen resolution dynamic, maybe take it on command line?
|
||||
CGameEngine *pGameEngine = new CGameEngine( hInstance, nCmdShow, 1024, 768 );
|
||||
|
||||
// Make sure it initialized ok
|
||||
if ( pGameEngine->BReadyForUse() )
|
||||
{
|
||||
// Initialize the game
|
||||
CSpaceWarClient *pGameClient = new CSpaceWarClient( pGameEngine, SteamUser()->GetSteamID() );
|
||||
|
||||
// Black background
|
||||
pGameEngine->SetBackgroundColor( 0, 0, 0, 0 );
|
||||
|
||||
// Set max FPS
|
||||
pGameEngine->SetMaxFPS( MAX_CLIENT_AND_SERVER_FPS );
|
||||
|
||||
// If +connect was used to specify a server address, connect now
|
||||
if ( pchServerAddress )
|
||||
{
|
||||
|
||||
int32 octet0 = 0, octet1 = 0, octet2 = 0, octet3 = 0;
|
||||
int32 uPort = 0;
|
||||
int nConverted = sscanf( pchServerAddress, "%d.%d.%d.%d:%d", &octet0, &octet1, &octet2, &octet3, &uPort );
|
||||
if ( nConverted == 5 )
|
||||
{
|
||||
char rgchIPAddress[128];
|
||||
_snprintf( rgchIPAddress, ARRAYSIZE( rgchIPAddress ), "%d.%d.%d.%d", octet0, octet1, octet2, octet3 );
|
||||
uint32 unIPAddress = ( octet3 ) + ( octet2 << 8 ) + ( octet1 << 16 ) + ( octet0 << 24 );
|
||||
pGameClient->InitiateServerConnection( unIPAddress, uPort );
|
||||
}
|
||||
}
|
||||
|
||||
while( !pGameEngine->BShuttingDown() )
|
||||
{
|
||||
if ( pGameEngine->StartFrame() )
|
||||
{
|
||||
// Run a game frame
|
||||
pGameClient->RunFrame();
|
||||
|
||||
pGameEngine->EndFrame();
|
||||
}
|
||||
}
|
||||
|
||||
delete pGameClient;
|
||||
}
|
||||
|
||||
// Cleanup the game engine
|
||||
delete pGameEngine;
|
||||
|
||||
// Shutdown the SteamAPI
|
||||
SteamAPI_Shutdown();
|
||||
|
||||
// exit
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Main entry point for the program
|
||||
//-----------------------------------------------------------------------------
|
||||
int APIENTRY WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow)
|
||||
{
|
||||
// All we do here is call the real main function after setting up our se translator
|
||||
// this allows us to catch exceptions and report errors to Steam.
|
||||
//
|
||||
// Note that you must set your compiler flags correctly to enable structured exception
|
||||
// handling in order for this particular setup method to work.
|
||||
|
||||
if ( IsDebuggerPresent() )
|
||||
{
|
||||
// We don't want to mask exceptions (or report them to Steam!) when debugging
|
||||
return RealMain( hInstance, hPrevInstance, lpCmdLine, nCmdShow );
|
||||
}
|
||||
|
||||
_set_se_translator( MiniDumpFunction );
|
||||
try // this try block allows the SE translator to work
|
||||
{
|
||||
return RealMain( hInstance, hPrevInstance, lpCmdLine, nCmdShow );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Class to define the main game menu
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "MainMenu.h"
|
||||
#include "SpaceWar.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CMainMenu::CMainMenu( CGameEngine *pGameEngine ) : CBaseMenu<EClientGameState>( pGameEngine )
|
||||
{
|
||||
AddMenuItem( MenuItem_t( "Start New Server", k_EClientGameStartServer ) );
|
||||
AddMenuItem( MenuItem_t( "Find LAN Servers", k_EClientFindLANServers ) );
|
||||
AddMenuItem( MenuItem_t( "Find Internet Servers", k_EClientFindInternetServers ) );
|
||||
AddMenuItem( MenuItem_t( "Create Lobby", k_EClientCreatingLobby ) );
|
||||
AddMenuItem( MenuItem_t( "Find Lobby", k_EClientFindLobby ) );
|
||||
AddMenuItem( MenuItem_t( "Instructions", k_EClientGameInstructions ) );
|
||||
AddMenuItem( MenuItem_t( "Stats and Achievements", k_EClientStatsAchievements ) );
|
||||
AddMenuItem( MenuItem_t( "Exit Game", k_EClientGameExiting ) );
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Class to define the main game menu
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef MAINMENU_H
|
||||
#define MAINMENU_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "GameEngine.h"
|
||||
#include "SpaceWar.h"
|
||||
#include "BaseMenu.h"
|
||||
#include "SpaceWarClient.h"
|
||||
|
||||
class CMainMenu : public CBaseMenu<EClientGameState>
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
CMainMenu( CGameEngine *pGameEngine );
|
||||
};
|
||||
|
||||
#endif // MAINMENU_H
|
||||
@@ -0,0 +1,119 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Defines the wire protocol for the game
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef MESSAGES_H
|
||||
#define MESSAGES_H
|
||||
|
||||
#include <map>
|
||||
|
||||
// Network message types
|
||||
enum EMessage
|
||||
{
|
||||
// Server messages
|
||||
k_EMsgServerBegin = 0,
|
||||
k_EMsgServerSendInfo = k_EMsgServerBegin+1,
|
||||
k_EMsgServerFailAuthentication = k_EMsgServerBegin+2,
|
||||
k_EMsgServerPassAuthentication = k_EMsgServerBegin+3,
|
||||
k_EMsgServerUpdateWorld = k_EMsgServerBegin+4,
|
||||
k_EMsgServerExiting = k_EMsgServerBegin+5,
|
||||
|
||||
// Client messages
|
||||
k_EMsgClientBegin = 500,
|
||||
k_EMsgClientInitiateConnection = k_EMsgClientBegin+1,
|
||||
k_EMsgClientBeginAuthentication = k_EMsgClientBegin+2,
|
||||
k_EMsgClientSendLocalUpdate = k_EMsgClientBegin+3,
|
||||
k_EMsgClientLeavingServer = k_EMsgClientBegin+4,
|
||||
|
||||
|
||||
// force 32-bit size enum so the wire protocol doesn't get outgrown later
|
||||
k_EForceDWORD = 0x7fffffff,
|
||||
};
|
||||
|
||||
|
||||
// Msg from the server to the client which is sent right after communications are established
|
||||
// and tells the client what SteamID the game server is using as well as whether the server is secure
|
||||
struct MsgServerSendInfo_t
|
||||
{
|
||||
MsgServerSendInfo_t() : m_dwMessageType( k_EMsgServerSendInfo ) {}
|
||||
const DWORD m_dwMessageType;
|
||||
|
||||
uint64 m_ulSteamIDServer;
|
||||
bool m_bIsVACSecure;
|
||||
char m_rgchServerName[128];
|
||||
};
|
||||
|
||||
// Msg from the server to the client when refusing a connection
|
||||
struct MsgServerFailAuthentication_t
|
||||
{
|
||||
MsgServerFailAuthentication_t() : m_dwMessageType( k_EMsgServerFailAuthentication ) {}
|
||||
const DWORD m_dwMessageType;
|
||||
};
|
||||
|
||||
// Msg from the server to client when accepting a pending connection
|
||||
struct MsgServerPassAuthentication_t
|
||||
{
|
||||
MsgServerPassAuthentication_t() : m_dwMessageType( k_EMsgServerPassAuthentication ) {}
|
||||
const DWORD m_dwMessageType;
|
||||
|
||||
uint32 m_uPlayerPosition;
|
||||
};
|
||||
|
||||
// Msg from the server to clients when updating the world state
|
||||
struct MsgServerUpdateWorld_t
|
||||
{
|
||||
MsgServerUpdateWorld_t() : m_dwMessageType( k_EMsgServerUpdateWorld ) {}
|
||||
const DWORD m_dwMessageType;
|
||||
|
||||
ServerSpaceWarUpdateData_t m_ServerUpdateData;
|
||||
};
|
||||
|
||||
// Msg from server to clients when it is exiting
|
||||
struct MsgServerExiting_t
|
||||
{
|
||||
MsgServerExiting_t() : m_dwMessageType( k_EMsgServerExiting ) {}
|
||||
const DWORD m_dwMessageType;
|
||||
};
|
||||
|
||||
// Msg from client to server when trying to connect
|
||||
struct MsgClientInitiateConnection_t
|
||||
{
|
||||
MsgClientInitiateConnection_t() : m_dwMessageType( k_EMsgClientInitiateConnection ) {}
|
||||
const DWORD m_dwMessageType;
|
||||
};
|
||||
|
||||
// Msg from client to server when initiating authentication
|
||||
struct MsgClientBeginAuthentication_t
|
||||
{
|
||||
MsgClientBeginAuthentication_t() : m_dwMessageType( k_EMsgClientBeginAuthentication ) {}
|
||||
const DWORD m_dwMessageType;
|
||||
|
||||
uint64 m_ulSteamID;
|
||||
|
||||
uint32 m_uTokenLen;
|
||||
char m_rgchToken[1024];
|
||||
};
|
||||
|
||||
// Msg from client to server when sending state update
|
||||
struct MsgClientSendLocalUpdate_t
|
||||
{
|
||||
MsgClientSendLocalUpdate_t() : m_dwMessageType( k_EMsgClientSendLocalUpdate ) {}
|
||||
const DWORD m_dwMessageType;
|
||||
|
||||
uint32 m_uShipPosition;
|
||||
ClientSpaceWarUpdateData_t m_ClientUpdateData;
|
||||
};
|
||||
|
||||
|
||||
// Msg from the client telling the server it is about to leave
|
||||
struct MsgClientLeavingServer_t
|
||||
{
|
||||
MsgClientLeavingServer_t() : m_dwMessageType( k_EMsgClientLeavingServer ) {}
|
||||
const DWORD m_dwMessageType;
|
||||
};
|
||||
|
||||
|
||||
#endif // MESSAGES_H
|
||||
@@ -0,0 +1,40 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Class for rendering photon beams
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "PhotonBeam.h"
|
||||
#include "SpaceWar.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CPhotonBeam::CPhotonBeam( CGameEngine *pGameEngine, float xPos, float yPos, DWORD dwBeamColor, float flInitialRotation, float flInitialXVelocity, float flInitialYVelocity )
|
||||
: CSpaceWarEntity( pGameEngine, 3, true )
|
||||
{
|
||||
// Beams only have a lifetime of 1 second
|
||||
m_ulTickCountToDieAt = m_pGameEngine->GetGameTickCount()+PHOTON_BEAM_LIFETIME_IN_TICKS;
|
||||
|
||||
// Set a really high max velocity for photon beams
|
||||
SetMaximumVelocity( 500 );
|
||||
|
||||
AddLine( -2.0f, -3.0f, -2.0f, 3.0f, dwBeamColor );
|
||||
AddLine( 2.0f, -3.0f, 2.0f, 3.0f, dwBeamColor );
|
||||
SetPosition( xPos, yPos );
|
||||
SetRotationDeltaNextFrame( flInitialRotation );
|
||||
SetVelocity( flInitialXVelocity, flInitialYVelocity );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Update with data from server
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPhotonBeam::OnReceiveServerUpdate( ServerPhotonBeamUpdateData_t UpdateData )
|
||||
{
|
||||
SetPosition( UpdateData.m_flXPosition, UpdateData.m_flYPosition );
|
||||
SetVelocity( UpdateData.m_flXVelocity, UpdateData.m_flYVelocity );
|
||||
SetAccumulatedRotation( UpdateData.m_flCurrentRotation );
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Class for rendering photon beams
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef PHOTONBEAM_H
|
||||
#define PHOTONBEAM_H
|
||||
|
||||
#include "GameEngine.h"
|
||||
#include "SpaceWarEntity.h"
|
||||
#include "SpaceWar.h"
|
||||
|
||||
class CPhotonBeam : public CSpaceWarEntity
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
CPhotonBeam( CGameEngine *pGameEngine, float xPos, float yPos, DWORD dwBeamColor, float flInitialRotation, float flInitialXVelocity, float flInitialYVelocity );
|
||||
|
||||
// Check if the photon beam needs to die
|
||||
bool BIsBeamExpired() { return m_pGameEngine->GetGameTickCount() > m_ulTickCountToDieAt; }
|
||||
|
||||
// Update with new data from server
|
||||
void OnReceiveServerUpdate( ServerPhotonBeamUpdateData_t UpdateData );
|
||||
|
||||
private:
|
||||
uint64 m_ulTickCountToDieAt;
|
||||
};
|
||||
|
||||
#endif // PHOTONBEAM_H
|
||||
@@ -0,0 +1,21 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Class to define the pause menu
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "QuitMenu.h"
|
||||
#include "SpaceWar.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CQuitMenu::CQuitMenu( CGameEngine *pGameEngine ) : CBaseMenu<EClientGameState>( pGameEngine )
|
||||
{
|
||||
AddMenuItem( MenuItem_t( "Resume Game", k_EClientGameActive ) );
|
||||
AddMenuItem( MenuItem_t( "Exit To Menu", k_EClientGameMenu ) );
|
||||
AddMenuItem( MenuItem_t( "Exit To Desktop", k_EClientGameExiting ) );
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Class to define the pause game menu
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef QUITMENU_H
|
||||
#define QUITMENU_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "GameEngine.h"
|
||||
#include "SpaceWar.h"
|
||||
#include "BaseMenu.h"
|
||||
#include "SpaceWarClient.h"
|
||||
|
||||
class CQuitMenu : public CBaseMenu<EClientGameState>
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
CQuitMenu( CGameEngine *pGameEngine );
|
||||
};
|
||||
|
||||
#endif // QUITMENU_H
|
||||
@@ -0,0 +1 @@
|
||||
480
|
||||
@@ -0,0 +1,176 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Class for handling finding servers, getting their details, and displaying
|
||||
// them inside the game
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ServerBrowser.h"
|
||||
#include "ServerBrowserMenu.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor -- initialize from steam gameserveritem_t
|
||||
//-----------------------------------------------------------------------------
|
||||
CGameServer::CGameServer( gameserveritem_t *pGameServerItem )
|
||||
{
|
||||
m_unIPAddress = pGameServerItem->m_NetAdr.GetIP();
|
||||
m_nConnectionPort = pGameServerItem->m_NetAdr.GetConnectionPort();
|
||||
m_nPing = pGameServerItem->m_nPing;
|
||||
strncpy( m_szMap, pGameServerItem->m_szMap, ARRAYSIZE( m_szMap ) );
|
||||
strncpy( m_szGameDescription, pGameServerItem->m_szGameDescription, ARRAYSIZE( m_szGameDescription ) );
|
||||
m_nPlayers = pGameServerItem->m_nPlayers;
|
||||
m_nMaxPlayers = pGameServerItem->m_nMaxPlayers;
|
||||
m_nBotPlayers = pGameServerItem->m_nBotPlayers;
|
||||
m_bPassword = pGameServerItem->m_bPassword;
|
||||
m_bSecure = pGameServerItem->m_bSecure;
|
||||
m_nServerVersion = pGameServerItem->m_nServerVersion;
|
||||
strncpy( m_szServerName, pGameServerItem->GetName(), ARRAYSIZE( m_szServerName ) );
|
||||
_snprintf( m_szServerString, ARRAYSIZE( m_szServerString ), "%s (%i/%i) at %s ping(%d)", pGameServerItem->GetName(), pGameServerItem->m_nPlayers, pGameServerItem->m_nMaxPlayers, pGameServerItem->m_NetAdr.GetConnectionAddressString(), pGameServerItem->m_nPing );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CServerBrowser::CServerBrowser( CGameEngine *pGameEngine )
|
||||
{
|
||||
m_pMenu = new CServerBrowserMenu( pGameEngine );
|
||||
m_pGameEngine = pGameEngine;
|
||||
m_nServers = 0;
|
||||
m_bRequestingServers = false;
|
||||
m_ServerType = eInternetServer;
|
||||
m_pMenu->Rebuild( m_ListGameServers, m_bRequestingServers );
|
||||
m_pMenu->SetHeading( "Internet Server browser" );
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CServerBrowser::~CServerBrowser()
|
||||
{
|
||||
if ( m_pMenu )
|
||||
delete m_pMenu;
|
||||
// ...
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Initiate a refresh of internet servers
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowser::RefreshInternetServers()
|
||||
{
|
||||
// If we are still finishing the previous refresh, then ignore this new request
|
||||
if ( m_bRequestingServers )
|
||||
return;
|
||||
|
||||
OutputDebugString( "Refreshing internet servers\n" );
|
||||
// Track that we are now in a refresh, what type of refresh, and reset our server count
|
||||
m_bRequestingServers = true;
|
||||
m_ServerType = eInternetServer;
|
||||
m_nServers = 0;
|
||||
m_ListGameServers.clear();
|
||||
m_pMenu->SetHeading( "Internet Server browser" );
|
||||
|
||||
m_pMenu->Rebuild( m_ListGameServers, m_bRequestingServers );
|
||||
|
||||
// Allocate some filters, there are some common pre-defined values that can be used:
|
||||
//
|
||||
// "gamedir" -- this is used to specify mods inside or a single product/appid
|
||||
// "secure" -- this is used to specify whether anti-cheat is enabled for a server
|
||||
// "gametype" -- this is used to specify game type and is set to whatever your game server code sets
|
||||
|
||||
MatchMakingKeyValuePair_t pFilters[2];
|
||||
MatchMakingKeyValuePair_t *pFilter = pFilters;
|
||||
|
||||
strncpy( pFilters[ 0 ].m_szKey, "gamedir", sizeof(pFilters[ 0 ].m_szKey) );
|
||||
strncpy( pFilters[ 0 ].m_szValue, "spacewar", sizeof(pFilters[ 0 ].m_szValue) );
|
||||
|
||||
strncpy( pFilters[ 1 ].m_szKey, "secure", sizeof(pFilters[ 1 ].m_szKey) );
|
||||
strncpy( pFilters[ 1 ].m_szValue, "1", sizeof(pFilters[ 1 ].m_szValue) );
|
||||
|
||||
//strncpy( pFilters[ 2 ].m_szKey, "gametype", sizeof(pFilters[ 1 ].m_szValue) );
|
||||
//strncpy( pFilters[ 2 ].m_szValue, "dm", sizeof(pFilters[ 1 ].m_szValue) );
|
||||
|
||||
// bugbug jmccaskey - passing just the appid without filters results in getting all servers rather than
|
||||
// servers filtered by appid alone. So, we'll use the filters to filter the results better.
|
||||
SteamMatchmakingServers()->RequestInternetServerList( SteamUtils()->GetAppID(), &pFilter, ARRAYSIZE(pFilters), this );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Initiate a refresh of LAN servers
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowser::RefreshLANServers()
|
||||
{
|
||||
// If we are still finishing the previous refresh, then ignore this new request
|
||||
if ( m_bRequestingServers )
|
||||
return;
|
||||
|
||||
OutputDebugString( "Refreshing internet servers\n" );
|
||||
// Track that we are now in a refresh, what type of refresh, and reset our server count
|
||||
m_bRequestingServers = true;
|
||||
m_ServerType = eLANServer;
|
||||
m_nServers = 0;
|
||||
m_ListGameServers.clear();
|
||||
m_pMenu->SetHeading( "LAN Server browser" );
|
||||
|
||||
m_pMenu->Rebuild( m_ListGameServers, m_bRequestingServers );
|
||||
|
||||
// LAN refresh doesn't accept filters like internet above does
|
||||
SteamMatchmakingServers()->RequestLANServerList( SteamUtils()->GetAppID(), this );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Callback from Steam telling us about a server that has responded
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowser::ServerResponded( int iServer )
|
||||
{
|
||||
gameserveritem_t *pServer = SteamMatchmakingServers()->GetServerDetails( m_ServerType, iServer );
|
||||
if ( pServer )
|
||||
{
|
||||
// Filter out servers that don't match our appid here (might get these in LAN calls since we can't put more filters on it)
|
||||
if ( pServer->m_nAppID == SteamUtils()->GetAppID() )
|
||||
{
|
||||
m_ListGameServers.push_back( CGameServer( pServer ) );
|
||||
m_nServers++;
|
||||
}
|
||||
}
|
||||
|
||||
// Rebuild menu
|
||||
m_pMenu->Rebuild( m_ListGameServers, m_bRequestingServers );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Callback from Steam telling us about a server that has failed to respond
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowser::ServerFailedToRespond( int iServer )
|
||||
{
|
||||
// bugbug jmccaskey - why would we ever need this? Remove servers from our list I guess?
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Callback from Steam telling us a refresh is complete
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowser::RefreshComplete( EMatchMakingServerResponse response )
|
||||
{
|
||||
// Doesn't really matter to us whether the response tells us the refresh succeeded or failed,
|
||||
// we just rack whether we are done refreshing or not
|
||||
m_bRequestingServers = false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Run a server browser frame (does stuff like checking KB input to change state)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowser::RunFrame()
|
||||
{
|
||||
m_pMenu->RunFrame();
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Class for handling finding servers, getting their details, and displaying
|
||||
// them inside the game
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef SERVERBROWSER_H
|
||||
#define SERVERBROWSER_H
|
||||
|
||||
#include "SpaceWar.h"
|
||||
#include "GameEngine.h"
|
||||
#include "steam/isteammatchmaking.h"
|
||||
#include "BaseMenu.h"
|
||||
#include <list>
|
||||
|
||||
class CSpaceWarClient;
|
||||
class CServerBrowserMenu;
|
||||
|
||||
// Class to encapsulate game server data
|
||||
class CGameServer
|
||||
{
|
||||
public:
|
||||
CGameServer( gameserveritem_t *pGameServerItem );
|
||||
|
||||
const char* GetName() { return m_szServerName; }
|
||||
|
||||
const char* GetDisplayString() { return m_szServerString; }
|
||||
|
||||
uint32 GetIP() { return m_unIPAddress; }
|
||||
|
||||
int32 GetPort() { return m_nConnectionPort; }
|
||||
|
||||
private:
|
||||
uint32 m_unIPAddress; // IP address for the server
|
||||
int32 m_nConnectionPort; // Port for game clients to connect to for this server
|
||||
int m_nPing; // current ping time in milliseconds
|
||||
char m_szMap[32]; // current map
|
||||
char m_szGameDescription[64]; // game description
|
||||
int m_nPlayers; // current number of players on the server
|
||||
int m_nMaxPlayers; // Maximum players that can join this server
|
||||
int m_nBotPlayers; // Number of bots (i.e simulated players) on this server
|
||||
bool m_bPassword; // true if this server needs a password to join
|
||||
bool m_bSecure; // Is this server protected by VAC
|
||||
int m_nServerVersion; // server version as reported to Steam
|
||||
char m_szServerName[64]; // Game server name
|
||||
char m_szServerString[128]; // String to show in server browser
|
||||
|
||||
};
|
||||
|
||||
class CServerBrowser : public ISteamMatchmakingServerListResponse
|
||||
{
|
||||
public:
|
||||
CServerBrowser( CGameEngine *pGameEngine );
|
||||
~CServerBrowser();
|
||||
|
||||
// Initiate a refresh of internet servers
|
||||
void RefreshInternetServers();
|
||||
|
||||
// Initiate a refresh of LAN servers
|
||||
void RefreshLANServers();
|
||||
|
||||
// Run a frame (to handle kb input and such as well as render)
|
||||
void RunFrame();
|
||||
|
||||
// ISteamMatchmakingServerListResponse
|
||||
void ServerResponded( int iServer );
|
||||
void ServerFailedToRespond( int iServer );
|
||||
void RefreshComplete( EMatchMakingServerResponse response );
|
||||
|
||||
private:
|
||||
|
||||
// Pointer to engine instance (so we can draw stuff)
|
||||
CGameEngine *m_pGameEngine;
|
||||
|
||||
// Track the number of servers we know about
|
||||
int m_nServers;
|
||||
|
||||
// Track whether we are in the middle of a refresh or not
|
||||
bool m_bRequestingServers;
|
||||
|
||||
// Track what type of servers we are currently displaying
|
||||
EMatchMakingType m_ServerType;
|
||||
|
||||
// Menu object
|
||||
CServerBrowserMenu *m_pMenu;
|
||||
|
||||
// List of game servers
|
||||
std::list< CGameServer > m_ListGameServers;
|
||||
};
|
||||
|
||||
#endif //SERVERBROWSER_H
|
||||
@@ -0,0 +1,41 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Class to find servers menu
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef SERVERBROWSERMENU_H
|
||||
#define SERVERBROWSERMENU_H
|
||||
|
||||
#include "BaseMenu.h"
|
||||
#include "ServerBrowser.h"
|
||||
|
||||
|
||||
class CServerBrowserMenu : public CBaseMenu<ServerBrowserMenuData_t>
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
CServerBrowserMenu( CGameEngine *pGameEngine ) : CBaseMenu<ServerBrowserMenuData_t>( pGameEngine ) {}
|
||||
|
||||
void Rebuild( std::list<CGameServer> &List, bool bIsRefreshing )
|
||||
{
|
||||
ClearMenuItems();
|
||||
|
||||
ServerBrowserMenuData_t data;
|
||||
std::list<CGameServer>::iterator iter;
|
||||
|
||||
for( iter = List.begin(); iter != List.end(); ++iter )
|
||||
{
|
||||
data.m_eStateToTransitionTo = k_EClientGameConnecting;
|
||||
data.m_unIPAddress = iter->GetIP();
|
||||
data.m_nConnectionPort = iter->GetPort();
|
||||
AddMenuItem( MenuItem_t( iter->GetDisplayString(), data ) );
|
||||
}
|
||||
|
||||
data.m_eStateToTransitionTo = k_EClientGameMenu;
|
||||
AddMenuItem( CServerBrowserMenu::MenuItem_t( "Return to main menu", data ) );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif SERVERBROWSERMENU_H
|
||||
@@ -0,0 +1,623 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Class for rendering the player ships
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Ship.h"
|
||||
#include "stdlib.h"
|
||||
#include "SpaceWarServer.h"
|
||||
#include "StatsAndAchievements.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor for thrusters
|
||||
//-----------------------------------------------------------------------------
|
||||
CForwardThrusters::CForwardThrusters( CGameEngine *pGameEngine, CShip *pShip ) : CVectorEntity( pGameEngine, 0 )
|
||||
{
|
||||
DWORD dwColor = D3DCOLOR_ARGB( 255, 255, 255, 102 );
|
||||
|
||||
// Initialize our geometry
|
||||
AddLine( 0.0, 12.0f, 0.0f, 19.0f, dwColor );
|
||||
AddLine( 1.0, 12.0f, 6.0f, 19.0f, dwColor );
|
||||
AddLine( 4.0, 12.0f, 11.0f, 19.0f, dwColor );
|
||||
AddLine( -1.0, 12.0f, -6.0f, 19.0f, dwColor );
|
||||
AddLine( -4.0, 12.0f, -11.0f, 19.0f, dwColor );
|
||||
|
||||
m_pShip = pShip;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Run Frame, updates us to be in the same position/rotation as the ship we belong to
|
||||
//-----------------------------------------------------------------------------
|
||||
void CForwardThrusters::RunFrame()
|
||||
{
|
||||
SetAccumulatedRotation( m_pShip->GetAccumulatedRotation() );
|
||||
SetPosition( m_pShip->GetXPos(), m_pShip->GetYPos() );
|
||||
|
||||
CVectorEntity::RunFrame();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor for reverse thrusters
|
||||
//-----------------------------------------------------------------------------
|
||||
CReverseThrusters::CReverseThrusters( CGameEngine *pGameEngine, CShip *pShip ) : CVectorEntity( pGameEngine, 0 )
|
||||
{
|
||||
DWORD dwColor = D3DCOLOR_ARGB( 255, 255, 255, 102 );
|
||||
|
||||
// Initialize our geometry
|
||||
AddLine( -8.875, 10.5f, -14.85f, 10.5f, dwColor );
|
||||
AddLine( -8.875, 10.5f, -13.765f, 5.61f, dwColor );
|
||||
AddLine( -8.875, 10.5f, -7.85f, 3.5f, dwColor );
|
||||
|
||||
AddLine( 8.875, 10.5f, 14.85f, 10.5f, dwColor );
|
||||
AddLine( 8.875, 10.5f, 13.765f, 5.61f, dwColor );
|
||||
AddLine( 8.875, 10.5f, 7.85f, 3.5f, dwColor );
|
||||
|
||||
m_pShip = pShip;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Run Frame, updates us to be in the same position/rotation as the ship we belong to
|
||||
//-----------------------------------------------------------------------------
|
||||
void CReverseThrusters::RunFrame()
|
||||
{
|
||||
SetAccumulatedRotation( m_pShip->GetAccumulatedRotation() );
|
||||
SetPosition( m_pShip->GetXPos(), m_pShip->GetYPos() );
|
||||
|
||||
CVectorEntity::RunFrame();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor for ship debris after explosion
|
||||
//-----------------------------------------------------------------------------
|
||||
CShipDebris::CShipDebris( CGameEngine *pGameEngine, float xPos, float yPos, DWORD dwDebrisColor ) : CSpaceWarEntity( pGameEngine, 0, true )
|
||||
{
|
||||
AddLine( 0.0f, 0.0f, 16.0f, 0.0f, dwDebrisColor );
|
||||
|
||||
// Random rotation between 0 and 360 degrees (6.28 radians)
|
||||
float flRotation = (float)(rand()%628)/100.0f;
|
||||
SetRotationDeltaNextFrame( flRotation );
|
||||
|
||||
// Rotation to apply per second
|
||||
int nRandRotation = rand()%(157*2) - (157);
|
||||
m_flRotationPerInterval = nRandRotation/100.0f;
|
||||
|
||||
float sinvalue = (float)sin( flRotation );
|
||||
float cosvalue = (float)cos( flRotation );
|
||||
|
||||
float xVelocity = GetXVelocity() + ( sinvalue * 80 );
|
||||
float yVelocity = GetYVelocity() - ( cosvalue * 80 );
|
||||
|
||||
// Offset out a bit from the center of the ship compensating for rotation
|
||||
float offset = (rand()%12)-6.0f;
|
||||
float xOffset = xPos + (cosvalue*-offset - sinvalue*-offset);
|
||||
float yOffset = yPos + (cosvalue*-offset + sinvalue*-offset);
|
||||
|
||||
// Set velocity
|
||||
SetVelocity( xVelocity, yVelocity );
|
||||
|
||||
// Set position
|
||||
SetPosition( xOffset, yOffset );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Run frame for debris (keep it spinning)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CShipDebris::RunFrame()
|
||||
{
|
||||
SetRotationDeltaNextFrame( m_flRotationPerInterval * min( m_pGameEngine->GetGameTicksFrameDelta(), 400.0f )/400.0f );
|
||||
CSpaceWarEntity::RunFrame();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
#pragma warning( push )
|
||||
// warning C4355: 'this' : used in base member initializer list
|
||||
// This is OK because the thruster classes won't use the ship object in their constructors (where it may still be only partly constructed)
|
||||
#pragma warning( disable : 4355 )
|
||||
CShip::CShip( CGameEngine *pGameEngine, bool bIsServerInstance, float xPos, float yPos, DWORD dwShipColor ) :
|
||||
CSpaceWarEntity( pGameEngine, 11, true ), m_ForwardThrusters( pGameEngine, this ), m_ReverseThrusters( pGameEngine, this )
|
||||
{
|
||||
m_bDisabled = false;
|
||||
m_bExploding = false;
|
||||
m_ulLastThrustStartedTickCount = 0;
|
||||
m_dwVKLeft = 0;
|
||||
m_dwVKRight = 0;
|
||||
m_dwVKForwardThrusters = 0;
|
||||
m_dwVKReverseThrusters = 0;
|
||||
m_dwVKFire = 0;
|
||||
m_ulLastPhotonTickCount = 0;
|
||||
m_dwShipColor = dwShipColor;
|
||||
m_bForwardThrustersActive = false;
|
||||
m_bReverseThrustersActive = false;
|
||||
m_bIsLocalPlayer = false;
|
||||
m_bFirePhotonBeamNextFrame = false;
|
||||
m_ulLastClientUpdateTick = 0;
|
||||
m_bIsServerInstance = bIsServerInstance;
|
||||
|
||||
memset( &m_SpaceWarClientUpdateData, 0, sizeof( m_SpaceWarClientUpdateData ) );
|
||||
|
||||
for( int i=0; i < MAX_PHOTON_BEAMS_PER_SHIP; ++i )
|
||||
{
|
||||
m_rgPhotonBeams[i] = NULL;
|
||||
}
|
||||
|
||||
// Initialize our geometry
|
||||
AddLine( -9.0f, 12.0f, 0.0f, -12.0f, dwShipColor );
|
||||
AddLine( 0.0f, -12.0f, 9.0f, 12.0f, dwShipColor );
|
||||
AddLine( 9.0f, 12.0f, -9.0f, 12.0f, dwShipColor );
|
||||
SetPosition( xPos, yPos );
|
||||
}
|
||||
#pragma warning( pop )
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CShip::~CShip()
|
||||
{
|
||||
// Cleanup beams
|
||||
{
|
||||
for( int i=0; i < MAX_PHOTON_BEAMS_PER_SHIP; ++i )
|
||||
{
|
||||
if ( m_rgPhotonBeams[i] )
|
||||
delete m_rgPhotonBeams[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup debris
|
||||
{
|
||||
std::list<CShipDebris *>::iterator iter;
|
||||
for ( iter = m_ListDebris.begin(); iter != m_ListDebris.end(); ++iter )
|
||||
{
|
||||
delete (*iter);
|
||||
}
|
||||
m_ListDebris.clear();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Update entity with updated data from the server
|
||||
//-----------------------------------------------------------------------------
|
||||
void CShip::OnReceiveServerUpdate( ServerShipUpdateData_t UpdateData )
|
||||
{
|
||||
if ( m_bIsServerInstance )
|
||||
{
|
||||
OutputDebugString( "Should not be receiving server updates on the server itself\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
SetDisabled( UpdateData.m_bDisabled );
|
||||
|
||||
SetExploding( UpdateData.m_bExploding );
|
||||
|
||||
SetPosition( UpdateData.m_flXPosition, UpdateData.m_flYPosition );
|
||||
SetVelocity( UpdateData.m_flXVelocity, UpdateData.m_flYVelocity );
|
||||
SetAccumulatedRotation( UpdateData.m_flCurrentRotation );
|
||||
|
||||
|
||||
m_bForwardThrustersActive = UpdateData.m_bForwardThrustersActive;
|
||||
m_bReverseThrustersActive = UpdateData.m_bReverseThrustersActive;
|
||||
|
||||
// Update the photon beams
|
||||
for ( int i=0; i < MAX_PHOTON_BEAMS_PER_SHIP; ++i )
|
||||
{
|
||||
if ( UpdateData.m_PhotonBeamData[i].m_bIsActive )
|
||||
{
|
||||
if ( !m_rgPhotonBeams[i] )
|
||||
{
|
||||
m_rgPhotonBeams[i] = new CPhotonBeam( m_pGameEngine,
|
||||
UpdateData.m_PhotonBeamData[i].m_flXPosition, UpdateData.m_PhotonBeamData[i].m_flYPosition,
|
||||
m_dwShipColor, UpdateData.m_PhotonBeamData[i].m_flCurrentRotation,
|
||||
UpdateData.m_PhotonBeamData[i].m_flXVelocity, UpdateData.m_PhotonBeamData[i].m_flYVelocity );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rgPhotonBeams[i]->OnReceiveServerUpdate( UpdateData.m_PhotonBeamData[i] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_rgPhotonBeams[i] )
|
||||
{
|
||||
delete m_rgPhotonBeams[i];
|
||||
m_rgPhotonBeams[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Update entity with updated data from the client
|
||||
//-----------------------------------------------------------------------------
|
||||
void CShip::OnReceiveClientUpdate( ClientSpaceWarUpdateData_t UpdateData )
|
||||
{
|
||||
if ( !m_bIsServerInstance )
|
||||
{
|
||||
OutputDebugString( "Should not be receiving client updates on non-server instances\n" );
|
||||
return;
|
||||
}
|
||||
memcpy( &m_SpaceWarClientUpdateData, &UpdateData, sizeof( ClientSpaceWarUpdateData_t ) );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Tell the server about any updates we have had client-side
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CShip::BGetClientUpdateData( ClientSpaceWarUpdateData_t *pUpdateData )
|
||||
{
|
||||
// Limit the rate at which we send updates, even if our internal frame rate is higher
|
||||
if ( m_pGameEngine->GetGameTickCount() - m_ulLastClientUpdateTick < 1000.0f/CLIENT_UPDATE_SEND_RATE )
|
||||
return false;
|
||||
|
||||
m_ulLastClientUpdateTick = m_pGameEngine->GetGameTickCount();
|
||||
|
||||
// Update playername before sending
|
||||
if ( m_bIsLocalPlayer )
|
||||
strncpy( m_SpaceWarClientUpdateData.m_rgchPlayerName, SteamFriends()->GetFriendPersonaName( SteamUser()->GetSteamID() ), ARRAYSIZE( m_SpaceWarClientUpdateData.m_rgchPlayerName ) );
|
||||
|
||||
memcpy( pUpdateData, &m_SpaceWarClientUpdateData, sizeof( ClientSpaceWarUpdateData_t ) );
|
||||
memset( &m_SpaceWarClientUpdateData, 0, sizeof( m_SpaceWarClientUpdateData ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Get the name for this ship (only really works server side)
|
||||
//-----------------------------------------------------------------------------
|
||||
const char* CShip::GetPlayerName()
|
||||
{
|
||||
return m_SpaceWarClientUpdateData.m_rgchPlayerName;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Run a frame for the ship
|
||||
//-----------------------------------------------------------------------------
|
||||
void CShip::RunFrame()
|
||||
{
|
||||
if ( m_bDisabled )
|
||||
return;
|
||||
|
||||
const uint64 ulCurrentTickCount = m_pGameEngine->GetGameTickCount();
|
||||
|
||||
// Look for expired photon beams
|
||||
int nNextAvailablePhotonBeamSlot = -1; // Track next available slot for use spawning new beams below
|
||||
for( int i=0; i < MAX_PHOTON_BEAMS_PER_SHIP; ++i )
|
||||
{
|
||||
if ( m_rgPhotonBeams[i] )
|
||||
{
|
||||
if ( m_rgPhotonBeams[i]->BIsBeamExpired() )
|
||||
{
|
||||
delete m_rgPhotonBeams[i];
|
||||
m_rgPhotonBeams[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !m_rgPhotonBeams[i] && nNextAvailablePhotonBeamSlot == -1 )
|
||||
nNextAvailablePhotonBeamSlot = i;
|
||||
}
|
||||
|
||||
// run all the photon beams we have outstanding
|
||||
for( int i=0; i < MAX_PHOTON_BEAMS_PER_SHIP; ++i )
|
||||
{
|
||||
if ( m_rgPhotonBeams[i] )
|
||||
m_rgPhotonBeams[i]->RunFrame();
|
||||
}
|
||||
|
||||
// run all the space debris
|
||||
{
|
||||
std::list<CShipDebris *>::iterator iter;
|
||||
for( iter = m_ListDebris.begin(); iter != m_ListDebris.end(); ++iter )
|
||||
(*iter)->RunFrame();
|
||||
}
|
||||
|
||||
if ( m_bIsLocalPlayer )
|
||||
{
|
||||
m_SpaceWarClientUpdateData.m_bTurnLeftPressed = false;
|
||||
m_SpaceWarClientUpdateData.m_bTurnRightPressed = false;
|
||||
|
||||
if ( m_pGameEngine->BIsKeyDown( m_dwVKLeft ) )
|
||||
{
|
||||
m_SpaceWarClientUpdateData.m_bTurnLeftPressed = true;
|
||||
}
|
||||
|
||||
if ( m_pGameEngine->BIsKeyDown( m_dwVKRight ) )
|
||||
{
|
||||
m_SpaceWarClientUpdateData.m_bTurnRightPressed = true;
|
||||
}
|
||||
}
|
||||
else if ( m_bIsServerInstance )
|
||||
{
|
||||
// Server side
|
||||
float flRotationDelta = 0.0f;
|
||||
if ( m_SpaceWarClientUpdateData.m_bTurnLeftPressed )
|
||||
{
|
||||
flRotationDelta += (PI_VALUE/2.0f) * -1.0f * (float)m_pGameEngine->GetGameTicksFrameDelta()/400.0f;
|
||||
}
|
||||
|
||||
if ( m_SpaceWarClientUpdateData.m_bTurnRightPressed )
|
||||
{
|
||||
flRotationDelta += (PI_VALUE/2.0f) * (float)m_pGameEngine->GetGameTicksFrameDelta()/400.0f;
|
||||
}
|
||||
SetRotationDeltaNextFrame( flRotationDelta );
|
||||
}
|
||||
|
||||
// Compute acceleration
|
||||
if ( m_bIsLocalPlayer )
|
||||
{
|
||||
// client side
|
||||
m_SpaceWarClientUpdateData.m_bReverseThrustersPressed = false;
|
||||
m_SpaceWarClientUpdateData.m_bForwardThrustersPressed = false;
|
||||
if ( m_pGameEngine->BIsKeyDown( m_dwVKForwardThrusters ) || m_pGameEngine->BIsKeyDown( m_dwVKReverseThrusters ) )
|
||||
{
|
||||
if ( m_pGameEngine->BIsKeyDown( m_dwVKReverseThrusters ) )
|
||||
{
|
||||
m_SpaceWarClientUpdateData.m_bReverseThrustersPressed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_SpaceWarClientUpdateData.m_bForwardThrustersPressed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( m_bIsServerInstance )
|
||||
{
|
||||
// Server side
|
||||
float xThrust = 0;
|
||||
float yThrust = 0;
|
||||
m_bReverseThrustersActive = false;
|
||||
m_bForwardThrustersActive = false;
|
||||
if ( m_SpaceWarClientUpdateData.m_bReverseThrustersPressed || m_SpaceWarClientUpdateData.m_bForwardThrustersPressed )
|
||||
{
|
||||
float flSign = 1.0f;
|
||||
if ( m_SpaceWarClientUpdateData.m_bReverseThrustersPressed )
|
||||
{
|
||||
m_bReverseThrustersActive = true;
|
||||
flSign = -1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bForwardThrustersActive = true;
|
||||
}
|
||||
|
||||
if ( m_ulLastThrustStartedTickCount == 0 )
|
||||
m_ulLastThrustStartedTickCount = ulCurrentTickCount;
|
||||
|
||||
// You have to hold the key for a second to reach maximum thrust
|
||||
float factor = min( ((float)(ulCurrentTickCount - m_ulLastThrustStartedTickCount) / 500.0f) + 0.2f, 1.0f );
|
||||
|
||||
xThrust = flSign * (float)(MAXIMUM_SHIP_THRUST * factor * sin( GetAccumulatedRotation() ) );
|
||||
yThrust = flSign * -1.0f * (float)(MAXIMUM_SHIP_THRUST * factor * cos( GetAccumulatedRotation() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ulLastThrustStartedTickCount = 0;
|
||||
}
|
||||
|
||||
SetAcceleration( xThrust, yThrust );
|
||||
}
|
||||
|
||||
|
||||
// We'll use these values in a few places below to compute positions of child objects
|
||||
// appropriately given our rotation
|
||||
float sinvalue = (float)sin( GetAccumulatedRotation() );
|
||||
float cosvalue = (float)cos( GetAccumulatedRotation() );
|
||||
|
||||
// See if we need to fire a photon beam
|
||||
bool bFirePhotonBeam = m_bFirePhotonBeamNextFrame;
|
||||
m_bFirePhotonBeamNextFrame = false;
|
||||
|
||||
if ( m_bIsLocalPlayer )
|
||||
{
|
||||
// client side
|
||||
if ( m_pGameEngine->BIsKeyDown( m_dwVKFire ) )
|
||||
{
|
||||
m_SpaceWarClientUpdateData.m_bFirePressed = true;
|
||||
}
|
||||
}
|
||||
else if ( m_bIsServerInstance )
|
||||
{
|
||||
// server side
|
||||
if ( nNextAvailablePhotonBeamSlot != -1 && !m_bExploding && m_SpaceWarClientUpdateData.m_bFirePressed && ulCurrentTickCount - PHOTON_BEAM_FIRE_INTERVAL_TICKS > m_ulLastPhotonTickCount )
|
||||
{
|
||||
m_ulLastPhotonTickCount = ulCurrentTickCount;
|
||||
|
||||
float xVelocity = GetXVelocity() + ( sinvalue * 275 );
|
||||
float yVelocity = GetYVelocity() - ( cosvalue * 275 );
|
||||
|
||||
// Offset 12 points up from the center of the ship, compensating for rotation
|
||||
float xPos = GetXPos() - sinvalue*-12.0f;
|
||||
float yPos = GetYPos() + cosvalue*-12.0f;
|
||||
|
||||
m_rgPhotonBeams[nNextAvailablePhotonBeamSlot] = new CPhotonBeam( m_pGameEngine, xPos, yPos, m_dwShipColor, GetAccumulatedRotation(), xVelocity, yVelocity );
|
||||
}
|
||||
}
|
||||
|
||||
CSpaceWarEntity::RunFrame();
|
||||
|
||||
// Finally, update the thrusters ( we do this after the base class call as they rely on our data being fully up-to-date)
|
||||
m_ForwardThrusters.RunFrame();
|
||||
m_ReverseThrusters.RunFrame();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Render the ship
|
||||
//-----------------------------------------------------------------------------
|
||||
void CShip::Render()
|
||||
{
|
||||
if ( m_bDisabled )
|
||||
return;
|
||||
|
||||
// render all the photon beams we have outstanding
|
||||
for( int i=0; i < MAX_PHOTON_BEAMS_PER_SHIP; ++i )
|
||||
{
|
||||
if ( m_rgPhotonBeams[i] )
|
||||
m_rgPhotonBeams[i]->Render();
|
||||
}
|
||||
|
||||
|
||||
if ( m_bExploding )
|
||||
{
|
||||
// Don't draw actual ship, instead draw the pieces created in the explosion
|
||||
std::list<CShipDebris *>::iterator iter;
|
||||
for( iter = m_ListDebris.begin(); iter != m_ListDebris.end(); ++iter )
|
||||
(*iter)->Render();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if we should be drawing thrusters
|
||||
if ( m_bForwardThrustersActive )
|
||||
{
|
||||
if ( rand()%3 == 0 )
|
||||
m_ForwardThrusters.Render();
|
||||
}
|
||||
|
||||
if ( m_bReverseThrustersActive )
|
||||
{
|
||||
if ( rand()%3 == 0 )
|
||||
m_ReverseThrusters.Render();
|
||||
}
|
||||
|
||||
CSpaceWarEntity::Render();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Set whether the ship is exploding
|
||||
//-----------------------------------------------------------------------------
|
||||
void CShip::SetExploding( bool bExploding )
|
||||
{
|
||||
// If we are already in the specified state, no need to do the below work
|
||||
if ( m_bExploding == bExploding )
|
||||
return;
|
||||
|
||||
// Track that we are exploding, and disable collision detection
|
||||
m_bExploding = bExploding;
|
||||
SetCollisionDetectionDisabled( m_bExploding );
|
||||
|
||||
if ( bExploding )
|
||||
{
|
||||
for( int i = 0; i < SHIP_DEBRIS_PIECES; ++i )
|
||||
{
|
||||
CShipDebris * pDebris = new CShipDebris( m_pGameEngine, GetXPos(), GetYPos(), m_dwShipColor );
|
||||
m_ListDebris.push_back( pDebris );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::list<CShipDebris *>::iterator iter;
|
||||
for( iter = m_ListDebris.begin(); iter != m_ListDebris.end(); ++iter )
|
||||
delete *iter;
|
||||
m_ListDebris.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Check for photons which have hit the target and remove them
|
||||
//-----------------------------------------------------------------------------
|
||||
void CShip::DestroyPhotonsColldingWith( CVectorEntity *pTarget )
|
||||
{
|
||||
for( int i=0; i < MAX_PHOTON_BEAMS_PER_SHIP; ++i )
|
||||
{
|
||||
if ( !m_rgPhotonBeams[i] )
|
||||
continue;
|
||||
|
||||
if ( m_rgPhotonBeams[i]->BCollidesWith( pTarget ) )
|
||||
{
|
||||
// Photon beam hit the entity, destroy beam
|
||||
delete m_rgPhotonBeams[i];
|
||||
m_rgPhotonBeams[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Check whether any of the photons this ship has fired are colliding with the target
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CShip::BCheckForPhotonsCollidingWith( CVectorEntity *pTarget )
|
||||
{
|
||||
for( int i=0; i < MAX_PHOTON_BEAMS_PER_SHIP; ++i )
|
||||
{
|
||||
if ( !m_rgPhotonBeams[i] )
|
||||
continue;
|
||||
|
||||
if ( m_rgPhotonBeams[i]->BCollidesWith( pTarget ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Build the update data to send from server to clients
|
||||
//-----------------------------------------------------------------------------
|
||||
void CShip::BuildServerUpdate( ServerShipUpdateData_t *pUpdateData )
|
||||
{
|
||||
pUpdateData->m_bDisabled = BIsDisabled();
|
||||
pUpdateData->m_bExploding = BIsExploding();
|
||||
pUpdateData->m_flXAcceleration = GetXAccelerationLastFrame();
|
||||
pUpdateData->m_flYAcceleration = GetYAccelerationLastFrame();
|
||||
pUpdateData->m_flXPosition = GetXPos();
|
||||
pUpdateData->m_flYPosition = GetYPos();
|
||||
pUpdateData->m_flXVelocity = GetXVelocity();
|
||||
pUpdateData->m_flYVelocity = GetYVelocity();
|
||||
pUpdateData->m_flCurrentRotation = GetAccumulatedRotation();
|
||||
pUpdateData->m_flRotationDeltaLastFrame = GetRotationDeltaLastFrame();
|
||||
pUpdateData->m_bForwardThrustersActive = m_bForwardThrustersActive;
|
||||
pUpdateData->m_bReverseThrustersActive = m_bReverseThrustersActive;
|
||||
|
||||
BuildServerPhotonBeamUpdate( pUpdateData->m_PhotonBeamData );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Build the photon beam update data to send from the server to clients
|
||||
//-----------------------------------------------------------------------------
|
||||
void CShip::BuildServerPhotonBeamUpdate( ServerPhotonBeamUpdateData_t *pUpdateData )
|
||||
{
|
||||
for( int i = 0; i < MAX_PHOTON_BEAMS_PER_SHIP; ++i )
|
||||
{
|
||||
if ( m_rgPhotonBeams[i] )
|
||||
{
|
||||
pUpdateData[i].m_bIsActive = true;
|
||||
pUpdateData[i].m_flXPosition = m_rgPhotonBeams[i]->GetXPos();
|
||||
pUpdateData[i].m_flYPosition = m_rgPhotonBeams[i]->GetYPos();
|
||||
pUpdateData[i].m_flXVelocity = m_rgPhotonBeams[i]->GetXVelocity();
|
||||
pUpdateData[i].m_flYVelocity = m_rgPhotonBeams[i]->GetYVelocity();
|
||||
pUpdateData[i].m_flCurrentRotation = m_rgPhotonBeams[i]->GetAccumulatedRotation();
|
||||
}
|
||||
else
|
||||
{
|
||||
pUpdateData[i].m_bIsActive = false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Accumulate stats for this ship
|
||||
//-----------------------------------------------------------------------------
|
||||
void CShip::AccumulateStats( CStatsAndAchievements *pStats )
|
||||
{
|
||||
if ( m_bIsLocalPlayer )
|
||||
{
|
||||
pStats->AddDistanceTraveled( GetDistanceTraveledLastFrame() );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Class for rendering the player ships
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef SHIP_H
|
||||
#define SHIP_H
|
||||
|
||||
#include <list>
|
||||
#include "GameEngine.h"
|
||||
#include "SpaceWarEntity.h"
|
||||
#include "PhotonBeam.h"
|
||||
#include "SpaceWar.h"
|
||||
|
||||
#define MAXIMUM_SHIP_THRUST 150
|
||||
|
||||
#define SHIP_DEBRIS_PIECES 6
|
||||
|
||||
// Forward declaration
|
||||
class CShip;
|
||||
class CSpaceWarServer;
|
||||
class CStatsAndAchievements;
|
||||
|
||||
// Simple class for the ship thrusters
|
||||
class CForwardThrusters : public CVectorEntity
|
||||
{
|
||||
public:
|
||||
CForwardThrusters( CGameEngine *pGameEngine, CShip *pShip );
|
||||
|
||||
// Run Frame
|
||||
void RunFrame();
|
||||
|
||||
private:
|
||||
CShip *m_pShip;
|
||||
};
|
||||
|
||||
// Again, but in reverse
|
||||
class CReverseThrusters : public CVectorEntity
|
||||
{
|
||||
public:
|
||||
CReverseThrusters( CGameEngine *pGameEngine, CShip *pShip );
|
||||
|
||||
// Run Frame
|
||||
void RunFrame();
|
||||
|
||||
private:
|
||||
CShip *m_pShip;
|
||||
};
|
||||
|
||||
// Class to represent debris after explosion
|
||||
class CShipDebris : public CSpaceWarEntity
|
||||
{
|
||||
public:
|
||||
CShipDebris( CGameEngine *pGameEngine, float xPos, float yPos, DWORD dwDebrisColor );
|
||||
|
||||
// Run Frame
|
||||
void RunFrame();
|
||||
private:
|
||||
|
||||
// We keep the debris spinning
|
||||
float m_flRotationPerInterval;
|
||||
};
|
||||
|
||||
class CShip : public CSpaceWarEntity
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
CShip( CGameEngine *pGameEngine, bool bIsServerInstance, float xPos, float yPos, DWORD dwShipColor );
|
||||
|
||||
// Destructor
|
||||
~CShip();
|
||||
|
||||
// Run a frame
|
||||
void RunFrame();
|
||||
|
||||
// Render a frame
|
||||
void Render();
|
||||
|
||||
// Update ship with data from server
|
||||
void OnReceiveServerUpdate( ServerShipUpdateData_t UpdateData );
|
||||
|
||||
// Update the ship with data from a client
|
||||
void OnReceiveClientUpdate( ClientSpaceWarUpdateData_t UpdateData );
|
||||
|
||||
// Get the update data for this ship client side (copying into memory passed in)
|
||||
bool BGetClientUpdateData( ClientSpaceWarUpdateData_t *pUpdatedata );
|
||||
|
||||
// Build update data for the ship to send to clients
|
||||
void BuildServerUpdate( ServerShipUpdateData_t *pUpdateData );
|
||||
|
||||
// Build update data for photon beams to send to clients
|
||||
void BuildServerPhotonBeamUpdate( ServerPhotonBeamUpdateData_t *pUpdateData );
|
||||
|
||||
// Reset vertex data for our object
|
||||
void ResetVertexData();
|
||||
|
||||
// Set whether the ship is exploding
|
||||
void SetExploding( bool bExploding );
|
||||
|
||||
// Set whether the ship is disabled
|
||||
void SetDisabled( bool bDisabled ) { m_bDisabled = bDisabled; }
|
||||
|
||||
// Set the initial rotation for the ship
|
||||
void SetInitialRotation( float flRotation ) { SetAccumulatedRotation( flRotation ); }
|
||||
|
||||
// Setters for key bindings
|
||||
void SetVKBindingLeft( DWORD dwVKLeft ) { m_dwVKLeft = dwVKLeft; }
|
||||
void SetVKBindingRight( DWORD dwVKRight ) { m_dwVKRight = dwVKRight; }
|
||||
void SetVKBindingForwardThrusters( DWORD dwVKForward ) { m_dwVKForwardThrusters = dwVKForward; }
|
||||
void SetVKBindingReverseThrusters( DWORD dwVKReverse ) { m_dwVKReverseThrusters = dwVKReverse; }
|
||||
void SetVKBindingFire( DWORD dwVKFire ) { m_dwVKFire = dwVKFire; }
|
||||
|
||||
// Check for photons which have hit the entity and destroy the photons
|
||||
void DestroyPhotonsColldingWith( CVectorEntity *pTarget );
|
||||
|
||||
// Check whether any of the photons this ship has fired are colliding with the target
|
||||
bool BCheckForPhotonsCollidingWith( CVectorEntity *pTarget );
|
||||
|
||||
// Check if the ship is currently exploding
|
||||
bool BIsExploding() { return m_bExploding; }
|
||||
|
||||
// Check if the ship is currently disabled
|
||||
bool BIsDisabled() { return m_bDisabled; }
|
||||
|
||||
// Set whether this ship instance is for the local player
|
||||
// (meaning it should pay attention to key input and such)
|
||||
void SetIsLocalPlayer( bool bValue ) { m_bIsLocalPlayer = bValue; }
|
||||
bool BIsLocalPlayer() { return m_bIsLocalPlayer; }
|
||||
|
||||
// Accumulate stats for this ship
|
||||
void AccumulateStats( CStatsAndAchievements *pStats );
|
||||
|
||||
// Get the name for this ship (only really works server side)
|
||||
const char* GetPlayerName();
|
||||
|
||||
private:
|
||||
|
||||
// Last time we sent an update on our local data to the server
|
||||
uint64 m_ulLastClientUpdateTick;
|
||||
|
||||
// Last time we detected the thrust key go down
|
||||
uint64 m_ulLastThrustStartedTickCount;
|
||||
|
||||
// Last time we fired a photon
|
||||
uint64 m_ulLastPhotonTickCount;
|
||||
|
||||
// is this ship our local ship, or a remote player?
|
||||
bool m_bIsLocalPlayer;
|
||||
|
||||
// Is this ship instance running inside the server (otherwise its a client...)
|
||||
bool m_bIsServerInstance;
|
||||
|
||||
// is the ship exploding?
|
||||
bool m_bExploding;
|
||||
|
||||
// is the ship disabled for now?
|
||||
bool m_bDisabled;
|
||||
|
||||
// Do we need to fire a photon beam next frame?
|
||||
bool m_bFirePhotonBeamNextFrame;
|
||||
|
||||
// vector of beams we have fired (in order of firing time)
|
||||
CPhotonBeam * m_rgPhotonBeams[MAX_PHOTON_BEAMS_PER_SHIP];
|
||||
|
||||
// vector of debris to draw after an explosion
|
||||
std::list< CShipDebris *> m_ListDebris;
|
||||
|
||||
// Color for this ship
|
||||
DWORD m_dwShipColor;
|
||||
|
||||
// Thrusters for this ship
|
||||
CForwardThrusters m_ForwardThrusters;
|
||||
|
||||
// Track whether to draw the thrusters next render call
|
||||
bool m_bForwardThrustersActive;
|
||||
|
||||
// Thrusters for this ship
|
||||
CReverseThrusters m_ReverseThrusters;
|
||||
|
||||
// Track whether to draw the thrusters next render call
|
||||
bool m_bReverseThrustersActive;
|
||||
|
||||
// This will get populated only if we are the local instance, and then
|
||||
// sent to the server in response to each server update
|
||||
ClientSpaceWarUpdateData_t m_SpaceWarClientUpdateData;
|
||||
|
||||
// key bindings
|
||||
DWORD m_dwVKLeft;
|
||||
DWORD m_dwVKRight;
|
||||
DWORD m_dwVKForwardThrusters;
|
||||
DWORD m_dwVKReverseThrusters;
|
||||
DWORD m_dwVKFire;
|
||||
};
|
||||
|
||||
#endif // SHIP_H
|
||||
@@ -0,0 +1,198 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Shared definitions for the communication between the server/client
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef SPACEWAR_H
|
||||
#define SPACEWAR_H
|
||||
|
||||
// Current game server version
|
||||
#define SPACEWAR_SERVER_VERSION "1.0.0.0"
|
||||
|
||||
// UDP port for the spacewar server to do authentication on (ie, talk to Steam on)
|
||||
#define SPACEWAR_AUTHENTICATION_PORT 8766
|
||||
|
||||
// UDP port for the spacewar server to listen on
|
||||
#define SPACEWAR_SERVER_PORT 27015
|
||||
|
||||
// UDP port for the master server updater to listen on
|
||||
#define SPACEWAR_MASTER_SERVER_UPDATER_PORT 27016
|
||||
|
||||
// How long to wait for a response from the server before resending our connection attempt
|
||||
#define SERVER_CONNECTION_RETRY_MILLISECONDS 350
|
||||
|
||||
// How long to wait for a client to send an update before we drop its connection server side
|
||||
#define SERVER_TIMEOUT_MILLISECONDS 5000
|
||||
|
||||
// Maximum packet size in bytes
|
||||
#define MAX_SPACEWAR_PACKET_SIZE 1024*512
|
||||
|
||||
// Maximum number of players who can join a server and play simultaneously
|
||||
#define MAX_PLAYERS_PER_SERVER 4
|
||||
|
||||
// Time to pause wait after a round ends before starting a new one
|
||||
#define MILLISECONDS_BETWEEN_ROUNDS 4000
|
||||
|
||||
// How long photon beams live before expiring
|
||||
#define PHOTON_BEAM_LIFETIME_IN_TICKS 1750
|
||||
|
||||
// How fast can photon beams be fired?
|
||||
#define PHOTON_BEAM_FIRE_INTERVAL_TICKS 250
|
||||
|
||||
// Amount of space needed for beams per ship
|
||||
#define MAX_PHOTON_BEAMS_PER_SHIP PHOTON_BEAM_LIFETIME_IN_TICKS/PHOTON_BEAM_FIRE_INTERVAL_TICKS
|
||||
|
||||
// Time to timeout a connection attempt in
|
||||
#define MILLISECONDS_CONNECTION_TIMEOUT 30000
|
||||
|
||||
// How many times a second does the server send world updates to clients
|
||||
#define SERVER_UPDATE_SEND_RATE 60
|
||||
|
||||
// How many times a second do we send our updated client state to the server
|
||||
#define CLIENT_UPDATE_SEND_RATE 30
|
||||
|
||||
// How fast does the server internally run at?
|
||||
#define MAX_CLIENT_AND_SERVER_FPS 86
|
||||
|
||||
|
||||
// Player colors
|
||||
DWORD const g_rgPlayerColors[ MAX_PLAYERS_PER_SERVER ] =
|
||||
{
|
||||
D3DCOLOR_ARGB( 255, 255, 150, 150 ), // red
|
||||
D3DCOLOR_ARGB( 255, 200, 200, 255 ), // blue
|
||||
D3DCOLOR_ARGB( 255, 255, 204, 102 ), // orange
|
||||
D3DCOLOR_ARGB( 255, 153, 255, 153 ), // green
|
||||
};
|
||||
|
||||
|
||||
// Enum for possible game states on the client
|
||||
enum EClientGameState
|
||||
{
|
||||
k_EClientGameStartServer,
|
||||
k_EClientGameActive,
|
||||
k_EClientGameWaitingForPlayers,
|
||||
k_EClientGameMenu,
|
||||
k_EClientGameQuitMenu,
|
||||
k_EClientGameExiting,
|
||||
k_EClientGameInstructions,
|
||||
k_EClientGameDraw,
|
||||
k_EClientGameWinner,
|
||||
k_EClientGameConnecting,
|
||||
k_EClientGameConnectionFailure,
|
||||
k_EClientFindInternetServers,
|
||||
k_EClientStatsAchievements,
|
||||
k_EClientCreatingLobby,
|
||||
k_EClientInLobby,
|
||||
k_EClientFindLobby,
|
||||
k_EClientJoiningLobby,
|
||||
k_EClientFindLANServers,
|
||||
};
|
||||
|
||||
|
||||
// Enum for possible game states on the server
|
||||
enum EServerGameState
|
||||
{
|
||||
k_EServerWaitingForPlayers,
|
||||
k_EServerActive,
|
||||
k_EServerDraw,
|
||||
k_EServerWinner,
|
||||
k_EServerExiting,
|
||||
};
|
||||
|
||||
|
||||
// Data sent per photon beam from the server to update clients photon beam positions
|
||||
struct ServerPhotonBeamUpdateData_t
|
||||
{
|
||||
// Does the photon beam exist right now?
|
||||
bool m_bIsActive;
|
||||
|
||||
// The current rotation
|
||||
float m_flCurrentRotation;
|
||||
|
||||
// The current velocity
|
||||
float m_flXVelocity;
|
||||
float m_flYVelocity;
|
||||
|
||||
// The current position
|
||||
float m_flXPosition;
|
||||
float m_flYPosition;
|
||||
};
|
||||
|
||||
|
||||
// This is the data that gets sent per ship in each update, see below for the full update data
|
||||
struct ServerShipUpdateData_t
|
||||
{
|
||||
// The current rotation of the ship
|
||||
float m_flCurrentRotation;
|
||||
|
||||
// The delta in rotation for the last frame (client side interpolation will use this)
|
||||
float m_flRotationDeltaLastFrame;
|
||||
|
||||
// The current thrust for the ship
|
||||
float m_flXAcceleration;
|
||||
float m_flYAcceleration;
|
||||
|
||||
// The current velocity for the ship
|
||||
float m_flXVelocity;
|
||||
float m_flYVelocity;
|
||||
|
||||
// The current position for the ship
|
||||
float m_flXPosition;
|
||||
float m_flYPosition;
|
||||
|
||||
// Is the ship exploding?
|
||||
bool m_bExploding;
|
||||
|
||||
// Is the ship disabled?
|
||||
bool m_bDisabled;
|
||||
|
||||
// Are the thrusters to be drawn?
|
||||
bool m_bForwardThrustersActive;
|
||||
bool m_bReverseThrustersActive;
|
||||
|
||||
// Photon beam positions and data
|
||||
ServerPhotonBeamUpdateData_t m_PhotonBeamData[MAX_PHOTON_BEAMS_PER_SHIP];
|
||||
};
|
||||
|
||||
|
||||
// This is the data that gets sent from the server to each client for each update
|
||||
struct ServerSpaceWarUpdateData_t
|
||||
{
|
||||
// What state the game is in
|
||||
EServerGameState m_eCurrentGameState;
|
||||
|
||||
// Who just won the game? -- only valid when m_eCurrentGameState == k_EGameWinner
|
||||
uint32 m_uPlayerWhoWonGame;
|
||||
|
||||
// which player slots are in use
|
||||
bool m_rgPlayersActive[MAX_PLAYERS_PER_SERVER];
|
||||
|
||||
// what are the scores for each player?
|
||||
uint32 m_rgPlayerScores[MAX_PLAYERS_PER_SERVER];
|
||||
|
||||
// array of ship data
|
||||
ServerShipUpdateData_t m_rgShipData[MAX_PLAYERS_PER_SERVER];
|
||||
|
||||
// array of players steamids for each slot, serialized to uint64
|
||||
uint64 m_rgPlayerSteamIDs[MAX_PLAYERS_PER_SERVER];
|
||||
};
|
||||
|
||||
|
||||
// This is the data that gets sent from each client to the server for each update
|
||||
struct ClientSpaceWarUpdateData_t
|
||||
{
|
||||
// Key's which are done
|
||||
bool m_bFirePressed;
|
||||
bool m_bTurnLeftPressed;
|
||||
bool m_bTurnRightPressed;
|
||||
bool m_bForwardThrustersPressed;
|
||||
bool m_bReverseThrustersPressed;
|
||||
|
||||
// Name of the player (needed server side to tell master server about)
|
||||
// bugbug jmccaskey - Really lame to send this every update instead of event driven...
|
||||
char m_rgchPlayerName[64];
|
||||
};
|
||||
|
||||
#endif // SPACEWAR_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,284 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Main class for the space war game client
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef SPACEWARCLIENT_H
|
||||
#define SPACEWARCLIENT_H
|
||||
|
||||
|
||||
#include "GameEngine.h"
|
||||
#include "SpaceWar.h"
|
||||
#include "Messages.h"
|
||||
#include "StarField.h"
|
||||
#include "Sun.h"
|
||||
#include "Ship.h"
|
||||
#include "steam\steam_api.h"
|
||||
#include "StatsAndAchievements.h"
|
||||
#include "BaseMenu.h"
|
||||
|
||||
// Forward class declaration
|
||||
class CMainMenu;
|
||||
class CQuitMenu;
|
||||
class CSpaceWarServer;
|
||||
class CServerBrowser;
|
||||
class CLobbyBrowser;
|
||||
class CLobby;
|
||||
|
||||
// Height of the HUD font
|
||||
#define HUD_FONT_HEIGHT 18
|
||||
|
||||
// Height for the instructions font
|
||||
#define INSTRUCTIONS_FONT_HEIGHT 24
|
||||
|
||||
// Enum for various client connection states
|
||||
enum EClientConnectionState
|
||||
{
|
||||
k_EClientNotConnected, // Initial state, not connected to a server
|
||||
k_EClientConnectedPendingAuthentication, // We've established communication with the server, but it hasn't authed us yet
|
||||
k_EClientConnectedAndAuthenticated, // Final phase, server has authed us, we are actually able to play on it
|
||||
};
|
||||
|
||||
// a game server as shown in the find servers menu
|
||||
struct ServerBrowserMenuData_t
|
||||
{
|
||||
EClientGameState m_eStateToTransitionTo;
|
||||
uint32 m_unIPAddress;
|
||||
int32 m_nConnectionPort;
|
||||
};
|
||||
|
||||
// a lobby as shown in the find lobbies menu
|
||||
struct LobbyBrowserMenuItem_t
|
||||
{
|
||||
CSteamID m_steamIDLobby;
|
||||
EClientGameState m_eStateToTransitionTo;
|
||||
};
|
||||
|
||||
// a user as shown in the lobby screen
|
||||
struct LobbyMenuItem_t
|
||||
{
|
||||
CSteamID m_steamIDUser; // the user who this is in the lobby
|
||||
bool m_bStartGame;
|
||||
bool m_bToggleReadyState;
|
||||
bool m_bLeaveLobby;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CSpaceWarClient
|
||||
{
|
||||
public:
|
||||
//Constructor
|
||||
CSpaceWarClient( CGameEngine *pEngine, CSteamID steamIDUser );
|
||||
|
||||
// Destructor
|
||||
~CSpaceWarClient();
|
||||
|
||||
// Run a game frame
|
||||
void RunFrame();
|
||||
|
||||
// Checks for any incoming network data, then dispatches it
|
||||
void ReceiveNetworkData();
|
||||
|
||||
// Connect to a server at a given IP address or game server steamID
|
||||
void InitiateServerConnection( uint32 unServerAddress, const int32 nPort );
|
||||
void InitiateServerConnection( CSteamID steamIDGameServer );
|
||||
|
||||
// Send data to a client at the given ship index
|
||||
bool BSendServerData( char *pData, uint32 nSizeOfData, bool bSendReliably );
|
||||
|
||||
// Menu callback handler (handles a bunch of menus that just change state with no extra data)
|
||||
void OnMenuSelection( EClientGameState eState ) { SetGameState( eState ); }
|
||||
|
||||
// Menu callback handler (handles server browser selections with extra data)
|
||||
void OnMenuSelection( ServerBrowserMenuData_t selection )
|
||||
{
|
||||
if ( selection.m_eStateToTransitionTo == k_EClientGameConnecting )
|
||||
{
|
||||
InitiateServerConnection( selection.m_unIPAddress, selection.m_nConnectionPort );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetGameState( selection.m_eStateToTransitionTo );
|
||||
}
|
||||
}
|
||||
|
||||
void OnMenuSelection( LobbyBrowserMenuItem_t selection )
|
||||
{
|
||||
// start joining the lobby
|
||||
if ( selection.m_eStateToTransitionTo == k_EClientJoiningLobby )
|
||||
{
|
||||
SteamMatchmaking()->JoinLobby( selection.m_steamIDLobby );
|
||||
|
||||
// the callback LobbyEnter_t will be received when we've joined
|
||||
}
|
||||
|
||||
SetGameState( selection.m_eStateToTransitionTo );
|
||||
}
|
||||
|
||||
void OnMenuSelection( LobbyMenuItem_t selection );
|
||||
|
||||
// Set game state
|
||||
void SetGameState( EClientGameState eState );
|
||||
EClientGameState GetGameState() { return m_eGameState; }
|
||||
|
||||
// set failure text
|
||||
void SetConnectionFailureText( const char *pchErrorText );
|
||||
|
||||
// Were we the winner?
|
||||
bool BLocalPlayerWonLastGame();
|
||||
|
||||
// Get the steam id for the local user at this client
|
||||
CSteamID GetLocalSteamID() { return m_SteamIDLocalUser; }
|
||||
|
||||
// Get the local players name
|
||||
const char* GetLocalPlayerName() { return SteamFriends()->GetFriendPersonaName( m_SteamIDLocalUser ); }
|
||||
|
||||
// Scale screen size to "real" size
|
||||
float PixelsToFeet( float flPixels );
|
||||
|
||||
// Get a Steam-supplied image
|
||||
HGAMETEXTURE GetSteamImageAsTexture( int iImage );
|
||||
|
||||
private:
|
||||
|
||||
// Receive a response from the server for a connection attempt
|
||||
void OnReceiveServerInfo( CSteamID steamIDGameServer, bool bVACSecure, const char *pchServerName );
|
||||
|
||||
// Receive a response from the server for a connection attempt
|
||||
void OnReceiveServerAuthenticationResponse( bool bSuccess, uint32 uPlayerPosition );
|
||||
|
||||
// Receive a state update from the server
|
||||
void OnReceiveServerUpdate( ServerSpaceWarUpdateData_t UpdateData );
|
||||
|
||||
// Handle the server exiting
|
||||
void OnReceiveServerExiting();
|
||||
|
||||
// Disconnects from a server (telling it so) if we are connected
|
||||
void DisconnectFromServer();
|
||||
|
||||
// game state changes
|
||||
void OnGameStateChanged( EClientGameState eGameStateNew );
|
||||
|
||||
// Draw the HUD text (should do this after drawing all the objects)
|
||||
void DrawHUDText();
|
||||
|
||||
// Draw instructions for how to play the game
|
||||
void DrawInstructions();
|
||||
|
||||
// Draw text telling the players who won (or that their was a draw)
|
||||
void DrawWinnerDrawOrWaitingText();
|
||||
|
||||
// Draw text telling the user that the connection attempt has failed
|
||||
void DrawConnectionFailureText();
|
||||
|
||||
// Draw connect to server text
|
||||
void DrawConnectToServerText();
|
||||
|
||||
// Draw text telling the user a connection attempt is in progress
|
||||
void DrawConnectionAttemptText();
|
||||
|
||||
// Server we are connected to
|
||||
CSpaceWarServer *m_pServer;
|
||||
|
||||
// SteamID for the local user on this client
|
||||
CSteamID m_SteamIDLocalUser;
|
||||
|
||||
// Our ship position in the array below
|
||||
uint32 m_uPlayerShipIndex;
|
||||
|
||||
// List of steamIDs for each player
|
||||
CSteamID m_rgSteamIDPlayers[MAX_PLAYERS_PER_SERVER];
|
||||
|
||||
// Ships for players, doubles as a way to check for open slots (pointer is NULL meaning open)
|
||||
CShip *m_rgpShips[MAX_PLAYERS_PER_SERVER];
|
||||
|
||||
// Player scores
|
||||
uint32 m_rguPlayerScores[MAX_PLAYERS_PER_SERVER];
|
||||
|
||||
// Who just won the game? Should be set if we go into the k_EGameWinner state
|
||||
uint32 m_uPlayerWhoWonGame;
|
||||
|
||||
// Current game state
|
||||
EClientGameState m_eGameState;
|
||||
|
||||
// true if we only just transitioned state
|
||||
bool m_bTransitionedGameState;
|
||||
|
||||
// Font handle for drawing the HUD text
|
||||
HGAMEFONT m_hHUDFont;
|
||||
|
||||
// Font handle for drawing the instructions text
|
||||
HGAMEFONT m_hInstructionsFont;
|
||||
|
||||
// Time the last state transition occurred (so we can count-down round restarts)
|
||||
uint64 m_ulStateTransitionTime;
|
||||
|
||||
// Time we started our last connection attempt
|
||||
uint64 m_ulLastConnectionAttemptRetryTime;
|
||||
|
||||
// Time we last got data from the server
|
||||
uint64 m_ulLastNetworkDataReceivedTime;
|
||||
|
||||
// Text to display if we are in an error state
|
||||
char m_rgchErrorText[256];
|
||||
|
||||
// Socket to use when communicating with servers
|
||||
SNetSocket_t m_hSocketClient;
|
||||
|
||||
// Server address data
|
||||
uint32 m_unServerIP;
|
||||
uint16 m_usServerPort;
|
||||
|
||||
// Track whether we are connected to a server (and what specific state that connection is in)
|
||||
EClientConnectionState m_eConnectedStatus;
|
||||
|
||||
// Star field instance
|
||||
CStarField *m_pStarField;
|
||||
|
||||
// Sun instance
|
||||
CSun *m_pSun;
|
||||
|
||||
// Main menu instance
|
||||
CMainMenu *m_pMainMenu;
|
||||
|
||||
// Pause menu instance
|
||||
CQuitMenu *m_pQuitMenu;
|
||||
|
||||
// pointer to game engine instance we are running under
|
||||
CGameEngine *m_pGameEngine;
|
||||
|
||||
// track which steam image indexes we have textures for, and what handle that texture has
|
||||
std::map<int, HGAMETEXTURE> m_MapSteamImagesToTextures;
|
||||
|
||||
CStatsAndAchievements *m_pStatsAndAchievements;
|
||||
|
||||
CServerBrowser *m_pServerBrowser;
|
||||
|
||||
// lobby handling
|
||||
bool m_bCreatingLobby;
|
||||
// the name of the lobby we're connected to
|
||||
CSteamID m_steamIDLobby;
|
||||
// callback for when we're creating a new lobby
|
||||
STEAM_CALLBACK( CSpaceWarClient, OnLobbyCreated, LobbyCreated_t, m_LobbyCreatedCallback );
|
||||
// callback for when we've joined a lobby
|
||||
STEAM_CALLBACK( CSpaceWarClient, OnLobbyEntered, LobbyEnter_t, m_LobbyEnteredCallback );
|
||||
// callback for when the lobby game server has started
|
||||
STEAM_CALLBACK( CSpaceWarClient, OnLobbyGameCreated, LobbyGameCreated_t, m_LobbyGameCreated );
|
||||
|
||||
// lobby browser menu
|
||||
CLobbyBrowser *m_pLobbyBrowser;
|
||||
|
||||
// local lobby display
|
||||
CLobby *m_pLobby;
|
||||
|
||||
// connection handler
|
||||
STEAM_CALLBACK( CSpaceWarClient, OnSocketStatusCallback, SocketStatusCallback_t, m_SocketStatusCallback );
|
||||
};
|
||||
|
||||
extern CSpaceWarClient *g_pSpaceWarClient;
|
||||
CSpaceWarClient *SpaceWarClient();
|
||||
|
||||
#endif // SPACEWARCLIENT_H
|
||||
@@ -0,0 +1,53 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: A SpaceWarEntity is just like a VectorEntity, except it knows how
|
||||
// to apply gravity from the SpaceWar Sun
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "SpaceWarEntity.h"
|
||||
#include "stdlib.h"
|
||||
#include <math.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CSpaceWarEntity::CSpaceWarEntity( CGameEngine *pGameEngine, uint32 uCollisionRadius, bool bAffectedByGravity )
|
||||
: CVectorEntity( pGameEngine, uCollisionRadius )
|
||||
{
|
||||
m_bAffectedByGravity = bAffectedByGravity;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: RunFrame
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSpaceWarEntity::RunFrame()
|
||||
{
|
||||
|
||||
if ( m_bAffectedByGravity )
|
||||
{
|
||||
float xAccel = GetXAcceleration();
|
||||
float yAccel = GetYAcceleration();
|
||||
|
||||
// Ships are also affected by the suns gravity, compute that here, sun is always at the center of the screen
|
||||
float xPosSun = (float)m_pGameEngine->GetViewportWidth()/2;
|
||||
float yPosSun = (float)m_pGameEngine->GetViewportHeight()/2;
|
||||
|
||||
float distanceToSun = (float)sqrt( pow( xPosSun - GetXPos(), 2 ) + pow( yPosSun - GetYPos(), 2 ) );
|
||||
float distancePower = (float)pow( distanceToSun, 2.0f ); // gravity power falls off exponentially
|
||||
float factor = min( 5200000.0f / distancePower, 150.0f ); // arbitrary value for power of gravity
|
||||
|
||||
float xDirection = (GetXPos() - xPosSun)/distanceToSun;
|
||||
float yDirection = (GetYPos() - yPosSun)/distanceToSun;
|
||||
|
||||
xAccel -= factor * xDirection;
|
||||
yAccel -= factor * yDirection;
|
||||
|
||||
// Set updated acceleration
|
||||
SetAcceleration( xAccel, yAccel );
|
||||
}
|
||||
|
||||
CVectorEntity::RunFrame();
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
//========= Copyright Š 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: A SpaceWarEntity is just like a VectorEntity, except it knows how
|
||||
// to apply gravity from the SpaceWar Sun
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef SPACEWARENTITY_H
|
||||
#define SPACEWARENTITY_H
|
||||
|
||||
#include "GameEngine.h"
|
||||
#include "VectorEntity.h"
|
||||
|
||||
class CSpaceWarEntity : public CVectorEntity
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
CSpaceWarEntity( CGameEngine *pGameEngine, uint32 uCollisionRadius, bool bAffectedByGravity );
|
||||
|
||||
// Destructor
|
||||
virtual ~CSpaceWarEntity() { return; }
|
||||
|
||||
// Run Frame
|
||||
void RunFrame();
|
||||
|
||||
private:
|
||||
bool m_bAffectedByGravity;
|
||||
};
|
||||
|
||||
#endif // SPACEWARENTITY_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,173 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Main class for the space war game server
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef SPACEWARSERVER_H
|
||||
#define SPACEWARSERVER_H
|
||||
|
||||
#include "GameEngine.h"
|
||||
#include "SpaceWar.h"
|
||||
#include "Ship.h"
|
||||
#include "Sun.h"
|
||||
|
||||
// Game server API code from Steam, lets us do authentication via Steam for who to allow to play,
|
||||
// also lets us get ourselves listed in the Steam master server so the server browser can find us
|
||||
#include "steam/steam_gameserver.h"
|
||||
|
||||
// Forward declaration
|
||||
class CSpaceWarClient;
|
||||
|
||||
struct ClientConnectionData_t
|
||||
{
|
||||
bool m_bActive; // Is this slot in use? Or is it available for new connections?
|
||||
|
||||
SNetSocket_t m_hSocket; // Socket to send data on to get to this client
|
||||
CSteamID m_SteamIDUser; // What is the steamid of the player?
|
||||
uint64 m_ulTickCountLastData; // What was the last time we got data from the player?
|
||||
};
|
||||
|
||||
class CSpaceWarServer
|
||||
{
|
||||
public:
|
||||
//Constructor
|
||||
CSpaceWarServer( CGameEngine *pEngine );
|
||||
|
||||
// Destructor
|
||||
~CSpaceWarServer();
|
||||
|
||||
// Run a game frame
|
||||
void RunFrame();
|
||||
|
||||
// Set game state
|
||||
void SetGameState( EServerGameState eState );
|
||||
|
||||
// Reset player scores (occurs when starting a new game)
|
||||
void ResetScores();
|
||||
|
||||
// Reset player positions (occurs in between rounds as well as at the start of a new game)
|
||||
void ResetPlayerShips();
|
||||
|
||||
// Checks various game objects for collisions and updates state appropriately if they have occurred
|
||||
void CheckForCollisions();
|
||||
|
||||
// data accessors
|
||||
bool IsConnectedToSteam() { return m_bConnectedToSteam; }
|
||||
uint32 GetIP();
|
||||
uint16 GetPort();
|
||||
CSteamID GetSteamID();
|
||||
|
||||
private:
|
||||
//
|
||||
// Various callback functions that Steam will call to let us know about events related to our
|
||||
// connection to the Steam servers for authentication purposes.
|
||||
//
|
||||
|
||||
// Tells us when we have successfully connected to Steam
|
||||
STEAM_GAMESERVER_CALLBACK( CSpaceWarServer, OnSteamServersConnected, SteamServersConnected_t, m_CallbackSteamServersConnected );
|
||||
|
||||
// Tells us when we have been logged out of Steam
|
||||
STEAM_GAMESERVER_CALLBACK( CSpaceWarServer, OnSteamServersDisconnected, SteamServersDisconnected_t, m_CallbackSteamServersDisconnected );
|
||||
|
||||
// Tells us that Steam has set our security policy (VAC on or off)
|
||||
STEAM_GAMESERVER_CALLBACK( CSpaceWarServer, OnPolicyResponse, GSPolicyResponse_t, m_CallbackPolicyResponse );
|
||||
|
||||
//
|
||||
// Various callback functions that Steam will call to let us know about whether we should
|
||||
// allow clients to play or we should kick/deny them.
|
||||
//
|
||||
|
||||
// Tells us a client has been authenticated and approved to play by Steam (passes auth, license check, VAC status, etc...)
|
||||
STEAM_GAMESERVER_CALLBACK( CSpaceWarServer, OnGSClientApprove, GSClientApprove_t, m_CallbackGSClientApprove );
|
||||
|
||||
// Tells us we should deny a player from accessing the server
|
||||
STEAM_GAMESERVER_CALLBACK( CSpaceWarServer, OnGSClientDeny, GSClientDeny_t, m_CallbackGSClientDeny );
|
||||
|
||||
// Tells us we should kick a player who was previously allowed to play (maybe they are no longer connected
|
||||
// to steam so their VAC status cannot be verified)
|
||||
STEAM_GAMESERVER_CALLBACK( CSpaceWarServer, OnGSClientKick, GSClientKick_t, m_CallbackGSClientKick );
|
||||
|
||||
// client connection state
|
||||
STEAM_GAMESERVER_CALLBACK( CSpaceWarServer, OnSocketStatusCallback, SocketStatusCallback_t, m_CallbackSocketStatus );
|
||||
|
||||
// Function to tell Steam about our servers details
|
||||
void SendUpdatedServerDetailsToSteam();
|
||||
|
||||
// Receive updates from client
|
||||
void OnReceiveClientUpdateData( uint32 uShipIndex, ClientSpaceWarUpdateData_t UpdateData );
|
||||
|
||||
// Checks for any incoming network data, then dispatches it
|
||||
void ReceiveNetworkData();
|
||||
|
||||
// Send data to a client at the given ship index
|
||||
bool BSendDataToClient( uint32 uShipIndex, char *pData, uint32 nSizeOfData );
|
||||
|
||||
// Send data to a client at the given pending index
|
||||
bool BSendDataToPendingClient( uint32 uShipIndex, char *pData, uint32 nSizeOfData );
|
||||
|
||||
// Send data to a client at a given address
|
||||
bool BSendDataToClientOnSocket( SNetSocket_t hSocket, char *pData, uint32 nSizeOfData );
|
||||
|
||||
// Connect a client, will send a success/failure response to the client
|
||||
void OnClientBeginAuthentication( SNetSocket_t hSocketClient, CSteamID steamIDUser, void *pToken, uint32 uTokenLen );
|
||||
|
||||
// Handles authentication completing for a client
|
||||
void OnAuthCompleted( bool bAuthSuccess, uint32 iPendingAuthIndex );
|
||||
|
||||
// Adds/initializes a new player ship at the given position
|
||||
void AddPlayerShip( uint32 uShipPosition );
|
||||
|
||||
// Removes a player from the server
|
||||
void RemovePlayerFromServer( uint32 uShipPosition );
|
||||
|
||||
// Send world update to all clients
|
||||
void SendUpdateDataToAllClients();
|
||||
|
||||
// Track whether our server is connected to Steam ok (meaning we can restrict who plays based on
|
||||
// ownership and VAC bans, etc...)
|
||||
bool m_bConnectedToSteam;
|
||||
|
||||
// Ships for players, doubles as a way to check for open slots (pointer is NULL meaning open)
|
||||
CShip *m_rgpShips[MAX_PLAYERS_PER_SERVER];
|
||||
|
||||
// Player scores
|
||||
uint32 m_rguPlayerScores[MAX_PLAYERS_PER_SERVER];
|
||||
|
||||
// server name
|
||||
std::string m_sServerName;
|
||||
|
||||
// Who just won the game? Should be set if we go into the k_EGameWinner state
|
||||
uint32 m_uPlayerWhoWonGame;
|
||||
|
||||
// Last time state changed
|
||||
uint64 m_ulStateTransitionTime;
|
||||
|
||||
// Last time we sent clients an update
|
||||
uint64 m_ulLastServerUpdateTick;
|
||||
|
||||
// Number of players currently connected, updated each frame
|
||||
uint32 m_uPlayerCount;
|
||||
|
||||
// Current game state
|
||||
EServerGameState m_eGameState;
|
||||
|
||||
// Sun instance
|
||||
CSun *m_pSun;
|
||||
|
||||
// Server socket (which has been bound to our known port)
|
||||
SNetSocket_t m_hSocketServer;
|
||||
|
||||
// pointer to game engine instance we are running under
|
||||
CGameEngine *m_pGameEngine;
|
||||
|
||||
// Vector to keep track of client connections
|
||||
ClientConnectionData_t m_rgClientData[MAX_PLAYERS_PER_SERVER];
|
||||
|
||||
// Vector to keep track of client connections which are pending auth
|
||||
ClientConnectionData_t m_rgPendingClientData[MAX_PLAYERS_PER_SERVER];
|
||||
};
|
||||
|
||||
|
||||
#endif // SPACEWARSERVER_H
|
||||
@@ -0,0 +1,50 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Class for rendering the starfield
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "StarField.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CStarField::CStarField( CGameEngine *pGameEngine )
|
||||
{
|
||||
m_pGameEngine = pGameEngine;
|
||||
|
||||
StarVertex_t StarVertex;
|
||||
int32 width = pGameEngine->GetViewportWidth();
|
||||
int32 height = pGameEngine->GetViewportHeight();
|
||||
|
||||
// Generate star field data
|
||||
for( int i=0; i < STARFIELD_STAR_COUNT; ++i )
|
||||
{
|
||||
int32 nRand = (rand()%(255-50))+50; //value between 50 and 255 for shades of gray
|
||||
StarVertex.color = D3DCOLOR_ARGB( 255, nRand, nRand, nRand );
|
||||
|
||||
StarVertex.x = (float)(rand()%width);
|
||||
StarVertex.y = (float)(rand()%height);
|
||||
|
||||
m_VecStars.push_back( StarVertex );
|
||||
|
||||
// bugbug jmccaskey - sometimes make "big stars" which are 4 points right next to each other?
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Render the star field
|
||||
//-----------------------------------------------------------------------------
|
||||
void CStarField::Render()
|
||||
{
|
||||
for( size_t i = 0; i < m_VecStars.size(); ++i )
|
||||
{
|
||||
m_pGameEngine->BDrawPoint( m_VecStars[i].x, m_VecStars[i].y, m_VecStars[i].color );
|
||||
}
|
||||
|
||||
m_pGameEngine->BFlushPointBuffer();
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Class for rendering the starfield
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef STARFIELD_H
|
||||
#define STARFIELD_H
|
||||
|
||||
#include <vector>
|
||||
#include "GameEngine.h"
|
||||
|
||||
#define STARFIELD_STAR_COUNT 600
|
||||
|
||||
struct StarVertex_t
|
||||
{
|
||||
float x, y;
|
||||
DWORD color;
|
||||
};
|
||||
|
||||
class CStarField
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
CStarField( CGameEngine *pGameEngine );
|
||||
|
||||
// Render the star field
|
||||
void Render();
|
||||
|
||||
private:
|
||||
|
||||
// Game engine instance we are running under
|
||||
CGameEngine *m_pGameEngine;
|
||||
|
||||
// Vector for starfield data
|
||||
std::vector<StarVertex_t> m_VecStars;
|
||||
};
|
||||
|
||||
#endif // STARFIELD_H
|
||||
@@ -0,0 +1,519 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Class for tracking stats and achievements
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "StatsAndAchievements.h"
|
||||
#include <math.h>
|
||||
#include "steam/isteamuserstats.h"
|
||||
#include "SpaceWarClient.h"
|
||||
|
||||
#define ACHDISP_FONT_HEIGHT 20
|
||||
#define ACHDISP_COLUMN_WIDTH 340
|
||||
#define ACHDISP_CENTER_SPACING 40
|
||||
#define ACHDISP_VERT_SPACING 10
|
||||
#define ACHDISP_IMG_SIZE 64
|
||||
#define ACHDISP_IMG_PAD 10
|
||||
|
||||
#define _ACH_ID( id, name ) { id, #id, name, "", 0, 0 }
|
||||
|
||||
Achievement_t g_rgAchievements[] =
|
||||
{
|
||||
_ACH_ID( ACH_WIN_ONE_GAME, "Winner" ),
|
||||
_ACH_ID( ACH_WIN_100_GAMES, "Champion" ),
|
||||
_ACH_ID( ACH_TRAVEL_FAR_ACCUM, "Interstellar" ),
|
||||
_ACH_ID( ACH_TRAVEL_FAR_SINGLE, "Orbiter" ),
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
#pragma warning( push )
|
||||
// warning C4355: 'this' : used in base member initializer list
|
||||
// This is OK because it's warning on setting up the Steam callbacks, they won't use this until after construction is done
|
||||
#pragma warning( disable : 4355 )
|
||||
CStatsAndAchievements::CStatsAndAchievements( CGameEngine *pGameEngine )
|
||||
:
|
||||
m_pGameEngine( pGameEngine ),
|
||||
m_pSteamUser( NULL ),
|
||||
m_pSteamUserStats( NULL ),
|
||||
m_GameID( SteamUtils()->GetAppID() ),
|
||||
m_CallbackUserStatsReceived( this, &CStatsAndAchievements::OnUserStatsReceived ),
|
||||
m_CallbackUserStatsStored( this, &CStatsAndAchievements::OnUserStatsStored ),
|
||||
m_CallbackAchievementStored( this, &CStatsAndAchievements::OnAchievementStored )
|
||||
{
|
||||
m_pSteamUser = SteamUser();
|
||||
m_pSteamUserStats = SteamUserStats();
|
||||
|
||||
m_bRequestedStats = false;
|
||||
m_bStatsValid = false;
|
||||
m_bStoreStats = false;
|
||||
|
||||
m_flGameFeetTraveled = 0;
|
||||
|
||||
m_nTotalGamesPlayed = 0;
|
||||
m_nTotalNumWins = 0;
|
||||
m_nTotalNumLosses = 0;
|
||||
m_flTotalFeetTraveled = 0;
|
||||
m_flMaxFeetTraveled = 0;
|
||||
|
||||
m_flAverageSpeed = 0;
|
||||
|
||||
m_hDisplayFont = pGameEngine->HCreateFont( ACHDISP_FONT_HEIGHT, FW_MEDIUM, false, "Arial" );
|
||||
if ( !m_hDisplayFont )
|
||||
OutputDebugString( "Stats font was not created properly, text won't draw\n" );
|
||||
}
|
||||
#pragma warning( pop )
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Run a frame for the CStatsAndAchievements
|
||||
//-----------------------------------------------------------------------------
|
||||
void CStatsAndAchievements::RunFrame()
|
||||
{
|
||||
if ( !m_bRequestedStats )
|
||||
{
|
||||
// Is Steam Loaded? if no, can't get stats, done
|
||||
if ( NULL == m_pSteamUserStats || NULL == m_pSteamUser )
|
||||
{
|
||||
m_bRequestedStats = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// If yes, are we connected to the back end? if no, wait
|
||||
if ( !m_pSteamUser->BLoggedOn() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If yes, request our stats
|
||||
bool bSuccess = m_pSteamUserStats->RequestCurrentStats( );
|
||||
|
||||
// This function should only return false if we weren't logged in, and we already checked that.
|
||||
// But handle it being false again anyway, just ask again later.
|
||||
m_bRequestedStats = bSuccess;
|
||||
}
|
||||
|
||||
if ( !m_bStatsValid )
|
||||
return;
|
||||
|
||||
// Get info from sources
|
||||
|
||||
// Evaluate achievements
|
||||
for ( int iAch = 0; iAch < ARRAYSIZE( g_rgAchievements ); ++iAch )
|
||||
{
|
||||
EvaluateAchievement( g_rgAchievements[iAch] );
|
||||
}
|
||||
|
||||
// Store stats
|
||||
StoreStatsIfNecessary();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Accumulate distance traveled
|
||||
//-----------------------------------------------------------------------------
|
||||
void CStatsAndAchievements::AddDistanceTraveled( float flDistance )
|
||||
{
|
||||
m_flGameFeetTraveled += SpaceWarClient()->PixelsToFeet( flDistance );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Game state has changed
|
||||
//-----------------------------------------------------------------------------
|
||||
void CStatsAndAchievements::OnGameStateChange( EClientGameState eNewState )
|
||||
{
|
||||
if ( !m_bStatsValid )
|
||||
return;
|
||||
|
||||
switch ( eNewState )
|
||||
{
|
||||
case k_EClientStatsAchievements:
|
||||
case k_EClientGameStartServer:
|
||||
case k_EClientGameMenu:
|
||||
case k_EClientGameQuitMenu:
|
||||
case k_EClientGameExiting:
|
||||
case k_EClientGameInstructions:
|
||||
case k_EClientGameConnecting:
|
||||
case k_EClientGameConnectionFailure:
|
||||
default:
|
||||
break;
|
||||
case k_EClientGameActive:
|
||||
// Reset per-game stats
|
||||
m_flGameFeetTraveled = 0;
|
||||
m_ulTickCountGameStart = m_pGameEngine->GetGameTickCount();
|
||||
break;
|
||||
case k_EClientFindInternetServers:
|
||||
break;
|
||||
case k_EClientGameWinner:
|
||||
if ( SpaceWarClient()->BLocalPlayerWonLastGame() )
|
||||
m_nTotalNumWins++;
|
||||
else
|
||||
m_nTotalNumLosses++;
|
||||
// fall through
|
||||
case k_EClientGameDraw:
|
||||
|
||||
// Tally games
|
||||
m_nTotalGamesPlayed++;
|
||||
|
||||
// Accumulate distances
|
||||
m_flTotalFeetTraveled += m_flGameFeetTraveled;
|
||||
|
||||
// New max?
|
||||
if ( m_flGameFeetTraveled > m_flMaxFeetTraveled )
|
||||
m_flMaxFeetTraveled = m_flGameFeetTraveled;
|
||||
|
||||
// Calc game duration
|
||||
m_flGameDurationSeconds = ( m_pGameEngine->GetGameTickCount() - m_ulTickCountGameStart ) / 1000.0;
|
||||
|
||||
// We want to update stats the next frame.
|
||||
m_bStoreStats = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: see if we should unlock this achievement
|
||||
//-----------------------------------------------------------------------------
|
||||
void CStatsAndAchievements::EvaluateAchievement( Achievement_t &achievement )
|
||||
{
|
||||
// Already have it?
|
||||
if ( achievement.m_bAchieved )
|
||||
return;
|
||||
|
||||
switch ( achievement.m_eAchievementID )
|
||||
{
|
||||
case ACH_WIN_ONE_GAME:
|
||||
if ( m_nTotalNumWins )
|
||||
{
|
||||
UnlockAchievement( achievement );
|
||||
}
|
||||
break;
|
||||
case ACH_WIN_100_GAMES:
|
||||
if ( m_nTotalNumWins >= 100 )
|
||||
{
|
||||
UnlockAchievement( achievement );
|
||||
}
|
||||
break;
|
||||
case ACH_TRAVEL_FAR_ACCUM:
|
||||
if ( m_flTotalFeetTraveled >= 5280 )
|
||||
{
|
||||
UnlockAchievement( achievement );
|
||||
}
|
||||
break;
|
||||
case ACH_TRAVEL_FAR_SINGLE:
|
||||
if ( m_flGameFeetTraveled > 500 )
|
||||
{
|
||||
UnlockAchievement( achievement );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Unlock this achievement
|
||||
//-----------------------------------------------------------------------------
|
||||
void CStatsAndAchievements::UnlockAchievement( Achievement_t &achievement )
|
||||
{
|
||||
achievement.m_bAchieved = true;
|
||||
|
||||
// the icon may change once it's unlocked
|
||||
achievement.m_iIconImage = 0;
|
||||
|
||||
// mark it down
|
||||
m_pSteamUserStats->SetAchievement( achievement.m_pchAchievementID );
|
||||
|
||||
// Store stats end of frame
|
||||
m_bStoreStats = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Store stats in the Steam database
|
||||
//-----------------------------------------------------------------------------
|
||||
void CStatsAndAchievements::StoreStatsIfNecessary()
|
||||
{
|
||||
if ( m_bStoreStats )
|
||||
{
|
||||
// already set any achievements in UnlockAchievement
|
||||
|
||||
// set stats
|
||||
m_pSteamUserStats->SetStat( "NumGames", m_nTotalGamesPlayed );
|
||||
m_pSteamUserStats->SetStat( "NumWins", m_nTotalNumWins );
|
||||
m_pSteamUserStats->SetStat( "NumLosses", m_nTotalNumLosses );
|
||||
m_pSteamUserStats->SetStat( "FeetTraveled", m_flTotalFeetTraveled );
|
||||
m_pSteamUserStats->SetStat( "MaxFeetTraveled", m_flMaxFeetTraveled );
|
||||
// Update average feet / second stat
|
||||
m_pSteamUserStats->UpdateAvgRateStat( "AverageSpeed", m_flGameFeetTraveled, m_flGameDurationSeconds );
|
||||
// The averaged result is calculated for us
|
||||
m_pSteamUserStats->GetStat( "AverageSpeed", &m_flAverageSpeed );
|
||||
|
||||
bool bSuccess = m_pSteamUserStats->StoreStats();
|
||||
// If this failed, we never sent anything to the server, try
|
||||
// again later.
|
||||
m_bStoreStats = !bSuccess;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: We have stats data from Steam. It is authoritative, so update
|
||||
// our data with those results now.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CStatsAndAchievements::OnUserStatsReceived( UserStatsReceived_t *pCallback )
|
||||
{
|
||||
if ( !m_pSteamUserStats )
|
||||
return;
|
||||
|
||||
// we may get callbacks for other games' stats arriving, ignore them
|
||||
if ( m_GameID.ToUint64() == pCallback->m_nGameID )
|
||||
{
|
||||
if ( k_EResultOK == pCallback->m_eResult )
|
||||
{
|
||||
OutputDebugString( "Received stats and achievements from Steam\n" );
|
||||
|
||||
m_bStatsValid = true;
|
||||
|
||||
// load achievements
|
||||
for ( int iAch = 0; iAch < ARRAYSIZE( g_rgAchievements ); ++iAch )
|
||||
{
|
||||
Achievement_t &ach = g_rgAchievements[iAch];
|
||||
m_pSteamUserStats->GetAchievement( ach.m_pchAchievementID, &ach.m_bAchieved );
|
||||
_snprintf( ach.m_rgchName, sizeof( ach.m_rgchName ), "%s",
|
||||
m_pSteamUserStats->GetAchievementDisplayAttribute( ach.m_pchAchievementID, "name" ) );
|
||||
_snprintf( ach.m_rgchDescription, sizeof( ach.m_rgchDescription ), "%s",
|
||||
m_pSteamUserStats->GetAchievementDisplayAttribute( ach.m_pchAchievementID, "desc" ) );
|
||||
}
|
||||
|
||||
// load stats
|
||||
m_pSteamUserStats->GetStat( "NumGames", &m_nTotalGamesPlayed );
|
||||
m_pSteamUserStats->GetStat( "NumWins", &m_nTotalNumWins );
|
||||
m_pSteamUserStats->GetStat( "NumLosses", &m_nTotalNumLosses );
|
||||
m_pSteamUserStats->GetStat( "FeetTraveled", &m_flTotalFeetTraveled );
|
||||
m_pSteamUserStats->GetStat( "MaxFeetTraveled", &m_flMaxFeetTraveled );
|
||||
m_pSteamUserStats->GetStat( "AverageSpeed", &m_flAverageSpeed );
|
||||
}
|
||||
else
|
||||
{
|
||||
char buffer[128];
|
||||
_snprintf( buffer, 128, "RequestStats - failed, %d\n", pCallback->m_eResult );
|
||||
OutputDebugString( buffer );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Our stats data was stored!
|
||||
//-----------------------------------------------------------------------------
|
||||
void CStatsAndAchievements::OnUserStatsStored( UserStatsStored_t *pCallback )
|
||||
{
|
||||
// we may get callbacks for other games' stats arriving, ignore them
|
||||
if ( m_GameID.ToUint64() == pCallback->m_nGameID )
|
||||
{
|
||||
if ( k_EResultOK == pCallback->m_eResult )
|
||||
{
|
||||
OutputDebugString( "StoreStats - success\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
char buffer[128];
|
||||
_snprintf( buffer, 128, "StoreStats - failed, %d\n", pCallback->m_eResult );
|
||||
OutputDebugString( buffer );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: An achievement was stored
|
||||
//-----------------------------------------------------------------------------
|
||||
void CStatsAndAchievements::OnAchievementStored( UserAchievementStored_t *pCallback )
|
||||
{
|
||||
// we may get callbacks for other games' stats arriving, ignore them
|
||||
if ( m_GameID.ToUint64() == pCallback->m_nGameID )
|
||||
{
|
||||
if ( 0 == pCallback->m_nMaxProgress )
|
||||
{
|
||||
char buffer[128];
|
||||
_snprintf( buffer, 128, "Achievement '%s' unlocked!", pCallback->m_rgchAchievementName );
|
||||
OutputDebugString( buffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
char buffer[128];
|
||||
_snprintf( buffer, 128, "Achievement '%s' progress callback, (%d,%d)\n",
|
||||
pCallback->m_rgchAchievementName, pCallback->m_nCurProgress, pCallback->m_nMaxProgress );
|
||||
OutputDebugString( buffer );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Display the user's stats and achievements
|
||||
//-----------------------------------------------------------------------------
|
||||
void CStatsAndAchievements::Render()
|
||||
{
|
||||
const int32 width = m_pGameEngine->GetViewportWidth();
|
||||
const int32 height = m_pGameEngine->GetViewportHeight();
|
||||
|
||||
const int32 pxColumn1Left = width / 2 - ACHDISP_COLUMN_WIDTH - ACHDISP_CENTER_SPACING / 2;
|
||||
const int32 pxColumn2Left = width / 2 + ACHDISP_CENTER_SPACING / 2;
|
||||
|
||||
RECT rect;
|
||||
|
||||
if ( !m_bStatsValid )
|
||||
{
|
||||
rect.top = 0;
|
||||
rect.bottom = m_pGameEngine->GetViewportHeight();
|
||||
rect.left = 0;
|
||||
rect.right = width;
|
||||
|
||||
char rgchBuffer[256];
|
||||
_snprintf( rgchBuffer, sizeof( rgchBuffer), "Unable to retrieve data from Steam\n" );
|
||||
m_pGameEngine->BDrawString( m_hDisplayFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), DT_CENTER|DT_VCENTER, rgchBuffer );
|
||||
|
||||
|
||||
rect.left = 0;
|
||||
rect.right = width;
|
||||
rect.top = LONG(m_pGameEngine->GetViewportHeight() * 0.7);
|
||||
rect.bottom = m_pGameEngine->GetViewportHeight();
|
||||
|
||||
_snprintf( rgchBuffer, sizeof( rgchBuffer ), "Press ESC to return to the Main Menu" );
|
||||
m_pGameEngine->BDrawString( m_hDisplayFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), DT_CENTER|DT_TOP, rgchBuffer );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// COLUMN 1
|
||||
// Achievements above the midline
|
||||
int32 pxVertOffset = height / 2 - 2 * ( ACHDISP_IMG_SIZE + ACHDISP_VERT_SPACING );
|
||||
rect.top = pxVertOffset;
|
||||
rect.bottom = rect.top + ACHDISP_IMG_SIZE;
|
||||
rect.left = pxColumn1Left;
|
||||
rect.right = rect.left + ACHDISP_COLUMN_WIDTH;
|
||||
pxVertOffset = rect.bottom + ACHDISP_VERT_SPACING;
|
||||
|
||||
DrawAchievementInfo( rect, g_rgAchievements[0] );
|
||||
|
||||
rect.top = pxVertOffset;
|
||||
rect.bottom = rect.top + ACHDISP_IMG_SIZE;
|
||||
pxVertOffset = rect.bottom + ACHDISP_VERT_SPACING;
|
||||
|
||||
DrawAchievementInfo( rect, g_rgAchievements[1] );
|
||||
|
||||
// Stats below the midline
|
||||
pxVertOffset = height / 2 + ACHDISP_VERT_SPACING;
|
||||
|
||||
rect.top = pxVertOffset;
|
||||
rect.bottom = rect.top + ACHDISP_FONT_HEIGHT;
|
||||
pxVertOffset = rect.bottom + ACHDISP_VERT_SPACING;
|
||||
|
||||
DrawStatInfo( rect, "Games Played", static_cast<float>( m_nTotalGamesPlayed ) );
|
||||
|
||||
rect.top = pxVertOffset;
|
||||
rect.bottom = rect.top + ACHDISP_FONT_HEIGHT;
|
||||
pxVertOffset = rect.bottom + ACHDISP_VERT_SPACING;
|
||||
|
||||
DrawStatInfo( rect, "Games Won", static_cast<float>( m_nTotalNumWins ) );
|
||||
|
||||
rect.top = pxVertOffset;
|
||||
rect.bottom = rect.top + ACHDISP_FONT_HEIGHT;
|
||||
pxVertOffset = rect.bottom + ACHDISP_VERT_SPACING;
|
||||
|
||||
DrawStatInfo( rect, "Games Lost", static_cast<float>( m_nTotalNumLosses ) );
|
||||
|
||||
// COLUMN 2
|
||||
// Achievements above the midline
|
||||
pxVertOffset = height / 2 - 2 * ( ACHDISP_IMG_SIZE + ACHDISP_VERT_SPACING );
|
||||
|
||||
rect.top = pxVertOffset;
|
||||
rect.bottom = rect.top + ACHDISP_IMG_SIZE;
|
||||
rect.left = pxColumn2Left;
|
||||
rect.right = rect.left + ACHDISP_COLUMN_WIDTH;
|
||||
pxVertOffset = rect.bottom + ACHDISP_VERT_SPACING;
|
||||
|
||||
DrawAchievementInfo( rect, g_rgAchievements[2] );
|
||||
|
||||
rect.top = pxVertOffset;
|
||||
rect.bottom = rect.top + ACHDISP_IMG_SIZE;
|
||||
pxVertOffset = rect.bottom + ACHDISP_VERT_SPACING;
|
||||
|
||||
DrawAchievementInfo( rect, g_rgAchievements[3] );
|
||||
|
||||
// Stats below the midline
|
||||
pxVertOffset = height / 2 + ACHDISP_VERT_SPACING;
|
||||
|
||||
rect.top = pxVertOffset;
|
||||
rect.bottom = rect.top + ACHDISP_FONT_HEIGHT;
|
||||
pxVertOffset = rect.bottom + ACHDISP_VERT_SPACING;
|
||||
|
||||
DrawStatInfo( rect, "Feet Traveled", m_flTotalFeetTraveled );
|
||||
|
||||
rect.top = pxVertOffset;
|
||||
rect.bottom = rect.top + ACHDISP_FONT_HEIGHT;
|
||||
pxVertOffset = rect.bottom + ACHDISP_VERT_SPACING;
|
||||
|
||||
DrawStatInfo( rect, "Max Feet Traveled", m_flMaxFeetTraveled );
|
||||
|
||||
rect.top = pxVertOffset;
|
||||
rect.bottom = rect.top + ACHDISP_FONT_HEIGHT;
|
||||
pxVertOffset = rect.bottom + ACHDISP_VERT_SPACING;
|
||||
|
||||
DrawStatInfo( rect, "Average Inches / Second", m_flAverageSpeed * 12.0f );
|
||||
|
||||
// Footer
|
||||
rect.left = 0;
|
||||
rect.right = width;
|
||||
rect.top = LONG(m_pGameEngine->GetViewportHeight() * 0.7);
|
||||
rect.bottom = m_pGameEngine->GetViewportHeight();
|
||||
|
||||
char rgchBuffer[256];
|
||||
_snprintf( rgchBuffer, sizeof( rgchBuffer ), "Press ESC to return to the Main Menu" );
|
||||
m_pGameEngine->BDrawString( m_hDisplayFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), DT_CENTER|DT_TOP, rgchBuffer );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void CStatsAndAchievements::DrawAchievementInfo( RECT &rect, Achievement_t &ach )
|
||||
{
|
||||
if ( ach.m_iIconImage == 0 )
|
||||
{
|
||||
ach.m_iIconImage = m_pSteamUserStats->GetAchievementIcon( ach.m_pchAchievementID );
|
||||
}
|
||||
|
||||
HGAMETEXTURE hTexture = SpaceWarClient()->GetSteamImageAsTexture( ach.m_iIconImage );
|
||||
|
||||
// don't modify the caller's rect, they may use it later to locate something else
|
||||
RECT rect2 = rect;
|
||||
|
||||
// could still be zero if the image isn't downloaded yet
|
||||
if (hTexture )
|
||||
{
|
||||
m_pGameEngine->BDrawTexturedQuad( (float)rect2.left, (float)rect2.top, (float)rect2.left+ACHDISP_IMG_SIZE, (float)rect2.bottom,
|
||||
0.0f, 0.0f, 1.0, 1.0, D3DCOLOR_ARGB( 255, 255, 255, 255 ), hTexture );
|
||||
|
||||
rect2.left += ACHDISP_IMG_SIZE + ACHDISP_IMG_PAD;
|
||||
}
|
||||
|
||||
// todo: divide up so can draw image
|
||||
char rgchBuffer[256];
|
||||
_snprintf( rgchBuffer, sizeof( rgchBuffer), "%s: %s\n%s",
|
||||
ach.m_rgchName,
|
||||
ach.m_bAchieved ? "Unlocked" : "Locked",
|
||||
ach.m_rgchDescription );
|
||||
|
||||
m_pGameEngine->BDrawString( m_hDisplayFont, rect2, D3DCOLOR_ARGB( 255, 25, 200, 25 ), DT_LEFT|DT_VCENTER, rgchBuffer );
|
||||
}
|
||||
|
||||
void CStatsAndAchievements::DrawStatInfo( RECT &rect, const char *pchName, float flValue )
|
||||
{
|
||||
// todo: divide up so can draw image
|
||||
char rgchBuffer[256];
|
||||
_snprintf( rgchBuffer, sizeof( rgchBuffer), "%s: %.1f", pchName, flValue );
|
||||
m_pGameEngine->BDrawString( m_hDisplayFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), DT_LEFT|DT_VCENTER, rgchBuffer );
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Class for tracking stats and achievements
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef STATS_AND_ACHIEVEMENTS_H
|
||||
#define STATS_AND_ACHIEVEMENTS_H
|
||||
|
||||
#include "SpaceWar.h"
|
||||
#include "GameEngine.h"
|
||||
#include "steam/isteamuserstats.h"
|
||||
|
||||
enum EAchievements
|
||||
{
|
||||
ACH_WIN_ONE_GAME = 0,
|
||||
ACH_WIN_100_GAMES = 1,
|
||||
ACH_HEAVY_FIRE = 2,
|
||||
ACH_TRAVEL_FAR_ACCUM = 3,
|
||||
ACH_TRAVEL_FAR_SINGLE = 4,
|
||||
};
|
||||
|
||||
struct Achievement_t
|
||||
{
|
||||
EAchievements m_eAchievementID;
|
||||
const char *m_pchAchievementID;
|
||||
char m_rgchName[128];
|
||||
char m_rgchDescription[256];
|
||||
bool m_bAchieved;
|
||||
int m_iIconImage;
|
||||
};
|
||||
|
||||
class ISteamUser;
|
||||
class CSpaceWarClient;
|
||||
|
||||
class CStatsAndAchievements
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
CStatsAndAchievements( CGameEngine *pGameEngine );
|
||||
|
||||
// Run a frame
|
||||
void RunFrame();
|
||||
|
||||
// Display the stats and achievements
|
||||
void Render();
|
||||
|
||||
// Game state changed
|
||||
void OnGameStateChange( EClientGameState eNewState );
|
||||
|
||||
// Accumulators
|
||||
void AddDistanceTraveled( float flDistance );
|
||||
|
||||
STEAM_CALLBACK( CStatsAndAchievements, OnUserStatsReceived, UserStatsReceived_t, m_CallbackUserStatsReceived );
|
||||
STEAM_CALLBACK( CStatsAndAchievements, OnUserStatsStored, UserStatsStored_t, m_CallbackUserStatsStored );
|
||||
STEAM_CALLBACK( CStatsAndAchievements, OnAchievementStored, UserAchievementStored_t, m_CallbackAchievementStored );
|
||||
|
||||
private:
|
||||
|
||||
// Determine if we get this achievement now
|
||||
void EvaluateAchievement( Achievement_t &achievement );
|
||||
void UnlockAchievement( Achievement_t &achievement );
|
||||
|
||||
// Store stats
|
||||
void StoreStatsIfNecessary();
|
||||
|
||||
// Render helpers
|
||||
void DrawAchievementInfo( RECT &rect, Achievement_t &ach );
|
||||
void DrawStatInfo( RECT &rect, const char *pchName, float flValue );
|
||||
|
||||
// our GameID
|
||||
CGameID m_GameID;
|
||||
|
||||
// Engine
|
||||
CGameEngine *m_pGameEngine;
|
||||
|
||||
// Steam User interface
|
||||
ISteamUser *m_pSteamUser;
|
||||
|
||||
// Steam UserStats interface
|
||||
ISteamUserStats *m_pSteamUserStats;
|
||||
|
||||
// Display font
|
||||
HGAMEFONT m_hDisplayFont;
|
||||
|
||||
// Did we get the stats from Steam?
|
||||
bool m_bRequestedStats;
|
||||
bool m_bStatsValid;
|
||||
|
||||
// Should we store stats this frame?
|
||||
bool m_bStoreStats;
|
||||
|
||||
// Current Stat details
|
||||
float m_flGameFeetTraveled;
|
||||
uint64 m_ulTickCountGameStart;
|
||||
double m_flGameDurationSeconds;
|
||||
|
||||
// Persisted Stat details
|
||||
int m_nTotalGamesPlayed;
|
||||
int m_nTotalNumWins;
|
||||
int m_nTotalNumLosses;
|
||||
float m_flTotalFeetTraveled;
|
||||
float m_flMaxFeetTraveled;
|
||||
float m_flAverageSpeed;
|
||||
};
|
||||
|
||||
#endif // STATS_AND_ACHIEVEMENTS_H
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual Studio 2005
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SteamworksExample", "SteamworksExample.vcproj", "{F9B80FD0-A31F-443F-9FFF-85813D209141}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{F9B80FD0-A31F-443F-9FFF-85813D209141}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{F9B80FD0-A31F-443F-9FFF-85813D209141}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{F9B80FD0-A31F-443F-9FFF-85813D209141}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{F9B80FD0-A31F-443F-9FFF-85813D209141}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,360 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="SteamworksExample"
|
||||
ProjectGUID="{F9B80FD0-A31F-443F-9FFF-85813D209141}"
|
||||
RootNamespace="SteamWorksExample"
|
||||
SccProvider="MSSCCI:Perforce SCM"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\$(ConfigurationName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="copy ..\redistributable_bin\steam_api.dll .\$(ConfigurationName)\steam_api.dll
"
|
||||
Outputs=".\$(ConfigurationName)\steam_api.dll"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\public;"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS"
|
||||
MinimalRebuild="true"
|
||||
ExceptionHandling="2"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="steam_api.lib"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="..\redistributable_bin;"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\$(ConfigurationName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="0"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="copy ..\redistributable_bin\steam_api.dll .\$(ConfigurationName)\steam_api.dll
"
|
||||
Outputs=".\$(ConfigurationName)\steam_api.dll"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="..\public;"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS"
|
||||
ExceptionHandling="2"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="steam_api.lib"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="..\redistributable_bin;"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Main.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.cpp"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="Engine"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\GameEngine.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\VectorEntity.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Game"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\BaseMenu.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Lobby.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\MainMenu.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\PhotonBeam.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\QuitMenu.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ServerBrowser.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Ship.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SpaceWarClient.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SpaceWarEntity.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SpaceWarServer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\StarField.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\StatsAndAchievements.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Sun.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\stdafx.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="Engine"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\GameEngine.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\VectorEntity.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Game"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\BaseMenu.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Lobby.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\MainMenu.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Messages.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\PhotonBeam.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\QuitMenu.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ServerBrowser.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ServerBrowserMenu.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Ship.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SpaceWar.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SpaceWarClient.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SpaceWarEntity.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SpaceWarServer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\StarField.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\StatsAndAchievements.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Sun.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -0,0 +1,42 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Class for rendering the sun
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Sun.h"
|
||||
#include <math.h>
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CSun::CSun( CGameEngine *pGameEngine ) : CSpaceWarEntity( pGameEngine, 2*SUN_VECTOR_SCALE_FACTOR, false )
|
||||
{
|
||||
float xcenter = (float)pGameEngine->GetViewportWidth()/2;
|
||||
float ycenter = (float)pGameEngine->GetViewportHeight()/2;
|
||||
float sqrtof2 = (float)sqrt( 2.0 );
|
||||
|
||||
DWORD dwColor = D3DCOLOR_ARGB( 255, 255, 255, 102 );
|
||||
|
||||
// Initialize our geometry
|
||||
AddLine( (2.0f*SUN_VECTOR_SCALE_FACTOR), 0.0f, (-2.0f*SUN_VECTOR_SCALE_FACTOR), 0.0f, dwColor );
|
||||
AddLine( 0.0f, (2.0f*SUN_VECTOR_SCALE_FACTOR), 0.0f, (-2.0f*SUN_VECTOR_SCALE_FACTOR), dwColor );
|
||||
AddLine( -1.0f*sqrtof2*SUN_VECTOR_SCALE_FACTOR, sqrtof2*SUN_VECTOR_SCALE_FACTOR, sqrtof2*SUN_VECTOR_SCALE_FACTOR, -1.0f*sqrtof2*SUN_VECTOR_SCALE_FACTOR, dwColor );
|
||||
AddLine( sqrtof2*SUN_VECTOR_SCALE_FACTOR, sqrtof2*SUN_VECTOR_SCALE_FACTOR, -1.0f*sqrtof2*SUN_VECTOR_SCALE_FACTOR, -1.0f*sqrtof2*SUN_VECTOR_SCALE_FACTOR, dwColor );
|
||||
|
||||
// Has to be after unlock since the base class will lock in this call
|
||||
SetPosition( xcenter, ycenter );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Run a frame for the sun
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSun::RunFrame()
|
||||
{
|
||||
// We want to rotate 90 degrees every 800ms (1.57 is 1/2pi, or 90 degrees in radians)
|
||||
SetRotationDeltaNextFrame( (PI_VALUE/2.0f) * (float)m_pGameEngine->GetGameTicksFrameDelta()/800.0f );
|
||||
CVectorEntity::RunFrame();
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Class for rendering the sun
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef SUN_H
|
||||
#define SUN_H
|
||||
|
||||
#include "GameEngine.h"
|
||||
#include "SpaceWarEntity.h"
|
||||
|
||||
#define SUN_VECTOR_SCALE_FACTOR 14
|
||||
|
||||
class CSun : public CSpaceWarEntity
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
CSun( CGameEngine *pGameEngine );
|
||||
|
||||
// Run a frame
|
||||
void RunFrame();
|
||||
|
||||
};
|
||||
|
||||
#endif // SUN_H
|
||||
@@ -0,0 +1,247 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Base class for representation objects in the game which are drawn as
|
||||
// vector art (ie, a series of lines)
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "VectorEntity.h"
|
||||
#include "stdlib.h"
|
||||
#include <math.h>
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CVectorEntity::CVectorEntity( CGameEngine *pGameEngine, uint32 uCollisionRadius )
|
||||
{
|
||||
m_uCollisionRadius = uCollisionRadius;
|
||||
m_pGameEngine = pGameEngine;
|
||||
m_flRotationDeltaNextFrame = 0.0;
|
||||
m_flAccumulatedRotation = 0.0;
|
||||
m_flXAccel = 0.0;
|
||||
m_flYAccel = 0.0;
|
||||
m_flXAccelLastFrame = 0.0;
|
||||
m_flYAccelLastFrame = 0.0;
|
||||
m_flXPos = 0.0;
|
||||
m_flYPos = 0.0;
|
||||
m_flXVelocity = 0.0;
|
||||
m_flYVelocity = 0.0;
|
||||
m_bDisableCollisions = false;
|
||||
m_flRotationDeltaLastFrame = 0.0;
|
||||
|
||||
// we should have at least one frame Run before
|
||||
// anyone asks for a delta, so this shouldn't cause
|
||||
// a large initial delta to our starting position, in theory
|
||||
m_flXPosLastFrame = 0;
|
||||
m_flYPosLastFrame = 0;
|
||||
|
||||
m_flMaximumVelocity = DEFAULT_MAXIMUM_VELOCITY;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CVectorEntity::~CVectorEntity()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Add a line to our geometry
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVectorEntity::AddLine( float xPos0, float yPos0, float xPos1, float yPos1, DWORD dwColor )
|
||||
{
|
||||
VectorEntityVertex_t vert;
|
||||
vert.x = xPos0;
|
||||
vert.y = yPos0;
|
||||
vert.color = dwColor;
|
||||
|
||||
m_VecVertexes.push_back( vert );
|
||||
|
||||
vert.x = xPos1;
|
||||
vert.y = yPos1;
|
||||
vert.color = dwColor;
|
||||
|
||||
m_VecVertexes.push_back( vert );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Set the current position for the object
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVectorEntity::SetPosition( float xPos, float yPos )
|
||||
{
|
||||
m_flXPos = xPos;
|
||||
m_flYPos = yPos;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Set the rotation to be applied next frame (in radians)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVectorEntity::SetRotationDeltaNextFrame( float flRotationInRadians )
|
||||
{
|
||||
m_flRotationDeltaNextFrame = flRotationInRadians;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Set the acceleration to be applied next frame
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVectorEntity::SetAcceleration( float flXAccel, float flYAccel )
|
||||
{
|
||||
m_flXAccel = flXAccel;
|
||||
m_flYAccel = flYAccel;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Run a frame for the vector entity (ie, compute rotation, position, etc...)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVectorEntity::RunFrame()
|
||||
{
|
||||
// Accumulate the rotation so we know our current rotation total at all times
|
||||
m_flAccumulatedRotation += m_flRotationDeltaNextFrame;
|
||||
m_flRotationDeltaLastFrame = m_flRotationDeltaNextFrame;
|
||||
m_flRotationDeltaNextFrame = 0.0f;
|
||||
|
||||
m_flXPosLastFrame = m_flXPos;
|
||||
m_flYPosLastFrame = m_flYPos;
|
||||
|
||||
// If the accumulated rotation is > 2pi (360) then wrap it (same for negative direction)
|
||||
// This prevents the value getting really large and losing precision
|
||||
int nInfiniteLoopProtector = 0;
|
||||
while ( m_flAccumulatedRotation >= 2.0f*PI_VALUE && ++nInfiniteLoopProtector < 100 )
|
||||
m_flAccumulatedRotation -= 2.0f*PI_VALUE;
|
||||
nInfiniteLoopProtector = 0;
|
||||
while ( m_flAccumulatedRotation <= -2.0f*PI_VALUE && ++nInfiniteLoopProtector < 100 )
|
||||
m_flAccumulatedRotation += 2.0f*PI_VALUE;
|
||||
|
||||
|
||||
// Update our acceleration, velocity, and finally position
|
||||
// Note: The min here is so we don't get massive acceleration if frames for some reason don't run for a bit
|
||||
float ulElapsedSeconds = min( (float)m_pGameEngine->GetGameTicksFrameDelta() / 1000.0f, 2 );
|
||||
m_flXVelocity += m_flXAccel * ulElapsedSeconds;
|
||||
m_flYVelocity += m_flYAccel * ulElapsedSeconds;
|
||||
|
||||
// Make sure velocity does not exceed maximum allowed
|
||||
if ( m_flXVelocity > 0 && m_flXVelocity > m_flMaximumVelocity )
|
||||
m_flXVelocity = m_flMaximumVelocity;
|
||||
else if ( m_flXVelocity < 0 && m_flYVelocity < -1.0f*m_flMaximumVelocity )
|
||||
m_flXVelocity = -1.0f * m_flMaximumVelocity;
|
||||
|
||||
if ( m_flYVelocity > 0 && m_flYVelocity > m_flMaximumVelocity )
|
||||
m_flYVelocity = m_flMaximumVelocity;
|
||||
else if ( m_flYVelocity < 0 && m_flYVelocity < -1.0f*m_flMaximumVelocity )
|
||||
m_flYVelocity = -1.0f * m_flMaximumVelocity;
|
||||
|
||||
m_flXPos += m_flXVelocity * ulElapsedSeconds;
|
||||
m_flYPos += m_flYVelocity * ulElapsedSeconds;
|
||||
|
||||
// Clear acceleration values, child classes should keep reseting it as appropriate each frame
|
||||
m_flXAccelLastFrame = m_flXAccel;
|
||||
m_flYAccelLastFrame = m_flYAccel;
|
||||
m_flXAccel = 0;
|
||||
m_flYAccel = 0;
|
||||
|
||||
// Check for wrapping around the screen
|
||||
float width = (float)m_pGameEngine->GetViewportWidth();
|
||||
float height = (float)m_pGameEngine->GetViewportHeight();
|
||||
|
||||
if ( m_flXPos > width )
|
||||
m_flXPos -= width;
|
||||
if ( m_flXPos < 0 )
|
||||
m_flXPos += width;
|
||||
|
||||
if ( m_flYPos > height )
|
||||
m_flYPos -= height;
|
||||
if ( m_flYPos < 0 )
|
||||
m_flYPos += height;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Render the entity
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVectorEntity::Render()
|
||||
{
|
||||
// Compute values which will be used for rotation below
|
||||
float flSinRotation = (float)sin(m_flAccumulatedRotation);
|
||||
float flCosRotation = (float)cos(m_flAccumulatedRotation);
|
||||
|
||||
// Iterate our vector of vertexes 2 at a time drawing lines
|
||||
for( size_t i=0; i < m_VecVertexes.size() - 1; ++i )
|
||||
{
|
||||
DWORD dwColor0, dwColor1;
|
||||
float xPos0, yPos0, xPos1, yPos1;
|
||||
float xPrime0, yPrime0, xPrime1, yPrime1;
|
||||
|
||||
// Grab the first point and apply rotation and translation
|
||||
xPos0 = m_VecVertexes[i].x;
|
||||
yPos0 = m_VecVertexes[i].y;
|
||||
dwColor0 = m_VecVertexes[i].color;
|
||||
|
||||
// Apply any needed rotation
|
||||
xPrime0 = flCosRotation*xPos0 - flSinRotation*yPos0;
|
||||
yPrime0 = flSinRotation*xPos0 + flCosRotation*yPos0;
|
||||
|
||||
// Apply translation to current position
|
||||
xPrime0 += m_flXPos;
|
||||
yPrime0 += m_flYPos;
|
||||
|
||||
// Next vertex, we use 2 per iteration
|
||||
++i;
|
||||
|
||||
// Grab the second point and apply rotation and translation
|
||||
xPos1 = m_VecVertexes[i].x;
|
||||
yPos1 = m_VecVertexes[i].y;
|
||||
dwColor1 = m_VecVertexes[i].color;
|
||||
|
||||
// Apply any needed rotation
|
||||
xPrime1 = flCosRotation*xPos1 - flSinRotation*yPos1;
|
||||
yPrime1 = flSinRotation*xPos1 + flCosRotation*yPos1;
|
||||
|
||||
// Apply translation to current position
|
||||
xPrime1 += m_flXPos;
|
||||
yPrime1 += m_flYPos;
|
||||
|
||||
// Have the game engine draw the actual line (it batches these operations)
|
||||
m_pGameEngine->BDrawLine( xPrime0, yPrime0, dwColor0, xPrime1, yPrime1, dwColor1 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Check if the entity is colliding with the other given entity
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVectorEntity::BCollidesWith ( CVectorEntity * pTarget )
|
||||
{
|
||||
|
||||
// Note: Yes, this is a lame way to do collision detection just using a set radius.
|
||||
// I don't care for the moment, just want it running!
|
||||
|
||||
if ( m_bDisableCollisions )
|
||||
return false;
|
||||
else if ( pTarget->BCollisionDetectionDisabled() )
|
||||
return false;
|
||||
|
||||
// Compute distance between the center of the two objects
|
||||
float distance = (float)sqrt( pow( m_flXPos - pTarget->GetXPos(), 2 ) + pow( m_flYPos - pTarget->GetYPos(), 2 ) );
|
||||
|
||||
if ( distance < m_uCollisionRadius + pTarget->GetCollisionRadius() )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Check if the entity is colliding with the other given entity
|
||||
//-----------------------------------------------------------------------------
|
||||
float CVectorEntity::GetDistanceTraveledLastFrame()
|
||||
{
|
||||
return (float)sqrt( pow( m_flXPos - m_flXPosLastFrame, 2 ) + pow( m_flYPos - m_flYPosLastFrame, 2 ) );
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: Base class for representation objects in the game which are drawn as
|
||||
// vector art (ie, a series of lines)
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VECTORENTITY_H
|
||||
#define VECTORENTITY_H
|
||||
|
||||
#include "GameEngine.h"
|
||||
#include <vector>
|
||||
|
||||
struct VectorEntityVertex_t
|
||||
{
|
||||
float x, y;
|
||||
DWORD color;
|
||||
};
|
||||
|
||||
#define DEFAULT_MAXIMUM_VELOCITY 350.0f
|
||||
|
||||
#define PI_VALUE 3.14159265f
|
||||
|
||||
class CVectorEntity
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
CVectorEntity( CGameEngine *pGameEngine, uint32 uCollisionRadius );
|
||||
|
||||
// Destructor
|
||||
virtual ~CVectorEntity();
|
||||
|
||||
// Run a frame
|
||||
virtual void RunFrame();
|
||||
|
||||
// Render the sun field
|
||||
virtual void Render();
|
||||
|
||||
// Check if the entity is colliding with another given entity
|
||||
bool BCollidesWith( CVectorEntity * pTarget );
|
||||
|
||||
// Get the rotation value that is to be applied next frame
|
||||
float GetRotationDeltaNextFrame() { return m_flRotationDeltaNextFrame; }
|
||||
|
||||
// Get the rotation value that was applied last frame
|
||||
float GetRotationDeltaLastFrame() { return m_flRotationDeltaLastFrame; }
|
||||
|
||||
// Get the cumulative rotation for this entity
|
||||
float GetAccumulatedRotation() { return m_flAccumulatedRotation; }
|
||||
|
||||
// Get the acceleration to be applied next frame
|
||||
float GetXAcceleration() { return m_flXAccel; }
|
||||
float GetYAcceleration() { return m_flYAccel; }
|
||||
|
||||
// Get the acceleration applied last frame
|
||||
float GetXAccelerationLastFrame() { return m_flXAccelLastFrame; }
|
||||
float GetYAccelerationLastFrame() { return m_flYAccelLastFrame; }
|
||||
|
||||
// Get the current velocity
|
||||
float GetXVelocity() { return m_flXVelocity; }
|
||||
float GetYVelocity() { return m_flYVelocity; }
|
||||
|
||||
// Get the current position of the object
|
||||
float GetXPos() { return m_flXPos; }
|
||||
float GetYPos() { return m_flYPos; }
|
||||
|
||||
// Get the distance traveled each frame
|
||||
float GetDistanceTraveledLastFrame();
|
||||
|
||||
protected:
|
||||
|
||||
// Add a line to the entity
|
||||
void AddLine( float xPos0, float yPos0, float xPos1, float yPos1, DWORD dwColor );
|
||||
|
||||
// Set the objects current position
|
||||
void SetPosition( float xPos, float yPos );
|
||||
|
||||
// Set the rotation to be applied next frame
|
||||
void SetRotationDeltaNextFrame( float flRotationInRadians );
|
||||
|
||||
// Set the acceleration to be applied next frame
|
||||
void SetAcceleration( float xAccel, float yAccel );
|
||||
|
||||
// Set the cumulative rotation for this entity (overriding any existing value)
|
||||
void SetAccumulatedRotation( float flRotation ) { m_flAccumulatedRotation = flRotation; }
|
||||
|
||||
// Set the velocity of the entity (normally you should just set acceleration and this will be computed)
|
||||
void SetVelocity ( float xVelocity, float yVelocity ) { m_flXVelocity = xVelocity; m_flYVelocity = yVelocity; }
|
||||
|
||||
// Reset velocity of the entity
|
||||
void ResetVelocity() { m_flXVelocity = 0; m_flYVelocity = 0; }
|
||||
|
||||
// Get the collision radius for the entity
|
||||
uint32 GetCollisionRadius() { return m_uCollisionRadius; }
|
||||
|
||||
// Enable/Disable collision detection for this entity
|
||||
void SetCollisionDetectionDisabled( bool bDisabled ) { m_bDisableCollisions = bDisabled; }
|
||||
|
||||
// Check whether collision detection has been disabled for the entity
|
||||
bool BCollisionDetectionDisabled() { return m_bDisableCollisions; }
|
||||
|
||||
// Set a maximum velocity other than the default
|
||||
void SetMaximumVelocity( float flMaximumVelocity ) { m_flMaximumVelocity = flMaximumVelocity; }
|
||||
|
||||
protected:
|
||||
// Game engine instance we are running under
|
||||
CGameEngine *m_pGameEngine;
|
||||
|
||||
private:
|
||||
// Vector of points (always built 2 at a time so it's actually lines)
|
||||
std::vector< VectorEntityVertex_t > m_VecVertexes;
|
||||
|
||||
// Previous position
|
||||
float m_flXPosLastFrame;
|
||||
float m_flYPosLastFrame;
|
||||
|
||||
// current position (position is at the center of the object)
|
||||
float m_flXPos;
|
||||
float m_flYPos;
|
||||
|
||||
// maximum velocity the object can have in either x/y
|
||||
float m_flMaximumVelocity;
|
||||
|
||||
// acceleration to be applied next frame
|
||||
float m_flXAccel;
|
||||
float m_flYAccel;
|
||||
|
||||
// acceleration applied last frame
|
||||
float m_flXAccelLastFrame;
|
||||
float m_flYAccelLastFrame;
|
||||
|
||||
// current velocity (affected by acceleration changes)
|
||||
float m_flXVelocity;
|
||||
float m_flYVelocity;
|
||||
|
||||
// rotation to apply this frame (in radians)
|
||||
float m_flRotationDeltaNextFrame;
|
||||
|
||||
// rotation which was applied last frame
|
||||
float m_flRotationDeltaLastFrame;
|
||||
|
||||
// total cumulative rotation that has been applied to this entity
|
||||
float m_flAccumulatedRotation;
|
||||
|
||||
// radius to use for collisions, this is applied from the center of the object out
|
||||
uint32 m_uCollisionRadius;
|
||||
|
||||
// bool to disable collision detection for this object
|
||||
bool m_bDisableCollisions;
|
||||
};
|
||||
|
||||
#endif // VECTORENTITY_H
|
||||
@@ -0,0 +1,18 @@
|
||||
//========= Copyright © 1996-2008 Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// SteamworksExample.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
#include <varargs.h>
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
||||
@@ -0,0 +1,62 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
// Modify the following defines if you have to target a platform prior to the ones specified below.
|
||||
// Refer to MSDN for the latest info on corresponding values for different platforms.
|
||||
#ifndef WINVER // Allow use of features specific to Windows 2k or later.
|
||||
#define WINVER 0x0500 // Change this to the appropriate value to target other versions of Windows.
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_WINNT // Allow use of features specific to Windows 2k or later.
|
||||
#define _WIN32_WINNT 0x0500 // Change this to the appropriate value to target other versions of Windows.
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
|
||||
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later.
|
||||
#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE.
|
||||
#endif
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
|
||||
|
||||
|
||||
#pragma comment( lib, "d3d9.lib" )
|
||||
#pragma comment( lib, "d3dx9.lib" )
|
||||
#pragma comment( lib, "dxguid.lib" )
|
||||
|
||||
// Windows Header Files:
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
// Winsock
|
||||
#include <winsock.h>
|
||||
#pragma comment(lib, "ws2_32.lib" )
|
||||
|
||||
// d3d header files
|
||||
#include "d3d9.h"
|
||||
#include "d3dx9.h"
|
||||
|
||||
typedef __int16 int16;
|
||||
typedef unsigned __int16 uint16;
|
||||
typedef __int32 int32;
|
||||
typedef unsigned __int32 uint32;
|
||||
typedef __int64 int64;
|
||||
typedef unsigned __int64 uint64;
|
||||
|
||||
// steam api header file
|
||||
#include "steam/steam_api.h"
|
||||
@@ -0,0 +1 @@
|
||||
480
|
||||
@@ -0,0 +1,26 @@
|
||||
#
|
||||
# *********** (C) Copyright 2008 Valve, L.L.C. All rights reserved. ***********
|
||||
#
|
||||
# Steam Client SDK configuration-override file
|
||||
#
|
||||
# This file is read by the Steam engine. This file should be located
|
||||
# in the same folder as steam.exe
|
||||
#
|
||||
|
||||
#
|
||||
# Use this value to specify the dot-notation IP address or hostname
|
||||
# of the Steam Content Server for development/test.
|
||||
# Use "127.0.0.1" to specify the primary NIC of current host.
|
||||
#
|
||||
# If you need to run multiple content servers, you can specify
|
||||
# multiple addresses on this line seperated by a space character
|
||||
# (e.g. "11.22.33.44 11.22.33.45")
|
||||
#
|
||||
SdkContentServerAdrs = "127.0.0.1"
|
||||
|
||||
#
|
||||
# Enable the manifest fingerprint check at cache startup.
|
||||
# In general, this should always be enabled if your client is connecting
|
||||
# to an SDK content server.
|
||||
#
|
||||
ManifestFingerprintCheck = enable
|
||||
Binary file not shown.
@@ -0,0 +1,40 @@
|
||||
//====== Copyright © 1996-2008, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose: interface to app data in Steam
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef ISTEAMAPPS_H
|
||||
#define ISTEAMAPPS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "steam/isteamapps.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: interface to app data
|
||||
//-----------------------------------------------------------------------------
|
||||
class ISteamApps
|
||||
{
|
||||
public:
|
||||
// returns 0 if the key does not exist
|
||||
// this may be true on first call, since the app data may not be cached locally yet
|
||||
// If you expect it to exists wait for the AppDataChanged_t after the first failure and ask again
|
||||
virtual int GetAppData( AppId_t nAppID, const char *pchKey, char *pchValue, int cchValueMax ) = 0;
|
||||
};
|
||||
|
||||
#define STEAMAPPS_INTERFACE_VERSION "STEAMAPPS_INTERFACE_VERSION001"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called when new information about an app has arrived
|
||||
//-----------------------------------------------------------------------------
|
||||
struct AppDataChanged_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamAppsCallbacks + 1 };
|
||||
uint32 m_nAppID; // appid that changed
|
||||
bool m_bBySteamUI; // change came from SteamUI
|
||||
bool m_bCDDBUpdate; // the cddb entry for this app changed
|
||||
};
|
||||
|
||||
#endif // ISTEAMAPPS_H
|
||||
@@ -0,0 +1,142 @@
|
||||
//====== Copyright © 1996-2008, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose: Main interface for loading and accessing Steamworks API's from the
|
||||
// Steam client.
|
||||
// For most uses, this code is wrapped inside of SteamAPI_Init()
|
||||
//=============================================================================
|
||||
|
||||
#ifndef ISTEAMCLIENT_H
|
||||
#define ISTEAMCLIENT_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "steamtypes.h"
|
||||
#include "steamclientpublic.h"
|
||||
|
||||
// handle to a communication pipe to the Steam client
|
||||
typedef int32 HSteamPipe;
|
||||
// handle to single instance of a steam user
|
||||
typedef int32 HSteamUser;
|
||||
// function prototype
|
||||
extern "C" typedef void (__cdecl *SteamAPIWarningMessageHook_t)(int, const char *);
|
||||
|
||||
// interface predec
|
||||
class ISteamUser;
|
||||
class ISteamGameServer;
|
||||
class ISteamFriends;
|
||||
class ISteamUtils;
|
||||
class ISteamMatchmaking;
|
||||
class ISteamContentServer;
|
||||
class ISteamMasterServerUpdater;
|
||||
class ISteamMatchmakingServers;
|
||||
class ISteamUserStats;
|
||||
class ISteamApps;
|
||||
class ISteamNetworking;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Interface to creating a new steam instance, or to
|
||||
// connect to an existing steam instance, whether it's in a
|
||||
// different process or is local.
|
||||
//
|
||||
// For most scenarios this is all handled automatically via SteamAPI_Init().
|
||||
// You'll only need to use these interfaces if you have a more complex versioning scheme,
|
||||
// where you want to get different versions of the same interface in different dll's in your project.
|
||||
//-----------------------------------------------------------------------------
|
||||
class ISteamClient
|
||||
{
|
||||
public:
|
||||
// Creates a communication pipe to the Steam client
|
||||
virtual HSteamPipe CreateSteamPipe() = 0;
|
||||
|
||||
// Releases a previously created communications pipe
|
||||
virtual bool BReleaseSteamPipe( HSteamPipe hSteamPipe ) = 0;
|
||||
|
||||
// connects to an existing global user, failing if none exists
|
||||
// used by the game to coordinate with the steamUI
|
||||
virtual HSteamUser ConnectToGlobalUser( HSteamPipe hSteamPipe ) = 0;
|
||||
|
||||
// used by game servers, create a steam user that won't be shared with anyone else
|
||||
virtual HSteamUser CreateLocalUser( HSteamPipe *phSteamPipe ) = 0;
|
||||
|
||||
// removes an allocated user
|
||||
virtual void ReleaseUser( HSteamPipe hSteamPipe, HSteamUser hUser ) = 0;
|
||||
|
||||
// retrieves the ISteamUser interface associated with the handle
|
||||
virtual ISteamUser *GetISteamUser( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0;
|
||||
|
||||
// retrieves the ISteamGameServer interface associated with the handle
|
||||
virtual ISteamGameServer *GetISteamGameServer( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0;
|
||||
|
||||
// set the local IP and Port to bind to
|
||||
// this must be set before CreateLocalUser()
|
||||
virtual void SetLocalIPBinding( uint32 unIP, uint16 usPort ) = 0;
|
||||
|
||||
// returns the ISteamFriends interface
|
||||
virtual ISteamFriends *GetISteamFriends( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0;
|
||||
|
||||
// returns the ISteamUtils interface
|
||||
virtual ISteamUtils *GetISteamUtils( HSteamPipe hSteamPipe, const char *pchVersion ) = 0;
|
||||
|
||||
// returns the ISteamMatchmaking interface
|
||||
virtual ISteamMatchmaking *GetISteamMatchmaking( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0;
|
||||
|
||||
// returns the ISteamContentServer interface
|
||||
virtual ISteamContentServer *GetISteamContentServer( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0;
|
||||
|
||||
// returns the ISteamMasterServerUpdater interface
|
||||
virtual ISteamMasterServerUpdater *GetISteamMasterServerUpdater( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0;
|
||||
|
||||
// returns the ISteamMatchmakingServers interface
|
||||
virtual ISteamMatchmakingServers *GetISteamMatchmakingServers( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0;
|
||||
|
||||
// returns the a generic interface
|
||||
virtual void *GetISteamGenericInterface( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0;
|
||||
|
||||
// this needs to be called every frame to process matchmaking results
|
||||
// redundant if you're already calling SteamAPI_RunCallbacks()
|
||||
virtual void RunFrame() = 0;
|
||||
|
||||
// returns the number of IPC calls made since the last time this function was called
|
||||
// Used for perf debugging so you can understand how many IPC calls your game makes per frame
|
||||
// Every IPC call is at minimum a thread context switch if not a process one so you want to rate
|
||||
// control how often you do them.
|
||||
virtual uint32 GetIPCCallCount() = 0;
|
||||
|
||||
// returns the ISteamUserStats interface
|
||||
virtual ISteamUserStats *GetISteamUserStats( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0;
|
||||
|
||||
// returns apps interface
|
||||
virtual ISteamApps *GetISteamApps( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0;
|
||||
|
||||
// networking
|
||||
virtual ISteamNetworking *GetISteamNetworking( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) = 0;
|
||||
|
||||
// API warning handling
|
||||
// 'int' is the severity; 0 for msg, 1 for warning
|
||||
// 'const char *' is the text of the message
|
||||
// callbacks will occur directly after the API function is called that generated the warning or message
|
||||
virtual void SetWarningMessageHook( SteamAPIWarningMessageHook_t pFunction ) = 0;
|
||||
};
|
||||
|
||||
#define STEAMCLIENT_INTERFACE_VERSION "SteamClient007"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Base values for callback identifiers, each callback must
|
||||
// have a unique ID.
|
||||
//-----------------------------------------------------------------------------
|
||||
enum { k_iSteamUserCallbacks = 100 };
|
||||
enum { k_iSteamGameServerCallbacks = 200 };
|
||||
enum { k_iSteamFriendsCallbacks = 300 };
|
||||
enum { k_iSteamBillingCallbacks = 400 };
|
||||
enum { k_iSteamMatchmakingCallbacks = 500 };
|
||||
enum { k_iSteamContentServerCallbacks = 600 };
|
||||
enum { k_iSteamUtilsCallbacks = 700 };
|
||||
enum { k_iClientFriendsCallbacks = 800 };
|
||||
enum { k_iClientUserCallbacks = 900 };
|
||||
enum { k_iSteamAppsCallbacks = 1000 };
|
||||
enum { k_iSteamUserStatsCallbacks = 1100 };
|
||||
enum { k_iSteamNetworkingCallbacks = 1200 };
|
||||
|
||||
|
||||
#endif // ISTEAMCLIENT_H
|
||||
@@ -0,0 +1,200 @@
|
||||
//====== Copyright © 1996-2008, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose: interface to both friends list data and general information about users
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef ISTEAMFRIENDS_H
|
||||
#define ISTEAMFRIENDS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "isteamclient.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: set of relationships to other users
|
||||
//-----------------------------------------------------------------------------
|
||||
enum EFriendRelationship
|
||||
{
|
||||
k_EFriendRelationshipNone = 0,
|
||||
k_EFriendRelationshipBlocked = 1,
|
||||
k_EFriendRelationshipRequestRecipient = 2,
|
||||
k_EFriendRelationshipFriend = 3,
|
||||
k_EFriendRelationshipRequestInitiator = 4,
|
||||
k_EFriendRelationshipIgnored = 5,
|
||||
k_EFriendRelationshipIgnoredFriend = 6,
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: list of states a friend can be in
|
||||
//-----------------------------------------------------------------------------
|
||||
enum EPersonaState
|
||||
{
|
||||
k_EPersonaStateOffline = 0, // friend is not currently logged on
|
||||
k_EPersonaStateOnline = 1, // friend is logged on
|
||||
k_EPersonaStateBusy = 2, // user is on, but busy
|
||||
k_EPersonaStateAway = 3, // auto-away feature
|
||||
k_EPersonaStateSnooze = 4, // auto-away for a long time
|
||||
k_EPersonaStateMax,
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: flags for enumerating friends list, or quickly checking a the relationship between users
|
||||
//-----------------------------------------------------------------------------
|
||||
enum k_EFriendFlags
|
||||
{
|
||||
k_EFriendFlagNone = 0x00,
|
||||
k_EFriendFlagBlocked = 0x01,
|
||||
k_EFriendFlagFriendshipRequested = 0x02,
|
||||
k_EFriendFlagImmediate = 0x04, // "regular" friend
|
||||
k_EFriendFlagClanMember = 0x08,
|
||||
k_EFriendFlagOnGameServer = 0x10,
|
||||
// k_EFriendFlagHasPlayedWith = 0x20, // not currently used
|
||||
// k_EFriendFlagFriendOfFriend = 0x40, // not currently used
|
||||
k_EFriendFlagRequestingFriendship = 0x80,
|
||||
k_EFriendFlagRequestingInfo = 0x100,
|
||||
k_EFriendFlagIgnored = 0x200,
|
||||
k_EFriendFlagIgnoredFriend = 0x400,
|
||||
k_EFriendFlagAll = 0xFFFF,
|
||||
};
|
||||
|
||||
// maximum number of characters in a users name
|
||||
enum { k_cchPersonaNameMax = 128 };
|
||||
|
||||
// size limit on chat room or member metadata
|
||||
const uint32 k_cubChatMetadataMax = 4096;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: interface to accessing information about individual users,
|
||||
// that can be a friend, in a group, on a game server or in a lobby with the local user
|
||||
//-----------------------------------------------------------------------------
|
||||
class ISteamFriends
|
||||
{
|
||||
public:
|
||||
// returns the local players name - guaranteed to not be NULL.
|
||||
// this is the same name as on the users community profile page
|
||||
// this is stored in UTF-8 format
|
||||
// like all the other interface functions that return a char *, it's important that this pointer is not saved
|
||||
// off; it will eventually be free'd or re-allocated
|
||||
virtual const char *GetPersonaName() = 0;
|
||||
|
||||
// sets the player name, stores it on the server and publishes the changes to all friends who are online
|
||||
virtual void SetPersonaName( const char *pchPersonaName ) = 0;
|
||||
|
||||
// gets the status of the current user
|
||||
virtual EPersonaState GetPersonaState() = 0;
|
||||
|
||||
// friend iteration
|
||||
// takes a set of k_EFriendFlags, and returns the number of users the client knows about who meet that criteria
|
||||
// then GetFriendByIndex() can then be used to return the id's of each of those users
|
||||
virtual int GetFriendCount( int iFriendFlags ) = 0;
|
||||
|
||||
// returns the steamID of a user
|
||||
// iFriend is a index of range [0, GetFriendCount())
|
||||
// iFriendsFlags must be the same value as used in GetFriendCount()
|
||||
// the returned CSteamID can then be used by all the functions below to access details about the user
|
||||
virtual CSteamID GetFriendByIndex( int iFriend, int iFriendFlags ) = 0;
|
||||
|
||||
// returns a relationship to a user
|
||||
virtual EFriendRelationship GetFriendRelationship( CSteamID steamIDFriend ) = 0;
|
||||
|
||||
// returns the current status of the specified user
|
||||
// this will only be known by the local user if steamIDFriend is in their friends list; on the same game server; in a chat room or lobby; or in a small group with the local user
|
||||
virtual EPersonaState GetFriendPersonaState( CSteamID steamIDFriend ) = 0;
|
||||
|
||||
// returns the name another user - guaranteed to not be NULL.
|
||||
// same rules as GetFriendPersonaState() apply as to whether or not the user knowns the name of the other user
|
||||
// note that on first joining a lobby, chat room or game server the local user will not known the name of the other users automatically; that information will arrive asyncronously
|
||||
//
|
||||
virtual const char *GetFriendPersonaName( CSteamID steamIDFriend ) = 0;
|
||||
|
||||
// gets the avatar of the current user, which is a handle to be used in IClientUtils::GetImageRGBA(), or 0 if none set
|
||||
virtual int GetFriendAvatar( CSteamID steamIDFriend ) = 0;
|
||||
// returns true if the friend is actually in a game
|
||||
virtual bool GetFriendGamePlayed( CSteamID steamIDFriend, uint64 *pulGameID, uint32 *punGameIP, uint16 *pusGamePort, uint16 *pusQueryPort ) = 0;
|
||||
// accesses old friends names - returns an empty string when their are no more items in the history
|
||||
virtual const char *GetFriendPersonaNameHistory( CSteamID steamIDFriend, int iPersonaName ) = 0;
|
||||
|
||||
// returns true if the specified user meets any of the criteria specified in iFriendFlags
|
||||
// iFriendFlags can be the union (binary or, |) of one or more k_EFriendFlags values
|
||||
virtual bool HasFriend( CSteamID steamIDFriend, int iFriendFlags ) = 0;
|
||||
|
||||
// clan (group) iteration and access functions
|
||||
virtual int GetClanCount() = 0;
|
||||
virtual CSteamID GetClanByIndex( int iClan ) = 0;
|
||||
virtual const char *GetClanName( CSteamID steamIDClan ) = 0;
|
||||
|
||||
// iterators for getting users in a chat room, lobby, game server or clan
|
||||
// note that large clans that cannot be iterated by the local user
|
||||
// steamIDSource can be the steamID of a group, game server, lobby or chat room
|
||||
virtual int GetFriendCountFromSource( CSteamID steamIDSource ) = 0;
|
||||
virtual CSteamID GetFriendFromSourceByIndex( CSteamID steamIDSource, int iFriend ) = 0;
|
||||
|
||||
// returns true if the local user can see that steamIDUser is a member or in steamIDSource
|
||||
virtual bool IsUserInSource( CSteamID steamIDUser, CSteamID steamIDSource ) = 0;
|
||||
|
||||
// User is in a game pressing the talk button (will suppress the microphone for all voice comms from the Steam friends UI)
|
||||
virtual void SetInGameVoiceSpeaking( CSteamID steamIDUser, bool bSpeaking ) = 0;
|
||||
|
||||
// activates the game overlay, with an optional dialog to open ("Friends", "Community", "Players", "Settings")
|
||||
virtual void ActivateGameOverlay( const char *pchDialog ) = 0;
|
||||
};
|
||||
|
||||
#define STEAMFRIENDS_INTERFACE_VERSION "SteamFriends003"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called when a friends' status changes
|
||||
//-----------------------------------------------------------------------------
|
||||
struct PersonaStateChange_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamFriendsCallbacks + 4 };
|
||||
|
||||
uint64 m_ulSteamID; // steamID of the friend who changed
|
||||
int m_nChangeFlags; // what's changed
|
||||
};
|
||||
|
||||
|
||||
// used in PersonaStateChange_t::m_nChangeFlags to describe what's changed about a user
|
||||
// these flags describe what the client has learned has changed recently, so on startup you'll see a name, avatar & relationship change for every friend
|
||||
enum EPersonaChange
|
||||
{
|
||||
k_EPersonaChangeName = 0x001,
|
||||
k_EPersonaChangeStatus = 0x002,
|
||||
k_EPersonaChangeComeOnline = 0x004,
|
||||
k_EPersonaChangeGoneOffline = 0x008,
|
||||
k_EPersonaChangeGamePlayed = 0x010,
|
||||
k_EPersonaChangeGameServer = 0x020,
|
||||
k_EPersonaChangeAvatar = 0x040,
|
||||
k_EPersonaChangeJoinedSource= 0x080,
|
||||
k_EPersonaChangeLeftSource = 0x100,
|
||||
k_EPersonaChangeRelationshipChanged = 0x200,
|
||||
k_EPersonaChangeNameFirstSet = 0x400,
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: posted when game overlay activates or deactivates
|
||||
// the game can use this to be pause or resume single player games
|
||||
//-----------------------------------------------------------------------------
|
||||
struct GameOverlayActivated_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamFriendsCallbacks + 31 };
|
||||
uint8 m_bActive; // true if it's just been activated, false otherwise
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called when the user tries to join a different game server from their friends list
|
||||
// game client should attempt to connect to specified server when this is received
|
||||
//-----------------------------------------------------------------------------
|
||||
struct GameServerChangeRequested_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamFriendsCallbacks + 32 };
|
||||
char m_rgchServer[64]; // server address ("127.0.0.1:27015", "tf2.valvesoftware.com")
|
||||
char m_rgchPassword[64]; // server password, if any
|
||||
};
|
||||
|
||||
#endif // ISTEAMFRIENDS_H
|
||||
@@ -0,0 +1,160 @@
|
||||
//====== Copyright © 1996-2008, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose: interface to steam for game servers
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef ISTEAMGAMESERVER_H
|
||||
#define ISTEAMGAMESERVER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "isteamclient.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Functions for authenticating users via Steam to play on a game server
|
||||
//-----------------------------------------------------------------------------
|
||||
class ISteamGameServer
|
||||
{
|
||||
public:
|
||||
// connection functions
|
||||
virtual void LogOn() = 0;
|
||||
virtual void LogOff() = 0;
|
||||
|
||||
// status functions
|
||||
virtual bool BLoggedOn() = 0;
|
||||
virtual bool BSecure() = 0;
|
||||
virtual CSteamID GetSteamID() = 0;
|
||||
|
||||
// Handles receiving a new connection from a Steam user. This call will ask the Steam
|
||||
// servers to validate the users identity, app ownership, and VAC status. If the Steam servers
|
||||
// are off-line, then it will validate the cached ticket itself which will validate app ownership
|
||||
// and identity. The AuthBlob here should be acquired on the game client using SteamUser()->InitiateGameConnection()
|
||||
// and must then be sent up to the game server for authentication.
|
||||
//
|
||||
// Return Value: true/false depending on whether the call succeeds. If the call succeeds then you
|
||||
// should expect a GSClientApprove_t or GSClientDeny_t callback which will tell you whether authentication
|
||||
// for the user has succeeded or failed.
|
||||
virtual void SendUserConnectAndAuthenticate( CSteamID steamIDUser, uint32 unIPClient, void *pvAuthBlob, uint32 cubAuthBlobSize ) = 0;
|
||||
|
||||
// Creates a fake user (ie, a bot) which will be listed as playing on the server, but skips validation.
|
||||
//
|
||||
// Return Value: Returns a SteamID for the user to be tracked with, you should call HandleUserDisconnect()
|
||||
// when this user leaves the server just like you would for a real user.
|
||||
virtual CSteamID CreateUnauthenticatedUserConnection() = 0;
|
||||
|
||||
// Should be called whenever a user leaves our game server, this lets Steam internally
|
||||
// track which users are currently on which servers for the purposes of preventing a single
|
||||
// account being logged into multiple servers, showing who is currently on a server, etc.
|
||||
virtual void SendUserDisconnect( CSteamID steamIDUser ) = 0;
|
||||
|
||||
// Update the data to be displayed in the server browser and matchmaking interfaces for a user
|
||||
// currently connected to the server. For regular users you must call this after you receive a
|
||||
// GSUserValidationSuccess callback.
|
||||
//
|
||||
// Return Value: true if successful, false if failure (ie, steamIDUser wasn't for an active player)
|
||||
virtual bool BUpdateUserData( CSteamID steamIDUser, const char *pchPlayerName, uint32 uScore ) = 0;
|
||||
|
||||
// You shouldn't need to call this as it is called internally by SteamGameServer_Init() and can only be called once.
|
||||
//
|
||||
// To update the data in this call which may change during the servers lifetime see UpdateServerStatus() below.
|
||||
//
|
||||
// Input: nGameAppID - The Steam assigned AppID for the game
|
||||
// unServerFlags - Any applicable combination of flags (see k_unServerFlag____ constants below)
|
||||
// unGameIP - The IP Address the server is listening for client connections on (might be INADDR_ANY)
|
||||
// unGamePort - The port which the server is listening for client connections on
|
||||
// unSpectatorPort - the port on which spectators can join to observe the server, 0 if spectating is not supported
|
||||
// usQueryPort - The port which the ISteamMasterServerUpdater API should use in order to listen for matchmaking requests
|
||||
// pchGameDir - A unique string identifier for your game
|
||||
// pchVersion - The current version of the server as a string like 1.0.0.0
|
||||
// bLanMode - Is this a LAN only server?
|
||||
//
|
||||
// bugbug jmccaskey - figure out how to remove this from the API and only expose via SteamGameServer_Init... or make this actually used,
|
||||
// and stop calling it in SteamGameServer_Init()?
|
||||
virtual bool BSetServerType( int32 nGameAppId, uint32 unServerFlags, uint32 unGameIP, uint16 unGamePort,
|
||||
uint16 unSpectatorPort, uint16 usQueryPort, const char *pchGameDir, const char *pchVersion, bool bLANMode ) = 0;
|
||||
|
||||
// Updates server status values which shows up in the server browser and matchmaking APIs
|
||||
virtual void UpdateServerStatus( int cPlayers, int cPlayersMax, int cBotPlayers,
|
||||
const char *pchServerName, const char *pSpectatorServerName,
|
||||
const char *pchMapName ) = 0;
|
||||
|
||||
// This can be called if spectator goes away or comes back (passing 0 means there is no spectator server now).
|
||||
virtual void UpdateSpectatorPort( uint16 unSpectatorPort ) = 0;
|
||||
|
||||
// Sets a string defining the "gametype" for this server, this is optional, but if it is set
|
||||
// it allows users to filter in the matchmaking/server-browser interfaces based on the value
|
||||
virtual void SetGameType( const char *pchGameType ) = 0;
|
||||
|
||||
// Ask if a user has a specific achievement for this game, will get a callback on reply
|
||||
virtual bool BGetUserAchievementStatus( CSteamID steamID, const char *pchAchievementName ) = 0;
|
||||
};
|
||||
|
||||
#define STEAMGAMESERVER_INTERFACE_VERSION "SteamGameServer004"
|
||||
|
||||
// game server flags
|
||||
const uint32 k_unServerFlagNone = 0x00;
|
||||
const uint32 k_unServerFlagActive = 0x01; // server has users playing
|
||||
const uint32 k_unServerFlagSecure = 0x02; // server wants to be secure
|
||||
const uint32 k_unServerFlagDedicated = 0x04; // server is dedicated
|
||||
const uint32 k_unServerFlagLinux = 0x08; // linux build
|
||||
const uint32 k_unServerFlagPassworded = 0x10; // password protected
|
||||
const uint32 k_unServerFlagPrivate = 0x20; // server shouldn't list on master server and
|
||||
// won't enforce authentication of users that connect to the server.
|
||||
// Useful when you run a server where the clients may not
|
||||
// be connected to the internet but you want them to play (i.e LANs)
|
||||
|
||||
|
||||
|
||||
// callbacks
|
||||
|
||||
|
||||
// client has been approved to connect to this game server
|
||||
struct GSClientApprove_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamGameServerCallbacks + 1 };
|
||||
CSteamID m_SteamID;
|
||||
};
|
||||
|
||||
|
||||
// client has been denied to connection to this game server
|
||||
struct GSClientDeny_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamGameServerCallbacks + 2 };
|
||||
CSteamID m_SteamID;
|
||||
EDenyReason m_eDenyReason;
|
||||
char m_rgchOptionalText[128];
|
||||
};
|
||||
|
||||
|
||||
// request the game server should kick the user
|
||||
struct GSClientKick_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamGameServerCallbacks + 3 };
|
||||
CSteamID m_SteamID;
|
||||
EDenyReason m_eDenyReason;
|
||||
};
|
||||
|
||||
// NOTE: callback values 4 and 5 are skipped because they are used for old deprecated callbacks,
|
||||
// do not reuse them here.
|
||||
|
||||
// client achievement info
|
||||
struct GSClientAchievementStatus_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamGameServerCallbacks + 6 };
|
||||
uint64 m_SteamID;
|
||||
char m_pchAchievement[128];
|
||||
bool m_bUnlocked;
|
||||
};
|
||||
|
||||
|
||||
// received when the game server requests to be displayed as secure (VAC protected)
|
||||
// m_bSecure is true if the game server should display itself as secure to users, false otherwise
|
||||
struct GSPolicyResponse_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamUserCallbacks + 15 };
|
||||
uint8 m_bSecure;
|
||||
};
|
||||
|
||||
#endif // ISTEAMGAMESERVER_H
|
||||
@@ -0,0 +1,103 @@
|
||||
//====== Copyright © 1996-2008, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose: interface to steam for retrieving list of game servers
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef ISTEAMMASTERSERVERUPDATER_H
|
||||
#define ISTEAMMASTERSERVERUPDATER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "isteamclient.h"
|
||||
|
||||
#define MASTERSERVERUPDATERPORT_USEGAMESOCKETSHARE ((uint16)-1)
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Game engines use this to tell the Steam master servers
|
||||
// about their games so their games can show up in the server browser.
|
||||
//-----------------------------------------------------------------------------
|
||||
class ISteamMasterServerUpdater
|
||||
{
|
||||
public:
|
||||
|
||||
// Call this as often as you like to tell the master server updater whether or not
|
||||
// you want it to be active (default: off).
|
||||
virtual void SetActive( bool bActive ) = 0;
|
||||
|
||||
// You usually don't need to modify this.
|
||||
// Pass -1 to use the default value for iHeartbeatInterval.
|
||||
// Some mods change this.
|
||||
virtual void SetHeartbeatInterval( int iHeartbeatInterval ) = 0;
|
||||
|
||||
|
||||
// These are in GameSocketShare mode, where instead of ISteamMasterServerUpdater creating its own
|
||||
// socket to talk to the master server on, it lets the game use its socket to forward messages
|
||||
// back and forth. This prevents us from requiring server ops to open up yet another port
|
||||
// in their firewalls.
|
||||
//
|
||||
// the IP address and port should be in host order, i.e 127.0.0.1 == 0x7f000001
|
||||
|
||||
// These are used when you've elected to multiplex the game server's UDP socket
|
||||
// rather than having the master server updater use its own sockets.
|
||||
//
|
||||
// Source games use this to simplify the job of the server admins, so they
|
||||
// don't have to open up more ports on their firewalls.
|
||||
|
||||
// Call this when a packet that starts with 0xFFFFFFFF comes in. That means
|
||||
// it's for us.
|
||||
virtual bool HandleIncomingPacket( const void *pData, int cbData, uint32 srcIP, uint16 srcPort ) = 0;
|
||||
|
||||
// AFTER calling HandleIncomingPacket for any packets that came in that frame, call this.
|
||||
// This gets a packet that the master server updater needs to send out on UDP.
|
||||
// It returns the length of the packet it wants to send, or 0 if there are no more packets to send.
|
||||
// Call this each frame until it returns 0.
|
||||
virtual int GetNextOutgoingPacket( void *pOut, int cbMaxOut, uint32 *pNetAdr, uint16 *pPort ) = 0;
|
||||
|
||||
|
||||
// Functions to set various fields that are used to respond to queries.
|
||||
|
||||
// Call this to set basic data that is passed to the server browser.
|
||||
virtual void SetBasicServerData(
|
||||
unsigned short nProtocolVersion,
|
||||
bool bDedicatedServer,
|
||||
const char *pRegionName,
|
||||
const char *pProductName,
|
||||
unsigned short nMaxReportedClients,
|
||||
bool bPasswordProtected,
|
||||
const char *pGameDescription ) = 0;
|
||||
|
||||
// Call this to clear the whole list of key/values that are sent in rules queries.
|
||||
virtual void ClearAllKeyValues() = 0;
|
||||
|
||||
// Call this to add/update a key/value pair.
|
||||
virtual void SetKeyValue( const char *pKey, const char *pValue ) = 0;
|
||||
|
||||
|
||||
// You can call this upon shutdown to clear out data stored for this game server and
|
||||
// to tell the master servers that this server is going away.
|
||||
virtual void NotifyShutdown() = 0;
|
||||
|
||||
// Returns true if the master server has requested a restart.
|
||||
// Only returns true once per request.
|
||||
virtual bool WasRestartRequested() = 0;
|
||||
|
||||
// Force it to request a heartbeat from the master servers.
|
||||
virtual void ForceHeartbeat() = 0;
|
||||
|
||||
// Manually edit and query the master server list.
|
||||
// It will provide name resolution and use the default master server port if none is provided.
|
||||
virtual bool AddMasterServer( const char *pServerAddress ) = 0;
|
||||
virtual bool RemoveMasterServer( const char *pServerAddress ) = 0;
|
||||
|
||||
virtual int GetNumMasterServers() = 0;
|
||||
|
||||
// Returns the # of bytes written to pOut.
|
||||
virtual int GetMasterServerAddress( int iServer, char *pOut, int outBufferSize ) = 0;
|
||||
};
|
||||
|
||||
#define STEAMMASTERSERVERUPDATER_INTERFACE_VERSION "SteamMasterServerUpdater001"
|
||||
|
||||
#endif // ISTEAMMASTERSERVERUPDATER_H
|
||||
@@ -0,0 +1,477 @@
|
||||
//====== Copyright © 1996-2008, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose: interface to steam managing game server/client match making
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef ISTEAMMATCHMAKING
|
||||
#define ISTEAMMATCHMAKING
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "steamtypes.h"
|
||||
#include "steamclientpublic.h"
|
||||
#include "matchmakingtypes.h"
|
||||
#include "isteamclient.h"
|
||||
#include "isteamfriends.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Functions for match making services for clients to get to favorites
|
||||
// and to operate on game lobbies.
|
||||
//-----------------------------------------------------------------------------
|
||||
class ISteamMatchmaking
|
||||
{
|
||||
public:
|
||||
// game server favorites storage
|
||||
// saves basic details about a multiplayer game server locally
|
||||
|
||||
// returns the number of favorites servers the user has stored
|
||||
virtual int GetFavoriteGameCount() = 0;
|
||||
|
||||
// returns the details of the game server
|
||||
// iGame is of range [0,GetFavoriteGameCount())
|
||||
// *pnIP, *pnConnPort are filled in the with IP:port of the game server
|
||||
// *punFlags specify whether the game server was stored as an explicit favorite or in the history of connections
|
||||
// *pRTime32LastPlayedOnServer is filled in the with the Unix time the favorite was added
|
||||
virtual bool GetFavoriteGame( int iGame, AppId_t *pnAppID, uint32 *pnIP, uint16 *pnConnPort, uint16 *pnQueryPort, uint32 *punFlags, uint32 *pRTime32LastPlayedOnServer ) = 0;
|
||||
|
||||
// adds the game server to the local list; updates the time played of the server if it already exists in the list
|
||||
virtual int AddFavoriteGame( AppId_t nAppID, uint32 nIP, uint16 nConnPort, uint16 nQueryPort, uint32 unFlags, uint32 rTime32LastPlayedOnServer ) =0;
|
||||
|
||||
// removes the game server from the local storage; returns true if one was removed
|
||||
virtual bool RemoveFavoriteGame( AppId_t nAppID, uint32 nIP, uint16 nConnPort, uint16 nQueryPort, uint32 unFlags ) = 0;
|
||||
|
||||
///////
|
||||
// Game lobby functions
|
||||
|
||||
// Get a list of relevant lobbies
|
||||
// this is an asynchronous request
|
||||
// results will be returned by LobbyMatchList_t callback, with the number of servers requested
|
||||
// if the user is not currently connected to Steam (i.e. SteamUser()->BLoggedOn() returns false) then
|
||||
// a LobbyMatchList_t callback will be posted immediately with no servers
|
||||
virtual void RequestLobbyList() = 0;
|
||||
|
||||
// returns the CSteamID of a lobby, as retrieved by a RequestLobbyList call
|
||||
// should only be called after a LobbyMatchList_t callback is received
|
||||
// iLobby is of the range [0, LobbyMatchList_t::m_nLobbiesMatching)
|
||||
// the returned CSteamID::IsValid() will be false if iLobby is out of range
|
||||
virtual CSteamID GetLobbyByIndex( int iLobby ) = 0;
|
||||
|
||||
// Create a lobby on the Steam servers.
|
||||
// If bPrivate is true, then the lobby will not be returned by any RequestLobbyList() call; the CSteamID
|
||||
// of the lobby will need to be communicated via game channels or via InviteUserToLobby()
|
||||
// this is an asynchronous request
|
||||
// results will be returned by LobbyCreated_t callback when the lobby has been created;
|
||||
// local user will the join the lobby, resulting in an additional LobbyEnter_t callback being sent
|
||||
// operations on the chat room can only proceed once the LobbyEnter_t has been received
|
||||
virtual void CreateLobby( bool bPrivate ) = 0;
|
||||
|
||||
// Joins an existing lobby
|
||||
// this is an asynchronous request
|
||||
// results will be returned by LobbyEnter_t callback when the lobby has been joined
|
||||
virtual void JoinLobby( CSteamID steamIDLobby ) = 0;
|
||||
|
||||
// Leave a lobby; this will take effect immediately on the client side
|
||||
// other users in the lobby will be notified by a LobbyChatUpdate_t callback
|
||||
virtual void LeaveLobby( CSteamID steamIDLobby ) = 0;
|
||||
|
||||
// Invite another user to the lobby
|
||||
// the target user will receive a LobbyInvite_t callback
|
||||
// will return true if the invite is successfully sent, whether or not the target responds
|
||||
// returns false if the local user is not connected to the Steam servers
|
||||
virtual bool InviteUserToLobby( CSteamID steamIDLobby, CSteamID steamIDInvitee ) = 0;
|
||||
|
||||
// Lobby iteration, for viewing details of users in a lobby
|
||||
// only accessible if the lobby user is a member of the specified lobby
|
||||
// persona information for other lobby members (name, avatar, etc.) will be asynchronously received
|
||||
// and accessible via ISteamFriends interface
|
||||
|
||||
// returns the number of users in the specified lobby
|
||||
virtual int GetNumLobbyMembers( CSteamID steamIDLobby ) = 0;
|
||||
// returns the CSteamID of a user in the lobby
|
||||
// iMember is of range [0,GetNumLobbyMembers())
|
||||
virtual CSteamID GetLobbyMemberByIndex( CSteamID steamIDLobby, int iMember ) = 0;
|
||||
|
||||
// Get data associated with this lobby
|
||||
// takes a simple key, and returns the string associated with it
|
||||
// "" will be returned if no value is set, or if steamIDLobby is invalid
|
||||
virtual const char *GetLobbyData( CSteamID steamIDLobby, const char *pchKey ) = 0;
|
||||
// Sets a key/value pair in the lobby metadata
|
||||
// each user in the lobby will be broadcast this new value, and any new users joining will receive any existing data
|
||||
// this can be used to set lobby names, map, etc.
|
||||
// to reset a key, just set it to ""
|
||||
// other users in the lobby will receive notification of the lobby data change via a LobbyDataUpdate_t callback
|
||||
virtual bool SetLobbyData( CSteamID steamIDLobby, const char *pchKey, const char *pchValue ) = 0;
|
||||
|
||||
// As above, but gets per-user data for someone in this lobby
|
||||
virtual const char *GetLobbyMemberData( CSteamID steamIDLobby, CSteamID steamIDUser, const char *pchKey ) = 0;
|
||||
// Sets per-user metadata (for the local user implicitly)
|
||||
virtual void SetLobbyMemberData( CSteamID steamIDLobby, const char *pchKey, const char *pchValue ) = 0;
|
||||
|
||||
// Broadcasts a chat message to the all the users in the lobby
|
||||
// users in the lobby (including the local user) will receive a LobbyChatMsg_t callback
|
||||
// returns true if the message is successfully sent
|
||||
virtual bool SendLobbyChatMsg( CSteamID steamIDLobby, const void *pvMsgBody, int cubMsgBody ) = 0;
|
||||
// Get a chat message as specified in a LobbyChatMsg_t callback
|
||||
// iChatID is the LobbyChatMsg_t::m_iChatID value in the callback
|
||||
// *pSteamIDUser is filled in with the CSteamID of the member
|
||||
// *pvData is filled in with the message itself
|
||||
// return value is the number of bytes written into the buffer
|
||||
virtual int GetLobbyChatEntry( CSteamID steamIDLobby, int iChatID, CSteamID *pSteamIDUser, void *pvData, int cubData, EChatEntryType *peChatEntryType ) = 0;
|
||||
|
||||
// Fetch metadata for a lobby you're not necessarily in right now
|
||||
// this will send down all the metadata associated with a lobby
|
||||
// this is an asynchronous call
|
||||
// returns false if the local user is not connected to the Steam servers
|
||||
virtual bool RequestLobbyData( CSteamID steamIDLobby ) = 0;
|
||||
|
||||
// sets the game server associated with the lobby
|
||||
// usually at this point, the users will leave the lobby and join the specified game server
|
||||
// either the IP/Port or the steamID of the game server has to be valid, depending on how you want the clients to be able to connect
|
||||
virtual void SetLobbyGameServer( CSteamID steamIDLobby, uint32 unGameServerIP, uint16 unGameServerPort, CSteamID steamIDGameServer ) = 0;
|
||||
|
||||
};
|
||||
#define STEAMMATCHMAKING_INTERFACE_VERSION "SteamMatchMaking002"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Callback interfaces for server list functions (see ISteamMatchmakingServers below)
|
||||
//
|
||||
// The idea here is that your game code implements objects that implement these
|
||||
// interfaces to receive callback notifications after calling asynchronous functions
|
||||
// inside the ISteamMatchmakingServers() interface below.
|
||||
//
|
||||
// This is different than normal Steam callback handling due to the potentially
|
||||
// large size of server lists.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Callback interface for receiving responses after a server list refresh
|
||||
// or an individual server update.
|
||||
//
|
||||
// Since you get these callbacks after requesting full list refreshes you will
|
||||
// usually implement this interface inside an object like CServerBrowser. If that
|
||||
// object is getting destructed you should use ISteamMatchMakingServers()->CancelQuery()
|
||||
// to cancel any in-progress queries so you don't get a callback into the destructed
|
||||
// object and crash.
|
||||
//-----------------------------------------------------------------------------
|
||||
class ISteamMatchmakingServerListResponse
|
||||
{
|
||||
public:
|
||||
// Server has responded ok with updated data
|
||||
virtual void ServerResponded( int iServer ) = 0;
|
||||
|
||||
// Server has failed to respond
|
||||
virtual void ServerFailedToRespond( int iServer ) = 0;
|
||||
|
||||
// A list refresh you had initiated is now 100% completed
|
||||
virtual void RefreshComplete( EMatchMakingServerResponse response ) = 0;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Callback interface for receiving responses after pinging an individual server
|
||||
//
|
||||
// These callbacks all occur in response to querying an individual server
|
||||
// via the ISteamMatchmakingServers()->PingServer() call below. If you are
|
||||
// destructing an object that implements this interface then you should call
|
||||
// ISteamMatchmakingServers()->CancelServerQuery() passing in the handle to the query
|
||||
// which is in progress. Failure to cancel in progress queries when destructing
|
||||
// a callback handler may result in a crash when a callback later occurs.
|
||||
//-----------------------------------------------------------------------------
|
||||
class ISteamMatchmakingPingResponse
|
||||
{
|
||||
public:
|
||||
// Server has responded successfully and has updated data
|
||||
virtual void ServerResponded( gameserveritem_t &server ) = 0;
|
||||
|
||||
// Server failed to respond to the ping request
|
||||
virtual void ServerFailedToRespond() = 0;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Callback interface for receiving responses after requesting details on
|
||||
// who is playing on a particular server.
|
||||
//
|
||||
// These callbacks all occur in response to querying an individual server
|
||||
// via the ISteamMatchmakingServers()->PlayerDetails() call below. If you are
|
||||
// destructing an object that implements this interface then you should call
|
||||
// ISteamMatchmakingServers()->CancelServerQuery() passing in the handle to the query
|
||||
// which is in progress. Failure to cancel in progress queries when destructing
|
||||
// a callback handler may result in a crash when a callback later occurs.
|
||||
//-----------------------------------------------------------------------------
|
||||
class ISteamMatchmakingPlayersResponse
|
||||
{
|
||||
public:
|
||||
// Got data on a new player on the server -- you'll get this callback once per player
|
||||
// on the server which you have requested player data on.
|
||||
virtual void AddPlayerToList( const char *pchName, int nScore, float flTimePlayed ) = 0;
|
||||
|
||||
// The server failed to respond to the request for player details
|
||||
virtual void PlayersFailedToRespond() = 0;
|
||||
|
||||
// The server has finished responding to the player details request
|
||||
// (ie, you won't get anymore AddPlayerToList callbacks)
|
||||
virtual void PlayersRefreshComplete() = 0;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Callback interface for receiving responses after requesting rules
|
||||
// details on a particular server.
|
||||
//
|
||||
// These callbacks all occur in response to querying an individual server
|
||||
// via the ISteamMatchmakingServers()->ServerRules() call below. If you are
|
||||
// destructing an object that implements this interface then you should call
|
||||
// ISteamMatchmakingServers()->CancelServerQuery() passing in the handle to the query
|
||||
// which is in progress. Failure to cancel in progress queries when destructing
|
||||
// a callback handler may result in a crash when a callback later occurs.
|
||||
//-----------------------------------------------------------------------------
|
||||
class ISteamMatchmakingRulesResponse
|
||||
{
|
||||
public:
|
||||
// Got data on a rule on the server -- you'll get one of these per rule defined on
|
||||
// the server you are querying
|
||||
virtual void RulesResponded( const char *pchRule, const char *pchValue ) = 0;
|
||||
|
||||
// The server failed to respond to the request for rule details
|
||||
virtual void RulesFailedToRespond() = 0;
|
||||
|
||||
// The server has finished responding to the rule details request
|
||||
// (ie, you won't get anymore RulesResponded callbacks)
|
||||
virtual void RulesRefreshComplete() = 0;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Typedef for handle type you will receive when querying details on an individual server.
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef int HServerQuery;
|
||||
const int HSERVERQUERY_INVALID = 0xffffffff;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Functions for match making services for clients to get to game lists and details
|
||||
//-----------------------------------------------------------------------------
|
||||
class ISteamMatchmakingServers
|
||||
{
|
||||
public:
|
||||
// Request a new list of servers of a particular type. These calls each correspond to one of the EMatchMakingType values.
|
||||
virtual void RequestInternetServerList( AppId_t iApp, MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0;
|
||||
virtual void RequestLANServerList( AppId_t iApp, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0;
|
||||
virtual void RequestFriendsServerList( AppId_t iApp, MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0;
|
||||
virtual void RequestFavoritesServerList( AppId_t iApp, MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0;
|
||||
virtual void RequestHistoryServerList( AppId_t iApp, MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0;
|
||||
virtual void RequestSpectatorServerList( AppId_t iApp, MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse ) = 0;
|
||||
|
||||
// Get details on a given server in the list, you can get the valid range of index
|
||||
// values by calling GetServerCount(). You will also receive index values in
|
||||
// ISteamMatchmakingServerListResponse::ServerResponded() callbacks
|
||||
virtual gameserveritem_t *GetServerDetails( EMatchMakingType eType, int iServer ) = 0;
|
||||
|
||||
// Cancel an request which is operation on the given list type. You should call this to cancel
|
||||
// any in-progress requests before destructing a callback object that may have been passed
|
||||
// to one of the above list request calls. Not doing so may result in a crash when a callback
|
||||
// occurs on the destructed object.
|
||||
virtual void CancelQuery( EMatchMakingType eType ) = 0;
|
||||
|
||||
// Ping every server in your list again but don't update the list of servers
|
||||
virtual void RefreshQuery( EMatchMakingType eType ) = 0;
|
||||
|
||||
// Returns true if the list is currently refreshing its server list
|
||||
virtual bool IsRefreshing( EMatchMakingType eType ) = 0;
|
||||
|
||||
// How many servers in the given list, GetServerDetails above takes 0... GetServerCount() - 1
|
||||
virtual int GetServerCount( EMatchMakingType eType ) = 0;
|
||||
|
||||
// Refresh a single server inside of a query (rather than all the servers )
|
||||
virtual void RefreshServer( EMatchMakingType eType, int iServer ) = 0;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Queries to individual servers directly via IP/Port
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Request updated ping time and other details from a single server
|
||||
virtual HServerQuery PingServer( uint32 unIP, uint16 usPort, ISteamMatchmakingPingResponse *pRequestServersResponse ) = 0;
|
||||
|
||||
// Request the list of players currently playing on a server
|
||||
virtual HServerQuery PlayerDetails( uint32 unIP, uint16 usPort, ISteamMatchmakingPlayersResponse *pRequestServersResponse ) = 0;
|
||||
|
||||
// Request the list of rules that the server is running (See ISteamMasterServerUpdater->SetKeyValue() to set the rules server side)
|
||||
virtual HServerQuery ServerRules( uint32 unIP, uint16 usPort, ISteamMatchmakingRulesResponse *pRequestServersResponse ) = 0;
|
||||
|
||||
// Cancel an outstanding Ping/Players/Rules query from above. You should call this to cancel
|
||||
// any in-progress requests before destructing a callback object that may have been passed
|
||||
// to one of the above calls to avoid crashing when callbacks occur.
|
||||
virtual void CancelServerQuery( HServerQuery hServerQuery ) = 0;
|
||||
};
|
||||
#define STEAMMATCHMAKINGSERVERS_INTERFACE_VERSION "SteamMatchMakingServers001"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Callbacks for ISteamMatchmaking which go through the regular Steam callback registration system
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// game server flags
|
||||
const uint32 k_unFavoriteFlagNone = 0x00;
|
||||
const uint32 k_unFavoriteFlagFavorite = 0x01; // this game favorite entry is for the favorites list
|
||||
const uint32 k_unFavoriteFlagHistory = 0x02; // this game favorite entry is for the history list
|
||||
|
||||
// callbacks
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: a server was added/removed from the favorites list, you should refresh now
|
||||
//-----------------------------------------------------------------------------
|
||||
struct FavoritesListChanged_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamMatchmakingCallbacks + 2 };
|
||||
uint32 m_nIP; // an IP of 0 means reload the whole list, any other value means just one server
|
||||
uint32 m_nQueryPort;
|
||||
uint32 m_nConnPort;
|
||||
uint32 m_nAppID;
|
||||
uint32 m_nFlags;
|
||||
bool m_bAdd; // true if this is adding the entry, otherwise it is a remove
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Someone has invited you to join a Lobby
|
||||
//-----------------------------------------------------------------------------
|
||||
struct LobbyInvite_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamMatchmakingCallbacks + 3 };
|
||||
|
||||
uint64 m_ulSteamIDUser; // Steam ID of the person making the invite
|
||||
uint64 m_ulSteamIDLobby; // Steam ID of the Lobby
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sent on entering a Lobby
|
||||
// m_EChatRoomEnterResponse will be set to k_EChatRoomEnterResponseSuccess on success,
|
||||
// or a higher value on failure (see enum EChatRoomEnterResponse)
|
||||
//-----------------------------------------------------------------------------
|
||||
struct LobbyEnter_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamMatchmakingCallbacks + 4 };
|
||||
|
||||
uint64 m_ulSteamIDLobby; // SteamID of the Lobby you have entered
|
||||
uint32 m_rgfChatPermissions; // Permissions of the current user
|
||||
bool m_bLocked; // If true, then only invited users may join
|
||||
uint32 m_EChatRoomEnterResponse; // EChatRoomEnterResponse
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: The lobby metadata has changed
|
||||
// if m_ulSteamIDMember is the steamID of a lobby member, use GetLobbyMemberData() to access per-user details
|
||||
// if m_ulSteamIDMember == m_ulSteamIDLobby, use GetLobbyData() to access lobby metadata
|
||||
//-----------------------------------------------------------------------------
|
||||
struct LobbyDataUpdate_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamMatchmakingCallbacks + 5 };
|
||||
|
||||
uint64 m_ulSteamIDLobby; // steamID of the Lobby
|
||||
uint64 m_ulSteamIDMember; // steamID of the member whose data changed, or the room itself
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: The lobby chat room state has changed
|
||||
// this is usually sent when a user has joined or left the lobby
|
||||
//-----------------------------------------------------------------------------
|
||||
struct LobbyChatUpdate_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamMatchmakingCallbacks + 6 };
|
||||
|
||||
uint64 m_ulSteamIDLobby; // Lobby ID
|
||||
uint64 m_ulSteamIDUserChanged; // user who's status in the lobby just changed - can be recipient
|
||||
uint64 m_ulSteamIDMakingChange; // Chat member who made the change (different from SteamIDUserChange if kicking, muting, etc.)
|
||||
// for example, if one user kicks another from the lobby, this will be set to the id of the user who initiated the kick
|
||||
uint32 m_rgfChatMemberStateChange; // bitfield of EChatMemberStateChange values
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: A chat message for this lobby has been sent
|
||||
// use GetLobbyChatEntry( m_iChatID ) to retrieve the contents of this message
|
||||
//-----------------------------------------------------------------------------
|
||||
struct LobbyChatMsg_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamMatchmakingCallbacks + 7 };
|
||||
|
||||
uint64 m_ulSteamIDLobby; // the lobby id this is in
|
||||
uint64 m_ulSteamIDUser; // steamID of the user who has sent this message
|
||||
uint8 m_eChatEntryType; // type of message
|
||||
uint32 m_iChatID; // index of the chat entry to lookup
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: A game created a game for all the members of the lobby to join,
|
||||
// as triggered by a SetLobbyGameServer()
|
||||
// it's up to the individual clients to take action on this; the usual
|
||||
// game behavior is to leave the lobby and connect to the specified game server
|
||||
//-----------------------------------------------------------------------------
|
||||
struct LobbyGameCreated_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamMatchmakingCallbacks + 9 };
|
||||
|
||||
uint64 m_ulSteamIDLobby; // the lobby we were in
|
||||
uint64 m_ulSteamIDGameServer; // the new game server that has been created or found for the lobby members
|
||||
uint32 m_unIP; // IP & Port of the game server (if any)
|
||||
uint16 m_usPort;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Number of matching lobbies found
|
||||
// iterate the returned lobbies with GetLobbyByIndex(), from values 0 to m_nLobbiesMatching-1
|
||||
//-----------------------------------------------------------------------------
|
||||
struct LobbyMatchList_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamMatchmakingCallbacks + 10 };
|
||||
uint32 m_nLobbiesMatching; // Number of lobbies that matched search criteria and we have SteamIDs for
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called when the lobby is being forcefully closed
|
||||
// lobby details functions will no longer be updated
|
||||
//-----------------------------------------------------------------------------
|
||||
struct LobbyClosing_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamMatchmakingCallbacks + 11 };
|
||||
uint64 m_ulSteamIDLobby; // Lobby
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called when the local user has been kicked from the lobby
|
||||
// lobby details functions will no longer be updated
|
||||
//-----------------------------------------------------------------------------
|
||||
struct LobbyKicked_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamMatchmakingCallbacks + 12 };
|
||||
uint64 m_ulSteamIDLobby; // Lobby
|
||||
uint64 m_ulSteamIDAdmin; // User who kicked you
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Result of our request to create a Lobby
|
||||
// m_eResult == k_EResultOK on success
|
||||
// at this point, the local user may not have finishing joining this lobby;
|
||||
// game code should wait until the subsequent LobbyEnter_t callback is received
|
||||
//-----------------------------------------------------------------------------
|
||||
struct LobbyCreated_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamMatchmakingCallbacks + 13 };
|
||||
EResult m_eResult; // Result
|
||||
uint64 m_ulSteamIDLobby; // chat room, zero if failed
|
||||
};
|
||||
|
||||
#endif // ISTEAMMATCHMAKING
|
||||
@@ -0,0 +1,135 @@
|
||||
//====== Copyright © 1996-2008, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose: interface to steam managing network connections between game clients & servers
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef ISTEAMNETWORKING
|
||||
#define ISTEAMNETWORKING
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "steamtypes.h"
|
||||
#include "steamclientpublic.h"
|
||||
|
||||
// handle to a socket
|
||||
typedef uint32 SNetSocket_t;
|
||||
typedef uint32 SNetListenSocket_t;
|
||||
|
||||
|
||||
// connection progress indicators
|
||||
enum ESNetSocketState
|
||||
{
|
||||
k_ESNetSocketStateInvalid = 0,
|
||||
|
||||
// communication is valid
|
||||
k_ESNetSocketStateConnected = 1,
|
||||
|
||||
// states while establishing a connection
|
||||
k_ESNetSocketStateInitiated = 10, // the connection state machine has started
|
||||
|
||||
// p2p connections
|
||||
k_ESNetSocketStateLocalCandidatesFound = 11, // we've found our local IP info
|
||||
k_ESNetSocketStateReceivedRemoteCandidates = 12,// we've received information from the remote machine, via the Steam back-end, about their IP info
|
||||
|
||||
// direct connections
|
||||
k_ESNetSocketStateChallengeHandshake = 15, // we've received a challenge packet from the server
|
||||
|
||||
// failure states
|
||||
k_ESNetSocketStateDisconnecting = 21, // the API shut it down, and we're in the process of telling the other end
|
||||
k_ESNetSocketStateLocalDisconnect = 22, // the API shut it down, and we've completed shutdown
|
||||
k_ESNetSocketStateTimeoutDuringConnect = 23, // we timed out while trying to creating the connection
|
||||
k_ESNetSocketStateRemoteEndDisconnected = 24, // the remote end has disconnected from us
|
||||
k_ESNetSocketStateConnectionBroken = 25, // connection has been broken; either the other end has disappeared or our local network connection has broke
|
||||
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Functions for making connections and sending data between clients,
|
||||
// traversing NAT's where possible
|
||||
//-----------------------------------------------------------------------------
|
||||
class ISteamNetworking
|
||||
{
|
||||
public:
|
||||
// creates a socket and listens others to connect
|
||||
// will trigger a SocketStatusCallback_t callback on another client connecting
|
||||
// nVirtualP2PPort is the unique ID that the client will connect to, in case you have multiple ports
|
||||
// this can usually just be 0 unless you want multiple sets of connections
|
||||
// unIP is the local IP address to bind to
|
||||
// pass in 0 if you just want the default local IP
|
||||
// unPort is the port to use
|
||||
// pass in 0 if you don't want users to be able to connect via IP/Port, but expect to be always peer-to-peer connections only
|
||||
virtual SNetListenSocket_t CreateListenSocket( int nVirtualP2PPort, uint32 nIP, uint16 nPort ) = 0;
|
||||
|
||||
// creates a socket and begin connection to a remote destination
|
||||
// can connect via a known steamID (client or game server), or directly to an IP
|
||||
// on success will trigger a SocketConnectCallback_t callback
|
||||
// on failure or timeout will trigger a SocketConnectionFailureCallback_t callback
|
||||
virtual SNetSocket_t CreateP2PConnectionSocket( CSteamID steamIDTarget, int nVirtualPort, int nTimeoutSec ) = 0;
|
||||
virtual SNetSocket_t CreateConnectionSocket( uint32 nIP, uint16 nPort, int nTimeoutSec ) = 0;
|
||||
|
||||
// disconnects the connection to the socket, if any, and invalidates the handle
|
||||
// any unread data on the socket will be thrown away
|
||||
// if bNotifyRemoteEnd is set, socket will not be completely destroyed until the remote end acknowledges the disconnect
|
||||
virtual bool DestroySocket( SNetSocket_t hSocket, bool bNotifyRemoteEnd ) = 0;
|
||||
// destroying a listen socket will automatically kill all the regular sockets generated from it
|
||||
virtual bool DestroyListenSocket( SNetListenSocket_t hSocket, bool bNotifyRemoteEnd ) = 0;
|
||||
|
||||
// sending data
|
||||
// must be a handle to a connected socket
|
||||
// data size cannot be more than 8k, although in UDP mode (default),
|
||||
// it's recommended packets be no larger than 1300 bytes
|
||||
// use the reliable flag with caution; although the resend rate is pretty aggressive,
|
||||
// it can still cause stalls in receiving data (like TCP)
|
||||
virtual bool SendDataOnSocket( SNetSocket_t hSocket, void *pubData, uint32 cubData, bool bReliable ) = 0;
|
||||
|
||||
// receiving data
|
||||
// returns false if there is no data remaining
|
||||
// fills out *pcubMsgSize with the size of the next message, in bytes
|
||||
virtual bool IsDataAvailableOnSocket( SNetSocket_t hSocket, uint32 *pcubMsgSize ) = 0;
|
||||
|
||||
// fills in pubDest with the contents of the message
|
||||
// messages are always complete, of the same size as was sent (i.e. packetized, not streaming)
|
||||
// if *pcubMsgSize < cubDest, only partial data is written
|
||||
// returns false if no data is available
|
||||
virtual bool RetrieveDataFromSocket( SNetSocket_t hSocket, void *pubDest, uint32 cubDest, uint32 *pcubMsgSize ) = 0;
|
||||
|
||||
// checks for data from any socket that has been connected off this listen socket
|
||||
// returns false if there is no data remaining
|
||||
// fills out *pcubMsgSize with the size of the next message, in bytes
|
||||
// fills out *phSocket with the socket that data is available on
|
||||
virtual bool IsDataAvailable( SNetListenSocket_t hListenSocket, uint32 *pcubMsgSize, SNetSocket_t *phSocket ) = 0;
|
||||
|
||||
// retrieves data from any socket that has been connected off this listen socket
|
||||
// fills in pubDest with the contents of the message
|
||||
// messages are always complete, of the same size as was sent (i.e. packetized, not streaming)
|
||||
// if *pcubMsgSize < cubDest, only partial data is written
|
||||
// returns false if no data is available
|
||||
// fills out *phSocket with the socket that data is available on
|
||||
virtual bool RetrieveData( SNetListenSocket_t hListenSocket, void *pubDest, uint32 cubDest, uint32 *pcubMsgSize, SNetSocket_t *phSocket ) = 0;
|
||||
|
||||
// returns information about the specified socket, filling out the contents of the pointers
|
||||
virtual bool GetSocketInfo( SNetSocket_t hSocket, CSteamID *pSteamIDRemote, int *peSocketStatus, uint32 *punIPRemote, uint16 *punPortRemote ) = 0;
|
||||
|
||||
// returns which local port the listen socket is bound to
|
||||
// *pnIP and *pnPort will be 0 if the socket is set to listen for P2P connections only
|
||||
virtual bool GetListenSocketInfo( SNetListenSocket_t hListenSocket, uint32 *pnIP, uint16 *pnPort ) = 0;
|
||||
|
||||
};
|
||||
#define STEAMNETWORKING_INTERFACE_VERSION "SteamNetworking001"
|
||||
|
||||
|
||||
// callback notification - status of a socket has changed
|
||||
struct SocketStatusCallback_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamNetworkingCallbacks + 1 };
|
||||
SNetSocket_t m_hSocket; // the socket used to send/receive data to the remote host
|
||||
SNetListenSocket_t m_hListenSocket; // this is the server socket that we were listening on; NULL if this was an outgoing connection
|
||||
CSteamID m_steamIDRemote; // remote steamID we have connected to, if it has one
|
||||
int m_eSNetSocketState; // socket state, ESNetSocketState
|
||||
};
|
||||
|
||||
|
||||
#endif // ISTEAMNETWORKING
|
||||
@@ -0,0 +1,150 @@
|
||||
//====== Copyright © 1996-2008, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose: interface to user account information in Steam
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef ISTEAMUSER_H
|
||||
#define ISTEAMUSER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "isteamclient.h"
|
||||
|
||||
// structure that contains client callback data
|
||||
// see callbacks documentation for more details
|
||||
struct CallbackMsg_t
|
||||
{
|
||||
HSteamUser m_hSteamUser;
|
||||
int m_iCallback;
|
||||
uint8 *m_pubParam;
|
||||
int m_cubParam;
|
||||
};
|
||||
|
||||
// reference to a steam call, to filter results by
|
||||
typedef int32 HSteamCall;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Functions for accessing and manipulating a steam account
|
||||
// associated with one client instance
|
||||
//-----------------------------------------------------------------------------
|
||||
class ISteamUser
|
||||
{
|
||||
public:
|
||||
// returns the HSteamUser this interface represents
|
||||
// this is only used internally by the API, and by a few select interfaces that support multi-user
|
||||
virtual HSteamUser GetHSteamUser() = 0;
|
||||
|
||||
// returns true if the Steam client current has a live connection to the Steam servers.
|
||||
// If false, it means there is no active connection due to either a networking issue on the local machine, or the Steam server is down/busy.
|
||||
// The Steam client will automatically be trying to recreate the connection as often as possible.
|
||||
virtual bool BLoggedOn() = 0;
|
||||
|
||||
// returns the CSteamID of the account currently logged into the Steam client
|
||||
// a CSteamID is a unique identifier for an account, and used to differentiate users in all parts of the Steamworks API
|
||||
virtual CSteamID GetSteamID() = 0;
|
||||
|
||||
// Multiplayer Authentication functions
|
||||
|
||||
// InitiateGameConnection() starts the state machine for authenticating the game client with the game server
|
||||
// It is the client portion of a three-way handshake between the client, the game server, and the steam servers
|
||||
//
|
||||
// Parameters:
|
||||
// void *pAuthBlob - a pointer to empty memory that will be filled in with the authentication token.
|
||||
// int cbMaxAuthBlob - the number of bytes of allocated memory in pBlob. Should be at least 2048 bytes.
|
||||
// CSteamID steamIDGameServer - the steamID of the game server, received from the game server by the client
|
||||
// CGameID gameID - the ID of the current game. For games without mods, this is just CGameID( <appID> )
|
||||
// uint32 unIPServer, uint16 usPortServer - the IP address of the game server
|
||||
// bool bSecure - whether or not the client thinks that the game server is reporting itself as secure (i.e. VAC is running)
|
||||
//
|
||||
// return value - returns the number of bytes written to pBlob. If the return is 0, then the buffer passed in was too small, and the call has failed
|
||||
// The contents of pBlob should then be sent to the game server, for it to use to complete the authentication process.
|
||||
virtual int InitiateGameConnection( void *pAuthBlob, int cbMaxAuthBlob, CSteamID steamIDGameServer, CGameID gameID, uint32 unIPServer, uint16 usPortServer, bool bSecure ) = 0;
|
||||
|
||||
// notify of disconnect
|
||||
// needs to occur when the game client leaves the specified game server, needs to match with the InitiateGameConnection() call
|
||||
virtual void TerminateGameConnection( uint32 unIPServer, uint16 usPortServer ) = 0;
|
||||
|
||||
// Legacy functions
|
||||
|
||||
// used by only a few games to track usage events
|
||||
virtual void TrackAppUsageEvent( CGameID gameID, int eAppUsageEvent, const char *pchExtraInfo = "" ) = 0;
|
||||
|
||||
// legacy authentication support - need to be called if the game server rejects the user with a 'bad ticket' error
|
||||
// this is only needed under very specific circumstances
|
||||
virtual void RefreshSteam2Login() = 0;
|
||||
};
|
||||
|
||||
#define STEAMUSER_INTERFACE_VERSION "SteamUser009"
|
||||
|
||||
|
||||
// callbacks
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called when a connections to the Steam back-end has been established
|
||||
// this means the Steam client now has a working connection to the Steam servers
|
||||
// usually this will have occurred before the game has launched, and should
|
||||
// only be seen if the user has dropped connection due to a networking issue
|
||||
// or a Steam server update
|
||||
//-----------------------------------------------------------------------------
|
||||
struct SteamServersConnected_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamUserCallbacks + 1 };
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called when a connection attempt has failed
|
||||
// this will occur periodically if the Steam client is not connected,
|
||||
// and has failed in it's retry to establish a connection
|
||||
//-----------------------------------------------------------------------------
|
||||
struct SteamServerConnectFailure_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamUserCallbacks + 2 };
|
||||
EResult m_eResult;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called if the client has lost connection to the Steam servers
|
||||
// real-time services will be disabled until a matching SteamServersConnected_t has been posted
|
||||
//-----------------------------------------------------------------------------
|
||||
struct SteamServersDisconnected_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamUserCallbacks + 3 };
|
||||
EResult m_eResult;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sent by the Steam server to the client telling it to disconnect from the specified game server,
|
||||
// which it may be in the process of or already connected to.
|
||||
// The game client should immediately disconnect upon receiving this message.
|
||||
// This can usually occur if the user doesn't have rights to play on the game server.
|
||||
//-----------------------------------------------------------------------------
|
||||
struct ClientGameServerDeny_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamUserCallbacks + 13 };
|
||||
|
||||
uint32 m_uAppID;
|
||||
uint32 m_unGameServerIP;
|
||||
uint16 m_usGameServerPort;
|
||||
uint16 m_bSecure;
|
||||
uint32 m_uReason;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called when the callback system for this client is in an error state (and has flushed pending callbacks)
|
||||
// When getting this message the client should disconnect from Steam, reset any stored Steam state and reconnect.
|
||||
// This usually occurs in the rare event the Steam client has some kind of fatal error.
|
||||
//-----------------------------------------------------------------------------
|
||||
struct CallbackPipeFailure_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamUserCallbacks + 17 };
|
||||
};
|
||||
|
||||
|
||||
#endif // ISTEAMUSER_H
|
||||
@@ -0,0 +1,98 @@
|
||||
//====== Copyright © 1996-2008, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose: interface to user account information in Steam
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef ISTEAMUSERSTATS_H
|
||||
#define ISTEAMUSERSTATS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "isteamclient.h"
|
||||
|
||||
// size limit on stat or achievement name
|
||||
const uint32 k_cchStatNameMax = 128;
|
||||
|
||||
class ISteamUserStats
|
||||
{
|
||||
public:
|
||||
|
||||
// Ask the server to send down this user's data and achievements for nGameID
|
||||
virtual bool RequestCurrentStats( ) = 0;
|
||||
|
||||
// Data accessors
|
||||
virtual bool GetStat( const char *pchName, int32 *pData ) = 0;
|
||||
virtual bool GetStat( const char *pchName, float *pData ) = 0;
|
||||
|
||||
// Set / update data
|
||||
virtual bool SetStat( const char *pchName, int32 nData ) = 0;
|
||||
virtual bool SetStat( const char *pchName, float fData ) = 0;
|
||||
virtual bool UpdateAvgRateStat( const char *pchName, float flCountThisSession, double dSessionLength ) = 0;
|
||||
|
||||
// Achievement flag accessors
|
||||
virtual bool GetAchievement( const char *pchName, bool *pbAchieved ) = 0;
|
||||
virtual bool SetAchievement( const char *pchName ) = 0;
|
||||
virtual bool ClearAchievement( const char *pchName ) = 0;
|
||||
|
||||
// Store the current data on the server, will get a callback when set
|
||||
// And one callback for every new achievement
|
||||
virtual bool StoreStats( ) = 0;
|
||||
|
||||
// Achievement / GroupAchievement metadata
|
||||
|
||||
// Gets the icon of the achievement, which is a handle to be used in IClientUtils::GetImageRGBA(), or 0 if none set
|
||||
virtual int GetAchievementIcon( const char *pchName ) = 0;
|
||||
// Get general attributes (display name / text, etc) for an Achievement
|
||||
virtual const char *GetAchievementDisplayAttribute( const char *pchName, const char *pchKey ) = 0;
|
||||
|
||||
// Achievement progress - triggers an AchievementProgress callback, that is all.
|
||||
// Calling this w/ N out of N progress will NOT set the achievement, the game must still do that.
|
||||
virtual bool IndicateAchievementProgress( const char *pchName, uint32 nCurProgress, uint32 nMaxProgress ) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define STEAMUSERSTATS_INTERFACE_VERSION "STEAMUSERSTATS_INTERFACE_VERSION003"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called when the latests stats and achievements have been received
|
||||
// from the server
|
||||
//-----------------------------------------------------------------------------
|
||||
struct UserStatsReceived_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamUserStatsCallbacks + 1 };
|
||||
uint64 m_nGameID; // Game these stats are for
|
||||
EResult m_eResult; // Success / error fetching the stats
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: result of a request to store the user stats for a game
|
||||
//-----------------------------------------------------------------------------
|
||||
struct UserStatsStored_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamUserStatsCallbacks + 2 };
|
||||
uint64 m_nGameID; // Game these stats are for
|
||||
EResult m_eResult; // success / error
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: result of a request to store the achievements for a game, or an
|
||||
// "indicate progress" call. If both m_nCurProgress and m_nMaxProgress
|
||||
// are zero, that means the achievement has been fully unlocked.
|
||||
//-----------------------------------------------------------------------------
|
||||
struct UserAchievementStored_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamUserStatsCallbacks + 3 };
|
||||
|
||||
uint64 m_nGameID; // Game this is for
|
||||
bool m_bGroupAchievement; // if this is a "group" achievement
|
||||
char m_rgchAchievementName[k_cchStatNameMax]; // name of the achievement
|
||||
uint32 m_nCurProgress; // current progress towards the achievement
|
||||
uint32 m_nMaxProgress; // "out of" this many
|
||||
};
|
||||
|
||||
|
||||
#endif // ISTEAMUSER_H
|
||||
@@ -0,0 +1,77 @@
|
||||
//====== Copyright © 1996-2008, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose: interface to utility functions in Steam
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef ISTEAMUTILS_H
|
||||
#define ISTEAMUTILS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "isteamclient.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: interface to user independent utility functions
|
||||
//-----------------------------------------------------------------------------
|
||||
class ISteamUtils
|
||||
{
|
||||
public:
|
||||
// return the number of seconds since the user
|
||||
virtual uint32 GetSecondsSinceAppActive() = 0;
|
||||
virtual uint32 GetSecondsSinceComputerActive() = 0;
|
||||
|
||||
// the universe this client is connecting to
|
||||
virtual EUniverse GetConnectedUniverse() = 0;
|
||||
|
||||
// Steam server time - in PST, number of seconds since January 1, 1970 (i.e unix time)
|
||||
virtual uint32 GetServerRealTime() = 0;
|
||||
|
||||
// returns the 2 digit ISO 3166-1-alpha-2 format country code this client is running in (as looked up via an IP-to-location database)
|
||||
// e.g "US" or "UK".
|
||||
virtual const char *GetIPCountry() = 0;
|
||||
|
||||
// returns true if the image exists, and valid sizes were filled out
|
||||
virtual bool GetImageSize( int iImage, uint32 *pnWidth, uint32 *pnHeight ) = 0;
|
||||
|
||||
// returns true if the image exists, and the buffer was successfully filled out
|
||||
// results are returned in RGBA format
|
||||
// the destination buffer size should be 4 * height * width * sizeof(char)
|
||||
virtual bool GetImageRGBA( int iImage, uint8 *pubDest, int nDestBufferSize ) = 0;
|
||||
|
||||
// returns the IP of the reporting server for valve - currently only used in Source engine games
|
||||
virtual bool GetCSERIPPort( uint32 *unIP, uint16 *usPort ) = 0;
|
||||
|
||||
// return the amount of battery power left in the current system in % [0..100], 255 for being on AC power
|
||||
virtual uint8 GetCurrentBatteryPower() = 0;
|
||||
|
||||
// returns the appID of the current process
|
||||
virtual uint32 GetAppID() = 0;
|
||||
};
|
||||
|
||||
#define STEAMUTILS_INTERFACE_VERSION "SteamUtils002"
|
||||
|
||||
|
||||
// callbacks
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: The country of the user changed
|
||||
//-----------------------------------------------------------------------------
|
||||
struct IPCountry_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamUtilsCallbacks + 1 };
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Fired when running on a laptop and less than 10 minutes of battery is left, fires then every minute
|
||||
//-----------------------------------------------------------------------------
|
||||
struct LowBatteryPower_t
|
||||
{
|
||||
enum { k_iCallback = k_iSteamUtilsCallbacks + 2 };
|
||||
uint8 m_nMinutesBatteryLeft;
|
||||
};
|
||||
|
||||
#endif // ISTEAMUTILS_H
|
||||
@@ -0,0 +1,235 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef MATCHMAKINGTYPES_H
|
||||
#define MATCHMAKINGTYPES_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
struct MatchMakingKeyValuePair_t
|
||||
{
|
||||
MatchMakingKeyValuePair_t() { m_szKey[0] = m_szValue[0] = 0; }
|
||||
MatchMakingKeyValuePair_t( const char *pchKey, const char *pchValue )
|
||||
{
|
||||
strncpy( m_szKey, pchKey, sizeof(m_szKey) ); // this is a public header, use basic c library string funcs only!
|
||||
strncpy( m_szValue, pchValue, sizeof(m_szValue) );
|
||||
}
|
||||
char m_szKey[ 256 ];
|
||||
char m_szValue[ 256 ];
|
||||
};
|
||||
|
||||
|
||||
enum EMatchMakingServerResponse
|
||||
{
|
||||
eServerResponded = 0,
|
||||
eServerFailedToRespond,
|
||||
eNoServersListedOnMasterServer // for the Internet query type, returned in response callback if no servers of this type match
|
||||
};
|
||||
|
||||
enum EMatchMakingType
|
||||
{
|
||||
eInternetServer = 0,
|
||||
eLANServer,
|
||||
eFriendsServer,
|
||||
eFavoritesServer,
|
||||
eHistoryServer,
|
||||
eSpectatorServer,
|
||||
eInvalidServer
|
||||
};
|
||||
|
||||
|
||||
// servernetadr_t is all the addressing info the serverbrowser needs to know about a game server,
|
||||
// namely: its IP, its connection port, and its query port.
|
||||
class servernetadr_t
|
||||
{
|
||||
public:
|
||||
|
||||
void Init( unsigned int ip, uint16 usQueryPort, uint16 usConnectionPort );
|
||||
#ifdef NETADR_H
|
||||
void Init( const netadr_t &ipAndQueryPort, uint16 usConnectionPort );
|
||||
netadr_t& GetIPAndQueryPort();
|
||||
#endif
|
||||
|
||||
// Access the query port.
|
||||
uint16 GetQueryPort() const;
|
||||
void SetQueryPort( uint16 usPort );
|
||||
|
||||
// Access the connection port.
|
||||
uint16 GetConnectionPort() const;
|
||||
void SetConnectionPort( uint16 usPort );
|
||||
|
||||
// Access the IP
|
||||
uint32 GetIP() const;
|
||||
void SetIP( uint32 );
|
||||
|
||||
// This gets the 'a.b.c.d:port' string with the connection port (instead of the query port).
|
||||
const char *GetConnectionAddressString() const;
|
||||
const char *GetQueryAddressString() const;
|
||||
|
||||
// Comparison operators and functions.
|
||||
bool operator<(const servernetadr_t &netadr) const;
|
||||
void operator=( const servernetadr_t &that )
|
||||
{
|
||||
m_usConnectionPort = that.m_usConnectionPort;
|
||||
m_usQueryPort = that.m_usQueryPort;
|
||||
m_unIP = that.m_unIP;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
const char *ToString( uint32 unIP, uint16 usPort ) const;
|
||||
uint16 m_usConnectionPort; // (in HOST byte order)
|
||||
uint16 m_usQueryPort;
|
||||
uint32 m_unIP;
|
||||
};
|
||||
|
||||
|
||||
inline void servernetadr_t::Init( unsigned int ip, uint16 usQueryPort, uint16 usConnectionPort )
|
||||
{
|
||||
m_unIP = ip;
|
||||
m_usQueryPort = usQueryPort;
|
||||
m_usConnectionPort = usConnectionPort;
|
||||
}
|
||||
|
||||
#ifdef NETADR_H
|
||||
inline void servernetadr_t::Init( const netadr_t &ipAndQueryPort, uint16 usConnectionPort )
|
||||
{
|
||||
Init( ipAndQueryPort.GetIP(), ipAndQueryPort.GetPort(), usConnectionPort );
|
||||
}
|
||||
|
||||
inline netadr_t& servernetadr_t::GetIPAndQueryPort()
|
||||
{
|
||||
static netadr_t netAdr;
|
||||
netAdr.SetIP( m_unIP );
|
||||
netAdr.SetPort( m_usQueryPort );
|
||||
return netAdr;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline uint16 servernetadr_t::GetQueryPort() const
|
||||
{
|
||||
return m_usQueryPort;
|
||||
}
|
||||
|
||||
inline void servernetadr_t::SetQueryPort( uint16 usPort )
|
||||
{
|
||||
m_usQueryPort = usPort;
|
||||
}
|
||||
|
||||
inline uint16 servernetadr_t::GetConnectionPort() const
|
||||
{
|
||||
return m_usConnectionPort;
|
||||
}
|
||||
|
||||
inline void servernetadr_t::SetConnectionPort( uint16 usPort )
|
||||
{
|
||||
m_usConnectionPort = usPort;
|
||||
}
|
||||
|
||||
inline uint32 servernetadr_t::GetIP() const
|
||||
{
|
||||
return m_unIP;
|
||||
}
|
||||
|
||||
inline void servernetadr_t::SetIP( uint32 unIP )
|
||||
{
|
||||
m_unIP = unIP;
|
||||
}
|
||||
|
||||
inline const char *servernetadr_t::ToString( uint32 unIP, uint16 usPort ) const
|
||||
{
|
||||
static char s[4][64];
|
||||
static int nBuf = 0;
|
||||
unsigned char *ipByte = (unsigned char *)&unIP;
|
||||
_snprintf (s[nBuf], sizeof( s[nBuf] ), "%u.%u.%u.%u:%i", (int)(ipByte[3]), (int)(ipByte[2]), (int)(ipByte[1]), (int)(ipByte[0]), usPort );
|
||||
const char *pchRet = s[nBuf];
|
||||
++nBuf;
|
||||
nBuf %= ( (sizeof(s)/sizeof(s[0])) );
|
||||
return pchRet;
|
||||
}
|
||||
|
||||
inline const char* servernetadr_t::GetConnectionAddressString() const
|
||||
{
|
||||
return ToString( m_unIP, m_usConnectionPort );
|
||||
}
|
||||
|
||||
inline const char* servernetadr_t::GetQueryAddressString() const
|
||||
{
|
||||
return ToString( m_unIP, m_usQueryPort );
|
||||
}
|
||||
|
||||
inline bool servernetadr_t::operator<(const servernetadr_t &netadr) const
|
||||
{
|
||||
return ( m_unIP < netadr.m_unIP ) || ( m_unIP == netadr.m_unIP && m_usQueryPort < netadr.m_usQueryPort );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Data describing a single server
|
||||
//-----------------------------------------------------------------------------
|
||||
class gameserveritem_t
|
||||
{
|
||||
public:
|
||||
gameserveritem_t();
|
||||
|
||||
const char* GetName() const;
|
||||
void SetName( const char *pName );
|
||||
|
||||
public:
|
||||
servernetadr_t m_NetAdr; // IP/Query Port/Connection Port for this server
|
||||
int m_nPing; // current ping time in milliseconds
|
||||
bool m_bHadSuccessfulResponse; // server has responded successfully in the past
|
||||
bool m_bDoNotRefresh; // server is marked as not responding and should no longer be refreshed
|
||||
char m_szGameDir[32]; // current game directory
|
||||
char m_szMap[32]; // current map
|
||||
char m_szGameDescription[64]; // game description
|
||||
int m_nAppID; // Steam App ID of this server
|
||||
int m_nPlayers; // current number of players on the server
|
||||
int m_nMaxPlayers; // Maximum players that can join this server
|
||||
int m_nBotPlayers; // Number of bots (i.e simulated players) on this server
|
||||
bool m_bPassword; // true if this server needs a password to join
|
||||
bool m_bSecure; // Is this server protected by VAC
|
||||
uint32 m_ulTimeLastPlayed; // time (in unix time) when this server was last played on (for favorite/history servers)
|
||||
int m_nServerVersion; // server version as reported to Steam
|
||||
|
||||
private:
|
||||
char m_szServerName[64]; // Game server name
|
||||
|
||||
// For data added after SteamMatchMaking001 add it here
|
||||
public:
|
||||
char m_szGameTags[128]; // the tags this server exposes
|
||||
};
|
||||
|
||||
|
||||
inline gameserveritem_t::gameserveritem_t()
|
||||
{
|
||||
m_szGameDir[0] = m_szMap[0] = m_szGameDescription[0] = m_szServerName[0] = 0;
|
||||
m_bHadSuccessfulResponse = m_bDoNotRefresh = m_bPassword = m_bSecure = false;
|
||||
m_nPing = m_nAppID = m_nPlayers = m_nMaxPlayers = m_nBotPlayers = m_ulTimeLastPlayed = m_nServerVersion = 0;
|
||||
m_szGameTags[0] = 0;
|
||||
}
|
||||
|
||||
inline const char* gameserveritem_t::GetName() const
|
||||
{
|
||||
// Use the IP address as the name if nothing is set yet.
|
||||
if ( m_szServerName[0] == 0 )
|
||||
return m_NetAdr.GetConnectionAddressString();
|
||||
else
|
||||
return m_szServerName;
|
||||
}
|
||||
|
||||
inline void gameserveritem_t::SetName( const char *pName )
|
||||
{
|
||||
strncpy( m_szServerName, pName, sizeof( m_szServerName ) );
|
||||
}
|
||||
|
||||
|
||||
#endif // MATCHMAKINGTYPES_H
|
||||
@@ -0,0 +1,308 @@
|
||||
//====== Copyright © 1996-2008, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef STEAM_API_H
|
||||
#define STEAM_API_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "isteamclient.h"
|
||||
#include "isteamuser.h"
|
||||
#include "isteamfriends.h"
|
||||
#include "isteamutils.h"
|
||||
#include "isteammatchmaking.h"
|
||||
#include "isteamuserstats.h"
|
||||
#include "isteamapps.h"
|
||||
#include "isteamnetworking.h"
|
||||
|
||||
// Steam API export macro
|
||||
#if defined( _WIN32 ) && !defined( _X360 )
|
||||
#if defined( STEAM_API_EXPORTS )
|
||||
#define S_API extern "C" __declspec( dllexport )
|
||||
#elif defined( STEAM_API_NODLL )
|
||||
#define S_API extern "C"
|
||||
#else
|
||||
#define S_API extern "C" __declspec( dllimport )
|
||||
#endif // STEAM_API_EXPORTS
|
||||
#elif defined( _LINUX )
|
||||
#if defined( STEAM_API_EXPORTS )
|
||||
#define S_API extern "C" __attribute__ ((visibility("default")))
|
||||
#else
|
||||
#define S_API extern "C"
|
||||
#endif // STEAM_API_EXPORTS
|
||||
#else // !WIN32
|
||||
#if defined( STEAM_API_EXPORTS )
|
||||
#define S_API extern "C"
|
||||
#else
|
||||
#define S_API extern "C"
|
||||
#endif // STEAM_API_EXPORTS
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------//
|
||||
// Steam API setup & shutdown
|
||||
//
|
||||
// These functions manage loading, initializing and shutdown of the steamclient.dll
|
||||
//
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------//
|
||||
|
||||
// S_API void SteamAPI_Init(); (see below)
|
||||
S_API void SteamAPI_Shutdown();
|
||||
|
||||
// crash dump recording functions
|
||||
S_API void SteamAPI_WriteMiniDump( uint32 uStructuredExceptionCode, void* pvExceptionInfo, uint32 uBuildID );
|
||||
S_API void SteamAPI_SetMiniDumpComment( const char *pchMsg );
|
||||
|
||||
// interface pointers, configured by SteamAPI_Init()
|
||||
S_API ISteamClient *SteamClient();
|
||||
|
||||
|
||||
//
|
||||
// VERSION_SAFE_STEAM_API_INTERFACES is usually not necessary, but it provides safety against releasing
|
||||
// new steam_api.dll's without recompiling/rereleasing modules that use it.
|
||||
//
|
||||
// If you use VERSION_SAFE_STEAM_API_INTERFACES, then you should call SteamAPI_InitSafe(). Also, to get the
|
||||
// Steam interfaces, you must create and Init() a CSteamAPIContext (below) and use the interfaces in there.
|
||||
//
|
||||
// If you don't use VERSION_SAFE_STEAM_API_INTERFACES, then you can use SteamAPI_Init() and the SteamXXXX()
|
||||
// functions below to get at the Steam interfaces.
|
||||
//
|
||||
#ifdef VERSION_SAFE_STEAM_API_INTERFACES
|
||||
S_API bool SteamAPI_InitSafe();
|
||||
#else
|
||||
S_API bool SteamAPI_Init();
|
||||
|
||||
S_API ISteamUser *SteamUser();
|
||||
S_API ISteamFriends *SteamFriends();
|
||||
S_API ISteamUtils *SteamUtils();
|
||||
S_API ISteamMatchmaking *SteamMatchmaking();
|
||||
S_API ISteamUserStats *SteamUserStats();
|
||||
S_API ISteamApps *SteamApps();
|
||||
S_API ISteamNetworking *SteamNetworking();
|
||||
S_API ISteamMatchmakingServers *SteamMatchmakingServers();
|
||||
#endif // VERSION_SAFE_STEAM_API_INTERFACES
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------//
|
||||
// steam callback helper functions
|
||||
//
|
||||
// The following classes/macros are used to be able to easily multiplex callbacks
|
||||
// from the Steam API into various objects in the app in a thread-safe manner
|
||||
//
|
||||
// These functors are triggered via the SteamAPI_RunCallbacks() function, mapping the callback
|
||||
// to as many functions/objects as are registered to it
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------//
|
||||
|
||||
S_API void SteamAPI_RunCallbacks();
|
||||
|
||||
|
||||
|
||||
// functions used by the utility CCallback objects to receive callbacks
|
||||
S_API void SteamAPI_RegisterCallback( class CCallbackBase *pCallback, int iCallback );
|
||||
S_API void SteamAPI_UnregisterCallback( class CCallbackBase *pCallback );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: base for callbacks,
|
||||
// used only by CCallback, shouldn't be used directly
|
||||
//-----------------------------------------------------------------------------
|
||||
class CCallbackBase
|
||||
{
|
||||
public:
|
||||
CCallbackBase() { m_nCallbackFlags = 0; }
|
||||
// don't add a virtual destructor because we export this binary interface across dll's
|
||||
virtual void Run( void *pvParam ) = 0;
|
||||
|
||||
protected:
|
||||
enum { k_ECallbackFlagsRegistered = 0x01, k_ECallbackFlagsGameServer = 0x02 };
|
||||
uint8 m_nCallbackFlags;
|
||||
private:
|
||||
int m_iCallback;
|
||||
friend class CCallbackMgr;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: maps a steam callback to a class member function
|
||||
// template params: T = local class, P = parameter struct
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, class P, bool bGameServer >
|
||||
class CCallback : private CCallbackBase
|
||||
{
|
||||
public:
|
||||
typedef void (T::*func_t)( P* );
|
||||
|
||||
// If you can't support constructing a callback with the correct parameters
|
||||
// then uncomment the empty constructor below and manually call
|
||||
// ::Register() for your object
|
||||
//CCallback() {}
|
||||
|
||||
// constructor for initializing this object in owner's constructor
|
||||
CCallback( T *pObj, func_t func ) : m_pObj( pObj ), m_Func( func )
|
||||
{
|
||||
if ( bGameServer )
|
||||
{
|
||||
m_nCallbackFlags |= k_ECallbackFlagsGameServer;
|
||||
}
|
||||
|
||||
Register( pObj, func );
|
||||
}
|
||||
|
||||
~CCallback()
|
||||
{
|
||||
SteamAPI_UnregisterCallback( this );
|
||||
}
|
||||
|
||||
// manual registration of the callback
|
||||
void Register( T *pObj, func_t func )
|
||||
{
|
||||
m_pObj = pObj;
|
||||
m_Func = func;
|
||||
SteamAPI_RegisterCallback( this, P::k_iCallback );
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void Run( void *pvParam )
|
||||
{
|
||||
(m_pObj->*m_Func)( (P *)pvParam );
|
||||
}
|
||||
|
||||
T *m_pObj;
|
||||
func_t m_Func;
|
||||
};
|
||||
|
||||
|
||||
// utility macro for declaring the function and callback object together
|
||||
#define STEAM_CALLBACK( thisclass, func, param, var ) CCallback< thisclass, param, false > var; void func( param *pParam )
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
// disable this warning; this pattern need for steam callback registration
|
||||
#pragma warning( disable: 4355 ) // 'this' : used in base member initializer list
|
||||
#endif
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------//
|
||||
// steamclient.dll private wrapper functions
|
||||
//
|
||||
// The following functions are part of abstracting API access to the steamclient.dll, but should only be used in very specific cases
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------//
|
||||
|
||||
// pumps out all the steam messages, calling the register callback
|
||||
S_API void Steam_RunCallbacks( HSteamPipe hSteamPipe, bool bGameServerCallbacks );
|
||||
|
||||
// register the callback funcs to use to interact with the steam dll
|
||||
S_API void Steam_RegisterInterfaceFuncs( void *hModule );
|
||||
|
||||
// returns the HSteamUser of the last user to dispatch a callback
|
||||
S_API HSteamUser Steam_GetHSteamUserCurrent();
|
||||
|
||||
// returns the filename path of the current running Steam process, used if you need to load an explicit steam dll by name
|
||||
S_API const char *SteamAPI_GetSteamInstallPath();
|
||||
|
||||
|
||||
#ifdef VERSION_SAFE_STEAM_API_INTERFACES
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------//
|
||||
// VERSION_SAFE_STEAM_API_INTERFACES uses CSteamAPIContext to provide interfaces to each module in a way that
|
||||
// lets them each specify the interface versions they are compiled with.
|
||||
//
|
||||
// It's important that these stay inlined in the header so the calling module specifies the interface versions
|
||||
// for whatever Steam API version it has.
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------//
|
||||
|
||||
S_API HSteamPipe GetHSteamPipe();
|
||||
S_API HSteamUser GetHSteamUser();
|
||||
|
||||
class CSteamAPIContext
|
||||
{
|
||||
public:
|
||||
CSteamAPIContext();
|
||||
void Clear();
|
||||
|
||||
bool Init();
|
||||
|
||||
ISteamUser* SteamUser() { return m_pSteamUser; }
|
||||
ISteamFriends* SteamFriends() { return m_pSteamFriends; }
|
||||
ISteamUtils* SteamUtils() { return m_pSteamUtils; }
|
||||
ISteamMatchmaking* SteamMatchmaking() { return m_pSteamMatchmaking; }
|
||||
ISteamUserStats* SteamUserStats() { return m_pSteamUserStats; }
|
||||
ISteamApps* SteamApps() { return m_pSteamApps; }
|
||||
ISteamMatchmakingServers* SteamMatchmakingServers() { return m_pSteamMatchmakingServers; }
|
||||
ISteamNetworking* SteamNetworking() { return m_pSteamNetworking; }
|
||||
|
||||
private:
|
||||
ISteamUser *m_pSteamUser;
|
||||
ISteamFriends *m_pSteamFriends;
|
||||
ISteamUtils *m_pSteamUtils;
|
||||
ISteamMatchmaking *m_pSteamMatchmaking;
|
||||
ISteamUserStats *m_pSteamUserStats;
|
||||
ISteamApps *m_pSteamApps;
|
||||
ISteamMatchmakingServers *m_pSteamMatchmakingServers;
|
||||
ISteamNetworking *m_pSteamNetworking;
|
||||
};
|
||||
|
||||
inline CSteamAPIContext::CSteamAPIContext()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
inline void CSteamAPIContext::Clear()
|
||||
{
|
||||
m_pSteamUser = NULL;
|
||||
m_pSteamFriends = NULL;
|
||||
m_pSteamUtils = NULL;
|
||||
m_pSteamMatchmaking = NULL;
|
||||
m_pSteamUserStats = NULL;
|
||||
m_pSteamApps = NULL;
|
||||
m_pSteamMatchmakingServers = NULL;
|
||||
m_pSteamNetworking = NULL;
|
||||
}
|
||||
|
||||
// This function must be inlined so the module using steam_api.dll gets the version names they want.
|
||||
inline bool CSteamAPIContext::Init()
|
||||
{
|
||||
if ( !SteamClient() )
|
||||
return false;
|
||||
|
||||
HSteamUser hSteamUser = GetHSteamUser();
|
||||
HSteamPipe hSteamPipe = GetHSteamPipe();
|
||||
|
||||
m_pSteamUser = SteamClient()->GetISteamUser( hSteamUser, hSteamPipe, STEAMUSER_INTERFACE_VERSION );
|
||||
if ( !m_pSteamUser )
|
||||
return false;
|
||||
|
||||
m_pSteamFriends = SteamClient()->GetISteamFriends( hSteamUser, hSteamPipe, STEAMFRIENDS_INTERFACE_VERSION );
|
||||
if ( !m_pSteamFriends )
|
||||
return false;
|
||||
|
||||
m_pSteamUtils = SteamClient()->GetISteamUtils( hSteamUser, STEAMUTILS_INTERFACE_VERSION );
|
||||
if ( !m_pSteamUtils )
|
||||
return false;
|
||||
|
||||
m_pSteamMatchmaking = SteamClient()->GetISteamMatchmaking( hSteamUser, hSteamPipe, STEAMMATCHMAKING_INTERFACE_VERSION );
|
||||
if ( !m_pSteamMatchmaking )
|
||||
return false;
|
||||
|
||||
m_pSteamMatchmakingServers = SteamClient()->GetISteamMatchmakingServers( hSteamUser, hSteamPipe, STEAMMATCHMAKINGSERVERS_INTERFACE_VERSION );
|
||||
if ( !m_pSteamMatchmakingServers )
|
||||
return false;
|
||||
|
||||
m_pSteamUserStats = SteamClient()->GetISteamUserStats( hSteamUser, hSteamPipe, STEAMUSERSTATS_INTERFACE_VERSION );
|
||||
if ( !m_pSteamUserStats )
|
||||
return false;
|
||||
|
||||
m_pSteamApps = SteamClient()->GetISteamApps( hSteamUser, hSteamPipe, STEAMAPPS_INTERFACE_VERSION );
|
||||
if ( !m_pSteamApps )
|
||||
return false;
|
||||
|
||||
m_pSteamNetworking = SteamClient()->GetISteamNetworking( hSteamUser, hSteamPipe, STEAMNETWORKING_INTERFACE_VERSION );
|
||||
if ( !m_pSteamNetworking )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // VERSION_SAFE_STEAM_API_INTERFACES
|
||||
|
||||
#endif // STEAM_API_H
|
||||
@@ -0,0 +1,45 @@
|
||||
//====== Copyright © 1996-2008, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef STEAM_GAMESERVER_H
|
||||
#define STEAM_GAMESERVER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "steam_api.h"
|
||||
#include "isteamgameserver.h"
|
||||
#include "isteammasterserverupdater.h"
|
||||
|
||||
enum EServerMode
|
||||
{
|
||||
eServerModeNoAuthentication = 1, // Don't authenticate user logins and don't list on the server list
|
||||
eServerModeAuthentication = 2, // Authenticate users, list on the server list, don't run VAC on clients that connect
|
||||
eServerModeAuthenticationAndSecure = 3, // Authenticate users, list on the server list and VAC protect clients
|
||||
};
|
||||
|
||||
// Note: if you pass MASTERSERVERUPDATERPORT_USEGAMESOCKETSHARE for usQueryPort, then it will use "GameSocketShare" mode,
|
||||
// which means that the game is responsible for sending and receiving UDP packets for the master
|
||||
// server updater. See references to GameSocketShare in isteammasterserverupdater.h.
|
||||
//
|
||||
// Pass 0 for usGamePort or usSpectatorPort if you're not using that. Then, the master server updater will report
|
||||
// what's running based on that.
|
||||
S_API bool SteamGameServer_Init( uint32 unIP, uint16 usPort, uint16 usGamePort, uint16 usSpectatorPort, uint16 usQueryPort, EServerMode eServerMode, int nGameAppId, const char *pchGameDir, const char *pchVersionString );
|
||||
S_API void SteamGameServer_Shutdown();
|
||||
S_API void SteamGameServer_RunCallbacks();
|
||||
|
||||
S_API bool SteamGameServer_BSecure();
|
||||
S_API uint64 SteamGameServer_GetSteamID();
|
||||
|
||||
S_API ISteamGameServer *SteamGameServer();
|
||||
S_API ISteamUtils *SteamGameServerUtils();
|
||||
S_API ISteamMasterServerUpdater *SteamMasterServerUpdater();
|
||||
S_API ISteamNetworking *SteamGameServerNetworking();
|
||||
|
||||
#define STEAM_GAMESERVER_CALLBACK( thisclass, func, param, var ) CCallback< thisclass, param, true > var; void func( param *pParam )
|
||||
|
||||
|
||||
#endif // STEAM_GAMESERVER_H
|
||||
@@ -0,0 +1,732 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef STEAMCLIENTPUBLIC_H
|
||||
#define STEAMCLIENTPUBLIC_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
//lint -save -e1931 -e1927 -e1924 -e613 -e726
|
||||
|
||||
// This header file defines the interface between the calling application and the code that
|
||||
// knows how to communicate with the connection manager (CM) from the Steam service
|
||||
|
||||
// This header file is intended to be portable; ideally this 1 header file plus a lib or dll
|
||||
// is all you need to integrate the client library into some other tree. So please avoid
|
||||
// including or requiring other header files if possible. This header should only describe the
|
||||
// interface layer, no need to include anything about the implementation.
|
||||
|
||||
#include "steamtypes.h"
|
||||
|
||||
|
||||
// General result codes
|
||||
enum EResult
|
||||
{
|
||||
k_EResultOK = 1, // success
|
||||
k_EResultFail = 2, // generic failure
|
||||
k_EResultNoConnection = 3, // no/failed network connection
|
||||
// k_EResultNoConnectionRetry = 4, // OBSOLETE - removed
|
||||
k_EResultInvalidPassword = 5, // password/ticket is invalid
|
||||
k_EResultLoggedInElsewhere = 6, // same user logged in elsewhere
|
||||
k_EResultInvalidProtocolVer = 7, // protocol version is incorrect
|
||||
k_EResultInvalidParam = 8, // a parameter is incorrect
|
||||
k_EResultFileNotFound = 9, // file was not found
|
||||
k_EResultBusy = 10, // called method busy - action not taken
|
||||
k_EResultInvalidState = 11, // called object was in an invalid state
|
||||
k_EResultInvalidName = 12, // name is invalid
|
||||
k_EResultInvalidEmail = 13, // email is invalid
|
||||
k_EResultDuplicateName = 14, // name is not unique
|
||||
k_EResultAccessDenied = 15, // access is denied
|
||||
k_EResultTimeout = 16, // operation timed out
|
||||
k_EResultBanned = 17, // VAC2 banned
|
||||
k_EResultAccountNotFound = 18, // account not found
|
||||
k_EResultInvalidSteamID = 19, // steamID is invalid
|
||||
k_EResultServiceUnavailable = 20, // The requested service is currently unavailable
|
||||
k_EResultNotLoggedOn = 21, // The user is not logged on
|
||||
k_EResultPending = 22, // Request is pending (may be in process, or waiting on third party)
|
||||
k_EResultEncryptionFailure = 23, // Encryption or Decryption failed
|
||||
k_EResultInsufficientPrivilege = 24, // Insufficient privilege
|
||||
k_EResultLimitExceeded = 25, // Too much of a good thing
|
||||
k_EResultRevoked = 26, // Access has been revoked (used for revoked guest passes)
|
||||
k_EResultExpired = 27, // License/Guest pass the user is trying to access is expired
|
||||
k_EResultAlreadyRedeemed = 28, // Guest pass has already been redeemed by account, cannot be acked again
|
||||
k_EResultDuplicateRequest = 29, // The request is a duplicate and the action has already occurred in the past, ignored this time
|
||||
k_EResultAlreadyOwned = 30, // All the games in this guest pass redemption request are already owned by the user
|
||||
k_EResultIPNotFound = 31, // IP address not found
|
||||
k_EResultPersistFailed = 32, // failed to write change to the data store
|
||||
k_EResultLockingFailed = 33, // failed to acquire access lock for this operation
|
||||
k_EResultLogonSessionReplaced = 34,
|
||||
k_EResultConnectFailed = 35,
|
||||
k_EResultHandshakeFailed = 36,
|
||||
k_EResultIOFailure = 37,
|
||||
k_EResultRemoteDisconnect = 38,
|
||||
k_EResultShoppingCartNotFound = 39, // failed to find the shopping cart requested
|
||||
k_EResultBlocked = 40, // a user didn't allow it
|
||||
k_EResultIgnored = 41, // target is ignoring sender
|
||||
};
|
||||
|
||||
// Result codes to GSHandleClientDeny/Kick
|
||||
typedef enum
|
||||
{
|
||||
k_EDenyInvalidVersion = 1,
|
||||
k_EDenyGeneric = 2,
|
||||
k_EDenyNotLoggedOn = 3,
|
||||
k_EDenyNoLicense = 4,
|
||||
k_EDenyCheater = 5,
|
||||
k_EDenyLoggedInElseWhere = 6,
|
||||
k_EDenyUnknownText = 7,
|
||||
k_EDenyIncompatibleAnticheat = 8,
|
||||
k_EDenyMemoryCorruption = 9,
|
||||
k_EDenyIncompatibleSoftware = 10,
|
||||
k_EDenySteamConnectionLost = 11,
|
||||
k_EDenySteamConnectionError = 12,
|
||||
k_EDenySteamResponseTimedOut = 13,
|
||||
k_EDenySteamValidationStalled = 14,
|
||||
} EDenyReason;
|
||||
|
||||
// Steam universes. Each universe is a self-contained Steam instance.
|
||||
enum EUniverse
|
||||
{
|
||||
k_EUniverseInvalid = 0,
|
||||
k_EUniversePublic = 1,
|
||||
k_EUniverseBeta = 2,
|
||||
k_EUniverseInternal = 3,
|
||||
k_EUniverseDev = 4,
|
||||
k_EUniverseRC = 5,
|
||||
|
||||
k_EUniverseMax
|
||||
};
|
||||
|
||||
// Steam account types
|
||||
enum EAccountType
|
||||
{
|
||||
k_EAccountTypeInvalid = 0,
|
||||
k_EAccountTypeIndividual = 1, // single user account
|
||||
k_EAccountTypeMultiseat = 2, // multiseat (e.g. cybercafe) account
|
||||
k_EAccountTypeGameServer = 3, // game server account
|
||||
k_EAccountTypeAnonGameServer = 4, // anonymous game server account
|
||||
k_EAccountTypePending = 5, // pending
|
||||
k_EAccountTypeContentServer = 6, // content server
|
||||
k_EAccountTypeClan = 7,
|
||||
k_EAccountTypeChat = 8,
|
||||
k_EAccountTypeP2PSuperSeeder = 9, // a fake steamid used by superpeers to seed content to users of Steam P2P stuff
|
||||
k_EAccountTypeAnonUser = 10,
|
||||
|
||||
// Max of 16 items in this field
|
||||
k_EAccountTypeMax
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// types of user game stats fields
|
||||
// WARNING: DO NOT RENUMBER EXISTING VALUES - STORED IN DATABASE
|
||||
//-----------------------------------------------------------------------------
|
||||
enum ESteamUserStatType
|
||||
{
|
||||
k_ESteamUserStatTypeINVALID = 0,
|
||||
k_ESteamUserStatTypeINT = 1,
|
||||
k_ESteamUserStatTypeFLOAT = 2,
|
||||
// Read as FLOAT, set with count / session length
|
||||
k_ESteamUserStatTypeAVGRATE = 3,
|
||||
k_ESteamUserStatTypeACHIEVEMENTS = 4,
|
||||
k_ESteamUserStatTypeGROUPACHIEVEMENTS = 5,
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Chat Entry Types (previously was only friend-to-friend message types)
|
||||
//-----------------------------------------------------------------------------
|
||||
enum EChatEntryType
|
||||
{
|
||||
k_EChatEntryTypeChatMsg = 1, // Normal text message from another user
|
||||
k_EChatEntryTypeTyping = 2, // Another user is typing (not used in multi-user chat)
|
||||
k_EChatEntryTypeInviteGame = 3, // Invite from other user into that users current game
|
||||
k_EChatEntryTypeEmote = 4, // text emote message
|
||||
k_EChatEntryTypeLobbyGameStart = 5, // lobby game is starting
|
||||
// Above are previous FriendMsgType entries, now merged into more generic chat entry types
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Chat Room Enter Responses
|
||||
//-----------------------------------------------------------------------------
|
||||
enum EChatRoomEnterResponse
|
||||
{
|
||||
k_EChatRoomEnterResponseSuccess = 1, // Success
|
||||
k_EChatRoomEnterResponseDoesntExist = 2, // Chat doesn't exist (probably closed)
|
||||
k_EChatRoomEnterResponseNotAllowed = 3, // General Denied - You don't have the permissions needed to join the chat
|
||||
k_EChatRoomEnterResponseFull = 4, // Chat room has reached its maximum size
|
||||
k_EChatRoomEnterResponseError = 5, // Unexpected Error
|
||||
k_EChatRoomEnterResponseBanned = 6, // You are banned from this chat room and may not join
|
||||
};
|
||||
|
||||
|
||||
typedef void (*PFNLegacyKeyRegistration)( const char *pchCDKey, const char *pchInstallPath );
|
||||
typedef bool (*PFNLegacyKeyInstalled)();
|
||||
|
||||
|
||||
#pragma pack( push, 1 )
|
||||
|
||||
// Steam ID structure (64 bits total)
|
||||
class CSteamID
|
||||
{
|
||||
public:
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CSteamID()
|
||||
{
|
||||
m_unAccountID = 0;
|
||||
m_EAccountType = k_EAccountTypeInvalid;
|
||||
m_EUniverse = k_EUniverseInvalid;
|
||||
m_unAccountInstance = 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
// Input : unAccountID - 32-bit account ID
|
||||
// eUniverse - Universe this account belongs to
|
||||
// eAccountType - Type of account
|
||||
//-----------------------------------------------------------------------------
|
||||
CSteamID( uint32 unAccountID, EUniverse eUniverse, EAccountType eAccountType )
|
||||
{
|
||||
Set( unAccountID, eUniverse, eAccountType );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
// Input : unAccountID - 32-bit account ID
|
||||
// unAccountInstance - instance
|
||||
// eUniverse - Universe this account belongs to
|
||||
// eAccountType - Type of account
|
||||
//-----------------------------------------------------------------------------
|
||||
CSteamID( uint32 unAccountID, unsigned int unAccountInstance, EUniverse eUniverse, EAccountType eAccountType )
|
||||
{
|
||||
#if defined(_SERVER) && defined(Assert)
|
||||
Assert( ! ( ( k_EAccountTypeIndividual == eAccountType ) && ( 1 != unAccountInstance ) ) ); // enforce that for individual accounts, instance is always 1
|
||||
#endif // _SERVER
|
||||
InstancedSet( unAccountID, unAccountInstance, eUniverse, eAccountType );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
// Input : ulSteamID - 64-bit representation of a Steam ID
|
||||
// Note: Will not accept a uint32 or int32 as input, as that is a probable mistake.
|
||||
// See the stubbed out overloads in the private: section for more info.
|
||||
//-----------------------------------------------------------------------------
|
||||
CSteamID( uint64 ulSteamID )
|
||||
{
|
||||
SetFromUint64( ulSteamID );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sets parameters for steam ID
|
||||
// Input : unAccountID - 32-bit account ID
|
||||
// eUniverse - Universe this account belongs to
|
||||
// eAccountType - Type of account
|
||||
//-----------------------------------------------------------------------------
|
||||
void Set( uint32 unAccountID, EUniverse eUniverse, EAccountType eAccountType )
|
||||
{
|
||||
m_unAccountID = unAccountID;
|
||||
m_EUniverse = eUniverse;
|
||||
m_EAccountType = eAccountType;
|
||||
m_unAccountInstance = 1;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sets parameters for steam ID
|
||||
// Input : unAccountID - 32-bit account ID
|
||||
// eUniverse - Universe this account belongs to
|
||||
// eAccountType - Type of account
|
||||
//-----------------------------------------------------------------------------
|
||||
void InstancedSet( uint32 unAccountID, uint32 unInstance, EUniverse eUniverse, EAccountType eAccountType )
|
||||
{
|
||||
m_unAccountID = unAccountID;
|
||||
m_EUniverse = eUniverse;
|
||||
m_EAccountType = eAccountType;
|
||||
m_unAccountInstance = unInstance;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Initializes a steam ID from its 52 bit parts and universe/type
|
||||
// Input : ulIdentifier - 52 bits of goodness
|
||||
//-----------------------------------------------------------------------------
|
||||
void FullSet( uint64 ulIdentifier, EUniverse eUniverse, EAccountType eAccountType )
|
||||
{
|
||||
m_unAccountID = ( ulIdentifier & 0xFFFFFFFF ); // account ID is low 32 bits
|
||||
m_unAccountInstance = ( ( ulIdentifier >> 32 ) & 0xFFFFF ); // account instance is next 20 bits
|
||||
m_EUniverse = eUniverse;
|
||||
m_EAccountType = eAccountType;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Initializes a steam ID from its 64-bit representation
|
||||
// Input : ulSteamID - 64-bit representation of a Steam ID
|
||||
//-----------------------------------------------------------------------------
|
||||
void SetFromUint64( uint64 ulSteamID )
|
||||
{
|
||||
m_unAccountID = ( ulSteamID & 0xFFFFFFFF ); // account ID is low 32 bits
|
||||
m_unAccountInstance = ( ( ulSteamID >> 32 ) & 0xFFFFF ); // account instance is next 20 bits
|
||||
|
||||
m_EAccountType = ( EAccountType ) ( ( ulSteamID >> 52 ) & 0xF ); // type is next 4 bits
|
||||
m_EUniverse = ( EUniverse ) ( ( ulSteamID >> 56 ) & 0xFF ); // universe is next 8 bits
|
||||
}
|
||||
|
||||
|
||||
#if defined( INCLUDED_STEAM_COMMON_STEAMCOMMON_H )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Initializes a steam ID from a Steam2 ID structure
|
||||
// Input: pTSteamGlobalUserID - Steam2 ID to convert
|
||||
// eUniverse - universe this ID belongs to
|
||||
//-----------------------------------------------------------------------------
|
||||
void SetFromSteam2( TSteamGlobalUserID *pTSteamGlobalUserID, EUniverse eUniverse )
|
||||
{
|
||||
m_unAccountID = pTSteamGlobalUserID->m_SteamLocalUserID.Split.Low32bits * 2 +
|
||||
pTSteamGlobalUserID->m_SteamLocalUserID.Split.High32bits;
|
||||
m_EUniverse = eUniverse; // set the universe
|
||||
m_EAccountType = k_EAccountTypeIndividual; // Steam 2 accounts always map to account type of individual
|
||||
m_unAccountInstance = 1; // individual accounts always have an account instance ID of 1
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Fills out a Steam2 ID structure
|
||||
// Input: pTSteamGlobalUserID - Steam2 ID to write to
|
||||
//-----------------------------------------------------------------------------
|
||||
void ConvertToSteam2( TSteamGlobalUserID *pTSteamGlobalUserID ) const
|
||||
{
|
||||
// only individual accounts have any meaning in Steam 2, only they can be mapped
|
||||
// Assert( m_EAccountType == k_EAccountTypeIndividual );
|
||||
|
||||
pTSteamGlobalUserID->m_SteamInstanceID = 0;
|
||||
pTSteamGlobalUserID->m_SteamLocalUserID.Split.High32bits = m_unAccountID % 2;
|
||||
pTSteamGlobalUserID->m_SteamLocalUserID.Split.Low32bits = m_unAccountID / 2;
|
||||
}
|
||||
#endif // defined( INCLUDED_STEAM_COMMON_STEAMCOMMON_H )
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Converts steam ID to its 64-bit representation
|
||||
// Output : 64-bit representation of a Steam ID
|
||||
//-----------------------------------------------------------------------------
|
||||
uint64 ConvertToUint64() const
|
||||
{
|
||||
return (uint64) ( ( ( (uint64) m_EUniverse ) << 56 ) + ( ( (uint64) m_EAccountType ) << 52 ) +
|
||||
( ( (uint64) m_unAccountInstance ) << 32 ) + m_unAccountID );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Converts the static parts of a steam ID to a 64-bit representation.
|
||||
// For multiseat accounts, all instances of that account will have the
|
||||
// same static account key, so they can be grouped together by the static
|
||||
// account key.
|
||||
// Output : 64-bit static account key
|
||||
//-----------------------------------------------------------------------------
|
||||
uint64 GetStaticAccountKey() const
|
||||
{
|
||||
// note we do NOT include the account instance (which is a dynamic property) in the static account key
|
||||
return (uint64) ( ( ( (uint64) m_EUniverse ) << 56 ) + ((uint64) m_EAccountType << 52 ) + m_unAccountID );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: create an anonymous game server login to be filled in by the AM
|
||||
//-----------------------------------------------------------------------------
|
||||
void CreateBlankAnonLogon( EUniverse eUniverse )
|
||||
{
|
||||
m_unAccountID = 0;
|
||||
m_EAccountType = k_EAccountTypeAnonGameServer;
|
||||
m_EUniverse = eUniverse;
|
||||
m_unAccountInstance = 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: create an anonymous game server login to be filled in by the AM
|
||||
//-----------------------------------------------------------------------------
|
||||
void CreateBlankAnonUserLogon( EUniverse eUniverse )
|
||||
{
|
||||
m_unAccountID = 0;
|
||||
m_EAccountType = k_EAccountTypeAnonUser;
|
||||
m_EUniverse = eUniverse;
|
||||
m_unAccountInstance = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Is this an anonymous game server login that will be filled in?
|
||||
//-----------------------------------------------------------------------------
|
||||
bool BBlankAnonAccount() const
|
||||
{
|
||||
return m_unAccountID == 0 && BAnonAccount() && m_unAccountInstance == 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Is this a game server account id?
|
||||
//-----------------------------------------------------------------------------
|
||||
bool BGameServerAccount() const
|
||||
{
|
||||
return m_EAccountType == k_EAccountTypeGameServer || m_EAccountType == k_EAccountTypeAnonGameServer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Is this a content server account id?
|
||||
//-----------------------------------------------------------------------------
|
||||
bool BContentServerAccount() const
|
||||
{
|
||||
return m_EAccountType == k_EAccountTypeContentServer;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Is this a clan account id?
|
||||
//-----------------------------------------------------------------------------
|
||||
bool BClanAccount() const
|
||||
{
|
||||
return m_EAccountType == k_EAccountTypeClan;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Is this a chat account id?
|
||||
//-----------------------------------------------------------------------------
|
||||
bool BChatAccount() const
|
||||
{
|
||||
return m_EAccountType == k_EAccountTypeChat;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Is this an individual user account id?
|
||||
//-----------------------------------------------------------------------------
|
||||
bool BIndividualAccount() const
|
||||
{
|
||||
return m_EAccountType == k_EAccountTypeIndividual;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Is this an anonymous account?
|
||||
//-----------------------------------------------------------------------------
|
||||
bool BAnonAccount() const
|
||||
{
|
||||
return m_EAccountType == k_EAccountTypeAnonUser || m_EAccountType == k_EAccountTypeAnonGameServer;
|
||||
}
|
||||
|
||||
|
||||
// simple accessors
|
||||
void SetAccountID( uint32 unAccountID ) { m_unAccountID = unAccountID; }
|
||||
uint32 GetAccountID() const { return m_unAccountID; }
|
||||
uint32 GetUnAccountInstance() const { return m_unAccountInstance; }
|
||||
EAccountType GetEAccountType() const { return ( EAccountType ) m_EAccountType; }
|
||||
EUniverse GetEUniverse() const { return m_EUniverse; }
|
||||
void SetEUniverse( EUniverse eUniverse ) { m_EUniverse = eUniverse; }
|
||||
bool IsValid() const { return ( m_EAccountType != k_EAccountTypeInvalid && m_EUniverse != k_EUniverseInvalid ); }
|
||||
|
||||
// this set of functions is hidden, will be moved out of class
|
||||
explicit CSteamID( const char *pchSteamID, EUniverse eDefaultUniverse = k_EUniverseInvalid );
|
||||
char * Render() const; // renders this steam ID to string
|
||||
static char * Render( uint64 ulSteamID ); // static method to render a uint64 representation of a steam ID to a string
|
||||
|
||||
void SetFromString( const char *pchSteamID, EUniverse eDefaultUniverse );
|
||||
bool SetFromSteam2String( const char *pchSteam2ID, EUniverse eUniverse );
|
||||
|
||||
bool operator==( const CSteamID &val ) const
|
||||
{
|
||||
return ( ( val.m_unAccountID == m_unAccountID ) && ( val.m_unAccountInstance == m_unAccountInstance )
|
||||
&& ( val.m_EAccountType == m_EAccountType ) && ( val.m_EUniverse == m_EUniverse ) );
|
||||
}
|
||||
|
||||
bool operator!=( const CSteamID &val ) const { return !operator==( val ); }
|
||||
bool operator<( const CSteamID &val ) const { return ConvertToUint64() < val.ConvertToUint64(); }
|
||||
bool operator>( const CSteamID &val ) const { return ConvertToUint64() > val.ConvertToUint64(); }
|
||||
|
||||
// DEBUG function
|
||||
bool BValidExternalSteamID() const;
|
||||
|
||||
private:
|
||||
// These are defined here to prevent accidental implicit conversion of a u32AccountID to a CSteamID.
|
||||
// If you get a compiler error about an ambiguous constructor/function then it may be because you're
|
||||
// passing a 32-bit int to a function that takes a CSteamID. You should explicitly create the SteamID
|
||||
// using the correct Universe and account Type/Instance values.
|
||||
CSteamID( uint32 );
|
||||
CSteamID( int32 );
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4201) // nameless union is nonstandard
|
||||
// 64 bits total
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
#endif
|
||||
uint32 m_unAccountID : 32; // unique account identifier
|
||||
unsigned int m_unAccountInstance : 20; // dynamic instance ID (used for multiseat type accounts only)
|
||||
unsigned int m_EAccountType : 4; // type of account - can't show as EAccountType, due to signed / unsigned difference
|
||||
EUniverse m_EUniverse : 8; // universe this account belongs to
|
||||
#ifdef _WIN32
|
||||
};
|
||||
|
||||
uint64 m_unAll64Bits;
|
||||
};
|
||||
#pragma warning(pop) // no more anonymous unions until next time
|
||||
#endif
|
||||
};
|
||||
|
||||
const int k_unSteamAccountIDMask = 0xFFFFFFFF;
|
||||
const int k_unSteamAccountInstanceMask = 0x000FFFFF;
|
||||
|
||||
|
||||
// Special flags for Chat accounts - they go in the top 8 bits
|
||||
// of the steam ID's "instance", leaving 12 for the actual instances
|
||||
enum EChatSteamIDInstanceFlags
|
||||
{
|
||||
k_EChatAccountInstanceMask = 0x00000FFF, // top 8 bits are flags
|
||||
|
||||
k_EChatInstanceFlagClan = ( k_unSteamAccountInstanceMask + 1 ) >> 1, // top bit
|
||||
k_EChatInstanceFlagLobby = ( k_unSteamAccountInstanceMask + 1 ) >> 2, // next one down, etc
|
||||
|
||||
// Max of 8 flags
|
||||
};
|
||||
|
||||
|
||||
// generic invalid CSteamID
|
||||
const CSteamID k_steamIDNil;
|
||||
|
||||
// This steamID comes from a user game connection to an out of date GS that hasnt implemented the protocol
|
||||
// to provide its steamID
|
||||
const CSteamID k_steamIDOutofDateGS( 0, 0, k_EUniverseInvalid, k_EAccountTypeInvalid );
|
||||
// This steamID comes from a user game connection to an sv_lan GS
|
||||
const CSteamID k_steamIDLanModeGS( 0, 0, k_EUniversePublic, k_EAccountTypeInvalid );
|
||||
// This steamID can come from a user game connection to a GS that has just booted but hasnt yet even initialized
|
||||
// its steam3 component and started logging on.
|
||||
const CSteamID k_steamIDNotInitYetGS( 1, 0, k_EUniverseInvalid, k_EAccountTypeInvalid );
|
||||
|
||||
|
||||
#ifdef STEAM
|
||||
// Returns the matching chat steamID, with the default instance of 0
|
||||
// If the steamID passed in is already of type k_EAccountTypeChat it will be returned with the same instance
|
||||
CSteamID ChatIDFromSteamID( CSteamID &steamID );
|
||||
// Returns the matching clan steamID, with the default instance of 0
|
||||
// If the steamID passed in is already of type k_EAccountTypeClan it will be returned with the same instance
|
||||
CSteamID ClanIDFromSteamID( CSteamID &steamID );
|
||||
// Asserts steamID type before conversion
|
||||
CSteamID ChatIDFromClanID( CSteamID &steamIDClan );
|
||||
// Asserts steamID type before conversion
|
||||
CSteamID ClanIDFromChatID( CSteamID &steamIDChat );
|
||||
|
||||
#endif // _STEAM
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: encapsulates an appID/modID pair
|
||||
//-----------------------------------------------------------------------------
|
||||
class CGameID
|
||||
{
|
||||
public:
|
||||
CGameID()
|
||||
{
|
||||
m_ulGameID = 0;
|
||||
}
|
||||
|
||||
explicit CGameID( uint64 ulGameID )
|
||||
{
|
||||
m_ulGameID = ulGameID;
|
||||
}
|
||||
|
||||
explicit CGameID( int32 nAppID )
|
||||
{
|
||||
m_ulGameID = 0;
|
||||
m_gameID.m_nAppID = nAppID;
|
||||
}
|
||||
|
||||
explicit CGameID( uint32 nAppID )
|
||||
{
|
||||
m_ulGameID = 0;
|
||||
m_gameID.m_nAppID = nAppID;
|
||||
}
|
||||
|
||||
CGameID( uint32 nAppID, uint32 nModID )
|
||||
{
|
||||
m_ulGameID = 0;
|
||||
m_gameID.m_nAppID = nAppID;
|
||||
m_gameID.m_nModID = nModID;
|
||||
m_gameID.m_nType = k_EGameIDTypeGameMod;
|
||||
}
|
||||
|
||||
// Hidden functions used only by Steam
|
||||
explicit CGameID( const char *pchGameID );
|
||||
char * Render() const; // renders this Game ID to string
|
||||
static char * Render( uint64 ulGameID ); // static method to render a uint64 representation of a Game ID to a string
|
||||
|
||||
// must include checksum_crc.h first to get this functionality
|
||||
#if defined( CHECKSUM_CRC_H )
|
||||
CGameID( uint32 nAppID, const char *pchModPath )
|
||||
{
|
||||
m_ulGameID = 0;
|
||||
m_gameID.m_nAppID = nAppID;
|
||||
m_gameID.m_nType = k_EGameIDTypeGameMod;
|
||||
|
||||
char rgchModDir[MAX_PATH];
|
||||
Q_FileBase( pchModPath, rgchModDir, sizeof( rgchModDir ) );
|
||||
CRC32_t crc32;
|
||||
CRC32_Init( &crc32 );
|
||||
CRC32_ProcessBuffer( &crc32, rgchModDir, Q_strlen( rgchModDir ) );
|
||||
CRC32_Final( &crc32 );
|
||||
|
||||
// set the high-bit on the mod-id
|
||||
// reduces crc32 to 31bits, but lets us use the modID as a guaranteed unique
|
||||
// replacement for appID's
|
||||
m_gameID.m_nModID = crc32 | (0x80000000);
|
||||
}
|
||||
|
||||
CGameID( const char *pchExePath, const char *pchAppName )
|
||||
{
|
||||
m_ulGameID = 0;
|
||||
m_gameID.m_nAppID = 0;
|
||||
m_gameID.m_nType = k_EGameIDTypeShortcut;
|
||||
|
||||
CRC32_t crc32;
|
||||
CRC32_Init( &crc32 );
|
||||
CRC32_ProcessBuffer( &crc32, pchExePath, Q_strlen( pchExePath ) );
|
||||
CRC32_ProcessBuffer( &crc32, pchAppName, Q_strlen( pchAppName ) );
|
||||
CRC32_Final( &crc32 );
|
||||
|
||||
// set the high-bit on the mod-id
|
||||
// reduces crc32 to 31bits, but lets us use the modID as a guaranteed unique
|
||||
// replacement for appID's
|
||||
m_gameID.m_nModID = crc32 | (0x80000000);
|
||||
}
|
||||
#endif
|
||||
|
||||
void SetAsShortcut()
|
||||
{
|
||||
m_gameID.m_nAppID = 0;
|
||||
m_gameID.m_nType = k_EGameIDTypeShortcut;
|
||||
}
|
||||
|
||||
void SetAsP2PFile()
|
||||
{
|
||||
m_gameID.m_nAppID = 0;
|
||||
m_gameID.m_nType = k_EGameIDTypeP2P;
|
||||
}
|
||||
|
||||
uint64 ToUint64() const
|
||||
{
|
||||
return m_ulGameID;
|
||||
}
|
||||
|
||||
uint64 *GetUint64Ptr()
|
||||
{
|
||||
return &m_ulGameID;
|
||||
}
|
||||
|
||||
bool IsMod() const
|
||||
{
|
||||
return ( m_gameID.m_nType == k_EGameIDTypeGameMod );
|
||||
}
|
||||
|
||||
bool IsShortcut() const
|
||||
{
|
||||
return ( m_gameID.m_nType == k_EGameIDTypeShortcut );
|
||||
}
|
||||
|
||||
bool IsP2PFile() const
|
||||
{
|
||||
return ( m_gameID.m_nType == k_EGameIDTypeP2P );
|
||||
}
|
||||
|
||||
bool IsSteamApp() const
|
||||
{
|
||||
return ( m_gameID.m_nType == k_EGameIDTypeApp );
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint32 ModID() const
|
||||
{
|
||||
return m_gameID.m_nModID;
|
||||
}
|
||||
|
||||
uint32 AppID() const
|
||||
{
|
||||
return m_gameID.m_nAppID;
|
||||
}
|
||||
|
||||
bool operator == ( const CGameID &rhs ) const
|
||||
{
|
||||
return m_ulGameID == rhs.m_ulGameID;
|
||||
}
|
||||
|
||||
bool operator != ( const CGameID &rhs ) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
bool operator < ( const CGameID &rhs ) const
|
||||
{
|
||||
return ( m_ulGameID < rhs.m_ulGameID );
|
||||
}
|
||||
|
||||
bool IsValid() const
|
||||
{
|
||||
return ( m_ulGameID != 0 );
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_ulGameID = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
enum EGameIDType
|
||||
{
|
||||
k_EGameIDTypeApp = 0,
|
||||
k_EGameIDTypeGameMod = 1,
|
||||
k_EGameIDTypeShortcut = 2,
|
||||
k_EGameIDTypeP2P = 3,
|
||||
};
|
||||
|
||||
struct GameID_t
|
||||
{
|
||||
unsigned int m_nAppID : 24;
|
||||
unsigned int m_nType : 8;
|
||||
unsigned int m_nModID : 32;
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
uint64 m_ulGameID;
|
||||
GameID_t m_gameID;
|
||||
};
|
||||
};
|
||||
|
||||
#pragma pack( pop )
|
||||
|
||||
const int k_cchGameExtraInfoMax = 64;
|
||||
|
||||
|
||||
// Max number of credit cards stored for one account
|
||||
const int k_nMaxNumCardsPerAccount = 1;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constants used for query ports.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define QUERY_PORT_NOT_INITIALIZED 0xFFFF // We haven't asked the GS for this query port's actual value yet.
|
||||
#define QUERY_PORT_ERROR 0xFFFE // We were unable to get the query port for this server.
|
||||
|
||||
#endif // STEAMCLIENTPUBLIC_H
|
||||
@@ -0,0 +1,85 @@
|
||||
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef STEAMTYPES_H
|
||||
#define STEAMTYPES_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// Steam-specific types. Defined here so this header file can be included in other code bases.
|
||||
#ifndef WCHARTYPES_H
|
||||
typedef unsigned char uint8;
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__x86_64__) || defined(_WIN64)
|
||||
#define X64BITS
|
||||
#endif
|
||||
|
||||
typedef unsigned char uint8;
|
||||
typedef signed char int8;
|
||||
|
||||
#if defined( _WIN32 )
|
||||
|
||||
typedef __int16 int16;
|
||||
typedef unsigned __int16 uint16;
|
||||
typedef __int32 int32;
|
||||
typedef unsigned __int32 uint32;
|
||||
typedef __int64 int64;
|
||||
typedef unsigned __int64 uint64;
|
||||
|
||||
#ifdef X64BITS
|
||||
typedef __int64 intp; // intp is an integer that can accomodate a pointer
|
||||
typedef unsigned __int64 uintp; // (ie, sizeof(intp) >= sizeof(int) && sizeof(intp) >= sizeof(void *)
|
||||
#else
|
||||
typedef __int32 intp;
|
||||
typedef unsigned __int32 uintp;
|
||||
#endif
|
||||
|
||||
#else // _WIN32
|
||||
|
||||
typedef short int16;
|
||||
typedef unsigned short uint16;
|
||||
typedef int int32;
|
||||
typedef unsigned int uint32;
|
||||
typedef long long int64;
|
||||
typedef unsigned long long uint64;
|
||||
#ifdef X64BITS
|
||||
typedef long long intp;
|
||||
typedef unsigned long long uintp;
|
||||
#else
|
||||
typedef int intp;
|
||||
typedef unsigned int uintp;
|
||||
#endif
|
||||
|
||||
#endif // else _WIN32
|
||||
|
||||
const int k_cubDigestSize = 20; // CryptoPP::SHA::DIGESTSIZE
|
||||
const int k_cubSaltSize = 8;
|
||||
|
||||
typedef uint8 SHADigest_t[ k_cubDigestSize ];
|
||||
typedef uint8 Salt_t[ k_cubSaltSize ];
|
||||
|
||||
typedef uint64 GID_t; // globally unique identifier
|
||||
|
||||
// this is baked into client messages and interfaces as an int,
|
||||
// make sure we never break this.
|
||||
typedef uint32 PackageId_t;
|
||||
const PackageId_t k_uPackageIdInvalid = 0xFFFFFFFF;
|
||||
|
||||
|
||||
// this is baked into client messages and interfaces as an int,
|
||||
// make sure we never break this.
|
||||
typedef uint32 AppId_t;
|
||||
const AppId_t k_uAppIdInvalid = 0xFFFFFFFF;
|
||||
|
||||
// RTime32
|
||||
// We use this 32 bit time representing real world time.
|
||||
// It offers 1 second resolution beginning on January 1, 1970 (Unix time)
|
||||
typedef uint32 RTime32;
|
||||
|
||||
#endif // STEAMTYPES_H
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,29 @@
|
||||
:Base ContentTool.hlp
|
||||
1 Getting Started
|
||||
2 What is ContentTool=IDH_ABOUT_CONTENTTOOL
|
||||
2 ContentTool Components=IDH_CONTENTTOOL_COMPONENTS
|
||||
2 Overview of Steam Publishing=IDH_CONTENTTOOL_OVERVIEW
|
||||
1 Step-by-Step Procedures
|
||||
2 Creating a New Depot=IDH_CREATE_NEW_DEPOT
|
||||
2 Adding Files to a Depot=IDH_ADDING_FILES
|
||||
2 Moving Files in the Depot=IDH_MOVING_FILES
|
||||
2 Deleting Files in the Depot=IDH_DELETING_FILES
|
||||
2 Assigning Attributes to Files=IDH_ASSIGNING_ATTRIBUTES
|
||||
2 Building the Depot=IDH_BUILING_DEPOT
|
||||
2 Adding New Versions=IDH_ADDING_NEW_VERSIONS
|
||||
2 Modifying Old Versions=IDH_MOD_OLD_VERSIONS
|
||||
2 Publishing your Depot=IDH_EDITCONTENT
|
||||
1 ContentTool Reference
|
||||
2 Menus
|
||||
3 File menu=menu_file
|
||||
3 Edit menu=menu_edit
|
||||
3 View menu=menu_view
|
||||
3 Project menu=menu_project
|
||||
3 Build menu=menu_build
|
||||
3 Reslist menu=menu_reslist
|
||||
3 Help menu=menu_help
|
||||
2 Scripting
|
||||
3 Scripting overview=IDH_SCRIPT_OVERVIEW
|
||||
3 Creating script files=IDH_SCRIPT_FILE
|
||||
3 Script commands=IDH_SCRIPT_CMDS
|
||||
3 Running scripts=IDH_SCRIPT_RUN
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,4 @@
|
||||
[autorun]
|
||||
OPEN=SETUP.EXE
|
||||
ICON=ICON.ICO
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,26 @@
|
||||
{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\froman\fcharset0 Times;}{\f1\froman\fcharset0 Times New Roman;}{\f2\fswiss\fcharset0 Arial;}}
|
||||
{\colortbl ;\red0\green0\blue0;}
|
||||
{\*\generator Msftedit 5.41.15.1507;}\viewkind4\uc1\pard\nowidctlpar\fi720\qc\b\f0\fs20 YOU SHOULD CAREFULLY READ THE ENTIRE FOLLOWING LICENSE AGREEMENT BEFORE INSTALLING THIS SOFTWARE PROGRAM. THIS AGREEMENT CONTAINS IMPORTANT TERMS THAT AFFECT YOUR LEGAL RIGHTS. BY INSTALLING THE SOFTWARE PROGRAM, YOU AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT. IF YOU DO NOT AGREE TO THE TERMS OF THIS AGREEMENT, PLEASE DO NOT INSTALL THIS SOFTWARE PROGRAM.\par
|
||||
\par
|
||||
\pard\nowidctlpar\sa120\qj\tx360\tx720\b0 The software application(s) (the \ldblquote\ul Program\ulnone\rdblquote ), and any and all copies of the Program are the copyrighted work of Valve Corporation (\ldblquote\ul Valve\ulnone\rdblquote ) or its suppliers. All rights reserved, except as expressly stated herein. The Program is provided solely for installation by end users according to the terms of this License Agreement. All use of the Program is governed by the terms of the Steam Agreement as described below. Any use, reproduction or redistribution of the Program not in accordance with the terms of the License Agreement and the Steam Agreement is expressly prohibited.\par
|
||||
\pard\nowidctlpar\qc\ul\b\f1 LICENSE AGREEMENT\par
|
||||
\pard\nowidctlpar\par
|
||||
\pard\nowidctlpar\qj\tx360\ulnone\b0\tab 1. \ul Limited Installation License\ulnone . \par
|
||||
\par
|
||||
\pard\nowidctlpar\fi720\qj\tx360 A. Valve hereby grants, and by installing the Program you thereby accept, a limited, non-exclusive license and right to install one (1) copy of the Program on a computer. In order to use the Program you will have to obtain an account with the Steam service and accept the terms of the \f0 Steam subscriber agreement (\ldblquote\ul Steam Agreement\ulnone\rdblquote )\f1 . \f0 By installing the Program, you agree that your future use of the Program will be subject to the terms of the Steam Agreement. A copy of the Steam Agreement is available at \ul www.steampowered.com/agreement.\ulnone \f1 The Steam Agreement will be displayed to you when you obtain an account with the Steam service. The Program is licensed, not sold. Your license confers no title or ownership in the Program or copies thereof.\par
|
||||
\pard\nowidctlpar\qj\tx360\par
|
||||
\pard\nowidctlpar\fi720 B. \f0 You may not, in whole or in part: copy, photocopy, reproduce, translate, reverse engineer\cf1 (with the exception of specific circumstances where such act is permitted by law)\cf0 , derive source code, modify, disassemble, decompile, or create derivative works based on the Program; remove any proprietary notices or labels on the Program; or attempt in any manner to circumvent any security measures designed to control access to the Program. The Program is licensed to you as a single product. Its component parts may not be separated for use on more than one computer. You may not sell, grant a security interest in or transfer reproductions of the Program to other parties in any way, nor to rent, lease or license the Program to others without the prior written consent of Valve.\f1\par
|
||||
\pard\nowidctlpar\sa120\qj\tx360\tx720\f0\tab\par
|
||||
\tab 2. \ul Ownership\ulnone . All title, ownership rights and intellectual property rights in and to the Program and any and all copies thereof (including but not limited to any titles, computer code, themes, objects, characters, character names, stories, dialog, catch phrases, locations, concepts, artwork, animations, sounds, musical compositions, audio-visual effects, methods of operation, moral rights, any related documentation, and \ldblquote applets\rdblquote incorporated into the Program) are owned by Valve or its licensors. The Program is protected by the copyright laws of the United States, international copyright treaties and conventions and other laws. All rights are reserved. The Program contains certain licensed materials and Valve\rquote s licensors may protect their rights in the event of any violation of this Agreement.\par
|
||||
\tab 3. \ul Termination\ulnone . This License Agreement is effective until terminated. You may terminate the License Agreement at any time by destroying the Program. Valve may, at its discretion, terminate this License Agreement in the event that you fail to comply with the terms and conditions contained herein. This License Agreement shall automatically terminate in the event that you fail to comply with the terms and conditions contained herein. In such event, you must immediately destroy the Program. The provisions of Sections 2, 3, and 5-8 will survive any termination of the Agreement. \par
|
||||
\tab 4. \ul Export Controls\ulnone . The Program may not be re-exported, downloaded or otherwise exported into (or to a national or resident of) any country to which the U.S. has embargoed goods, or to anyone on the U.S. Treasury Department\rquote s list of Specially Designated Nationals or the U.S. Commerce Department\rquote s Table of Denial Orders. By installing the Program, you are agreeing to the foregoing and you are representing and warranting that you are not located in, under the control of, or a national or resident of any such country or on any such list.\par
|
||||
\pard\nowidctlpar\fi360\qj\tx8100\f1 5. \ul Limited Warranty\ulnone . The entire risk arising out of use or performance of the Program and any printed material(s) remains with the User.\f2 \f1 EXCEPT AS PROVIDED ABOVE, \caps The Program and ANY PRINTED MATERIAL(s) are provided "as is" without warranty of any kind, either express or implied, including, without limitation, the implied warranties of merchantability, fitness for a particular purpose, or noninfringement. \caps0 ANY WARRANTY AGAINST INFRINGEMENT THAT MAY BE PROVIDED IN SECTION 2-312(3) OF THE UNIFORM COMMERCIAL CODE AND/OR IN ANY OTHER COMPARABLE STATE STATUTE IS EXPRESSLY DISCLAIMED. Some states/jurisdictions do not allow the exclusion or limitation of implied warranties, so the above limitations may not apply to you.\par
|
||||
\pard\nowidctlpar\qj\tx360\tx720\f0\fs18\par
|
||||
\pard\nowidctlpar\qj\tx360\f1\tab 6. \ul\fs20 Limitation of Liability\ulnone . VALVE, ITS SUPPLIERS AND DISTRIBUTORS SHALL NOT BE LIABLE IN ANY WAY FOR LOSS OR DAMAGE OF ANY KIND RESULTING FROM THE USE OF THE PROGRAM INCLUDING, BUT NOT LIMITED TO, LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES. ANY WARRANTY AGAINST INFRINGEMENT THAT MAY BE PROVIDED IN SECTION 2-312(3) OF THE UNIFORM COMMERCIAL CODE AND/OR IN ANY OTHER COMPARABLE STATE STATUTE IS EXPRESSLY DISCLAIMED. \caps Valve CANNOT AND WILL NOT BE RESPONSIBLE FOR ANY SOFTWARE OR HARDWARE FAILURES OR ANY OTHER EVENT WHICH MAY RESULT IN A LOSS OF DATA OR DISRUPTION OF SERVICE. \caps0 Some states/jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so the above limitations may not apply. \par
|
||||
\pard\nowidctlpar\qj\par
|
||||
\pard\nowidctlpar\sa120\qj\tx360\tab 7. \ul Equitable Remedies\ulnone . You hereby agree that Valve would be irreparably damaged if the terms of this License Agreement were not specifically enforced, and therefore you agree that Valve shall be entitled to appropriate equitable remedies with respect to breaches of this License Agreement, in addition to such other remedies as Valve may otherwise have available to it under applicable laws. In the event any litigation is brought by either party in connection with this License Agreement, the prevailing party in such litigation shall be entitled to recover from the other party all the costs, attorneys\rquote fees and other expenses incurred by such prevailing party in the litigation.\par
|
||||
\tab 8. \ul Miscellaneous\ulnone .\cf1 The terms of this paragraph do not apply to European Union consumers in the sense of Art. 5 of the Convention on the Law Applicable to Contractual Obligations opened for signature in Rome on 19 June 1980 (Rome Convention, 80/934/EEC) and national legislation based thereon.\cf0 You agree that this Agreement shall be deemed to have been made and executed in the State of Washington, and any dispute arising hereunder shall be resolved in accordance with the law of Washington. You agree that any claim asserted in any legal proceeding by you against Valve shall only be commenced and maintained in any state or federal court located in King County, Washington, and you agree to submit to the exclusive jurisdiction of those courts. In any dispute arising under this Agreement, the prevailing party will be entitled to attorneys' fees and expenses. This License Agreement may be amended, altered or modified only by an instrument in writing, specifying such amendment, alteration or modification, executed by both you and Valve. In the event that any provision of this License Agreement shall be held by a court or other tribunal of competent jurisdiction to be unenforceable, such provision will be enforced to the maximum extent permissible and the remaining portions of this License Agreement shall remain in full force and effect. This License Agreement and the Steam Agreement constitute and contain the entire agreement between the parties with respect to the subject matter hereof and supersede any prior oral or written agreements.\par
|
||||
You hereby acknowledge that you have read and understand the foregoing License Agreement and agree that the action of installing the Program is an acknowledgment of your agreement to be bound by the terms and conditions of the License Agreement contained herein.\par
|
||||
\par
|
||||
}
|
||||
| ||||