+ y% W3 ?1 o, Y' S; Y<> * c$ M" x% t/ V' n//-----------------------------------------------------------------------------/ Y- p/ L1 o& W; g0 e5 B A
// Name: " I; z" W# r- x: ]
// Desc: " k0 q' c& I5 b) i//----------------------------------------------------------------------------- 7 T/ L* x" L( n+ h% c' [void CMazeServer:ockCell( DWORD x, DWORD y ) ( o! R& M- f' ^& Q* K6 u{ % p) C. a8 c; o- i' E$ z if( x == 0xffff ) ! y) G- [9 S# G6 `5 S p4 v m_OffMapLock.Enter(); 1 t# B3 \+ z: C( c% F else ! R' y( {2 X. K, g4 w8 R2 O5 P9 ^ m_LockGrid.LockCell(x>>m_dwMazeXShift,y>>m_dwMazeYShift);8 ? ^" V* A( r0 V8 V: H
}</P> 1 ~9 `# G8 B2 K6 e- z( D 9 o! z- X$ G- h m- [! h6 }<>+ H0 s5 Q2 E2 P0 R- V5 b
//-----------------------------------------------------------------------------0 ]: I2 ~7 ~# R' Q) g4 k; i5 `
// Name: ; V9 |9 Y% [: i2 G+ ~9 k2 N3 g
// Desc: 7 T9 O# s' u7 ? v: N* A z//----------------------------------------------------------------------------- 5 A! D. x1 I, l* v6 } {/ V; X. Pvoid CMazeServer::UnlockCell( DWORD x, DWORD y )2 H. ]: ]6 _ _& r) |7 P
{6 e9 b' E) M4 K3 v
if( x == 0xffff ) , Z: R8 d, c' @ m_OffMapLock.Leave();8 l O9 h$ L; j9 w- I% H: m
else, |" W ]2 l7 y# r: }" s
m_LockGrid.UnlockCell(x>>m_dwMazeXShift,y>>m_dwMazeYShift); 0 w+ N1 F+ U' a}</P> 7 B! N7 ~7 y; |1 ?, i( G9 l3 W5 u0 M% ~8 ]* |: W- K* t3 H9 g+ c, K( K
<> . k$ b8 B' r+ w5 x4 ^* A9 T//-----------------------------------------------------------------------------7 L, ?* v L% b$ N
// Name: ' m* g3 t6 [. U. k7 ?* B& G4 A% j7 h// Desc: + j3 _; Y5 `6 n& E5 M9 A" a
//----------------------------------------------------------------------------- ( |1 z1 J% e0 {5 u2 {4 \) Yvoid CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )+ ]2 O, b( r& A$ O, K" t
{ % o1 P# m( }& }* f# G/ O2 [6 B if( x1 == x2 && y1 == y2 ) ! O/ O1 s$ K5 k9 l& H; B { % T9 G9 |9 ?% k) w$ Y v7 a6 i if( x1 != 0xffff && y2 != 0xffff )9 R) m8 a U8 }* ^, `
LockCell( x1, y1 );. W" o+ Y+ I+ D( Q3 [$ i
else% X, k$ c" C2 y) |8 s/ s
m_OffMapLock.Enter();</P> * N6 A/ Z4 ^6 z- X) R7 x9 O& A<> return; $ `' C6 x. G9 L0 H$ P5 }* A- ? }</P>' |6 I4 z; }3 U U ?" R2 [
<> DWORD x1shift = x1>>m_dwMazeXShift;8 ?- A1 A Q$ @8 Y: j
DWORD x2shift = x2>>m_dwMazeXShift; : E. N, m6 I' v4 s6 d DWORD y1shift = y1>>m_dwMazeYShift; w" s( Y( m' N% w: d5 n0 ~ DWORD y2shift = y2>>m_dwMazeYShift;</P> $ V; w P, w1 v& b+ G! g: }* i<> if( x1 == 0xffff ) / L9 J" E+ b) R( A% ~) ^ { & Z2 o ~; ~+ q: j7 x m_OffMapLock.Enter(); ! I, @; {7 T3 s5 @9 }5 t m_LockGrid.LockCell(x2shift,y2shift); 1 k4 z. C8 G/ ^6 j1 N' e" m }+ `6 R& d, Z4 G
else if( x2 == 0xffff ) 3 C7 d4 r, I- Z- p1 V+ z2 }, E6 {2 g! t { 1 v) W/ J* a# _% k, Z; k! B m_OffMapLock.Enter();3 E N% U" X1 C; X/ }8 P
m_LockGrid.LockCell(x1shift,y1shift); * Y, P' e% b [0 A } % [" Q0 @" B3 @7 K: X else 7 \6 @: \4 h% u( p& B/ o+ q. m+ L
{ ' y/ o! G% g; u m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift); ; l; Q( G7 ]/ Q c9 L) q) K! ` } / y0 F. C. b5 Z. b. s}</P> 5 n2 q. v; N* _# T' [: e0 S# [6 ]' H r/ y+ W9 L1 }
<>$ n" g) k' B- @ j E
//----------------------------------------------------------------------------- 1 S% y4 \% R$ y! f8 y% d) M// Name: $ m' Z7 l& R; s3 _& p! s// Desc: 1 a# v- m8 e- j( V
//-----------------------------------------------------------------------------3 w# j* A1 t% J% S3 ]! X8 H" o0 K. R
void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )( S6 v0 Z' f, X& h" R: I' Y
{ ( @. t& ]1 ^+ y1 e Z if( x1 == x2 && y1 == y2 ) & Z0 U. g( ]0 t4 D { $ C% N5 A# U5 e4 }- |& j! w if( x1 != 0xffff && y2 != 0xffff )$ f' A- x8 \+ j: X+ c7 z
UnlockCell( x1, y1 ); + T/ k; ?7 z- e4 _% I% t else& N( i/ T% m1 `+ z
m_OffMapLock.Leave();</P> $ P" }5 M* L9 o0 K/ U<> return; * ?" Y/ \. F( q, {3 ~: F }</P> 6 ^) J" M( X2 m& V<P> DWORD x1shift = x1>>m_dwMazeXShift;+ j% O8 E: N' {+ _7 x' {) I r E3 h/ M
DWORD x2shift = x2>>m_dwMazeXShift; 2 }" C& j( T* F4 U DWORD y1shift = y1>>m_dwMazeYShift; # t) C8 F7 I$ A) s/ y( y DWORD y2shift = y2>>m_dwMazeYShift;</P> ! C- M# ?; P4 U; `2 r' M<P> if( x1 == 0xffff )4 M1 C4 W6 G9 u3 [" T
{: l- @$ T1 W2 Y8 o) z# I
m_LockGrid.UnlockCell(x2shift,y2shift); , a+ D. {. x# w m_OffMapLock.Leave();+ [. C: n- o( ~% F# p7 `/ F* y
}7 S0 ~1 n7 Y5 A# s
else if( x2 == 0xffff )0 j9 \9 H0 G: e) \$ e0 W
{ ' A* H( ?4 I5 v1 W m_LockGrid.UnlockCell(x1shift,y1shift);. a' I' l6 R h5 e
m_OffMapLock.Leave(); ' j: c/ \( j3 z4 U8 m }" V: \6 V* W8 q( B/ S# O5 t
else - c, |0 D, ~% t8 _" i1 n p& k {# F& u0 x% F. v& x! B! I [; I0 I
m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift); 9 G% X- N; e- g' g7 l, K/ `5 Q } ) R" @& ]5 F2 h, M! O- c y4 w% _}</P>; j! I2 L/ @# N- W q+ r
0 t+ E2 w( R% L* _: f$ y, ~2 x<P> ) u2 z3 D) J2 t! O) t//----------------------------------------------------------------------------- ) H1 c+ O1 l( E3 t0 V// Name: ( x9 W' e* Z2 V# D" i// Desc: " L, G8 C8 L: J
//-----------------------------------------------------------------------------8 Y- }, m( {, ?+ v7 y% P- v
void CMazeServer::OnAddConnection( DWORD id ) * F" y$ U" j. H{3 [- ^0 ^) k" }7 L) Z
m_AddRemoveLock.Enter();</P>/ X) D5 g/ k- N* Z% {
<P> // Increment our count of players. b) x6 f; Y7 X9 E) e3 y) V
m_dwPlayerCount++; ; T9 s+ U" E u5 F if( m_dwLogLevel > 0 ). x: m8 l% u/ F8 C
{ . [+ W% Q+ C) i) G4 Q ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );, `! j+ \ E5 o! ?7 g: ]
ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount ); ; U) F9 n3 q l' {4 A }</P>* {9 r$ S$ \) z) o4 W7 g. @
<P> if( m_dwPlayerCount > m_dwPeakPlayerCount )& c/ [( h% T3 A$ y' U
m_dwPeakPlayerCount = m_dwPlayerCount;</P> % z& p0 _; s1 X; U% k/ g<P> // Create a player for this client + l; o, b d8 b) t) w PlayerData* pPlayerData = CreatePlayerData();1 Z& \6 [/ S0 i% @" L
if( pPlayerData == NULL ) + H$ d$ t7 ~- _ { & p1 d, ~: E5 A7 n, H ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );" _6 \6 m' n2 z# N/ _
DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL ); , z1 ^. \: q8 d3 T" e8 m3 C. [2 N m_AddRemoveLock.Leave();$ y* {6 G: \7 J' l: b
return; 3 c9 y9 o7 y- |& X; m4 {0 z }</P> 2 {0 U- r6 P7 b! g6 M<P> // Store that pointer as local player data 8 Q+ } j9 i4 p1 {3 q* V: R SetPlayerDataForID( id, pPlayerData );</P> P1 N g2 y0 B/ I
<P> // Grab net config into to send to client . x& C r; k0 s m_ClientNetConfigLock.Enter();: }3 |+ K- C: Y& H. g+ D Q" V% D
ServerConfigPacket packet( m_ClientNetConfig );$ A: e# s+ J/ G, c3 x+ o# k
m_ClientNetConfigLock.Leave();</P>- u# O8 |5 t! S" W8 r; H, a0 d- L$ U
<P> // Send it+ w" k. y$ D) k9 T
SendPacket( id, &packet, sizeof(packet), TRUE, 0 );</P> 4 V, L# ]& J, W% @$ x2 T' V4 V<P> m_AddRemoveLock.Leave();9 O# j' v3 J9 o9 U! J$ }$ }
}</P>, t: c# U. J' [! u# T2 H6 q
- g% x, ~6 T& x' B/ P S5 h
<P> ' b$ k- s$ P& }/ j" U//-----------------------------------------------------------------------------+ ^" x( Y* x9 y# _$ u
// Name: 5 o! G& d0 D: H, j4 g8 ]// Desc: 2 `' D* s6 U. Q) z4 P( T4 Z//-----------------------------------------------------------------------------4 I( j1 Q. H1 N+ }3 v _
void CMazeServer::OnRemoveConnection( DWORD id ) 8 E8 Q9 C% M+ h: M{ % a5 w- v3 x5 U m_AddRemoveLock.Enter();</P> 3 {3 @+ P" |. ~4 Y<P> // Decrement count of players d' L$ m0 d" c0 ]" b9 ` m_dwPlayerCount--;</P> ! N1 Z; P3 h- }<P> if( m_dwLogLevel > 0 ) 4 x8 e7 g5 k @! Q3 d4 z6 O { }: I+ r1 L; I; j, N ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id ); 9 L1 z* y$ O7 j ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount ); . |+ i, s* v" N* w0 |: E }</P> ! H1 ^* R( p. n' Q<P> // Find playerdata for this client7 {8 B4 [4 m& @3 @
PlayerData* pPlayerData = GetPlayerDataForID( id ); , J' ~6 }9 x0 d. f, j& T if( pPlayerData != NULL ) 3 j# E u/ B/ c4 P { 6 X- f" D5 B- M0 W2 o, O# B% q0 x // Destroy it " ^- ^5 Q3 j) n1 R RemovePlayerDataID( pPlayerData );" z) U7 Z' W I/ C. _9 C
DestroyPlayerData( pPlayerData ); , k2 `+ v! S, m' j }</P>0 C0 l5 R* r0 t( T) _
<P> m_AddRemoveLock.Leave();, G5 ]( t n ^# F/ t$ {
}</P> ( O a; h" D1 q- t" _0 I" e6 ~/ z% [. R' Z4 F, y/ |
<P>. F; N, ?( c d8 d* @. d% l, _
//-----------------------------------------------------------------------------. I! T- c, }. K, O, S( \
// Name: / A- e3 g( O8 \ {
// Desc: % f& |7 Q/ R3 s; z; |' @: p$ J//-----------------------------------------------------------------------------; G! l M! {$ o$ n
HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size ) * @0 m& x6 z. \{' v" {$ F5 M7 t# [9 T! M
BOOL fFoundSize = FALSE;</P> j, [" s; v& N2 {5 }<P> // Increment the number of thread we have in this process. ; u/ h$ q u S3 D/ v! ? m_csThreadCountLock.Enter();</P> 5 T9 G: O% ^4 m% c- e<P> //Get the start time of when we entered the message handler.8 L I1 m" K$ m: b1 U8 Z
FLOAT fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P> ( T( Z' ^! i; g<P> m_wActiveThreadCount++;$ Y/ n" I* n, h6 }
if(m_wActiveThreadCount > m_wMaxThreadCount) , p% P) v4 z; L! H% X m_wMaxThreadCount = m_wActiveThreadCount;: {$ ]. A+ Q- k
1 A8 l+ x4 X, k' F# l // Calculate and average.% T m7 d6 ^( ]" l
FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;- D% h B4 p4 q6 w$ h
m_fAvgThreadCount += fdiff/32;4 h$ a, Y3 F( c5 t5 g
7 ~# t$ z1 R# L" v& y m_csThreadCountLock.Leave();</P> y6 ^; ]/ ^$ H
<P> 0 c8 s% j$ n, o/ P4 U4 ] ClientPacket* pClientPack = (ClientPacket*)pData; ; W8 t6 A, k! s, U: j switch( pClientPack->wType )" b: Q4 ^; j! ~% q) |* p' D
{ + D1 Q& t; @* e M! D case PACKETTYPE_CLIENT_POS: % p5 @) y! V9 g! k% W & i6 l* c& C8 |4 O/ X // Check to see if the packet has a valid size. Including & J4 f8 Y/ W9 n( z
// the custom pack size.- _2 |, ~. ]( E% ?9 J; M, a
if( size < sizeof(ClientPosPacket))% i6 T( L4 z* _$ W) Z4 v0 ], w
fFoundSize = FALSE; ) m& I3 T! e. G else if( ! IsValidPackSize(size - sizeof(ClientPosPacket))) 7 c& d$ _" ~5 f4 H* @9 S fFoundSize = FALSE; + N% s5 a* s# ?; p else# m+ B" I8 S* e$ f6 r: a' D
fFoundSize = TRUE;</P> 3 v4 j7 q2 D! w6 @<P> // If valid sized packet, handle the position. 7 x' ^+ M" ~% b* N# n if(fFoundSize)% g; E1 |# p1 z4 q$ \% G" P: L
HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );, w0 R6 S# q2 v5 |, g7 h
else % x2 Y! I& `9 p$ U( a7 x m_pNet->RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P> , s% r7 y( X. V5 i# g5 Q<P> break;</P> $ l3 C- n! w. ~: {/ `# d; G& @<P> case PACKETTYPE_CLIENT_VERSION: . f) {+ b0 _9 W/ Z2 V' q if( size == sizeof(ClientVersionPacket) ) $ _; e* R# U3 e HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack ); r a( k$ G: u' p# m/ T5 Y% G
else ! h2 T8 A8 k3 } m_pNet->RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE ); 7 E9 o0 w# _5 R' g$ M8 E2 B break;</P> ! S' _4 ~( x* j1 O* @) b% ?% W<P> case PACKETTYPE_SERVER_CONFIG:</P> . V5 ^: z! N& H9 _: b0 H5 j9 g<P> // Server config packet sent to all users (including server). Just ignore and continue.</P> 5 ~( |! }0 A( Z<P> break;2 q- Y( U1 b1 d2 N' ]
default: : P! |+ F" o( {3 P J HandleUnknownPacket( dwFrom, pClientPack, size ); $ Q* ]8 W4 X4 e* z3 k break; 6 M4 S- m" Q8 I4 Y9 ` }</P> 7 t5 r. T& k8 z! b9 o9 E5 W5 d/ U<P> //If the user wants to hold the thread, Sleep for given amount of time. 6 J( X: o, e6 G8 \ if ( m_dwServerThreadWait > 0 )6 q8 K. D$ u8 k$ j& E% E
{5 K0 Y! K, L9 ^4 Y; T
Sleep( m_dwServerThreadWait );; Q$ k, ]7 X' k) g' ^. d% ~) l
}2 {' ?1 N \4 }: t
8 {* t: F5 Y- L$ b2 P+ a5 D
// Retrieve thread data for this process. 4 P$ ^% a" f: \/ P; N7 h9 x m_csThreadCountLock.Enter();</P>5 C h: @3 S) \ T9 ]3 h8 `& R
<P> m_wActiveThreadCount--;</P> / ^: q. j$ i" _* w# b# d; i( q<P> FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime; $ E6 S; M! d6 ^( P$ a4 E4 Z( D2 Z m_fAvgThreadTime += fDiffTime/32;</P> . w1 @- H( K3 b! Z3 i<P> //Get the Max time in the thread.$ `$ j5 P) z2 _2 k( n
if ( fDiffTime > m_fMaxThreadTime ) 6 k7 I/ W1 H h, N: `4 \ {" r, l* G0 j" a- X
m_fMaxThreadTime = fDiffTime;3 ~8 F$ r; d2 I7 f+ P1 {9 E* v4 S# N
}</P>; b& o Q0 {5 {
<P> m_csThreadCountLock.Leave();</P>) K( Y, w% A* a; G3 F
<P> return S_OK; + t, M! O [' I0 o+ ]- s& s' J}</P>) J- t; e+ H# i
% k: m- n9 j- y S k
<P>//----------------------------------------------------------------------------- ; C/ c- |, |+ V5 o7 D! U. g// Name: ( V3 B! h, _/ d+ X6 \// Desc: # |: C) v) q% A' E0 V+ U0 I" @* ^
//-----------------------------------------------------------------------------9 W0 I+ {; K7 x; C' i
BOOL CMazeServer::IsValidPackSize( DWORD dwSize ) " o% @2 t0 q. C; w3 S{ 0 f/ _! h* f- z" K BOOL fFoundSize = FALSE; 3 }2 i9 V& O5 i7 p, n BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex; 4 q' R j3 ?4 a3 G" e 8 p0 G, H& F. U( h // Check through the array of valid pack sizes. 9 V# W B0 M% d! |+ Y! Z1 S/ l( {) O if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation]) # r% Z& W3 j9 Y; j3 u+ F {) E( b" p5 ?% E8 Z7 i2 L
for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)5 d* s4 P9 p9 x# q+ R: s; J
{* ?- F9 Z5 H; {' Z4 z M
if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])) \* u% K/ Q. z% {+ O w9 }0 R
{ ; f! P$ \3 A q1 y // Found valid size in the array. , d7 a) ~, p5 b, Y$ T1 d fFoundSize = TRUE;6 z% J8 j( y: f- a. E
break;8 b( g! E1 Y @
}8 U: t5 X d2 ^/ B) ]5 l6 i& a
if(ubPackLocation >= PACK_ARRAY_SIZE) ubPackLocation = PACK_ARRAY_SIZE; //Wrap the array. 5 ?, K% F3 F+ F4 M }/ B! i: v+ q0 f
}3 j; f. H0 u) Z$ i3 h5 V' a
else 2 k! g# y/ `' N, B% r) V/ D9 y% ` {4 K5 O$ |# Q- _& V \5 s
fFoundSize = TRUE; k' b2 G) e) A) g$ v9 n b
}</P>) b/ `% i [$ n& A3 U
<P> return fFoundSize;, S; H# a) p6 G( J3 R) v
}</P> , h, K! N8 y1 B2 R- p( y: `<P>* m) u0 G( _/ A1 P+ ^4 t. X3 x
//-----------------------------------------------------------------------------% k) G* f' o% \
// Name: / V! Q9 A7 z- Q! v// Desc: 7 r' q3 h5 s- \8 j8 j//-----------------------------------------------------------------------------9 S: w% j- {1 ^9 [4 D
void CMazeServer::OnSessionLost( DWORD dwReason ) 7 e1 Z! c7 R! r1 a0 m{ x- q- z1 D* H3 |. |
ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") ); 3 Q, W) g) J8 `# b! B}</P># L+ v) Q! a B: Y, r
5 e1 y9 n; m" a, w& G" G; T
<P>8 n% Z- g7 e, X8 s( V. t1 y0 W6 h* l
//----------------------------------------------------------------------------- ) A% E! \$ H" t// Name: 0 {, P/ A9 O/ c' \' ]. a6 ~& I// Desc: 9 O# I( {9 j5 y) P1 Q/ k# f7 p
//----------------------------------------------------------------------------- 8 _0 H ^# C! }7 V/ {PlayerData* CMazeServer::CreatePlayerData()) d1 J1 m q; I* Y' {
{8 D! v3 \ k* Y9 ~( a7 i) d. g$ g
m_PlayerDataListLock.Enter();</P>% l5 l+ i, t! Z9 ]& W& O7 e3 F, V; g8 R
<P> // Grab first free player in the list : \! z3 c& e N/ ` PlayerData* pPlayerData = m_pFirstFreePlayerData;</P> N% Q3 O8 K+ l0 O) r5 R# Q7 b s
<P> if( pPlayerData )+ S' @5 u% m/ B5 B
{ + f/ d& z5 y6 T. S LockPlayerData( pPlayerData );</P>$ f& |) J n2 b" X* L
<P> // Got one, so remove it from the free list 5 e% k( W2 d1 T! {4 x! e" K if( pPlayerData->pPrevious ) . k* q. S* v6 { pPlayerData->pPrevious->pNext = pPlayerData->pNext; % \5 p6 m4 z& [3 S if( pPlayerData->pNext ) $ I8 C' ?3 B" c& B4 m8 m pPlayerData->pNext->pPrevious = pPlayerData->pPrevious; k: }% D. j2 B1 s& |
m_pFirstFreePlayerData = pPlayerData->pNext;</P>' r5 Z }! \0 ^% k! V& P4 |
<P> // Add it to the active list % k) a/ B8 O& h0 S5 y if( m_pFirstActivePlayerData ) ! V9 e0 y9 N/ _- r3 U; s0 o m_pFirstActivePlayerData->pPrevious = pPlayerData; $ l6 X7 V8 Y, x7 m2 I9 ? pPlayerData->pNext = m_pFirstActivePlayerData; 7 _( k( `4 w) ]1 o) y& ]9 n pPlayerData->pPrevious = NULL; , e* ^6 u7 B/ T: P! a( a; h m_pFirstActivePlayerData = pPlayerData;</P> 1 H6 l# M5 f, c0 f- ~8 ?<P> // Update count of players' _) y7 z' z. d+ ]6 k
m_dwActivePlayerDataCount++;</P> + j. r8 g- `2 b6 L<P> // Generate the ID for this player" P, H/ ]% t! s \' y
m_dwPlayerDataUniqueValue++;, x4 f s4 {7 r. E
pPlayerData->dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue<<PLAYER_OBJECT_SLOT_BITS));</P> % Y" U& z9 T- j3 `<P> pPlayerData->pNextInIDHashBucket = NULL; 5 A; R& ]. ]) V' j pPlayerData->NetID = 0;; u2 W7 N% i! M3 c# V- I) k6 y( E# f! U
pPlayerData->dwNumNearbyPlayers = 0;</P>- r2 ~/ \- X' b) K# y
<P> // Insert into the "off-map" cell 9 ~" ]! q# g( u' i- [4 u pPlayerData->fPosX = pPlayerData->fPosY = -1; T/ N A5 K9 R9 V pPlayerData->wCellX = pPlayerData->wCellY = 0xffff; ) L. y4 G- X! m. ]. p5 f m_OffMapLock.Enter(); : d( w9 C, u q' H# s pPlayerData->pNextInCell = m_OffMapCell.pFirstPlayerData; 4 [% y! Z! w2 e6 A/ t m_OffMapCell.pFirstPlayerData = pPlayerData;, }' S* M# h* } V4 ]# M
m_OffMapLock.Leave();</P> o, s3 o& ]& {- S# N- r$ M<P> // Mark as active {: N3 O" n5 H D
pPlayerData->bActive = TRUE;</P>$ [/ S' e( A; ?. R( p, |
<P> UnlockPlayerData( pPlayerData ); - g ?9 d( T# [, l: h% W% D& v% S ~9 ] }</P>/ }3 V- ~& L: z0 g; }! c
<P> m_PlayerDataListLock.Leave();</P>$ M" s# W% W9 s! W7 X9 A
<P> return pPlayerData;3 a3 m2 X/ Z/ S$ w3 Z
}</P> , A4 \) ?# v4 l8 C& `% J R4 B 6 ~3 }1 ]3 r* a<P>5 \7 f) Y2 z) D; ]5 |- v: E
//----------------------------------------------------------------------------- 3 F6 o2 `4 g$ p, M# y# A// Name: - D' k6 K# L/ U8 k* k
// Desc: " P, @) e: |8 x( L
//----------------------------------------------------------------------------- 2 j6 i# @* k$ q6 X' Jvoid CMazeServer:estroyPlayerData( PlayerData* pPlayerData )7 |' a7 { J4 ?, ?, D. e
{ & h+ R' ?9 a' L m_PlayerDataListLock.Enter();) [4 i& u" ~2 \8 c+ _
LockPlayerData( pPlayerData );</P>) C0 @0 h% p8 y, w% ^* ^) m5 u9 x7 {
<P> // Remove the player from its cell$ C' k: Y3 _6 ~; c( @
RemovePlayerDataFromCell( pPlayerData );</P>( _9 v7 M+ T6 [4 I" J
<P> // Mark as inactive / C; i, `4 D: s/ q( \- H/ m pPlayerData->bActive = FALSE;</P>) o- d" h: ?) @+ Y* E) ^
<P> // Remove player from active list4 o# Q J+ p. c9 @+ u" X% _
if( pPlayerData->pPrevious ) 9 S v4 V3 {% G9 I# a4 Q pPlayerData->pPrevious->pNext = pPlayerData->pNext;9 X. D j0 B9 Y' _
if( pPlayerData->pNext )- Z7 U1 b( {) x2 H0 R
pPlayerData->pNext->pPrevious = pPlayerData->pPrevious;</P># n5 `# X$ D% D8 M% u# p! o
<P> if( m_pFirstActivePlayerData == pPlayerData )% O% G+ y+ ^, ~! B- Z# v) K5 w# \0 C
m_pFirstActivePlayerData = pPlayerData->pNext;</P> - r2 O8 E1 a0 H5 }5 R6 b<P> // Add it to the free list! O# ]* G1 H N
if( m_pFirstFreePlayerData ) 2 @2 o c& M7 q6 b' e m_pFirstFreePlayerData->pPrevious = pPlayerData; 0 r; Q0 e; V1 x0 I2 u pPlayerData->pNext = m_pFirstFreePlayerData; / P/ z2 V$ b+ e3 `1 F* r9 c1 \. Z pPlayerData->pPrevious = NULL; * v4 P5 a* I x1 } m_pFirstFreePlayerData = pPlayerData;</P>& `0 v; q8 K, g W
<P> // Update count of players$ I3 W4 O9 v: i8 N( S8 }7 l
m_dwActivePlayerDataCount--;</P> , h8 B" b: w9 Z" K% |2 E<P> UnlockPlayerData( pPlayerData );, r/ {8 u7 G% E1 b+ `
m_PlayerDataListLock.Leave();# s: p' K1 O& P/ c
}</P>3 i" t. ]! q. h0 @0 e4 U/ |! a3 o2 m) a
: Q6 ]$ z, ?% u, J9 B
<P>/ P/ i& i4 O' ^: E0 G
//----------------------------------------------------------------------------- 0 L* i7 x7 U4 T$ h// Name: 4 B8 c# ?6 c; n% m4 [* j5 M {, I// Desc: + W; @! p& L% o, g( r ?
//----------------------------------------------------------------------------- f: M W; R$ h- B+ x0 q! Xvoid CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )4 I! I& w* R8 N* |3 p, ^4 _
{ " ~* V" `( c2 V) G) a- Y // Lock the player9 n& X, m* j* Y& j2 B( Q/ m* @
LockPlayerData( pPlayerData );</P>% S! Z! r& V+ L- j+ U: Y
<P> // Lock the cell the player is in y3 f! v" p8 }4 Q6 V8 q
ServerCell* pCell; 3 R" m" F# o5 L5 i# W$ o% f if( pPlayerData->wCellX == 0xffff )" [) P$ B) \6 X) O
{' r/ A5 m: @8 \
m_OffMapLock.Enter();# T4 V, _, L: p! v+ i
pCell = &m_OffMapCell;7 G* `( U9 I! c) j; Y8 m) @% I" r
}+ }! m( t d; H7 R
else: d5 K, n5 W. z% ] e
{+ x# [1 B/ J( g/ H* s, z1 A
LockCell( pPlayerData->wCellX, pPlayerData->wCellY ); 5 V- _: S2 o" x9 f; r pCell = &m_Cells[pPlayerData->wCellY][pPlayerData->wCellX]; % s0 |0 O$ j* ~2 n3 X9 l6 c }</P> ) K, X2 Y! S* V2 k# \6 U2 W<P> // Remove it from the cell % q' r1 M; c5 a' z5 w! e PlayerData* pPt = pCell->pFirstPlayerData; 3 ?' A; w2 j0 Q0 a" C1 m0 o PlayerData* pPrev = NULL; " K6 a* c$ g& G, c while ( pPt )$ f" k% D$ e4 x% z7 g" ~
{# e( M/ N5 L( h
if( pPt == pPlayerData ) 1 l+ i9 k- ? Z; z% ` {" U9 b0 ], N! a! y0 V5 K
if( pPrev )" ^8 O( h+ T& v6 S
pPrev->pNextInCell = pPlayerData->pNextInCell; . T4 e+ j8 s& T3 m, l+ {7 u' w( A( z else' }# A2 P; p' z1 f- p
pCell->pFirstPlayerData = pPlayerData->pNextInCell;</P>, u: A: _1 m2 S
<P> pPlayerData->pNextInCell = NULL; 7 L/ d; n6 H6 r$ h# i0 |' S break;/ T. W- Q- V5 c8 j
} $ r+ a" z9 P7 O pPrev = pPt;( e R: l. ]- G/ J3 V0 @
pPt = pPt->pNextInCell; % I# X. r0 d# H6 J% k% o }</P>- t3 n6 ~! T( S v" Z# v( D
<P> // Unlock the cell" m( A0 R1 Q0 L: `/ i7 `( A
if( pPlayerData->wCellX == 0xffff )! l8 ^$ O1 k4 s8 v
m_OffMapLock.Leave();, X+ j. r; j2 a9 g
else6 u8 t, s9 \0 W) ~: V
UnlockCell( pPlayerData->wCellX, pPlayerData->wCellY );</P> # |; v7 C0 `3 h2 v0 w<P> // Unlock the player/ w5 Q5 l, U! t# g
UnlockPlayerData( pPlayerData ); + c! m( \. S4 _# ?7 c}</P> - k: G/ E3 w! c' e, Q; y. Z) `6 `1 A, ^ 2 I0 i! H' a/ R- v<P>; x: v. q0 O( C# S
//-----------------------------------------------------------------------------4 q2 W j9 ?. i1 E) ^1 {0 A: h* J
// Name: 8 p% P2 i/ t! e
// Desc: : e& A% _- d" ^: \, x//-----------------------------------------------------------------------------8 z- D/ ~% k8 y( b( N( g6 ]
void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData ) 4 D3 s* t: n' b, O- q{ - j$ p1 \! Q! r6 A$ v* L5 P; P1 t. b$ k ServerCell* pCell = GetCell( pPlayerData ); ! q' H, m5 U7 G3 l3 m/ s z PlayerData* pPt = pCell->pFirstPlayerData;, `# W" f$ y3 N& H5 @
PlayerData* pPrev = NULL; # X$ `+ E" I+ k5 h% L q3 P$ j- N while ( pPt ); u4 l$ _5 K2 L7 t/ t. T. c8 U' S
{& q- T- L& M/ t1 Q% j0 k8 ~4 \
if( pPt == pPlayerData )' |, I: L3 t1 b, o; T2 T8 D3 u
{ $ B1 v" K6 C9 K9 o6 ]5 { M; M if( pPrev )/ Y+ S3 f. a/ R4 X
pPrev->pNextInCell = pPlayerData->pNextInCell; 7 \' b3 ~: T ?' b$ i else ; Z2 I3 P4 v1 f9 |4 C }' G pCell->pFirstPlayerData = pPlayerData->pNextInCell; 4 ~& A; w% u/ _3 ?3 U7 r+ c5 i( w pPlayerData->pNextInCell = NULL; - v+ y6 z- _' _ break; ) U1 Z7 E! L! Y6 j6 t } 8 p4 s9 |9 c$ @6 \1 m. a pPrev = pPt;$ A2 _ |% [7 p$ ^
pPt = pPt->pNextInCell; 3 S+ B/ n/ {( n4 r+ v( b; G5 C$ f; ` }5 g0 O# y) A# I
}</P>* v; H2 e6 Q& S, b9 [+ \
N% R3 h) b, ^1 O( I
<P>& v* l1 b% t9 [$ _, L- e; Q
//----------------------------------------------------------------------------- ' [! h% \( K8 F5 ]3 i% ^: l0 l! R// Name: * d g/ H4 `6 {- \
// Desc: " h5 R! O7 B# b. u f5 A//----------------------------------------------------------------------------- 4 h" C% L- _, B* Nvoid CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )8 M% R. {* g1 D
{ 6 @' t, A8 ^4 ], }, Y4 o/ L# I; M ServerCell* pCell = GetCell( pPlayerData );6 S b; O( U3 ]: x; F
pPlayerData->pNextInCell = pCell->pFirstPlayerData; , ]8 I1 o' Q3 h* Q, Y* r: H" A: D pCell->pFirstPlayerData = pPlayerData; $ c. P3 K" h& l! D6 J* V' h: p}</P>' R. g- Z/ A- }/ @! L' U
: @8 a/ v4 f7 N+ c8 j) J
<P>9 V" M# Q/ w e+ V, D: b( V5 v5 m6 w
//----------------------------------------------------------------------------- + I3 \( Q3 a4 ~" t. O// Name: $ Q; o3 ^$ a3 b& `$ G* C% X% F. j! h
// Desc: 6 H& A: s8 K8 M3 X b
//----------------------------------------------------------------------------- 4 k q9 [/ @( q: V; h! ~; wvoid CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack ) / F/ l5 H3 [" A+ I- V{5 s, d5 ^/ H. b: ]6 Z7 j! K. I1 [/ T
// Grab player for this client and lock it0 U/ ]9 |0 b# H
PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );, h; b! G( V9 ]2 F" s( M
if( pFromPlayer == NULL ) ' S) b [" j% P8 K% ]% { {$ u- K2 |- w9 g( Z2 c
if( m_dwLogLevel > 1 ) + I8 |. P7 C, h( j6 m, J9 P4 B. @ ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer->NetID ); " ]% P9 A+ X% P E return; 4 A9 b; s/ l4 y& h }</P> 3 g9 @, w6 i3 `% W# |: {- }<P> LockPlayerData( pFromPlayer );</P> % j8 @2 q# R8 u3 [& W( V ]<P> if( FALSE == pFromPlayer->bAllow )& `. C1 T/ {$ b8 F
{3 O* j" e2 ^1 r( y: C* s
if( m_dwLogLevel > 0 ) : ^: T$ i/ [" X" C+ T ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client. Rejecting client"), pFromPlayer->NetID );</P> % \- l/ d- R$ b& _<P> m_pNet->RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE ); 7 f3 ~* ?" w* B* J/ D UnlockPlayerData( pFromPlayer );7 S! }; p y* Q8 s' v
return;2 M8 w- \; g0 j5 U- W
}</P> " K3 x" k" D+ K; T& F: W<P> // Compute the cell the player should be in now 7 H3 q/ y1 v8 G6 X. _" Y: k# b DWORD newcellx = int(pClientPosPack->fX); - `, u! t- K' ]0 ~ DWORD newcelly = int(pClientPosPack->fY); & e8 k7 H6 W. F% R1 X5 Y. U DWORD oldcellx = pFromPlayer->wCellX; 8 K6 V9 J9 O! d3 B' b DWORD oldcelly = pFromPlayer->wCellY;</P> 8 ]9 Q1 U- }" x9 l6 P S, A<P> // Have we moved cell? 1 P) Z& }! K" _( o1 Q if( newcellx != oldcellx || newcelly != oldcelly )9 [4 w) X) K! R: z# o: `
{. x3 K: h+ A) T0 n" X" }
// Yes, so lock the pair of cells in question+ @9 _/ o' j& R+ L; m+ L
LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P> 1 G; I. w! ~/ X<P> // Remove from old cell and add to new cell. u* R, v/ D: ` O5 @' {0 q
UnsafeRemovePlayerDataFromCell( pFromPlayer );2 A7 `* W) ?6 t4 m/ K
pFromPlayer->wCellX = WORD(newcellx); pFromPlayer->wCellY = WORD(newcelly);! E7 z# v: J- `1 z
UnsafeAddPlayerDataToCell( pFromPlayer );</P>$ s N2 f9 p) ~- {
<P> // Unlock cells $ l! `0 ^. I) w, v$ N UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );( }& T$ l" x7 ]: }, e9 R
}</P> , A W+ |' B: [; |, ?<P> // Update player position* y% t* P: m$ i/ I B7 ?' T
pFromPlayer->fPosX = pClientPosPack->fX;4 m9 X9 i% ?* [) Y- @3 ~
pFromPlayer->fPosY = pClientPosPack->fY; & G! c$ x8 T+ f! r pFromPlayer->aCameraYaw = pClientPosPack->aCameraYaw;</P>2 X+ H4 M A$ U# A; F# h
<P> // Allocate space to build the reply packet, and fill in header 4 U& v. ]+ q8 z7 D$ L( \ DWORD dwAllocSize;( z6 R1 I6 k" {) C5 d- x; p
ServerAckPacket* pSvrAckPack = NULL;</P>2 Z3 z. P9 W8 H# m9 R
<P> // Begin by allocating a buffer sized according to " m) N5 U( h/ e/ {2 ]: e0 D) o: F' W" { // the current number of nearby players + 4. This will give 6 z- h, e' Q8 P' B" y( K+ P( h
// a little room for more players to come 'near' without resize# `6 _$ J, d1 e# X' D
// the buffer./ n* r0 `& f$ h! B( k
DWORD dwMaxPlayerStatePackets = pFromPlayer->dwNumNearbyPlayers + 4;</P> 2 k- j" |7 ^7 \* o( A3 B<P> dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket); N' O T9 a# L( l* R! p pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );7 Z; `2 |5 {1 U0 {& K
if( NULL == pSvrAckPack ) 6 A. B8 \* A- D5 u; P" ?( Z- a+ N* Y { / l1 A# U" A% |# E% T2 r$ ~ // Out of mem. Cleanup and return 8 h: m4 k! M% O. b UnlockPlayerData( pFromPlayer );7 l3 l) x' |9 C
return; 7 {, L g+ j& Y5 h }# k* t6 B; J- k) O% \2 j
ZeroMemory( pSvrAckPack, dwAllocSize );</P>) \% y2 p9 U$ ]( j
<P> *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);4 L b+ D G ~7 \; x- j9 x8 {% |
pSvrAckPack->wPlayerStatePacketCount = 0;( [. o6 U3 s+ V7 F- W* ^
PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P> * U4 U" \3 V0 r+ D S- I" t<P> // Compute range of cells we're going to scan for players to send ) R! Q! H* Q2 F! x DWORD minx = (newcellx > 7) ? (newcellx - 7) : 0;. g$ P* C0 q5 n( `) z; C7 p
DWORD miny = (newcelly > 7) ? (newcelly - 7) : 0;5 o% H& O% M2 M; f1 V
DWORD maxx = (newcellx+7 >= m_dwWidth) ? m_dwWidth-1 : newcellx+7;# W& W1 \3 G: f) p
DWORD maxy = (newcelly+7 >= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>" Q0 X4 G7 q+ K9 W6 h
<P> // Lock that range of cells: s" I6 F* p( p. t/ Q
LockRange( minx, miny, maxx, maxy );</P>6 O9 L8 q2 H- j; O: S
<P> // Scan through the cells, tagging player data onto the end of3 e/ W& b4 ~* U" _ Q X
// our pSvrAckPacket until we run out of room; c' s1 m @0 H+ J$ A; m2 R0 W
for( DWORD y = miny; y <= maxy; y++ ) ( l( m$ @( R b" w* ~+ H0 S { 6 e1 o! m$ ^+ O$ k0 X6 h0 X for( DWORD x = minx; x <= maxx; x++ )8 Q3 L0 L; a7 N
{9 A4 Q% R) `2 h! Z7 u+ X; Y
PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData; 6 W' s: n2 P% b% s8 U+ t; L while ( pCurPlayerData )7 W) k- }5 j$ l- a5 r( i% B u
{ N, `, K1 Z4 {2 l X
if( pCurPlayerData != pFromPlayer ) 5 B$ w" X- J3 p) J7 C { 7 Z8 k+ M) _, @, N5 \- x if( pSvrAckPack->wPlayerStatePacketCount >= dwMaxPlayerStatePackets ) , O& r' K3 h+ B0 h3 U- O { # Q9 c* c; n8 I9 F" z* p // Make sure pChunk is where we think it is( @7 _( g6 Z- i3 x
assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack->wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P> f" N, i4 F2 K<P> // There are more than just 4 new nearby players, so resize the 4 }7 B" Z7 L! L$ R; u# N0 ?2 v
// buffer pSvrAckPack to allow 16 more PlayerStatePacket's. 0 K. G# k' `0 G. Q" L* ?% r& F dwMaxPlayerStatePackets += 16; 4 S/ L% J; G: q dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket); % R" R- s, A( t$ O: n( G ServerAckPacket* pNewSvrAckPack = NULL; 8 g2 l7 j& c, I pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );$ A+ U0 S& w* t
if( NULL == pNewSvrAckPack ) ! z; B+ ]+ C8 s; X' R/ Z {- G' b: o9 |$ \8 Y% @! s5 t
// Out of mem. Cleanup and return1 i, n3 H* c: Y3 Z/ L( }
free( pSvrAckPack );+ T5 O% P1 e5 G3 z [- t
UnlockRange( minx, miny, maxx, maxy );0 y8 E! z8 V; W: d( j7 c9 V# p
UnlockPlayerData( pFromPlayer ); ( ]" k- ~7 g4 |+ ?; c4 w return; ( R* T* [8 X& f2 @' d
}</P> 5 i; v/ h( b, p8 @# t: ~5 b$ y- o<P> pSvrAckPack = pNewSvrAckPack;- `% n# h0 y4 }
pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack->wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P> & S/ D4 ^, N& J: H6 b' K" e<P> // Make sure pChunk is still where its supposed to be: j3 Z# Q9 g; l
assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack->wPlayerStatePacketCount*sizeof(PlayerStatePacket)) ); 0 }& V7 H0 p/ S! X; R+ q5 G5 F* _ }</P>- r* |6 }' p1 k4 x4 q: g
<P> pChunk->dwID = pCurPlayerData->dwID; : _7 v; r! ]) a9 Q9 D pChunk->fX = pCurPlayerData->fPosX; / H( o. M y* C' w( A, {% m pChunk->fY = pCurPlayerData->fPosY; . [) S" _, \7 G# X) t! o' H pChunk->aCameraYaw = pCurPlayerData->aCameraYaw; + p0 ], L* j8 I0 @ pChunk++; ! A, V1 a7 o7 E: ? pSvrAckPack->wPlayerStatePacketCount++; - D3 m" `$ |6 m0 s" _% S } : C2 J% ~6 L; ]* V+ Z" Y" v pCurPlayerData = pCurPlayerData->pNextInCell;, y) D& V' ` _# M1 V; r6 C
}1 C/ {1 T3 x* D& Y, v! X) _
} # m: X& V$ z3 U* @7 x7 |. Y* | }</P> 2 P; x6 v b: y$ H; T g8 Q" s<P> // Update the dwNumNearbyPlayers for this player( r5 O* c0 D' N0 t! n
pFromPlayer->dwNumNearbyPlayers = pSvrAckPack->wPlayerStatePacketCount;</P>) {0 U( E1 |; `& w# Q2 _
<P> // Unlock range of cells& O: l5 }9 t, j+ ]: a: s6 t' S
UnlockRange( minx, miny, maxx, maxy );</P>6 a$ P) d3 d- n) j" M5 H
<P> if( m_dwLogLevel > 2 ) " y- K: L5 L6 f8 l) F' B" q { ( n5 i9 w9 { J+ `- j+ c, _ ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer->NetID, pFromPlayer->fPosX, pFromPlayer->fPosY ); , l, @6 O' F8 C0 z/ ~ } ( H, B* w+ C; L B else if( m_dwLogLevel == 2 )1 t6 j0 N0 b. e8 H6 L; c+ I! s$ x
{ G: j1 R9 e2 L6 N+ Y; K% G FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );5 w- u% f: k1 H" d- ^/ v$ x' a
if( fTime - pFromPlayer->fLastDisplayTime > 60.0f )! o H. h# |0 o. |
{ 7 H! l8 D, { S' z. b; X ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer->NetID, pFromPlayer->fPosX, pFromPlayer->fPosY ); ' C4 S1 ]( ]; L( b) l! p6 y6 Y pFromPlayer->fLastDisplayTime = fTime;9 ~# r) i: a& Y d- f( A' t. D9 e
}$ B1 D3 m8 M6 i, A5 N
}</P>& A4 [: R" f7 v7 n, W+ P7 _6 N
<P> // Unlock the playerdata9 _2 r0 O: m3 ^" z# x; B
UnlockPlayerData( pFromPlayer );</P> $ m! n& I* E3 J, Q+ ^- i7 J<P> // Send acknowledgement back to client, including list of nearby players 7 W* z! {/ ]0 y/ Q" k$ u9 @( E" i DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack->wPlayerStatePacketCount * sizeof(PlayerStatePacket)); : d% u; y: ^. B; z 9 s0 U& ~: V: I // Pack the buffer with dummy data. 4 U3 Q4 f! n, x7 A' m if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] > 0)5 b* `6 p6 r6 F) y) c
{ - s) F0 K3 A# {. F5 t, \ DWORD dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex]; 9 q* `$ x0 k- _9 ~2 k VOID* pTempBuffer = 0;</P> ( z& y0 t6 g/ H b# V<P> pTempBuffer = malloc(dwBufferSize);; u! Y8 Y: o7 p% S
if( NULL == pTempBuffer )/ r8 ] u+ G2 q( A- d
{ * ~' ?3 I* Q$ r$ e. q% d6 j //Out of memory / E: U/ G3 I v& ?4 Y4 p1 Q& F DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY ); 4 [' a3 T! a' e+ Q5 Q free( pSvrAckPack );2 C$ O- f \! A$ D& I$ f
return;- P2 c, ?9 j7 H9 ^7 o: V
}</P>5 o) D3 A$ C" Y
<P> FillMemory(pTempBuffer, dwBufferSize, 'Z');8 k/ `- ]* N# ?9 F' ?# N
memcpy(pTempBuffer, pSvrAckPack, acksize);</P> 0 y3 f! R7 B- j) Z+ ~: n<P> SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );+ [( V J. C( u! i
3 V7 x, W( G, t% a, `: R' Y+ d' a+ P
free(pTempBuffer);4 S) ~" z) m8 |) c
} " b, y8 u. ^4 j1 @
else: E' Z+ _ C% D5 s9 [
{- o0 _) u( ^5 W; s, ]$ V$ F
SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout ); 4 i# n- D7 Z2 u! i4 P( r }</P> * h5 k& d5 x" k- B" R9 t<P> free( pSvrAckPack );</P>( G$ B o& ^0 x2 ?4 w
<P>}</P> , g* A- d) z ~0 Y; n* l0 G1 p) e i$ ?4 Z3 G d
<P>. R3 n& C& @9 u
//----------------------------------------------------------------------------- 3 n3 O2 _# P- N2 }// Name: ( r+ \% I4 a1 z( w5 m: i// Desc: 0 s8 \" r+ x r% E
//----------------------------------------------------------------------------- ; Y' j; a4 Z( l" k% i" dvoid CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack ) 3 f {1 {' C7 C3 S8 f) B& |9 A{ F& |6 A. x2 d* L# `& G( w" p/ Z // Grab playerdata for this client and lock it5 a, a" @! C& n! a4 O T8 O
PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );# Q! y) h3 e; E8 ~9 q9 s+ [
if( pPlayerData == NULL ) 6 x: A# Y P# R2 R# C return; . {8 k: R: ^- N* W- T/ v LockPlayerData( pPlayerData );</P>' j( D5 _' J/ `' J( f+ r
<P> // Record the version number 2 p; P$ y/ P* Z7 d2 o/ l
pPlayerData->dwVersion = pClientVersionPack->dwVersion;</P> 1 `6 N* M+ E. k8 D+ w<P> if( m_bLocalLoopback ). F; I+ c- z) M
pPlayerData->bAllow = TRUE;9 J0 h: L( E4 @7 w- a
else - k0 @/ y% O/ X& Y. K' F pPlayerData->bAllow = IsClientVersionSupported( pClientVersionPack->dwVersion );</P> 2 V6 X) J- v+ n* d& ?- `<P> if( m_dwLogLevel > 0 ) 4 o/ m: m7 d" X) B: ?9 D( b9 J ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Client version=%d (%s)"), pPlayerData->NetID, pPlayerData->dwVersion, pPlayerData->bAllow ? TEXT("Accepted") : TEXT("Rejected") );</P>7 w* w) ^9 ~+ [/ H, T9 ] { L
<P> if( FALSE == pPlayerData->bAllow ) . u$ k* R V6 C7 q. S {4 O1 o" B3 h; K9 e9 |, f
if( m_dwLogLevel > 0 ) / [1 l3 b' Z2 I9 Q# X. v' w ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData->NetID );</P> 3 J4 y& u6 s! ]5 o* F/ A- E<P> m_pNet->RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE ); _# Z# s H5 Y: ^" O4 A
UnlockPlayerData( pPlayerData ); : p# `4 Y( J5 L return; ! Q, Q/ S6 X" A7 w# C7 q+ E }</P> ! S' u' G% ?6 H: |# l9 m<P> // Unlock the playerdata8 W$ i* a9 Z, x. H4 W7 _5 ?
UnlockPlayerData( pPlayerData );</P>' `% e4 j6 ~& ~ k6 C- K
<P> // Send acknowledgement to client that the client was either accepted or rejected# {1 ]- O$ _: X* K9 _# {
ServerAckVersionPacket packet( pPlayerData->bAllow, dwFrom );+ e6 A4 O* O3 e/ x
SendPacket( dwFrom, &packet, sizeof(packet), TRUE, 0 ); 2 j* `( H# L% e& H( J}</P> $ U! G/ k; ^6 ^# `1 @ " H( e. O# n1 m' y8 Y<P>5 s, E. U5 V$ T: M
//----------------------------------------------------------------------------- : D( n2 X9 t3 S3 u! }& Q// Name: j7 e% _9 z0 T: B( Z) J% T
// Desc: : ?: Z( r0 a/ U' H# G& Q6 V//-----------------------------------------------------------------------------" w& [3 g J4 ^
BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion ) / P6 X6 f( w8 N' `{ / S$ o4 P5 Q" U9 N switch( dwClientVersion ) ; _* u F& v P$ Q/ p5 T {9 E% M% Q* b' C$ h/ z
case 107: // only v107 is supported % f% T4 G2 r% `/ p0 Q1 M( U) S return TRUE;% _! b) }/ }' j8 I
default:- ]1 X1 Q8 D$ z' ], r- X
return FALSE; 9 v A3 k' @* D6 S }& u0 z8 Y% ~+ y1 \1 t% H" I0 c) l
}</P>; V. A8 K+ n/ K+ x# ? X
$ B' t5 \0 o( K3 j$ b- Y
<P>! M8 ~7 u8 d0 X( @0 @
//----------------------------------------------------------------------------- U4 a V1 S9 r# F2 q2 `3 n
// Name: ! T3 N2 L' K6 U: P, c0 e+ ]2 R
// Desc: , H1 E3 t4 e! ~+ L: ^//----------------------------------------------------------------------------- 7 g2 H; V b, _void CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size ) 6 ^- c' O& |/ z* S/ Z% {{6 t/ N- F* R& ?
if( m_dwLogLevel > 1 ) + G$ X6 [( L( f3 a0 l( y1 @ ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P> l0 s, J; G3 i3 ?$ v<P> m_pNet->RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE ); . W6 c2 v2 J, I! n f}</P> 4 A5 [+ i1 l9 I( \% k( N. b. u4 F, \5 C) b
<P> 6 @5 ^' ~7 ?: e: q0 {//-----------------------------------------------------------------------------5 j: U$ _ H& i: l$ h5 \, L
// Name: " w0 a% C! G: X' L# N5 e
// Desc: # J" J$ \0 H! {4 _" _
//----------------------------------------------------------------------------- 5 e) C6 k* Q1 `* s! Q: q+ F# e9 kDWORD CMazeServer::IDHash( DWORD id ) - N! L1 p: A+ Z! w{5 E7 A- O3 [# u3 ]6 z. n( I x( @
DWORD hash = ((id) + (id>>8) + (id>>16) + (id>>24)) & (NUM_ID_HASH_BUCKETS-1);* v( M" w! L9 u8 h1 \1 s
return hash;2 Q- f+ m; D8 C+ q
}</P>$ }( E7 f% t7 Z# N8 H2 M
" A; w! J" G! r3 }* W
<P>0 q8 ?7 V, K6 ]4 y8 z
//----------------------------------------------------------------------------- 2 j/ z4 U4 ?. K2 m* Z// Name: # s7 X% c! Z! c& {: q1 v% S// Desc: + H% @8 j7 w0 P' p& z//----------------------------------------------------------------------------- 6 g. u [1 F% }void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData ) 9 l" V6 i4 R7 z+ h; [! u8 G{ k [0 b" S) k) L8 o' b' I // Hash the ID to a bucket number 4 n( i) ]3 ~5 Y# d4 p DWORD bucket = IDHash( pPlayerData->NetID );</P> , @8 q3 [! K5 E* W<P> // Lock that hash bucket " x% }6 ?# p, s) r) R* ]. ] const DWORD buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS; 3 `6 C& [2 U' m# _8 s m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>; o3 I' \9 s i# W8 \) T6 @
<P> // Loop though players in bucket until we find the right one 7 F+ m' j2 }6 J: H PlayerData* pPt = m_pstIDHashBucket[bucket];1 _2 s/ i/ x2 }8 Y {2 E& T5 A
PlayerData* pPrev = NULL;& _- f ?0 R4 c5 d, O
while( pPt ) ; F2 ]" [+ y; [. W% W* Z {+ p4 j3 g3 I$ T+ t! ]) {4 Z
if( pPt == pPlayerData )* e1 @1 d5 i4 b. M! V7 n3 w
break;: a, @& G- C3 s/ r6 }7 f7 ]
pPrev = pPt;+ m* `$ `/ S, x7 Q
pPt = pPt->pNextInIDHashBucket;1 _# d4 p4 u+ H: }0 l8 {- P- j
}</P> , Z2 q. l# [: M# b! Q( e t<P> if( pPt )/ c% c/ C; n/ E, N! l3 l2 ^ y
{ 0 w" O$ E& s0 V) q1 G" |. p if( pPrev ) , n' _3 ^) X7 J7 ]! N7 p pPrev->pNextInIDHashBucket = pPt->pNextInIDHashBucket;2 u V& J4 `& g0 \2 ]
else + N/ o5 M+ K4 r+ x m_pstIDHashBucket[bucket] = pPt->pNextInIDHashBucket; ' Z( W/ ]6 L9 `6 r$ U( F C: d4 \ pPt->pNextInIDHashBucket = NULL; 5 \& l; J0 o- q }</P> ( N9 l% S) ^! {6 O<P> // Unlock the hash bucket2 K3 K# t! b. K) Y E x4 q8 j D% w
m_IDHashBucketLocks[bucket/buckets_per_lock].Leave(); , \: R3 U5 X) _# F3 l# e" q}</P> ; g# o; [. s1 h! x3 l5 Z+ B. \7 _" ~6 B& r$ Q& e, [6 y
<P>2 C) Y$ L1 X6 t) {. `& Z0 z! f6 i/ [
//----------------------------------------------------------------------------- 3 g0 e9 [8 F7 _// Name: 7 _# c/ L, R" C* v% g// Desc: 5 \ M; X1 A! Z2 @ O9 m//----------------------------------------------------------------------------- + c* _4 l4 H5 Q- D9 K7 c, Uvoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData ) 2 K$ b, p" \$ |! x/ R. E6 L# b{# P, X$ l; B9 J8 F' D
// Make sure this player isn't added twice to the m_pstIDHashBucket[] : g" P4 v4 l0 w5 H. F // otherwise there will be a circular reference# L" |# M' o4 y, K& i2 ?
PlayerData* pSearch = GetPlayerDataForID( id );' m/ \) [5 C; { V! [/ X* ]
if( pSearch != NULL )8 u( I1 d5 S% C/ M
return;</P>9 r5 ^4 [6 a+ w1 `" y
<P> // Hash the ID to a bucket number - \3 m* z4 Y) @' ] DWORD bucket = IDHash( id );</P> m8 y! Y7 w' q8 s/ ~
<P> // Lock that hash bucket1 ~. z* a3 |) V1 t5 I% d3 f
const DWORD buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;+ _6 [) ^2 C7 o/ w. `
m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P> , c; M! z' v# o<P> // Add player onto hash bucket chain " D& B2 r) M+ z* O pPlayerData->pNextInIDHashBucket = m_pstIDHashBucket[bucket];, i& T, a' m7 V) H% P8 t; c8 y
m_pstIDHashBucket[bucket] = pPlayerData;</P>' w3 ^& ?$ @; s2 o
<P> // Store net id in player0 P0 w& f3 I2 Z, U1 f
pPlayerData->NetID = id;</P>7 @( p% W& y- n; p7 k6 [
<P> // Unlock the hash bucket( F, ]/ v) T% r
m_IDHashBucketLocks[bucket/buckets_per_lock].Leave(); 2 h" _, b$ F" A+ [* K}</P>- f7 ^! b1 W: f. \2 U" U
. F M$ J: G; U1 g4 S
<P> 6 `0 g9 x1 d; ^4 u3 |7 H0 ?) Y//-----------------------------------------------------------------------------: A5 ^+ Y* ?& j0 k0 }3 H9 h* m
// Name: ' I( i5 \6 F, Y. \; c// Desc: - M/ {* m8 h+ D6 l/ a4 K" U/ w//----------------------------------------------------------------------------- . R; l1 `# M* ^ C: m9 ^4 T( BPlayerData* CMazeServer::GetPlayerDataForID( DWORD id ) 8 k2 E- I3 ~3 v{ + t; W1 a& o) _/ W! W" J, N; D // Hash the ID to a bucket number , `, R, B* ?4 x4 U8 K; D4 [3 l DWORD bucket = IDHash( id );</P>0 d; m+ z" u$ b1 s' R
<P> // Lock that hash bucket. ~. R5 S( j6 d% O
const DWORD buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS; % @" u6 b6 d7 K4 v' S. P m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>2 K' g9 ]2 ^8 Q
<P> // Loop though players in bucket until we find the right one 7 S+ J! \' b' T PlayerData* pPlayerData = m_pstIDHashBucket[bucket]; 6 s) Q) a0 T/ a5 s: T$ ~ while ( pPlayerData ) 0 e1 y7 i0 h. o% E {% e+ X3 t4 c( b1 e
if( pPlayerData->NetID == id ) p* E6 d, @0 a) q6 k- J% ^$ c break; ) y$ g: s$ k4 i4 _+ l2 T; L' U pPlayerData = pPlayerData->pNextInIDHashBucket;8 y# z# a, F. Y- P/ r% f
}</P>, K6 @9 c4 O/ f- P6 I
<P> // Unlock the hash bucket4 w3 \5 m& f4 X& i3 d, F
m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P> - }' G; }0 o5 |8 V( |<P> // Return the player we found (will be NULL if we couldn't find it) 9 `3 s3 d/ S; {3 t3 e return pPlayerData; 2 g0 Z% \8 \$ ]! N5 ~}</P> , a: Y+ D$ i2 \& n' s( m7 T( t* H( v1 P: C
<P>& W9 l4 Q$ E3 W1 f# u3 e. X! x
//-----------------------------------------------------------------------------# k# `9 X5 a$ C1 |1 H/ l2 [
// Name: 5 M0 N" m/ t' S8 }& U
// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner" M+ `: {1 a3 J6 L4 Q+ B/ B
//----------------------------------------------------------------------------- ^) j7 F6 P/ D. c" rvoid CMazeServer:isplayNextConnectionInfo()0 T6 Q' u/ _ M4 `+ }$ f+ k6 {
{1 u0 v8 U/ _8 C" ~. M. l7 |
if( m_pNet )6 ]0 p# x8 S2 _ d1 K
{6 Y" L7 I4 S" M. @
// Find the player that was displayed the longest time ago, and display it. . Z$ m! J, B7 Y FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );$ X4 q2 R1 G! x5 ]# K8 a
PlayerData* pOldestPlayerData = NULL; ( O2 Y! T! `& E$ v1 g% f FLOAT fOldestTime = 0.0f;</P>/ P8 ?* c; K5 o$ T, T1 A8 D
<P> m_PlayerDataListLock.Enter();</P> 2 K/ z8 @' m1 C<P> PlayerData* pPlayerData = m_pFirstActivePlayerData; + |3 c3 `2 h- x) J: F while ( pPlayerData ); ? Z6 T" F% A ~
{ 2 s5 t* ^, ?8 Z" K- e if( fCurTime - pPlayerData->fLastCITime > fOldestTime )7 F/ l0 R0 a9 b/ a, W. A9 s
{ + ]! {8 e: P1 e6 g P) g4 W fOldestTime = fCurTime - pPlayerData->fLastCITime; # L/ l9 G. d0 F, ~; f3 y0 w pOldestPlayerData = pPlayerData; : b1 j3 G1 {2 Q }</P>- j+ Y2 H. l( y
<P> pPlayerData = pPlayerData->pNext;. h- X8 v( t2 R. Q
}</P>* V$ N2 U1 F0 r2 g& ]7 P+ j6 D. l
<P> // Display the player with the oldest CI field, and update its CI field. 8 \( Z Q3 F/ l3 _6 Y if( pOldestPlayerData )+ F' b8 @1 R7 d$ c3 Z9 i
{# G2 r) J6 U& ^& \8 I, Z
ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") ); $ Q/ N# J7 T: y DisplayConnectionInfo( pOldestPlayerData->NetID ); ( T7 f* w0 R/ N( ` pOldestPlayerData->fLastCITime = fCurTime;$ F6 h% E! z: _+ C L" c
}9 M2 A y" [* G# ] j v$ Y# T
else " d' F4 M, R; i" X; j9 n0 r { 7 X$ w5 s* p+ l% T: B5 B ConsolePrintf( SLINE_LOG, TEXT("No players found") );+ |# p$ M$ k' F" B
}</P> # \9 u& f: S8 k& H w<P> m_PlayerDataListLock.Leave();5 y3 x& S% o1 l7 y: U
}) m4 U, R0 g8 d/ A1 W
}</P>" _$ m% x9 @- m& t2 e* e5 k
0 C6 U* n8 i/ X1 m
<P> ( o& U- z3 V( w//-----------------------------------------------------------------------------( E6 w" \1 w4 d% J: Y9 @% n8 C
// Name: V" ] } _$ L4 r; t$ l" h+ _
// Desc: ; a7 V) B" J! }4 O1 s* z! M) s//----------------------------------------------------------------------------- ! U( _ h2 \- d- h" u! d6 O+ O' Hvoid CMazeServer:rintStats()4 D2 k7 V& s1 l* R6 x- i
{ , `$ m4 q1 @% i$ w- X% |- l ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"), ; K$ ~! j" U" k* w$ }6 Y) J& Z m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount ); + T2 Z3 |6 }6 a9 @* k& Q ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),- J9 M5 ?* _# c8 X; X
m_fAvgThreadTime, m_fMaxThreadTime ); * \+ a/ [( s5 C ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount ); 2 ]# D/ I8 U' i/ M0 a# d ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount ); $ D3 V" \: d8 A' f3 e; U3 Y}</P>6 s a! J) y2 h+ \0 n8 O- i
" j6 W4 E e) T9 U<P>) T+ O, Q; u, @
//----------------------------------------------------------------------------- . h& e. M3 ?% [0 w, P! m// Name: , l+ v$ @6 |- \
// Desc: , @) g) ^% G3 v3 m
//----------------------------------------------------------------------------- % u; u/ ~! ?" x6 l2 ^6 t$ Mvoid CMazeServer:isplayConnectionInfo( DWORD dwID ) ) C4 h3 g8 F" o" \& q{6 d6 T4 [5 d" B' J: ?+ h
TCHAR strInfo[5000]; 3 B0 Y7 I- P5 x+ } TCHAR* strEndOfLine;% h7 E/ s" i9 n# k
TCHAR* strStartOfLine;</P> 0 ~7 y! R" u9 d, p6 _3 T<P> // Query the IOutboudNet for info about the connection to this user # O2 M2 g6 n1 L& M6 D m_pNet->GetConnectionInfo( dwID, strInfo );</P>$ A5 g% [2 P) m7 [) ?; |- c: r+ P
<P> ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID ); ! T# m. L! a; K6 s% g P" l* h' E ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>( B& S# | i) J4 B2 z- Z H
<P> // Display each line seperately8 M6 h3 p( h6 C, x3 w6 U& }& J: _
strStartOfLine = strInfo; 3 U8 P( ]' o4 l+ @0 u/ u: V while( TRUE )& s9 v/ S. x# c* P4 f
{- h, R1 e$ J" R! Y; I j% i: J
strEndOfLine = _tcschr( strStartOfLine, '\n' );4 o" @( V$ P# ~% k' i# @/ y& I* \+ w
if( strEndOfLine == NULL )( A+ U0 ?* ?0 s* ~
break;</P>/ P( g1 R7 y. p
<P> *strEndOfLine = 0; 8 Q) M4 J/ \* g# S8 r# z- ? ConsolePrintf( SLINE_LOG, strStartOfLine ); 4 R( w9 @1 y6 R8 ]+ E$ ?+ Y6 K strStartOfLine = strEndOfLine + 1;. E+ R5 z F, }% l# s* L- s1 a
} . t/ A$ o. ?3 y7 Z; @$ i( A+ H! `}</P>, _3 g' D' h/ }2 Z% J+ n8 O) m
' ?5 N+ x5 i* a; b
<P> / D! Q* Z/ Z3 X* t$ H//----------------------------------------------------------------------------- ) S3 m$ l2 E: y0 T' l5 M// Name: 6 w) p# Y& K- q: _, C
// Desc: 4 U3 { B. E% p! v% z: D* T//----------------------------------------------------------------------------- $ u% Y1 W# w. V1 V8 eHRESULT CMazeServer::SendPacket( DWORD to, void* pData, 2 g" M# H, n, }6 W" g# o DWORD size, BOOL reliable, DWORD dwTimeout ). S. X. v0 \ k9 ~
{ ! }2 u9 ]. K1 n" A4 u: N2 z // Chance of forcing any packet to be delivered reliably # [) S* n0 _! p5 e2 D0 n' r( N if( m_Rand.Get( 100 ) < m_dwServerReliableRate )$ }# v: L7 E1 Q* `' m
reliable = TRUE;</P>0 n( ~5 f) M o0 n) E, \; ?
<P> return m_pNet->SendPacket( to, pData, size, reliable, dwTimeout ); ; Q4 U2 j' ~) ]8 ?}</P>8 b; ~# [; @1 i, ] H* R5 D7 n
J( d7 f) V' _: ~
<P> 7 f3 h0 Y7 k4 Y7 ?* x* `7 [! b//-----------------------------------------------------------------------------1 c6 Y$ W8 z! D& W! U
// Name: 0 q! a8 }( V; o% V// Desc: # d% Y. ^; T: }" s
//-----------------------------------------------------------------------------! P c# A$ P! V% i# O# V" S
void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket ), f/ o5 T: ?" ]
{) p2 Q) D- I% O- W
// If we're up and running, then send this new information to all clients, o5 a% [. \+ B# o
if( m_pNet ) ! l, [9 L, n' S {: d5 x& u; b: S6 ]3 J
//Use the AllPlayers ID! s$ o8 q+ c" x* f: P
SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 ); 8 E. z0 a/ E1 e- s" T } + D. ^' p6 o" I( k$ B/ S}</P> # x' C$ h, \* k. U$ E+ z& X) F2 i& v& q& Y9 p5 i) Z; p
<P> 9 |- f7 e: [+ G, `//----------------------------------------------------------------------------- % k* k5 m0 \/ u- @# l# ~ c& o// Name: 2 Z6 j* T2 v2 Q6 w3 n3 u: { A3 k
// Desc: : l! f! ], x8 p% L- q. N//-----------------------------------------------------------------------------9 g. S& Q* b& j# H
void CMazeServer::SetClientReliableRate( DWORD percent )) l9 M$ D! [1 {6 B
{ & V# y W! d5 r5 D // Update client config, and build packet containing that data 5 T& F6 ?7 u4 Y5 D3 R- R9 g m_ClientNetConfigLock.Enter(); 4 F6 E# B0 M2 C m_ClientNetConfig.ubReliableRate = BYTE(percent);* u6 z" t& H6 W- Q! w% i) @- X# l j
ServerConfigPacket packet( m_ClientNetConfig );1 J3 M- M0 |. N' v9 ^- t4 V
m_ClientNetConfigLock.Leave();</P>/ j, W7 p0 N! @8 K, i5 i/ {$ o# j) Z
<P> SendConfigPacketToAll( &packet ); - K3 Z8 V' G. A}</P> 1 |) t/ F& M+ \, m+ j* X$ a 6 }! m7 L' X s8 x b3 Z<P> & @' t6 z; ]! P/ V' @) o, S( ^/ A//-----------------------------------------------------------------------------' S U" g7 C7 q: y1 Z7 B9 e
// Name: * n3 k' R( t) u! S9 d
// Desc: + m4 p' G2 Y6 I; K7 P//----------------------------------------------------------------------------- & J. l( k8 o9 Y# ^' N( _! Svoid CMazeServer::SetClientUpdateRate( DWORD rate )! `9 B1 d y! z4 z \2 P$ G- w( X
{ - X: Z1 ^6 [- _* y // Update client config, and build packet containing that data5 g, }% `- O2 S& X$ }
m_ClientNetConfigLock.Enter(); ) R/ E3 f# k# J8 n7 M, T' ?' H1 I2 Z m_ClientNetConfig.wUpdateRate = WORD(rate); $ N. q" c/ V$ l1 u3 o ServerConfigPacket packet( m_ClientNetConfig );( s! M1 C. h; m0 r& W5 j i( |7 B
m_ClientNetConfigLock.Leave();</P> ( N: D# D( v9 H+ K, g" @4 K<P> SendConfigPacketToAll( &packet );) G. [ Y- q3 ]+ N$ ?
}</P> / _5 d" v# C7 ~ , R$ m2 R* e8 F* ?( D3 p& S<P> ( V( f* `; ~4 } R//----------------------------------------------------------------------------- 1 f& [7 d/ T- b5 H8 m8 ~5 P// Name: . v% @0 o0 a; m0 @- _1 p: c
// Desc: 3 {0 r [( ? J) |; N
//-----------------------------------------------------------------------------$ `: l" y! P, S5 j( w4 z. I
void CMazeServer::SetClientTimeout( DWORD timeout ) * [, i+ h* x0 P+ m- t{5 O" `9 i+ @8 u( M6 b7 t' s
// Update client config, and build packet containing that data 8 V8 q7 O& N& _; \4 _3 e* D2 Q' j m_ClientNetConfigLock.Enter(); ! ]2 e0 V q- |! w m_ClientNetConfig.wTimeout = WORD(timeout); * V9 k0 f% a* z. \0 \. j, W* G6 C ServerConfigPacket packet( m_ClientNetConfig );6 t7 K1 U7 s. C9 o- R( b* l6 ?5 e* Z
m_ClientNetConfigLock.Leave();</P> 9 K, Y% Y) H/ g; ?* j<P> SendConfigPacketToAll( &packet ); : W( _& c" r7 A}</P>* A6 |- Y" o. g+ U X9 z
3 B0 t! }$ P, v, b# L& q8 @' s
<P>; K7 g; N5 _0 I
//-----------------------------------------------------------------------------. C8 Q2 ?, |% \% V2 H: M
// Name: 4 Q- ]- x- A, n# f! ~" _3 R
// Desc: / |, a$ t" T# n& G: c( Q4 N//----------------------------------------------------------------------------- # s. S. S E5 v' Cvoid CMazeServer::SetClientPackSize( DWORD size ) a! s. x4 b3 Y) M* t! L{3 U( a7 R1 R7 s* o0 n
// Update client config, and build packet containing that data& B: y1 t' A, h1 T$ G8 b
m_ClientNetConfigLock.Enter();. w( z }. K% x% B3 Z/ w( A
5 p" S5 `: M4 `$ a
m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array. % _3 X; n* S N0 w if(m_ClientNetConfig.ubClientPackIndex >= PACK_ARRAY_SIZE) 7 \3 k5 k% g. U( b
m_ClientNetConfig.ubClientPackIndex = 0;</P>: K& Q. o; `2 I: Q5 D
<P> m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size); ) L; o6 M# m }$ G% Q8 f ServerConfigPacket packet( m_ClientNetConfig ); 6 [. f! h& I5 m5 T, S( o7 l9 ] m_ClientNetConfigLock.Leave();</P> 8 t9 @5 _0 Z$ J; E9 e/ @1 C' ~<P> SendConfigPacketToAll( &packet ); # C! f8 y }. \}</P> $ i; q' v& A' W, h& S" g+ G9 W) A% m4 h3 U" _
<P> ( l0 H% w- f. z% k//-----------------------------------------------------------------------------0 W) B' Z. v3 ~! I, I; c
// Name: 2 r6 E! k$ k K* L! e% x( u// Desc: ; h1 v1 M* Q1 J3 E
//-----------------------------------------------------------------------------( t. M5 a; k9 E) W- Z$ g- N
void CMazeServer::SetServerPackSize( DWORD size )6 U. P$ ^3 H2 S( J. Y. ^0 M' d; X
{! l2 y3 y. F$ C3 V3 q9 T0 W- T
// Update client config, and build packet containing that data L8 {7 h/ {- j. f9 g0 s# T
m_ClientNetConfigLock.Enter(); # o# ?+ m( L9 }! z- C $ O1 b4 g) G7 r, r! C
m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.- C! j/ r- A4 ^3 X5 k3 l, @( ~1 b
if(m_ClientNetConfig.ubServerPackIndex >= PACK_ARRAY_SIZE) & ^3 x; \' W+ i, `0 H
m_ClientNetConfig.ubServerPackIndex = 0;</P>. I$ i5 X; u" n( o; s- `, q! p6 J5 V& a
<P> m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);/ @5 h: [9 G( i- ]0 K* }% R0 F
ServerConfigPacket packet( m_ClientNetConfig ); ; e( H, T, i0 V, L, D5 q m_ClientNetConfigLock.Leave();</P> $ J) Q* J4 A5 ^! H; I0 q+ u; q R7 {" P<P> SendConfigPacketToAll( &packet ); % I3 Q8 e5 h4 J" d' k/ _}</P> 4 |$ P. u& L. n: w6 t* O: a+ n<P>6 h: ^" y/ y: `) t3 m8 S# M
//-----------------------------------------------------------------------------. B9 n* [' H: W& s- ~* @
// Name: ; m4 ~- G. ^& J
// Desc: B4 s! A- v; k//----------------------------------------------------------------------------- # W6 `3 u4 F' h: D' qvoid CMazeServer::SetClientThreadWait( DWORD dwThreadWait )4 |9 d6 E) i1 J! s/ @$ [3 \ E
{ . j; f: ~ G1 {' c) e0 W: |) O // Update client config, and build packet containing that data 6 B5 T7 _% J" n- K3 C m_ClientNetConfigLock.Enter(); $ t2 I, y) \+ d! Q $ U7 u! g: I! o5 X# l$ f m_ClientNetConfig.dwThreadWait = dwThreadWait; ; g: b' @& S* b+ l% n5 {6 p ServerConfigPacket packet( m_ClientNetConfig );8 I0 E4 Y. k8 _: d8 t+ I- a) p8 B
m_ClientNetConfigLock.Leave();</P> & h$ {' p% m/ y; w7 m0 N- t<P> SendConfigPacketToAll( &packet );0 m( f7 F% _- v6 g, t# z
}</P></DIV>