数学建模社区-数学中国

标题: [分享]MazeServer源码示例 [打印本页]

作者: ilikenba    时间: 2005-1-31 11:52
标题: [分享]MazeServer源码示例
<DIV class=HtmlCode>* ?) w& T: d0 @0 |( K- R% ]$ R
<>// File: mazeserver.cpp
6 V& V3 l* U1 U& l//
$ O% m% z$ l; s) }7 B7 N  R// Desc: see main.cpp
. H- L) T* X: f6 T+ `& W//2 q" c2 I5 f  ^% z
// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
  N- ]6 n; h" J, Y/ n* ^//-----------------------------------------------------------------------------
4 r; U5 w9 L# `4 S) }% J4 `/ F#define STRICT" D8 q5 Q; z" O, `+ y: O: \- s
#define D3D_OVERLOADS
" }+ j* {" ?& z, O#include &lt;windows.h&gt;" p# o5 ]* L! G/ O4 F* y
#include &lt;d3dx.h&gt;0 |, _- ^7 T+ ?
#include &lt;stdio.h&gt;
! a" l8 ~4 M7 h; x8 D#include &lt;math.h&gt;4 H9 v# F1 q; e
#include &lt;mmsystem.h&gt;
7 n+ V2 h" h" B* [#include &lt;dplay8.h&gt;
& ]; k! Z& F7 n( T2 y#include &lt;dpaddr.h&gt;) @! m6 g2 `& v
#include &lt;dxerr8.h&gt;
/ p( R: E- x- F/ t" }#include "DXUtil.h"% n  ]; N$ P+ {  X; e
#include "MazeServer.h"
: C3 l7 A! i  a  @#include "ackets.h"  _, r* r! Y: J0 r7 v' n, `
#include "Maze.h"
: B1 e6 Y" D$ ?9 {#include &lt;malloc.h&gt;; t5 b. L+ i: y( u! g
#include &lt;tchar.h&gt;</P>" C% ]  x) U5 I. L4 u1 Y( @

6 ^8 G9 H+ U. {! @, T- ]5 p% Q% L<>//------------------------------------------------------------------------------ u# c* {; L3 e/ n
// Name:
3 n: B# D/ `$ e$ t6 v7 ~$ [// Desc:
$ v2 R8 H( q7 c//-----------------------------------------------------------------------------/ {; u) o% m; @1 K, U4 n
CMazeServer::CMazeServer()* a* n! x4 d7 G5 H7 O4 E
{
" @# F# n5 M- b! r& p" V/ H    m_dwPlayerCount         = 0;
4 q$ h' X( D) d: a- l9 {' j   
, B& ^6 E* h& P9 f    m_wActiveThreadCount   = 0;
. x& @- z# A4 a$ g( m    m_wMaxThreadCount      = 0;
4 w4 y5 ~# ^0 Z- e    m_fAvgThreadCount      = 0;
& w- B# x! i9 c* s8 `5 c. |! V    m_fAvgThreadTime       = 0;+ y) o* M3 U0 g2 g
    m_fMaxThreadTime       = 0;</P>, z( M% |: Q5 J7 p
<>    m_dwServerReliableRate  = 15;# ?4 n* ?5 S: z, }0 `% Y1 S' u0 G
    m_dwServerTimeout       = 150;
. p1 E% r& W- `! F! ?    m_dwLogLevel            = 2;
4 `4 C6 f) \7 T6 h* d1 `    m_pMaze                 = NULL;</P>9 a5 o/ A8 V9 S
<>    m_ClientNetConfig.ubReliableRate = 15;# e1 \$ x. X  n  ]$ a1 b0 {. ?
    m_ClientNetConfig.wUpdateRate    = 150;& e- x# D0 W  P  O1 C, j
    m_ClientNetConfig.wTimeout       = 150;</P>+ k& P0 s  Y2 D- u  |
<>    m_ClientNetConfig.dwThreadWait = 0;</P>( e1 K/ R. H/ k4 m1 N
<>    m_ClientNetConfig.ubClientPackIndex = 0;
8 O8 F4 P8 I+ Z( P- D+ k    m_ClientNetConfig.ubServerPackIndex = 0;% G- r5 G$ I' U0 A8 P
    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)
9 l" J6 X2 ~/ z    {" f( B% H7 o8 I. r* d
        m_ClientNetConfig.wClientPackSizeArray[x] = 0;* u) r" [  m7 y' I/ M
        m_ClientNetConfig.wServerPackSizeArray[x] = 0;! z/ s5 O) Z0 e5 C- }+ z
    }9 y+ {7 m/ A( S9 m. L
}</P>/ u' U! f2 l( V% K; \. H: l# _

; ?: b5 g- s8 W3 ~6 b<>/ N: v; c* `0 N" S
//-----------------------------------------------------------------------------
7 w8 q) |7 G1 n8 u* x3 Z' a; P// Name: 0 u  a7 r6 x! b  C! h
// Desc: $ H  \  p/ `. K6 o0 l
//-----------------------------------------------------------------------------1 x6 V" N  g. D6 p  C/ `
HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze ): O6 |( O2 p* _5 m5 K- X
{
3 I% ~: w" u" M9 ?! C    m_bLocalLoopback = bLocalLoopback;% d" Q& K3 M/ R6 @9 q; ^* W
    m_pMaze = pMaze;
# X6 c# A" E) o    if( m_pMaze == NULL )9 s- [: \0 ]& f5 l
        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
1 O+ x) R& F( @1 y8 h% I& a. ~/ q<>    // Grab height and width of maze
4 f7 m& o' L) q7 w2 b    m_dwWidth = m_pMaze-&gt;GetWidth();. H" o# W$ n( H. I# S% R- m1 g  v
    m_dwHeight = m_pMaze-&gt;GetHeight();</P>; x5 {- ^' V& b- }' I! s) \
<>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
( ]9 Q( n% N3 Z( j1 k    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
" X7 l1 d: K$ N& `# f4 n; s<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.
9 A+ j5 L+ B. U+ S    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
2 y$ ]3 a1 [, x" H' y4 I        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );+ ^* C8 X1 a8 Y, [7 r
    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )$ O" c) W; X" d+ O  P+ L+ N
        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>) H: K8 S4 M) [; A8 r5 h5 A& t! |
<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;
' R2 m+ B# }- S, X    m_dwMazeXShift = 0;
, a: k! Z: N) W* T2 L. o0 D    while ( (scale &gt;&gt;= 1) )& f; L; [8 _# }3 a- k5 L# ?/ X
        m_dwMazeXShift++;</P>
3 R" {# g5 M/ [5 L. c2 s<>    scale = m_dwHeight / LOCK_GRID_SIZE;
2 t8 M+ O1 }0 ~5 f5 A    m_dwMazeYShift = 0;
$ i. z8 T/ ~3 \, ~; S4 t7 _6 C6 f; l    while ( (scale &gt;&gt;= 1) )4 f) o- M- j2 b% }
        m_dwMazeYShift++;</P>
8 Z3 \5 N% S9 ]% \<>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||7 N) v  ^, G. O4 V; u
        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )" q0 m, }8 o0 b$ [' Z
        return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>6 a! v3 J7 ^4 e1 h
<>    // Initialise the player list
$ G  D2 G" p8 w3 s    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );7 X' @7 B( f, C* Q$ H' b+ c; ?7 E
    m_pFirstActivePlayerData = NULL;8 q  a' q) C+ F. g) J, `
    m_pFirstFreePlayerData = m_PlayerDatas;2 y0 |) T7 t! q7 |- L! Q
    for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )2 G4 V3 P# X  a' W; X
    {
) ]- M. f" x- ]3 H        m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];# `' h, r' b. L) A" g
        m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];2 }  S: ^& b- G/ c
    }</P>
) D1 k' T7 e$ n6 X' J6 X5 l<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];" q0 s+ Y' n$ K/ P! ?( y
    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];
/ p0 j( V. p6 L. }6 t    m_dwActivePlayerDataCount = 0;
% p9 n6 |8 y( ^    m_dwPlayerDataUniqueValue = 0;</P>( N4 U# {( s& `9 n
<>    // Initialise the cells
+ P% R% u( w  h7 a    ZeroMemory( m_Cells, sizeof(m_Cells) );9 t7 K" j- K1 T: J# L, R
    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>* g2 T$ {' X; X. V9 d
<>    return S_OK;! o' c8 G/ _! `2 x& E* S+ x
}</P>
! ~( Z8 ?% b% z
6 v. ]% o+ \+ W7 w<>
: e; _; B( z: l1 Y6 W# W  M//-----------------------------------------------------------------------------
) u; V3 J# {) Z! K// Name:
( X4 p2 h; |5 ~1 ^7 a3 d// Desc: 5 ?6 O( ^5 X6 U
//-----------------------------------------------------------------------------7 S, V3 ]2 p- B) N# ~
void CMazeServer::Shutdown()
) b' e) b3 j9 t& k, t{
0 h4 L' u" r& i; x}</P>) e- V2 v, j7 o- t. W% H
% R! l/ a6 i1 `* ?* X7 H
<>
, P9 q1 q* k. Y& e6 G//-----------------------------------------------------------------------------8 L' L$ ?& x+ @8 D6 S
// Name: , I3 ?$ T$ ^) y# z
// Desc: ) j( v& ~4 E: n
//-----------------------------------------------------------------------------
+ l8 G( w# q- s$ G3 S1 Tvoid CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )7 |" |! y8 ?* O$ E& ?0 [: z, ^
{$ @) O9 d+ c/ u* ?4 g6 S- Z
    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,4 F2 P/ b5 P9 i4 F) Z
                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );, }  m! O. C; P; S9 J% i) ^4 W
}</P>$ m+ B8 [. w* N' X
! o) p) h  n0 k
<>8 E0 b% L  j: h% D& j
//-----------------------------------------------------------------------------; G8 Q- T7 [: F# A3 l+ }
// Name: 4 D) d+ x& X- V  y5 s& t  ^
// Desc: & ^: T% a4 I7 A- {9 ]5 N
//-----------------------------------------------------------------------------8 y% ?. T5 G0 @5 }+ A
void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
% e0 s8 h: i1 g9 O# }{
% ^: N  N4 v# a    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,. c7 b; n- q5 s' l) \& k( _2 R
                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
( ~. r; M5 u7 l) |3 |6 h}</P>  V+ D( |  y5 ]+ c! P, E& l& M
4 H! m/ p8 b& s  M5 n4 _, `
<>% A8 s2 m) n$ x4 g- \# W1 F; A2 n
//-----------------------------------------------------------------------------3 o# {6 p0 {) M1 d, _) Y6 x
// Name:
6 i! Q8 R3 o7 Q  Y$ R// Desc: 2 ]4 U' S$ |& B+ N0 F% I* H: P6 {
//-----------------------------------------------------------------------------
* e, ]& D' m8 \9 Z1 x, ~" g; x9 {3 }) [. avoid CMazeServer:ockCell( DWORD x, DWORD y ). U- V& u( I- Q; V* C
{( }/ s  I. q  @3 Z
    if( x == 0xffff )
* X& h) v1 D) ~; A- m& @5 W        m_OffMapLock.Enter();
" R0 K1 ]0 N  |( y, Y$ D    else! [8 }4 ^% C- z; c9 x
        m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);* W1 Y; _1 F6 `5 H: r$ ?7 E
}</P>
  a4 `9 B/ G3 T* L+ b: e
, [& [  g9 E- j8 e) E<># ?# o! p0 o1 u
//-----------------------------------------------------------------------------/ z9 i! M+ d/ R1 g! `
// Name: . G* F; C0 q/ d/ q4 A
// Desc:
( Q! u9 U% ^6 x, B* N  B//-----------------------------------------------------------------------------! z+ g( M  u. V  [
void CMazeServer::UnlockCell( DWORD x, DWORD y )
( @$ k0 E3 ^/ q. Z+ f' J6 P/ n{: P. U9 D1 s4 R
    if( x == 0xffff )
6 ~" ~- V; n! K  X7 o        m_OffMapLock.Leave();% G6 @' \& \7 |  w: t6 o3 z7 ~( q
    else
7 [. K+ P$ _8 ^3 v8 K9 K        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
$ C; J3 \  z& \, m; X}</P>
3 N$ x9 ^" @' T% U# {5 s- I: [* [5 Y( h3 i4 o
<>* q7 Q$ z; J) K9 q' H
//-----------------------------------------------------------------------------$ ^# _! S0 Q& y
// Name:
% H+ d1 `9 Q' c// Desc:
3 s4 ~: @5 q4 \. f* B1 H3 V4 L//-----------------------------------------------------------------------------* r0 I, E6 `2 ^
void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 ): C* g/ i. D+ z  V8 I9 J5 e4 ^
{
. B4 I! D+ `/ Q- Y0 T3 l! s    if( x1 == x2 &amp;&amp; y1 == y2 )
' G, D3 s4 P# {) X! K  C2 f    {
. R( |3 C: N2 V        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
4 w& [4 Z$ C8 u7 Q; x* S            LockCell( x1, y1 );
5 E5 [& A4 g3 u  n/ K% H+ g& N        else4 e. X( a! S3 i6 `1 M
            m_OffMapLock.Enter();</P>
4 Q% O& I2 \) I+ q7 v- ^<>        return;
+ W/ e; h% x% q/ U    }</P>
/ y. g; F% q5 M4 K" N# g3 `. h<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;# Y! E  j+ Y! h2 q4 a# X: N
    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
- I" l& ]  [) O4 i2 A: e, q    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
& `; D7 Q3 e0 A: _2 _  c    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
2 b# X+ [& L' ?0 _+ X' }<>    if( x1 == 0xffff )3 `/ B) K! S1 W5 \% O: D3 X
    {
! \) o% c& i, R! M" n        m_OffMapLock.Enter();1 A: B: O; @9 _/ p+ O
        m_LockGrid.LockCell(x2shift,y2shift);
6 M7 M5 O% I$ M    }+ r8 d* i; u1 D1 Q9 c
    else if( x2 == 0xffff )0 z& @0 V- _1 |- V- m( S( K
    {
8 f$ z( \$ g" g& m5 P4 q: e        m_OffMapLock.Enter();- \% V/ d3 n  b1 f' h8 H
        m_LockGrid.LockCell(x1shift,y1shift);
5 @* l) j! M9 s- x" l# q2 V. ], e    }% w6 {: A/ W7 l; P4 h$ \6 t
    else . f/ ]; @- j3 @1 Y
    {# c  X; c, N7 A9 w
        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);7 V& z1 P8 S: B7 z3 |
    }
# f1 S( @/ B5 E9 y}</P>1 z9 t4 q5 ?' r/ M- v+ H2 F

$ v: m) s. L+ M1 H<>
! C/ @: R* N* I) `3 |' s//-----------------------------------------------------------------------------
% D9 a0 R; ?) y// Name: . d6 E( q2 \3 |6 Y
// Desc:
& m# n& y) D, L& X. C1 P( a) D7 r2 V//-----------------------------------------------------------------------------7 O0 ]1 ^2 N8 b; C9 }: R7 z
void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
# i" ?) X2 S3 b  D( G! w{
) K9 `* ]" N  v9 I* \3 y0 g5 O    if( x1 == x2 &amp;&amp; y1 == y2 )% z2 b5 {# U, Z/ H; t. n) v: e
    {: C$ }  u- _6 F. d8 h* ^: V  ?
        if( x1 != 0xffff &amp;&amp; y2 != 0xffff ); j$ c* H# S: _, M/ k0 t
            UnlockCell( x1, y1 );9 ?2 G1 y4 _" F# z) Y4 M2 u9 C
        else% h6 B! P1 F' ~
            m_OffMapLock.Leave();</P>4 L+ V+ S- e3 `3 d1 n& l
<>        return;" h7 \2 ^( F6 G5 \# C6 `: t
    }</P>' f0 p2 q- ~1 s
<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;3 B% ~) R- i5 z4 z4 O8 Q8 V# {7 i
    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
1 ?0 @  w; p$ K+ H/ r6 l    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;0 i9 F4 [5 Z$ i4 S' n7 Z
    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
0 A4 B7 q6 h4 X: b<P>    if( x1 == 0xffff )3 k: J8 X4 L: G( x- o
    {# Q2 c) }0 I9 h$ v
        m_LockGrid.UnlockCell(x2shift,y2shift);
- M8 b$ N- H3 O* y2 V5 E        m_OffMapLock.Leave();6 f0 Y8 j+ g$ X8 N* E# G
    }
! c# r6 M4 ~' ~" G7 _    else if( x2 == 0xffff )
. Q# G: g4 O" m7 i' u: e( q) ~2 d    {
) {3 U6 `8 l* y0 @# c        m_LockGrid.UnlockCell(x1shift,y1shift);
8 L8 f7 Q$ t: V6 ~& G. K! ~/ b: V& I5 ~        m_OffMapLock.Leave();
2 W( z! s5 s& [4 P/ G. \4 @    }
# y) L, I1 K6 j: m7 C, u    else
& c/ m( f* ?. O2 B" S* R" B4 V( i    {$ q- o& y8 b% \+ s
        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);- R! C% d% }# F5 L4 X. G1 |
    }2 O8 n5 f, P3 X) t/ \; U- _" N
}</P>2 U1 N- `+ m* S/ @
  W, r  g8 y" J/ S' b/ D! Z
<P>2 T% z1 Q2 _* ~* j- y& I0 P, \4 ^7 o
//-----------------------------------------------------------------------------+ `5 C4 A0 u; @) ?) X; D% p. J& m
// Name: % b: t3 t+ M9 J6 L8 @
// Desc:
. X# V5 \% |9 ?8 U4 p' |4 H5 `7 ]//-----------------------------------------------------------------------------
- F/ t0 G5 Q1 I# Z9 Wvoid CMazeServer::OnAddConnection( DWORD id )
' k4 L3 S' e* s+ ^{
' ]+ g: @3 Z2 K- }( j3 L7 b    m_AddRemoveLock.Enter();</P>* ~  m7 r- [& T! z4 k9 u( |
<P>    // Increment our count of players
! @0 J) H( }3 g" i    m_dwPlayerCount++;
: H4 K& L; n: T- ]- g: g    if( m_dwLogLevel &gt; 0 )+ j; }- L# I# [! m' Y
    {1 Q+ y$ J8 E% k- _1 c
        ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
8 I/ v7 w& N" F1 q, C) O        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );8 d3 G  n3 b2 R4 G
    }</P>
. p5 E+ r# C) \; S! M; \- {- `<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
" |2 K2 r% n% F! t0 D" c6 P        m_dwPeakPlayerCount = m_dwPlayerCount;</P>4 Z2 G" M! p4 j
<P>    // Create a player for this client
+ L8 L1 i& k, _8 W. _& Z    PlayerData* pPlayerData = CreatePlayerData();
/ n. X4 ]3 |( i% l" q- `: m    if( pPlayerData == NULL )
/ G9 f6 Q+ h8 t* o3 k4 v    {
- ^% R8 V& i( }' ~: \; p( R        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );$ ^' S0 Y$ Q$ a! ]( ]# v7 h
        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );( X7 p) h& d; M' i; x7 ^9 x
        m_AddRemoveLock.Leave();+ a, ~( m; m; k6 M% j
        return;1 S! ^2 t' k$ @: t" b- \
    }</P>& S# Y8 F7 [1 O
<P>    // Store that pointer as local player data2 }7 t. H- d3 s3 b5 W5 v' W- f
    SetPlayerDataForID( id, pPlayerData );</P>
. b. t5 A' f  T: ]2 D8 s  r<P>    // Grab net config into to send to client2 h5 d0 Y- u! z  s- L
    m_ClientNetConfigLock.Enter();
. U4 w' n: {7 }( B* F    ServerConfigPacket packet( m_ClientNetConfig );$ L* Q1 Y( a) L$ P, X6 U
    m_ClientNetConfigLock.Leave();</P>
- X- X1 `) e' i# b9 K* C<P>    // Send it
7 g) J# D6 f0 f+ D    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>
) n. b0 e3 T( J% A<P>    m_AddRemoveLock.Leave();6 U: _; k3 Q/ w: {$ a7 S* D1 C
}</P>
' Z. H1 ~2 }1 L8 V/ g( q* ~4 f
% Z0 T! L6 \0 o4 @<P>
6 x* z( w. X- k# E6 B* f) q0 @//-----------------------------------------------------------------------------
$ h1 ]- c& q4 A% t( H0 E, b+ N' \// Name: 8 b7 A" Y8 y+ d6 [9 n% X
// Desc: . A1 s# K& x: s# `9 B# M4 |. N0 j0 Z* p
//-----------------------------------------------------------------------------' j# H) F! Z* v2 `
void CMazeServer::OnRemoveConnection( DWORD id )
2 ?7 l# _: E7 m2 Z{
  G" v8 @. a& w. c7 G    m_AddRemoveLock.Enter();</P>
2 m% N' H+ P, H. w! }<P>    // Decrement count of players
5 {, d: _& j. z3 W    m_dwPlayerCount--;</P>
! f8 n; e7 @' z" `7 ?( U<P>    if( m_dwLogLevel &gt; 0 )$ F) H! j# h) G( i6 K2 e
    {" a2 T, v( C1 H0 M3 }- f1 `6 _
        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
0 [. \. m2 K& e" w/ _, s7 E        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );* Q: ^- g: d4 w$ n7 j
    }</P>4 C7 O5 ?, |+ u* N6 U" O
<P>    // Find playerdata for this client7 ^* v8 C, n; |2 U2 r8 k; h: c
    PlayerData* pPlayerData = GetPlayerDataForID( id );% W% j. |! v- b4 h4 ]8 m2 M+ f
    if( pPlayerData != NULL )
1 A; f4 m: p4 y4 T, s/ v  H% }    {
. l2 j0 \& ?& \8 @% I        // Destroy it0 \- v8 t0 T3 S6 g- X
        RemovePlayerDataID( pPlayerData );! I! Z( `+ t" d1 H' k6 I, C" s! H
        DestroyPlayerData( pPlayerData );
. X. Y  v: B( _1 Y    }</P>* o7 \9 T8 c" I2 |9 Z3 O
<P>    m_AddRemoveLock.Leave();- o$ c0 C  A# S* X9 U
}</P>. n8 v" P( ?; Q, V1 P( {9 y- _

% m3 v/ x% i+ }+ Z! q7 i<P>
) N# T; D& P3 a8 y1 p( g//-----------------------------------------------------------------------------
0 I3 i! f& W' \- t2 a// Name: , [! ~' n! g( Y* ?* Z5 m- Y# D
// Desc:
; o$ l% G4 H. N3 `- ]//-----------------------------------------------------------------------------
4 K- D* i; _% }6 xHRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )
  ~) o' q3 b& f( X: @3 r{/ {* z+ V/ I2 R* r7 U
    BOOL fFoundSize = FALSE;</P>0 X5 X: y. ]! |
<P>    // Increment the number of thread we have in this process.1 G2 O; j6 }, w! m4 g: a
    m_csThreadCountLock.Enter();</P>9 X  w7 j6 J" W! a) y7 E
<P>    //Get the start time of when we entered the message handler.
) ~  X' o5 y( C- V+ f  ~% b    FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>" ?7 l7 c: n5 J5 \) f
<P>    m_wActiveThreadCount++;0 I4 _) j. U, ?$ Z3 i% c- F7 j$ _- ?
    if(m_wActiveThreadCount &gt; m_wMaxThreadCount), A# C9 j( `! }1 b
        m_wMaxThreadCount = m_wActiveThreadCount;
% T, B- w% B3 j* w( b0 s   
! h( ?- }/ G' D    // Calculate and average.
$ m( J  P3 B; {; R& l  y% J' R* z1 `    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;0 C' b7 t# A3 B; Z" E( M
    m_fAvgThreadCount += fdiff/32;) O( r( s8 B! b5 ?
   
& ?3 R; [  N* o3 J8 }0 a5 z0 F4 J    m_csThreadCountLock.Leave();</P>
0 ^9 V* J, K% t' u3 l' K<P>
7 |' p5 N* o3 \$ o8 |; v4 |% A    ClientPacket* pClientPack = (ClientPacket*)pData;9 m$ P1 y# x  K; L8 }* b, t
    switch( pClientPack-&gt;wType )
) J% r5 _, J) O+ a' [# W' d    {$ B. s5 l5 S1 f' `9 m
        case PACKETTYPE_CLIENT_POS:5 N# s0 i' B: z8 t7 l1 a
            
; O  _7 w, o7 x            // Check to see if the packet has a valid size. Including 9 k  t) ]/ R0 R3 C" ?" v0 ?9 G
            // the custom pack size.
' B. A5 P/ _6 C; i7 a; G1 H: G2 I            if( size &lt; sizeof(ClientPosPacket))
3 x3 O$ d7 u- r  E3 W& g: S' L                fFoundSize = FALSE;0 O1 Q% d* l. A4 q1 u
            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))
) E. r& ^0 t% K6 |( f4 ~                fFoundSize = FALSE;
6 b) \) \6 `  g, C! D            else
% A: k$ ]1 G2 l% i3 Y  b                fFoundSize = TRUE;</P>$ @" g: f' o- E1 {
<P>            // If valid sized packet, handle the position.8 O, [% r+ c% N- s: u5 v
            if(fFoundSize)9 f2 {9 F9 C% ?; a7 L' n
                HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );8 z+ |# h! b/ v! \6 Z* z2 B/ m
            else' K) p0 Q1 @  D1 F3 A
                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
. T* Q+ _6 w9 h; a<P>            break;</P>% ]/ V" ]+ u+ p; I4 u4 T
<P>        case PACKETTYPE_CLIENT_VERSION:
/ i. O) Z6 E  v( L3 j6 o' o1 h            if( size == sizeof(ClientVersionPacket) )! m  C' a- C" ]# P. n/ W
                HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );! p& ]& v$ ?! }$ ^3 K, u& ~" f
            else& [: _' j" z6 ~# ]( d
                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );" a9 L3 b/ R. y
            break;</P>1 |$ K: w1 L5 H+ P6 z! e
<P>        case PACKETTYPE_SERVER_CONFIG:</P>0 k2 ]$ Y5 `! i2 }% C
<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>6 d, P# y$ H7 N
<P>            break;7 _/ P$ E2 A  P0 F& Z
        default:0 ~3 r9 T7 X% Q: U
            HandleUnknownPacket( dwFrom, pClientPack, size );( W  H  Q( L* g- b4 X* w
            break;! t* w: V9 E) G/ `
    }</P>
" e0 V7 Q( Q; N( @" `<P>    //If the user wants to hold the thread, Sleep for given amount of time.; y0 k; h' k9 B3 y5 [( F
    if ( m_dwServerThreadWait &gt; 0 )
9 k) Q& i; G! [9 O  u1 p    {) K# T3 h8 C# w
        Sleep( m_dwServerThreadWait );
: o5 h5 V  p5 U, q; y5 `0 K    }8 r9 a; {$ ?8 t: |
   
) h2 y, E  @# \) k. h+ w    // Retrieve thread data for this process./ ^  M( b7 m9 q% L' w- c) l6 c
    m_csThreadCountLock.Enter();</P>( w0 h% U3 f/ Z+ _
<P>    m_wActiveThreadCount--;</P>
) a) F# D- B3 m* X; u5 t6 }7 K<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;% \! E$ P# ^2 g" E) e2 U
    m_fAvgThreadTime += fDiffTime/32;</P>- j/ t$ w3 r; }. N8 N
<P>    //Get the Max time in the thread.
2 \/ m. f. U5 p+ r+ m    if ( fDiffTime &gt; m_fMaxThreadTime )9 E$ \8 Q$ _1 N2 ]
    {
+ V& t% f- f9 m        m_fMaxThreadTime = fDiffTime;
0 ^5 \* v) [5 q/ N    }</P>" z6 e! A2 o1 Z- X& R  N6 W9 u
<P>    m_csThreadCountLock.Leave();</P>+ O. p$ m* B5 N% W' Q
<P>    return S_OK;. `: K. G& ~0 L" q  |: t- c$ b+ w
}</P>9 @' Y8 K5 B8 K0 w

% C5 J) n5 V# J  o. {, J<P>//-----------------------------------------------------------------------------
8 B9 K) D/ _* v9 D7 I& y! |// Name:
5 ?# J# e5 T, G" R3 W// Desc: 2 x3 S& \3 f! b  b
//-----------------------------------------------------------------------------
) g- q/ }3 k# m) D3 x& D, Z* n+ [BOOL CMazeServer::IsValidPackSize( DWORD dwSize )
4 u0 Z; S) L; d: w1 G6 k+ r; m, \% @{& t. m0 [/ R9 U- `2 M7 `% X+ Q
    BOOL fFoundSize = FALSE;, t2 v6 n0 N8 [& F/ i0 D
    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;
* N! s. q$ x  A) K    . j$ w5 w% P/ p" }9 _' r9 O
    // Check through the array of valid pack sizes.
9 v1 ^4 X/ A- ~- I) U* V0 O( }    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation]), T4 L( ]6 `3 H2 H# s( q, R7 E
    {
% Y8 c# o8 }4 x4 V        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)
9 `# B8 }4 F) L# K  N( P        {# f, g9 [6 f3 g/ N8 q
            if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
. Q6 a* }' f' N3 X; U            {
  V/ S9 n* G, q6 e$ X                // Found valid size in the array.
7 B3 i7 q8 Z6 ?, s% ^                fFoundSize = TRUE;5 y" ^: d9 f0 K  E
                break;3 B- F2 G) E& B6 |* h7 J1 f
            }* i- \: g+ J: s5 r! Y' f5 y' E
            if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array./ v. J  A8 z' c
        }
$ c8 H, B- A" F! I    }
: h) Z1 U( _! k, d& a% B    else& K5 l: i" ]  v1 P4 f1 D' p
    {, y% x# J/ y0 P% R2 b8 F$ a
        fFoundSize = TRUE;* K2 e7 p; r7 U. f, s8 k
    }</P>
/ ^3 f$ f; ~0 Q4 Z6 d# j3 K2 U<P>    return fFoundSize;
+ s1 k. o+ S8 j- e. f}</P>: g; l. e6 P) W+ `1 p
<P>  H5 k$ k8 q" D; l! V0 w
//-----------------------------------------------------------------------------$ T& H5 e# \. ?
// Name: % M; G3 d: H; n  e
// Desc:
% ], i( v$ J6 `. l5 Q7 W5 Z9 w//-----------------------------------------------------------------------------
4 ~4 x# z2 u* [3 C4 K5 W  N1 Ovoid CMazeServer::OnSessionLost( DWORD dwReason )
: g$ R' f9 F( x. B5 `: W# ]{
% _: L" W# C0 o) |    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
6 ]  N0 |. T% k% q" r9 ~& j9 g; c) x}</P>6 u8 X8 P- u+ h3 M1 n7 i& E8 O7 Q8 V
' _. d8 _. e$ ]9 G( S; P, P" ?
<P>
4 {2 a5 ]% q" C5 D8 d' k% L//-----------------------------------------------------------------------------! I3 ]9 Y+ j0 j0 x" E
// Name: 4 o/ c7 K, {! ?- ]& d
// Desc:
+ ]4 R; |( o: H/ W2 W/ E  \//-----------------------------------------------------------------------------
% Y# S* |  D# S1 S$ A, ~; R+ ZPlayerData* CMazeServer::CreatePlayerData()  U; V0 M: \9 S* C) k. {7 T
{
/ h+ ~+ Y* b! ?4 i$ x% t    m_PlayerDataListLock.Enter();</P>
, u" p0 t2 G3 |1 f# g" I<P>    // Grab first free player in the list
' h6 v7 \$ Y( u3 V3 p2 ^    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>
: @3 x6 d: R0 C  i! U5 K5 \<P>    if( pPlayerData ), v, C% R' M8 Q( Z
    {: U1 i1 w7 q: N% r# J
        LockPlayerData( pPlayerData );</P>4 z2 ?8 D# T$ ~% P& S1 q" j- T& q
<P>        // Got one, so remove it from the free list
+ Y$ H9 W" e, m+ t9 H        if( pPlayerData-&gt;pPrevious )  c" r$ O1 D  D4 I, N! n& h* o- z5 N/ _6 h
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;2 o$ m8 @  l+ G# @- n6 i" @, u
        if( pPlayerData-&gt;pNext )
/ @7 B& i2 r" ?7 ]. X& y            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;! A* Q" V* ~* ^- A; z1 v# A
        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>
7 ?5 k% W$ a* b/ e4 K9 d<P>        // Add it to the active list
% \8 P4 p  l' x' e- h        if( m_pFirstActivePlayerData ). O& d0 N8 k. X9 y% r% L! ]: A! A
            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
& m% u' H0 S* k- q! s        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;
( J2 X0 D- G' j5 N1 C        pPlayerData-&gt;pPrevious = NULL;
8 k  V( D! a2 ^8 q" S/ j- R        m_pFirstActivePlayerData = pPlayerData;</P>' b% {0 Y% C7 d2 Q4 `/ T
<P>        // Update count of players
1 [0 W- ?+ q% n; t! X, t        m_dwActivePlayerDataCount++;</P>
  K( t5 D  l2 z7 u0 v<P>        // Generate the ID for this player
7 ~% |5 U" J: Y, v) e  C  K        m_dwPlayerDataUniqueValue++;2 a2 o+ A; t' K! b9 O& C# o
        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>& P: Z% L0 x* p
<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;* A6 l- X4 Z; l1 J' V8 V/ ^
        pPlayerData-&gt;NetID = 0;
1 T7 L; K; e9 o& t8 n        pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>
  Y3 Y! h. V. Z' N* N<P>        // Insert into the "off-map" cell
$ e5 k' A, J1 K$ ~* _: T8 b1 R        pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;# e  K: u3 j1 E+ C7 k
        pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;. L4 i8 u$ I. @5 Q* H
        m_OffMapLock.Enter();1 V4 @& Q9 p/ i$ _8 z) H% r
        pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;
1 K3 c/ O4 x7 l1 w0 h0 N/ w( S2 D        m_OffMapCell.pFirstPlayerData = pPlayerData;
( C& D) p" m7 @. ^7 @        m_OffMapLock.Leave();</P>
; l& N' }% ~, C  Z+ p0 u<P>        // Mark as active
# W" p6 P; f+ f) ^+ _        pPlayerData-&gt;bActive = TRUE;</P>
' @1 M# M( t, I1 H& m<P>        UnlockPlayerData( pPlayerData );
! H& s/ @8 Y% S! h$ D( N    }</P>
$ }5 k' ?4 S. l' `+ F/ J9 a( \<P>    m_PlayerDataListLock.Leave();</P>+ `7 v$ X5 {3 j5 g; b
<P>    return pPlayerData;
: `! i! T8 }! h0 n; u- C}</P>: g( B( Q4 S! c# W
" [) \6 d! P2 V
<P>
, B1 a6 l+ L( O: S//-----------------------------------------------------------------------------2 N: ~. S: w& L1 n0 j0 f8 A  w( ^
// Name: : Z! J" `* m& i- n& s8 t& {
// Desc:
; D8 U. g% z8 C( r4 V" O: ^//-----------------------------------------------------------------------------* t0 |4 k; @$ Z
void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )) ?# h) V/ [6 d1 {- t% T
{
/ Z+ g/ }  N; |& e9 J+ B" e/ j    m_PlayerDataListLock.Enter();
" m% j+ R& B* o" M3 J    LockPlayerData( pPlayerData );</P>
2 q, K, L3 i9 J7 r<P>    // Remove the player from its cell9 s4 _$ Y3 V  p' p2 e% m+ z
    RemovePlayerDataFromCell( pPlayerData );</P>
, @- E$ f8 O+ z# v<P>    // Mark as inactive
4 V/ D5 x' }( |* o    pPlayerData-&gt;bActive = FALSE;</P>
  M2 r7 y" o3 x3 C<P>    // Remove player from active list
( G1 ]+ e( a& {    if( pPlayerData-&gt;pPrevious )
4 y* b* J% G7 H9 e  I# P& T        pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
- P4 b( B% {4 V% j3 [5 f2 C    if( pPlayerData-&gt;pNext )
- p/ W) u! v4 U0 i$ \/ |        pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>+ F' }* a) h# Y$ G$ d
<P>    if( m_pFirstActivePlayerData == pPlayerData )+ s/ F/ K' r& }- U
        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>, l) O' H5 c3 m" b% ?
<P>    // Add it to the free list
7 [; H+ O* x$ ]8 K    if( m_pFirstFreePlayerData )
' l" }: n4 C/ h2 G* p$ Q        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
" X7 x% a1 k- I  h4 B# B6 F    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;
8 w: b: K# |# @+ q! S0 `    pPlayerData-&gt;pPrevious = NULL;
- @/ C+ r/ d! V8 Q4 B    m_pFirstFreePlayerData = pPlayerData;</P>4 |! A0 O) Z) ]4 g
<P>    // Update count of players" v  d' ]2 t6 I! n4 e) v
    m_dwActivePlayerDataCount--;</P>3 I4 m: [. G; {( |5 U* S
<P>    UnlockPlayerData( pPlayerData );
- ^% y' z% W* J! g; y+ j    m_PlayerDataListLock.Leave();
" c" }# a, a( O* J}</P>
$ T& b0 y' [# e0 c
# ?8 O" E8 x- T<P>
! W/ l' `# \& t. E2 B# c! ]//-----------------------------------------------------------------------------& K! q6 ]" ^" O. u5 I" r6 x5 q
// Name:
/ \: o$ l/ [0 \! m3 ^, F: T// Desc: % M3 n0 Y$ {+ n0 E; f
//-----------------------------------------------------------------------------
3 m$ i! o! i( p+ A% Wvoid CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )
! K' T( C' J! x{6 g, w  X' j* C
    // Lock the player
  i9 O8 C7 F* _+ V, m6 Q% e2 p    LockPlayerData( pPlayerData );</P>
! y0 O% I' W# e* G% F<P>    // Lock the cell the player is in
5 Y" a9 s' p: h5 F. c    ServerCell* pCell;
/ {6 }: K$ @9 b( A% c    if( pPlayerData-&gt;wCellX == 0xffff )7 {" F" H0 f$ h+ ]4 X* y  a
    {& n/ c# p3 f% _/ p6 M
        m_OffMapLock.Enter();6 V8 `" u! d# _6 @" `
        pCell = &amp;m_OffMapCell;6 C: d/ v, L6 x
    }
  ]! H2 o% T! ^; m, g6 K# X    else6 c8 F+ Z& l+ |# q" M
    {% i& z1 g4 J0 s* w8 y! w# b  F
        LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );8 _0 Q# F3 H, S
        pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];. V  ~2 _5 @  w/ ~1 w  f
    }</P>3 V, _" l% Q" A) }" }# \! v; T
<P>    // Remove it from the cell
/ v; P& u2 m' ]% H% R! F    PlayerData* pPt = pCell-&gt;pFirstPlayerData;
( h( H! a& c: `% m# n    PlayerData* pPrev = NULL;0 E3 d1 p+ m% E
    while ( pPt )
- y# x/ D& h: u    {
6 @3 H# H8 d. |  n8 a8 x: \5 R        if( pPt == pPlayerData )
, }( I5 G1 @; Z# G2 p        {) _9 Z: K$ U0 n3 Z
            if( pPrev )
& G! t# d2 ]4 G% s& A                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;- {/ O: O- ~: V- k7 h! T
            else
% V! L  U4 x0 [                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>; g& f0 R5 [+ }& Q( ?
<P>            pPlayerData-&gt;pNextInCell = NULL;
, ~+ E; v  L2 {4 L. w( K            break;
3 }( B( A4 l6 }' H  A6 a        }$ O5 D% [0 y/ A9 A  B$ h$ ?; X
        pPrev = pPt;
. |$ e2 `2 M$ s7 ^+ I7 ~- u, b        pPt = pPt-&gt;pNextInCell;  j% q, D; S0 f% k, M
    }</P>5 @3 @$ k5 e' S! _
<P>    // Unlock the cell
" n5 y3 H! o2 ]/ Q( _5 i: |: e    if( pPlayerData-&gt;wCellX == 0xffff )) _9 w; A) Y5 s2 k0 L% r4 s9 x
        m_OffMapLock.Leave();
7 v) G( s* P/ Q# S3 j, ]8 x    else
; L! X1 {; T% r3 i. a        UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>
4 j2 [- M) H* ^& o<P>    // Unlock the player
  s2 P# p" ~* X$ p    UnlockPlayerData( pPlayerData );. P2 @6 o* H) ^% k
}</P>
6 l- x: Y3 G9 J& k6 X) ^" r0 [- Z. ]' Q
<P>
% e! O5 N7 _6 k/ X/ j4 v//-----------------------------------------------------------------------------
- c# \' s0 h- c6 H" d& Y6 o// Name:
  o" a: |! e% C/ d$ s// Desc: ( J  C% K& ^' k
//-----------------------------------------------------------------------------
& L* R( @  l( R+ evoid CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )( s' Y& D4 u! Z! k/ u: J/ u
{; H0 n- [1 t# w4 O% d# W* o. c" u
    ServerCell* pCell = GetCell( pPlayerData );
. p$ H# O& t. m* V    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
% U; Q) m9 w  s  i    PlayerData* pPrev = NULL;- ]( a) L4 P; k' z0 H
    while ( pPt )3 L( z0 ]/ R+ }) C1 K
    {2 r9 s5 V) o8 `* q
        if( pPt == pPlayerData )
3 i8 i# ^" {% R  _1 |        {
, s6 c1 @. M  Z            if( pPrev )
$ Q9 k7 v( z! }' [( ?                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;: X* T- B' n4 c4 T5 I
            else. j) h, I' \5 u8 q  _  d2 a
                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;
" b7 t: @" Q4 |+ V% Q- B3 ~            pPlayerData-&gt;pNextInCell = NULL;: j: Q) C0 z: \# m7 E
            break;% F3 m  q+ |) c' m
        }3 ^0 I1 {2 ]" J
        pPrev = pPt;9 D, e0 J' u1 X
        pPt = pPt-&gt;pNextInCell;7 O* p% c' i" |% V
    }. M! b' Y6 r7 p
}</P>
9 P) O2 F, a" U' \
& @& C7 V9 g# i6 D/ y<P>
. L# F7 o* T/ P8 ^: P7 l# @0 k: B//-----------------------------------------------------------------------------
% a9 m% T5 b4 Q// Name: ; }% F# b0 e  c" e4 l$ j! M
// Desc:
* D0 N& R5 ^# q5 u8 A5 }% F5 e; H, z//-----------------------------------------------------------------------------
8 l: n- I$ s; c7 B5 F# X" ~% Wvoid CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )
/ b! J9 a6 l/ X7 M{7 y- ]2 v1 G/ g% D
    ServerCell* pCell   = GetCell( pPlayerData );
; X4 U& f$ O1 q0 ~  g2 M    pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;: k' w( U2 P$ |+ Z7 {
    pCell-&gt;pFirstPlayerData = pPlayerData;8 h7 `5 A( L* y6 @
}</P>! t7 t( E* v1 h: v+ `; A6 t
* _- k) x% U6 R; }* s
<P>3 _1 E& k, z$ P7 W8 _- G
//-----------------------------------------------------------------------------8 [) [! Q$ \4 \" K2 l: l
// Name:
. e( ]* B1 C. M8 K9 L// Desc:
8 U/ _, W  o) K- p- N6 ?//-----------------------------------------------------------------------------% H! K2 {0 L/ I/ U( N& P
void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )
4 n/ c3 O8 d& \5 \, A! z' i' p{
9 ~! p2 d4 N; \' Z0 ?  ]0 k7 H    // Grab player for this client and lock it* |/ D  I. x4 o$ q/ b
    PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );
: L* q  T. E3 x, s5 U    if( pFromPlayer == NULL )
" b( N9 j6 {8 I7 V6 Z    {4 f. m. O1 O% \# s) ?6 w4 l# F
        if( m_dwLogLevel &gt; 1 )
2 j, a' \" A; z0 W+ E2 D+ F            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );9 I1 y3 A% K9 W
        return;3 Y' x! x0 p  |5 c. X
    }</P>
3 D# u  a5 ~' j3 z, o<P>    LockPlayerData( pFromPlayer );</P>4 f) ~4 s/ h9 l; e+ ^
<P>    if( FALSE == pFromPlayer-&gt;bAllow )3 B- k4 U+ h! S* B, W
    {, u8 g: B/ c: v9 T* Q+ u( Q: A! s+ J+ S! h
        if( m_dwLogLevel &gt; 0 )8 \) c! Z" k% e) P
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
8 D8 v" x" ?$ o2 D& l& a# ~<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );+ r( c( o- V% L7 z5 T, T( l+ L
        UnlockPlayerData( pFromPlayer );
: F! o* u8 l% ~* S. q, {3 M6 Q% }        return;( {/ k  m6 ]+ @0 z5 \) }! Y% k$ J
    }</P>
- D( |& M, @/ a' Y; K# b<P>    // Compute the cell the player should be in now% T4 |% D) m  U/ C# l  I; K
    DWORD newcellx = int(pClientPosPack-&gt;fX);
- U: b' S6 y3 i$ ]: S. L    DWORD newcelly = int(pClientPosPack-&gt;fY);
9 ~: i) e: P/ y) J    DWORD oldcellx = pFromPlayer-&gt;wCellX;
0 U- S) C* v. U( |! F" E0 W    DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>
4 a5 j2 v- t8 ]1 `) s- _<P>    // Have we moved cell?
6 {' M" ], ^7 G- \# _    if( newcellx != oldcellx || newcelly != oldcelly )" B& E2 [5 g2 I5 W" w) U# H
    {$ \+ n+ ^5 J  I3 f: \! Q: i
        // Yes, so lock the pair of cells in question' C* v& g/ n! v* h4 w4 u
        LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>- W% F$ d3 t( w# i
<P>        // Remove from old cell and add to new cell- j2 w" A! p7 g: d1 X9 Y
        UnsafeRemovePlayerDataFromCell( pFromPlayer );- ?0 I. i# l  @+ _: G$ j
        pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
" O7 N2 k7 @, [2 A" e8 Z        UnsafeAddPlayerDataToCell( pFromPlayer );</P>  G& L' b6 i  f& o: h. n
<P>        // Unlock cells' X$ {$ j) b& f5 a
        UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );
4 p$ q! Q& a" |    }</P>
: I! U3 E5 f. Y7 n8 B& S: K2 G6 E<P>    // Update player position
+ n# p0 L- H7 Q' Z3 Z9 s+ p7 l1 s    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
' |( k% @# N) b2 }    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
  R/ G6 a. z) r0 t9 t    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>& G6 @) G5 A2 c( H* U# u
<P>    // Allocate space to build the reply packet, and fill in header
$ h. }+ O, P  O$ N2 I    DWORD dwAllocSize;4 s+ K6 V8 r( }, P& F8 B- I
    ServerAckPacket* pSvrAckPack = NULL;</P>& ~6 }# Y6 i) m6 ~% X) [& n
<P>    // Begin by allocating a buffer sized according to% g6 F7 w8 ?9 P) m5 q: H, z. V" l( \
    // the current number of nearby players + 4.  This will give # w8 h2 l  B# P0 Z; A
    // a little room for more players to come 'near' without resize/ o4 }4 I# b4 v4 n
    // the buffer.7 M) @1 Y5 r' F( R7 l2 N; H
    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>
4 I) x* N% z9 ~- b<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
. x/ G, S  a# K" W7 Q' S" Z    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
3 @8 {& p/ O9 e: b  h    if( NULL == pSvrAckPack )7 v9 K* g8 y9 a# w1 _" }
    {
5 Q; p' `1 N) j, M- }& Y9 b6 T" R        // Out of mem.  Cleanup and return- K8 [8 [( \8 x* X1 y% e
        UnlockPlayerData( pFromPlayer );
& d( `! g$ n! E5 E        return;       9 ~' |0 C. R0 u% e: ]" e
    }
( l: J: R4 i+ O    ZeroMemory( pSvrAckPack, dwAllocSize );</P>
( [4 a2 A: m: a<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);! r  U( r- _, a' y" v' M! y
    pSvrAckPack-&gt;wPlayerStatePacketCount = 0;5 m$ Z' i& ]2 r5 F& v. n' f
    PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>; L) o& O3 j. F
<P>    // Compute range of cells we're going to scan for players to send5 i) O8 U9 W; D# k/ L
    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;
3 a! k1 }+ {1 s2 B% K    DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;' F) x) v. e  ?8 m% m
    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;4 q/ ~6 o2 s. c" i# a( F
    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>
& A- M. B- r" R! c8 H' M3 E" s' r/ ]<P>    // Lock that range of cells
6 t6 F/ y3 ]2 S    LockRange( minx, miny, maxx, maxy );</P>
' x7 r0 z* x. Q# \! p% W9 e/ H* j+ ]( R<P>    // Scan through the cells, tagging player data onto the end of
/ R( e- D0 i. M! J    // our pSvrAckPacket until we run out of room8 ]# R: V9 r0 i) n2 H* b
    for( DWORD y = miny; y &lt;= maxy; y++ )
1 k$ ~8 [3 p4 \' Y+ S  C. N    {
+ Y5 z. s! t. D; v+ |: ~7 K& E        for( DWORD x = minx; x &lt;= maxx; x++ )
* u# R/ S" [+ M: D1 K$ b' r        {% Y! ^$ I( U9 N, k) i* ?4 Y
            PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;% G+ V1 k# P+ Y" `
            while ( pCurPlayerData )
% b5 ?* X- O# i/ Q            {
6 y8 N# I  d/ V* N" C* ~5 W                if( pCurPlayerData != pFromPlayer )
8 O& [. o$ J2 x5 Y* ]                {6 l9 G% q- }9 I  Z# `/ M
                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )
2 {) G$ [, q0 ^) b7 B                    {: y& h' Y/ z( T& o  D0 s& O
                        // Make sure pChunk is where we think it is7 d; B  k. u8 A! G4 e5 P/ H
                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>
: P. n$ ~7 M9 P<P>                        // There are more than just 4 new nearby players, so resize the
2 o- N8 l+ J8 R! G& e6 N                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.0 X" `) c7 O' S4 B! Y/ l( {% m
                        dwMaxPlayerStatePackets += 16;' r; x% c( M- @* t
                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
% b" q  z2 I+ r  J- \5 k; R, ~7 a9 }                        ServerAckPacket* pNewSvrAckPack = NULL;
& ~; f0 Z; U3 Q" e% m0 d9 ^                        pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );+ v# H# x! H  G) x6 G6 e$ r6 i( ?
                        if( NULL == pNewSvrAckPack )/ n( ^7 V/ q% _% W4 O
                        {8 f. u2 F& t2 N- M3 g% R) p
                            // Out of mem.  Cleanup and return; O, f( Z* y5 E3 {0 D4 d
                            free( pSvrAckPack );
& D& ]- S1 j7 G                            UnlockRange( minx, miny, maxx, maxy );
  \' T# e+ k" b% b  {  R4 w0 Q# h                            UnlockPlayerData( pFromPlayer );. p$ w1 \: B$ B; j
                            return;      
% n& j  N! z" ]% z( V% m+ P" Y                        }</P>
- `* y5 C) {/ [) W- H1 K! L<P>                        pSvrAckPack = pNewSvrAckPack;* O1 V6 e& L8 Q5 y# H/ t1 n9 X6 N
                        pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>9 [& B( G" W) }" z) ]
<P>                        // Make sure pChunk is still where its supposed to be
% z6 T- \# F! n1 u/ Q3 `* q& `0 H                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );, W6 |# r" C# g! a  I5 M9 T$ `9 R* J
                    }</P>
) @+ F" w( D: Y) p, d, E<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;
5 u& |1 S5 N& z- G5 P# E. M" E- D                    pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
* a2 I* a1 f, h+ H6 E                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;2 s# l( ^7 B% I( t3 @
                    pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;2 P- x* y3 [  o6 v
                    pChunk++;: U* c- O4 i- h) }% U
                    pSvrAckPack-&gt;wPlayerStatePacketCount++;
# S) n. |8 V- m; f                }
: T+ ^, X+ Q$ J6 Q- r0 P                pCurPlayerData = pCurPlayerData-&gt;pNextInCell;
8 {2 q7 T) ^# ]! y2 H0 S            }
" \. g3 N- E: s- W  \        }' O1 U) b5 {5 c4 g: ?/ [
    }</P>
) m( s7 x; k5 X1 ?<P>    // Update the dwNumNearbyPlayers for this player
2 d; u+ Y& T% ~7 q    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>
/ \# D' l# \2 ^1 O/ U7 B1 x4 _<P>    // Unlock range of cells/ p  u5 {$ O# n1 ?7 }
    UnlockRange( minx, miny, maxx, maxy );</P>
5 k6 H% e" s, y* w. [1 M- L0 c<P>    if( m_dwLogLevel &gt; 2 )- Q. F, Y+ \' _  \$ P# |
    {
7 G- l- K  u6 @1 t; j* W        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );9 f6 n0 y0 d* G/ O
    }  p% B9 _3 G# @: W9 t
    else if( m_dwLogLevel == 2 )
# B- T7 b+ K: S1 c+ u    {
! B% @+ X* Y9 t1 i; R        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
8 P1 m6 Y+ q, c+ _        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )
9 l' |% f9 _+ y% K- Y- b1 F        {" H2 B' \" d! O  d
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );4 J9 ?$ E+ G8 ?% U
            pFromPlayer-&gt;fLastDisplayTime = fTime;
  E, L% p' I3 h3 Z5 y8 [        }+ x, N: M/ ?- k7 G: y8 U' i
    }</P>: a8 j$ @; J2 N) s
<P>    // Unlock the playerdata& q6 R9 ^# S6 B! _5 ~# w8 |2 V
    UnlockPlayerData( pFromPlayer );</P>9 u" S$ F' ^3 x! T* u
<P>    // Send acknowledgement back to client, including list of nearby players / U; y  S2 D. k7 `. g) t
    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));0 E4 p& R2 t( t4 s
1 X) _6 j; r" }5 W; H. y9 E
    // Pack the buffer with dummy data.
8 m' S. U8 z8 z# {8 J    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)
/ M8 H$ l' f, n$ z' P    {. J: M2 g, S; @$ I$ ^
        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];
6 a  s6 z& ]# Y. L( ?# }; B* e        VOID*   pTempBuffer = 0;</P>
" X) b% ^8 ~) x0 T: W( X+ ]<P>        pTempBuffer = malloc(dwBufferSize);+ W3 E, r* t" L, F7 f- d6 u" q
        if( NULL == pTempBuffer )" e7 ~' j. F1 u$ |3 Z, P
        {
, f) r7 ]: X" S& q; E! D            //Out of memory( c' B. a8 \* b% i! F
            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );5 a- A' Q! c# q
            free( pSvrAckPack );
- G3 m, `/ C0 z0 h6 Q1 f            return;
/ N# y6 N4 `% Z2 }% |        }</P>1 m$ i! t) P1 S1 ^3 w+ x! Y) @0 k
<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');7 E! L% [1 d: Z# J, K! Q5 k1 p
        memcpy(pTempBuffer, pSvrAckPack, acksize);</P>/ Q/ t- q6 }4 v" P
<P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );
2 }/ x/ a6 }  Q) ], c7 p    5 N7 c8 L0 ~. L5 i5 o
        free(pTempBuffer);
5 d, S8 s5 W7 U. c    }   1 y  O/ ^7 h6 H, L
    else
- u1 b# Z# g% ]2 @( O3 P    {
; c9 s+ G. g/ U        SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );3 W% b3 F! _3 w% `
    }</P>
: \* @! H  }) }. i* h8 ]<P>    free( pSvrAckPack );</P>
3 o! O9 C" ]9 f<P>}</P>
0 Z) M5 f! ]! g* r2 Q0 q  U1 H% r- x' z8 V
<P>4 c7 S) [$ q, {
//-----------------------------------------------------------------------------
" v8 ?( I" a/ [6 Z/ l! E/ |; ~- y// Name:
% J* L$ S" Q5 o8 t( T// Desc:
4 m: n9 D) B; u7 |2 j//-----------------------------------------------------------------------------
) i9 B0 F' L2 `5 C$ N( u! gvoid CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )& g4 f( H' b; T/ ?& F5 c3 I; K
{) }, k3 R0 Q$ F. y) ~
    // Grab playerdata for this client and lock it  e2 }/ g$ H; I
    PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
2 Q6 E; v& T3 r    if( pPlayerData == NULL )' ]. P/ X5 ?4 W( x9 n6 C
        return;
2 c6 F/ b/ |2 N    LockPlayerData( pPlayerData );</P>
" T- Q7 _# N4 f9 P2 Q<P>    // Record the version number . O) H. ]' r  K- a: a5 s9 L7 {& L
    pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
" @* r6 s. `% y$ @. @) w3 I<P>    if( m_bLocalLoopback )7 c6 x6 Q9 v* G( t: r, }. _
        pPlayerData-&gt;bAllow = TRUE;7 j; o+ N  |( I6 r' B8 G: h
    else
* c, M- A/ i) i0 r; z* j        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>
3 \1 \0 _- B! I/ t6 N; E$ Y<P>    if( m_dwLogLevel &gt; 0 )
5 l$ H+ A& Q$ W0 U8 P4 j, J1 q1 Z        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Client version=%d (%s)"), pPlayerData-&gt;NetID, pPlayerData-&gt;dwVersion, pPlayerData-&gt;bAllow ? TEXT("Accepted") : TEXT("Rejected") );</P>
+ U, d6 b8 s% o1 b7 L) c. [, M<P>    if( FALSE == pPlayerData-&gt;bAllow )+ n& f; _- N) j+ z
    {, e0 n. @! B) d) B8 ?
        if( m_dwLogLevel &gt; 0 )& v: \7 I/ b8 v' L0 ~* v5 b2 i0 ?
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>" O! y0 x5 x" Q3 {, u
<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );/ _# R, _! E. h8 E
        UnlockPlayerData( pPlayerData );2 Z/ X4 |$ s. L! p4 [
        return;- d! J5 a4 w) E
    }</P>
. p6 P  [0 A* n8 j5 r+ y' S9 i<P>    // Unlock the playerdata  `  b2 D2 R6 i3 X8 p
    UnlockPlayerData( pPlayerData );</P>
- b" l$ B  {" Q& O<P>    // Send acknowledgement to client that the client was either accepted or rejected
& H  N' O( Z7 g" ~0 Q+ S3 t: E    ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );6 v% h6 V) j( B: r* C! K+ P1 F
    SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );2 j' o) J+ H/ [
}</P>; ^4 C3 y9 b4 `+ b& L
! p( [& J# @. E6 ~: n5 J: E: W% W9 ]
<P>
3 a: F3 u" b2 e//-----------------------------------------------------------------------------2 u$ \; t$ l* S7 ]7 S% k
// Name:
9 C) c9 H5 G0 {4 m// Desc: / h, T; q( y) V  m9 k
//-----------------------------------------------------------------------------6 G7 @% H# R9 ?
BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )5 X) j- L$ H% B8 _+ d
{
0 v& r2 c( }5 N5 N8 Z    switch( dwClientVersion )
7 {) \2 w) K  M% Z    {
- n# @+ x$ A  M" W) \        case 107: // only v107 is supported* Q6 h9 [3 q! v$ u9 u0 l
            return TRUE;
: K7 S2 f0 Q3 ]) u! m        default:
. y7 Y5 `2 j, B& X* v0 \            return FALSE;7 p9 g/ I& }8 Q# g
    }9 X" X. ~5 I" O! Q3 V
}</P>% `6 u3 D" C4 y* x
5 r+ i$ x" |9 \  [$ V
<P>: k# E% j( [( j  s) ?
//-----------------------------------------------------------------------------* p0 D* s: R, a6 F3 `" T
// Name: 2 J+ p) }) w! A4 G1 l! p4 x
// Desc:
% g$ u8 V" C. ]: _: i//-----------------------------------------------------------------------------
" s: c& `; {1 d- _( G7 Avoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )& f: j  f3 R; _  N6 f( S
{/ f( ^; ]7 d1 r1 T% k$ h
    if( m_dwLogLevel &gt; 1 )& L* ~% w0 D( w
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>% ~: I9 B/ N- P; M/ v. l5 B
<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
, B. t$ [" b) K$ G7 v; r}</P>
' `1 c' _6 n! d$ ?3 S! v7 g# N
$ r% F+ e+ @; z5 ]<P>
6 j5 O( {& Z! Z* J//-----------------------------------------------------------------------------, L# c# R0 M) T  g6 G
// Name:
9 z$ [. {: R' p// Desc: / m1 U6 S; i$ J2 K. a
//-----------------------------------------------------------------------------; V9 U: `8 ~/ K3 f# [7 V; K( G
DWORD   CMazeServer::IDHash( DWORD id )3 g5 B( w6 e6 J% v. i
{" J% r- h6 r5 P* N2 X# g# D
    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);7 l8 m8 |( c5 i! ]
    return hash;: w& a) \: X  h, ~! ~
}</P>$ E: @! A- Q; H4 L7 U# {) I

3 Y7 K* ]3 z: B* f8 `3 W- A! a% P0 l<P>* [) k3 ]; K& e" c) u2 ]! W+ k. K0 j
//------------------------------------------------------------------------------ H$ m* b( C. i: ]' K
// Name:
% ~" Z! G9 d6 {6 h# a7 y8 m// Desc:
7 y2 V, Q; L# a  h//-----------------------------------------------------------------------------
( T, V1 m. H0 R3 N8 dvoid CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
/ b0 ^! K% {5 }1 ~9 a0 j{. E5 G) S7 c4 ]2 b  g7 P+ g' E( D, ?
    // Hash the ID to a bucket number, J3 @! W# p9 t7 o- }2 G5 j( P, n6 I
    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>4 l! B0 u: p: j% Z+ D  _! T
<P>    // Lock that hash bucket
5 i% R: ^" @5 G6 q2 ~* V) t; g# W# a    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;3 T% ~& K  o% o* P8 }8 V
    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>  j1 O9 Q. Q( y- s0 ]8 u) {6 t
<P>    // Loop though players in bucket until we find the right one2 Y0 L1 n" e7 N, w" h
    PlayerData* pPt = m_pstIDHashBucket[bucket];
* J9 G5 S) Z$ ?: k    PlayerData* pPrev = NULL;
7 `+ J+ v% j4 n* U2 ]# \    while( pPt )- R3 y$ N) F! @" V) n1 r' u
    {5 O5 O9 ]. I% Y: \+ O! l, B5 |
        if( pPt == pPlayerData )4 ~+ w) h0 c; M- m
            break;
# t* ]0 V$ H' K7 o7 M7 t        pPrev = pPt;% y  J+ w9 E" }3 [1 a' p: U
        pPt = pPt-&gt;pNextInIDHashBucket;
6 Y0 F$ J: z% G; E- Z+ l# Z    }</P>
+ P* v1 O. q* e( q6 {2 v  {# V$ I<P>    if( pPt )
: h. ~5 \/ n9 x* t    {
1 A, c. F. c0 W5 C" O        if( pPrev )0 @6 K: ]  N% P" d$ g: q; |  y
            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;: J( F- ~0 N5 t4 U0 k) q* ?
        else
: Z; g6 b4 g% U4 D! y            m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
' y- f5 n& p- T2 c1 h$ G/ ~. U. s/ O        pPt-&gt;pNextInIDHashBucket = NULL;; w# T; a, l% s. e: E/ o& E
    }</P>
' s) E( D: N  W& X<P>    // Unlock the hash bucket; E, D. c1 e6 N( n; i
    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
' u5 b0 ~/ X8 b$ Z/ E}</P>
7 M1 E, V3 j" |. _$ ]
5 L' I* ]# W: c" U<P>/ y5 R+ O: P+ P3 b; s# T
//-----------------------------------------------------------------------------$ x, q, X* T; _1 d4 A" L7 ?' v
// Name: 0 C; E) |6 v- s* j$ G/ J
// Desc:
# U7 Q/ I  w( e, S3 a/ C//-----------------------------------------------------------------------------# O$ [9 r! y; b8 D
void CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
% H, O  [" U3 J3 L, d& s{
* n! k( b; r) e  w; p% a% `( H5 c    // Make sure this player isn't added twice to the m_pstIDHashBucket[]
9 v* l& F4 R9 |' l: ^7 v! ^    // otherwise there will be a circular reference2 j3 h! X  v( A0 r8 Q0 t2 ], M
    PlayerData* pSearch = GetPlayerDataForID( id );8 A& u- K% _8 v1 V: U
    if( pSearch != NULL )
- p- P# V0 `( n1 b3 E. [. X' q        return;</P>- K& x/ p, ?* {+ c' a
<P>    // Hash the ID to a bucket number" W! u9 m6 x4 A  T  v
    DWORD   bucket = IDHash( id );</P>
# q; x# W6 ]7 a; s4 |<P>    // Lock that hash bucket
& F, s3 d: w9 a) o" r. C: g& {    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;9 s- D" d1 H+ K6 L  k
    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>% y& z. n1 N  C2 ^7 H" N
<P>    // Add player onto hash bucket chain
: v$ @$ U+ R7 ^2 k0 J; a& l4 l" E    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];
/ N5 W: s7 F* W+ ^# z/ L8 s5 m    m_pstIDHashBucket[bucket] = pPlayerData;</P>
9 e7 u+ G5 D& I<P>    // Store net id in player
- |& _7 v! k# r1 m    pPlayerData-&gt;NetID = id;</P>
# n& a/ J( K6 m<P>    // Unlock the hash bucket
- u5 a$ \( ^5 b' w/ r' O* t3 @    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();. S! {* Z2 l" u! X) i( I# J$ E6 O
}</P>* ]& n) K$ d, Y) h: ?6 y3 \

, G7 \1 W0 v4 r( m4 \<P>
$ ]' g1 v& T+ Q& }6 X% A//-----------------------------------------------------------------------------# Q" I6 j6 R5 e& J2 A
// Name:
% e; w+ I: Z& [7 X6 t% k- @2 J// Desc: 8 B0 D4 H' a" Q' p! U
//-----------------------------------------------------------------------------
: ~4 [6 U( i7 S7 j; IPlayerData* CMazeServer::GetPlayerDataForID( DWORD id )3 d6 |: T4 t" b2 |, M
{
7 u1 v! ^; R1 d5 x" d    // Hash the ID to a bucket number
( \' M& r+ s' _. A( j( l% [    DWORD   bucket = IDHash( id );</P>0 T4 W# j& x) O* }# h' R
<P>    // Lock that hash bucket' o& i) [, O( K, H% ]
    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
: `6 \8 j5 g9 ~5 G    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
) x( `5 [8 t% q; b8 `6 D+ T! r) ^<P>    // Loop though players in bucket until we find the right one
$ a+ l. F& T6 `. h0 `8 ~9 l    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
) l' J& B! f: x  g9 n) l3 w- h    while ( pPlayerData )
, R0 L6 i9 i4 X: b$ g- q  J    {
! x1 M7 o3 I: u) ~        if( pPlayerData-&gt;NetID == id )
8 q9 V0 b2 f8 c( X( C' N            break;
# c7 X! J# }) Y" }" B; l        pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
, I2 u% V+ J% i; ?/ y3 _    }</P>
9 _% j5 F7 s$ }. h; J5 C  i<P>    // Unlock the hash bucket
7 a2 d0 `% K! ~0 _5 u; B, ^    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>
* Y# I9 y2 d0 J; `<P>    // Return the player we found (will be NULL if we couldn't find it)
. v7 I3 O2 V' `    return pPlayerData;( D& w" k+ t- n0 k  M
}</P>) }. ^1 D: ~+ J5 l+ }9 \

0 L7 J( \* ?2 e8 _' S<P>1 J- \9 d  x- k  q5 r
//-----------------------------------------------------------------------------
% c; L; o- u- }1 k4 _// Name: 3 [2 e* e3 X/ `$ x% i8 O; [9 z
// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner2 o/ x0 p2 Y) z- B; `3 _, b
//-----------------------------------------------------------------------------) r- y  O5 {4 m& w' S" Q
void CMazeServer:isplayNextConnectionInfo()) {: d1 T: T9 S% ]
{
% x3 C) v7 G2 S5 a. R! ?, U    if( m_pNet )# m3 b# g  e3 ^9 o6 E1 I
    {$ D( H! R3 l* O) b4 ^  I9 h
        // Find the player that was displayed the longest time ago, and display it./ U* E2 I( Q' S, ]
        FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );, w  V6 {  C/ U+ D2 O  j, I% a
        PlayerData* pOldestPlayerData = NULL;
9 w/ x. ]9 |. b5 H' F        FLOAT fOldestTime = 0.0f;</P>
$ T1 y- o  \7 [7 ^<P>        m_PlayerDataListLock.Enter();</P>
" i: I5 }9 U9 U' U- J$ R<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
( N2 @& n* @* C/ Q        while ( pPlayerData )
% U+ K6 Y) ~8 c        {* {! z4 u* a; g* |8 \* ^
            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
0 ^5 I4 V$ `" G  P; Q& Y; s/ k            {1 |; w& G% f6 l) h, O
                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;
3 c* S( A: N9 k0 W                pOldestPlayerData = pPlayerData;
9 X" \! _3 v+ A            }</P>
1 z) ]& g9 P) Y# C3 Q  q<P>            pPlayerData = pPlayerData-&gt;pNext;
. X7 f5 ?" M6 f$ ^4 p& h        }</P>
5 Z$ x2 l2 d5 ]9 L$ ]& Z' N: t, B# A<P>        // Display the player with the oldest CI field, and update its CI field.
- T: b# S: U5 I6 I: _# u        if( pOldestPlayerData )
' g. b" n9 u5 L) h! m9 H9 |9 \+ b/ T6 t        {6 M( g, E. f  z3 q2 w/ [' \
            ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
( Q7 p1 H$ \/ ~. g( S; z! j- t& g            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
) ?& c$ p. X! G9 a( [" g            pOldestPlayerData-&gt;fLastCITime = fCurTime;
3 o1 g1 S. N( B; q5 e4 M# S        }* d# N7 i3 B% n  p
        else
, e6 k% h! g' l: J        {+ Q0 ^# P  l* u4 N3 D
            ConsolePrintf( SLINE_LOG, TEXT("No players found") );/ k+ d, O* n; X0 g
        }</P>
0 ~! Y+ p' x& x/ Z* t<P>        m_PlayerDataListLock.Leave();
* x2 E+ P2 s! y' n# A: a) u    }
6 `) [  z7 V4 u. K' ^}</P>
4 \7 `2 e* Q, l; ^8 w! U# u
7 X: G, A. e; p$ u<P>
  v$ x) H# ?' N) _6 y//-----------------------------------------------------------------------------( R1 C# f' \- F2 J4 d; }& C
// Name:
3 x$ k( S! l: E# Q4 T" n+ C  D// Desc:
- u& _1 B% P- H5 f7 ?//-----------------------------------------------------------------------------
! R2 M- ], P1 q8 J- ivoid CMazeServer:rintStats()
  L3 S' k. Z6 a) z" y{# M+ H- j( P6 R
    ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
( s" ^8 E- x# t9 e5 X- J: j' R* u                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );
% p; v2 u) S& V    ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),/ j/ k7 L  A4 e7 Y1 Q; j8 P7 }( r
                                    m_fAvgThreadTime, m_fMaxThreadTime );, l% |- I! L5 r, C0 k7 J5 S
    ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
0 N$ u; ^  I& G/ [% O/ T    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );' {% D. T% [% v: F  U$ e% b# R
}</P>
; X/ u2 T6 {! Z$ _  t+ ?
: m  ~: _0 n: C7 `( d% [7 L# r<P>" A9 [( `9 T/ M- ]+ R+ B
//-----------------------------------------------------------------------------3 |: |% s2 D9 p4 Q
// Name: ; P+ D( C$ z" O' t8 k: F, ?
// Desc:
: C4 ]! s0 X, v& M! Q) y/ j//-----------------------------------------------------------------------------) H  i! g# L1 E$ G( ]! l9 o
void CMazeServer:isplayConnectionInfo( DWORD dwID ), c) s% s7 Y% I0 L- z
{& R# x5 n! ?! J" J6 U; x
    TCHAR strInfo[5000];- |) s5 R9 b. z( E' V# j' G5 A
    TCHAR* strEndOfLine;" H5 ?; @$ d% s* x/ a7 F
    TCHAR* strStartOfLine;</P>
- t$ W- x6 @! W) E, I<P>    // Query the IOutboudNet for info about the connection to this user
9 Q* F, K7 Q& t* n0 M' }    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>5 p1 e: i# r, L, R
<P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );9 ^9 y# S5 f" e, K3 X: p/ d
    ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
& C# s2 T! U! o3 ]% d) k3 |<P>    // Display each line seperately
4 j, g: N1 c. |! y& X+ n    strStartOfLine = strInfo;
# r7 G1 E( B" T    while( TRUE )' Z' Z& M4 g" ?0 n6 q3 i7 z
    {
3 K7 P% [9 }: U7 F& V# J        strEndOfLine = _tcschr( strStartOfLine, '\n' );, m8 \+ G1 i' g: S3 \7 `
        if( strEndOfLine == NULL )
; f$ Y$ C" w& a, P. ~            break;</P>
. C! {3 H; E  t' B<P>        *strEndOfLine = 0;; ~, z7 _$ X0 u3 |' I: B
        ConsolePrintf( SLINE_LOG, strStartOfLine );& V6 b# d+ M1 _8 V/ p. {* ~
        strStartOfLine = strEndOfLine + 1;
  Q  W1 m& S, q    }
5 |8 I% j( S1 C% ?; D  w- S}</P>9 J7 N$ \; d9 o8 J" D

! f/ X  S! |& u<P>5 B7 c" [; E5 X- o; I8 T
//-----------------------------------------------------------------------------0 p8 N- u: h) x
// Name:
6 o) O& g7 V3 @# m; r$ Y# m// Desc: 6 X. X4 p) J( y" [! L
//-----------------------------------------------------------------------------2 T) J  R, q8 G1 ]% M
HRESULT CMazeServer::SendPacket( DWORD to, void* pData, . d' _4 Y& T8 Q' q6 @) o
                                 DWORD size, BOOL reliable, DWORD dwTimeout )5 ^6 N/ u" z' B  l. `" p2 F4 T
{% m& K; h* ?- T- [3 t" J
    // Chance of forcing any packet to be delivered reliably" e& k% K" k% j5 @
    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )
0 o. d& j1 x% D  R# s7 n        reliable = TRUE;</P>
0 {5 `1 m3 X0 w0 C% v! M! T7 T<P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
1 A8 a& W- h! O* L8 K}</P>
2 W. {. d% `3 N: l) M( k/ u( ^- G0 y8 L3 v" q% W5 y
<P>5 Q9 b/ |% |9 c
//-----------------------------------------------------------------------------' `9 e% W: m. g) d4 Q
// Name: , a% ]$ T& q! ?! u* n- I
// Desc:
; x9 ~9 p1 Q) a. i3 ?. n( K! ~7 z& |//-----------------------------------------------------------------------------
2 G% T4 \/ H" b9 \2 y( H7 T8 fvoid CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )4 |- B# `! w: b- L& ^  i. ]! }
{
1 {- @: _4 n) o, D( y    // If we're up and running, then send this new information to all clients% w8 G# _3 Q( q. |
    if( m_pNet )+ O0 H- k" R5 c8 k
    {
8 v" i- }$ i0 z- U        //Use the AllPlayers ID7 A. z8 }# H% W  z
        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );0 z  z* B0 b& e! K" x
    }
9 J2 m; _& O0 [0 W2 `$ W# c}</P>. g4 {' c8 S2 X3 D
! v( D$ M) L0 N. v! F; P
<P>" v; f' o* p5 i- E/ \( Y+ p
//-----------------------------------------------------------------------------
8 V' Y1 q. x8 \1 R5 Q5 c: ^// Name: , o0 e: u: P0 R3 U/ e% }
// Desc:
; i. [. N# {7 n0 G0 O//-----------------------------------------------------------------------------
0 J' t' l* K" g( x6 D& _/ I+ \9 jvoid CMazeServer::SetClientReliableRate( DWORD percent )0 K3 L( W: u/ W& y4 ~$ V
{
5 ~0 ~6 z' E0 \$ R, d9 F    // Update client config, and build packet containing that data5 b5 n$ {7 B  n% r  H
    m_ClientNetConfigLock.Enter();6 L# B2 b  z9 }4 p3 R
    m_ClientNetConfig.ubReliableRate = BYTE(percent);  i% w4 X6 ~3 m: s* }7 D
    ServerConfigPacket packet( m_ClientNetConfig );: s; H+ }0 C% A( P9 `; b
    m_ClientNetConfigLock.Leave();</P>
( k1 F) i+ }3 k7 Y<P>    SendConfigPacketToAll( &amp;packet );- H: H' z# b4 @9 s6 \3 G
}</P>
" k6 S0 H. A' l4 K7 l3 H
, d& e& r2 O$ g& o; Z0 z5 @<P>3 I/ a2 c* \1 m1 D8 R9 E( G
//-----------------------------------------------------------------------------
' W+ N+ V6 z6 C// Name: ! f5 g. p1 H3 T7 X
// Desc: ! X" J7 b8 p# I( M
//-----------------------------------------------------------------------------
: o$ R& r- D9 _, }5 g8 \void CMazeServer::SetClientUpdateRate( DWORD rate )
' d9 m: U8 n6 V/ V& o{+ g/ V5 Y$ y$ h! [! c
    // Update client config, and build packet containing that data& y7 b2 d8 b$ N' c: g" E' R3 x; R
    m_ClientNetConfigLock.Enter();
. b$ Z4 A# R' O9 Y( R    m_ClientNetConfig.wUpdateRate = WORD(rate);
: R8 ~4 r9 ^" ^& l    ServerConfigPacket  packet( m_ClientNetConfig );. g, f4 Y. u2 h
    m_ClientNetConfigLock.Leave();</P>
2 ~* \/ E* q! _; c- b  Z<P>    SendConfigPacketToAll( &amp;packet );) O" y1 L/ j/ @" P4 X3 a' @
}</P>- ~. T# ?, O5 }( P8 Y1 t# y

& i9 }- `) k  i9 [<P>
* h4 l, R1 G# ?1 E//-----------------------------------------------------------------------------
# v" w7 R# y* z- ~3 {- N" G1 ^0 h, a// Name: 3 i( V! e! P/ j, k- I" y  I
// Desc: " V; b* N( W% M4 Y
//-----------------------------------------------------------------------------
, Z0 o) d: d! I! evoid CMazeServer::SetClientTimeout( DWORD timeout )( z' D7 j8 |5 J; w
{# u; W, ~( b9 N
    // Update client config, and build packet containing that data
6 c7 x$ H' |1 n0 |( r( h    m_ClientNetConfigLock.Enter();, d( @. k) ~- g0 L- D% F% I9 g
    m_ClientNetConfig.wTimeout = WORD(timeout);, v# J6 b$ K" j
    ServerConfigPacket  packet( m_ClientNetConfig );
: ~. C) m% W5 J    m_ClientNetConfigLock.Leave();</P>
- S3 R4 t* u5 v9 C# E2 l# t2 B<P>    SendConfigPacketToAll( &amp;packet );% M3 f% K5 |$ _8 r
}</P>
1 `/ k: J# p2 \' O) h. q. r: @1 v3 V; t) }9 D' y9 W
<P>8 O/ {$ B4 I# ^; J$ B
//-----------------------------------------------------------------------------& L$ ~2 b3 F4 t# z7 Z7 }
// Name: 4 z" A  ~& n% L4 t
// Desc:
% I! b2 C; B1 ^9 [. ?/ S- a( r* n//-----------------------------------------------------------------------------3 m( E/ i2 g) n
void CMazeServer::SetClientPackSize( DWORD size )
4 X9 K. r* z' s) ]{
. A  U+ S1 s3 ^. c$ Q    // Update client config, and build packet containing that data  c' j( F7 u, r  `
    m_ClientNetConfigLock.Enter();) ]$ j" Q0 ^7 d+ R$ M) s
    % H6 g% z  m- r; i) A. k- G, H
    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.: x$ Z0 H0 A" o+ H( l
    if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   
) B0 N% Z: Q+ K1 @( o0 P        m_ClientNetConfig.ubClientPackIndex = 0;</P>
% @8 B4 E, z, ?6 u7 O. m/ Q. H<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);
1 t+ G! P5 S* {# x* F; m    ServerConfigPacket packet( m_ClientNetConfig );0 T7 u+ b  L# {/ m$ ~+ M
    m_ClientNetConfigLock.Leave();</P>' i& p: |$ d5 J" Q' s  g4 `
<P>    SendConfigPacketToAll( &amp;packet );1 _8 K" B/ Y+ \" n; [2 G& m$ X
}</P>3 D! H% ^0 o# }
* y4 Y8 L( ^' t3 [/ p
<P>
. i! s0 W7 Q; z, @//-----------------------------------------------------------------------------
5 l+ M$ @% j& c% M& w. a, T; @// Name:
) t" i; f9 Z- m7 ]// Desc:
4 d. @+ }0 u- U# @( q  I//-----------------------------------------------------------------------------" {' _# C8 J0 A& n4 O4 {
void CMazeServer::SetServerPackSize( DWORD size )
: g% N; Q: i+ K/ Y8 g- ]{- k+ C; [3 I: M; J+ k1 C% M/ Z0 p
    // Update client config, and build packet containing that data
. j/ [( ~9 F' A$ b6 V    m_ClientNetConfigLock.Enter();& |+ I2 a! R8 ~+ p' U
    1 h% d' G4 B4 j2 x0 X3 X% W/ t
    m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.
" ~$ R) e, s& H; w    if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   2 F* f8 n9 c) k4 Z
        m_ClientNetConfig.ubServerPackIndex = 0;</P>2 k/ e2 X+ a6 n: a
<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
8 x- e3 @, }* n1 M% p8 t4 W0 g    ServerConfigPacket packet( m_ClientNetConfig );
$ C! S' s0 Z+ B# G    m_ClientNetConfigLock.Leave();</P>
6 o" Z- L5 Q" i! t. X* _) W$ v1 l% I% \<P>    SendConfigPacketToAll( &amp;packet );
$ g4 m& j/ m; ]; h1 I* h: T}</P>) H5 p3 W5 Y! T. U
<P>0 E4 E5 n0 C* b2 p  w# y! n
//-----------------------------------------------------------------------------) F8 k/ ?& Y/ t% |
// Name:
% r# Q+ v$ t  O9 H/ Y9 G// Desc: 5 V" l1 Y; Z! `+ C4 J
//-----------------------------------------------------------------------------: \4 Y7 S" I  e/ g
void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )9 h3 ]# E3 S( y# \2 N
{
/ U: k% E  v2 \1 l1 A' F$ B    // Update client config, and build packet containing that data+ l8 w( P& o: N. M
    m_ClientNetConfigLock.Enter();  q' Z' v6 P1 p# k: R' m
    6 H+ }1 J5 }" i+ t* w
    m_ClientNetConfig.dwThreadWait = dwThreadWait;
1 j1 S: a$ C- u4 c* o  P7 f  c    ServerConfigPacket packet( m_ClientNetConfig );6 p+ m% `% k5 g7 F) r7 F
    m_ClientNetConfigLock.Leave();</P>
% K  X: U* |7 q' s<P>    SendConfigPacketToAll( &amp;packet );
, l# k/ Y0 ~: M' C}</P></DIV>




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5