QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4204|回复: 0
打印 上一主题 下一主题

[分享]MazeServer源码示例

[复制链接]
字体大小: 正常 放大
ilikenba 实名认证       

1万

主题

49

听众

2万

积分

  • TA的每日心情
    奋斗
    2024-6-23 05:14
  • 签到天数: 1043 天

    [LV.10]以坛为家III

    社区QQ达人 新人进步奖 优秀斑竹奖 发帖功臣

    群组万里江山

    群组sas讨论小组

    群组长盛证券理财有限公司

    群组C 语言讨论组

    群组Matlab讨论组

    跳转到指定楼层
    1#
    发表于 2005-1-31 11:52 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    <DIV class=HtmlCode>
    . s& L9 r  x/ L. j- [2 {<>// File: mazeserver.cpp
    0 t) W# p/ x7 ^. c. K3 W//
    9 U0 N  |  J8 v2 [+ t// Desc: see main.cpp0 M. a% a, y1 n# t0 H, n3 p' B1 P
    //$ v/ q9 m  R; L" z- R! ]+ f
    // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved., D) Q' Y% C: l: Z6 e0 U
    //-----------------------------------------------------------------------------  ^+ E3 |0 y6 Y; a0 @
    #define STRICT* ]; _4 Y' n0 j. |
    #define D3D_OVERLOADS1 [0 i( C" i, Z; b' k+ W- S; X
    #include &lt;windows.h&gt;+ [" S6 ]- Z1 ?+ C% i) n$ |
    #include &lt;d3dx.h&gt;7 r& W; Q! p7 l. p# a9 \  z
    #include &lt;stdio.h&gt;
    " x3 v0 `( M0 h0 z#include &lt;math.h&gt;
    & [& _2 H/ l4 x  n' r3 W#include &lt;mmsystem.h&gt;
    0 J5 H  l1 g2 R0 e8 q#include &lt;dplay8.h&gt;+ a* h& o) t( P! N- e
    #include &lt;dpaddr.h&gt;$ A0 J  M  C8 p2 ~/ l
    #include &lt;dxerr8.h&gt;3 A9 j6 p1 f. b; w
    #include "DXUtil.h"
    0 }8 J2 L1 ?5 T) P4 G8 Q; K#include "MazeServer.h"
    , e0 f: d( }) ]! c! |9 |#include "ackets.h"
    $ v7 B# U& X1 K, t#include "Maze.h"
    1 ~& o$ {) G- p2 L7 @#include &lt;malloc.h&gt;
    6 m- A2 v7 h: D! Q8 {#include &lt;tchar.h&gt;</P>: w7 a( g! m+ W0 @2 w
    8 k/ V+ s4 e' G( r# o
    <>//-----------------------------------------------------------------------------
    7 Q5 C% C: Z6 i// Name:
    & G4 d- I3 s5 p8 V- r// Desc:
    , _8 N4 h8 ]7 {5 E( J//------------------------------------------------------------------------------ c- N9 ^* s! I4 D
    CMazeServer::CMazeServer()
    5 k6 v: R8 b  c# b9 _{
    0 q4 J3 j6 t0 Z3 g) ?. X" b    m_dwPlayerCount         = 0;: a" @- K0 b( O$ o7 P1 n3 C
       
    7 |8 m1 ~1 n. r5 X$ h3 `: p$ P    m_wActiveThreadCount   = 0;& e, \  `! E6 c  J2 J* T( z
        m_wMaxThreadCount      = 0;
    0 c, z5 N2 R: M* `    m_fAvgThreadCount      = 0;; @  {! q) z7 |* Y  K5 A  C$ V& ?
        m_fAvgThreadTime       = 0;# \0 I7 e3 H3 _
        m_fMaxThreadTime       = 0;</P>
    ' s6 @  o8 X: t<>    m_dwServerReliableRate  = 15;( I2 X  o0 P0 R/ `( @9 O/ f
        m_dwServerTimeout       = 150;. x1 ?3 n. E7 B$ [7 }
        m_dwLogLevel            = 2;
    4 @& [5 k) o$ {" G) y4 _1 C+ u    m_pMaze                 = NULL;</P>
    * v5 [. K  j9 @# l<>    m_ClientNetConfig.ubReliableRate = 15;; Z% N2 S) L3 G: E7 ]# q+ Y/ c& Q
        m_ClientNetConfig.wUpdateRate    = 150;- v7 U* L# C8 F; U
        m_ClientNetConfig.wTimeout       = 150;</P>, F; i, Z$ l+ j( H! D) `, _
    <>    m_ClientNetConfig.dwThreadWait = 0;</P>
    8 W( v4 l1 [- r$ k, @2 X<>    m_ClientNetConfig.ubClientPackIndex = 0;5 o: _' U1 @  b, k9 y) l4 @
        m_ClientNetConfig.ubServerPackIndex = 0;
    & ]. ?: _, E% }0 _. K1 I+ c5 k    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)
    ! a- N( c, k6 f7 }& p    {) @6 U) C4 s0 J2 N- k! \0 s3 j# M, r
            m_ClientNetConfig.wClientPackSizeArray[x] = 0;5 y& Z0 q$ t- [; q6 g$ o1 |" e
            m_ClientNetConfig.wServerPackSizeArray[x] = 0;; V$ a! U9 F* d4 S8 l/ k
        }6 j/ S- J2 j* y1 Q/ E
    }</P>
    9 L3 c" v* [* u' J; u
    7 h  x+ X1 N( Q5 D9 c7 m/ O2 W* {<>2 ^; g: R- m% @
    //-----------------------------------------------------------------------------, ^8 D' S7 g* |: t$ X, q0 H; O
    // Name:
    ! f& D9 m8 s$ R+ h// Desc: 4 m% _2 f* H2 l% u  D( _" s. N+ ]
    //-----------------------------------------------------------------------------
    - ?8 b% B" j5 q! A4 n$ Z5 NHRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )/ Q+ V% D" e" P  k
    {
    / l6 p! g% \% p  m* B    m_bLocalLoopback = bLocalLoopback;6 z" t$ T' t% Z6 {
        m_pMaze = pMaze;
    - ~# \: g# }+ r6 b: j: g    if( m_pMaze == NULL )' F8 X+ M) T: C( R+ O, R, e8 J
            return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
    . T8 f% b" ?0 \) G3 b9 d<>    // Grab height and width of maze/ L) e  P. d0 u4 g2 i7 y- h5 X
        m_dwWidth = m_pMaze-&gt;GetWidth();* Y+ F& u( v  N& Y3 w
        m_dwHeight = m_pMaze-&gt;GetHeight();</P>
    5 m* v8 n2 ?, o# Z<>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;6 w8 J' R/ r/ x+ V0 L
        m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
    1 X8 r! U" M0 H9 c- Z3 x<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.) ^6 y# H) _; C  b, \7 I
        if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    1 O4 e+ d8 `) J$ K1 t+ H/ X  X1 _1 O        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );4 v' J  Z! a8 b( U! n5 }
        if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )0 O  q8 M, U+ _, W: r/ Y6 Y( v
            return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>( b& g0 l9 r. ^) c' `$ @
    <>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;# e' b- {; f7 v: R1 B$ s# f
        m_dwMazeXShift = 0;1 }( w- b' L7 B2 Q! {, L
        while ( (scale &gt;&gt;= 1) )+ u1 L8 d, D; k
            m_dwMazeXShift++;</P>
    * y# s" U" n& ?' W9 U& i<>    scale = m_dwHeight / LOCK_GRID_SIZE;
    & {! ]- b8 S- U) o; o    m_dwMazeYShift = 0;4 {: r1 k5 v& g0 {/ {  k0 R6 |- A. e
        while ( (scale &gt;&gt;= 1) )
    % z; L" {! y" y8 L. F; q* T        m_dwMazeYShift++;</P>$ m6 B9 t. ^  p
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    0 f9 ?: ?0 e% N) M! M0 J  p        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )
    3 s: _  v) X. A        return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>* R) O4 @& |; H' }9 i$ ?
    <>    // Initialise the player list1 p7 P/ w" P# z4 }
        ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );4 ^' `! U3 C7 }& D
        m_pFirstActivePlayerData = NULL;0 L$ z4 s4 p  I. S. F! P( U# w
        m_pFirstFreePlayerData = m_PlayerDatas;7 I$ q4 K  d( \* W0 v
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )6 [# t% z! W! Z- P9 p/ e
        {9 u% L1 F& ~# E" }1 _* K
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];7 j9 U8 z% S& F2 @3 }: Z
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];* f. `/ N, K  S8 B
        }</P>
    : a0 _' {% ^. X7 `; q<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];0 h( l: r. n- j% t5 J. H
        m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];; N# G. k% c4 ~+ l+ [
        m_dwActivePlayerDataCount = 0;
    ! t# L3 f$ p2 \4 I9 \9 |( j8 ^    m_dwPlayerDataUniqueValue = 0;</P>
    7 c: Y$ `5 g- `. v<>    // Initialise the cells. g3 W( V7 F' |7 G0 B" }
        ZeroMemory( m_Cells, sizeof(m_Cells) );6 U! x) ~3 I! Y' r
        ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>- |  w% q( E9 Z1 b
    <>    return S_OK;
    . J% U7 U4 X$ h6 g}</P>
    6 Y- ~1 j0 E  |# Q8 u& B
    1 u6 w5 x; V5 h1 A<>$ P4 R* f3 C7 o5 p* g& \- O' `: N5 L
    //-----------------------------------------------------------------------------
    ' n3 h. N4 x+ Q: t( e5 b' v5 s// Name: 9 x% T3 @0 L0 e( Q4 D
    // Desc:
    , W9 Q- `5 ?& l, i//-----------------------------------------------------------------------------. j3 s7 F% ^- h4 L7 u* n7 {( v3 f" Y' a
    void CMazeServer::Shutdown()
    / h( P7 T9 E0 f: h- ^4 q5 \4 x6 d{) m% H  c7 s% [/ x/ p: D
    }</P>/ W5 |3 {+ O3 X& Y

    ( P6 Q9 _2 C/ c! h* s<>
    4 L5 N- @. ]$ m- t  l1 k$ ]//-----------------------------------------------------------------------------/ V7 M% B9 o$ |$ A
    // Name: . f9 D4 z8 J: f  x5 o
    // Desc:
    ! o: c2 @8 M! B8 M//-----------------------------------------------------------------------------
    0 ?8 Q3 ?0 K- e4 K+ p0 S" ?void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    5 n" k) z- ~! E7 ^' n. X0 \* L{. t/ E" u/ h! R- x
        m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,9 @( k2 Q$ D) G
                              x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    1 }* Z' ]  Q. G' e- K}</P>7 E* o. ]9 q7 w# k: h3 u
    ' F! W$ b$ W+ s; I2 a& k# E* u& U4 q
    <>0 S) M3 a8 c+ ^0 w/ X" \9 ?  r
    //-----------------------------------------------------------------------------
    ' r: h8 V3 B& z1 n5 e, F, U// Name:
    9 R$ w9 w5 x! F6 l// Desc: " S' M9 E8 x  j: t' |
    //-----------------------------------------------------------------------------
    / }& A! R. E$ I7 o6 T; fvoid CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )& @4 m& }7 Y9 W0 @- z" {: S) ?  l- x
    {
    8 W* N8 D+ Z7 o5 h# ?) R    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    - F% z2 j7 {) ^- m1 }                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    , b% V4 e5 f: P* L0 z}</P>" e2 |2 r  H7 g7 ~

    1 Z8 T- Q" _9 @0 M<>
    ) s9 W: U0 c! Q" @" m; |# O( q//-----------------------------------------------------------------------------" s. D% Z0 J3 q" ]9 d
    // Name: + P( }  r. b9 c7 `
    // Desc:
    % ?! ^7 V0 U8 F! ~6 x$ E9 C//-----------------------------------------------------------------------------6 F& [# z/ M; [+ A
    void CMazeServer:ockCell( DWORD x, DWORD y )
    ( D: |2 e- ~$ V: g: V7 r$ G{- Z; h/ X5 w7 u2 y3 y
        if( x == 0xffff )  h. H, q5 N- s; a, w) @& K& [( N
            m_OffMapLock.Enter();0 v* s8 q/ Z3 }7 ~, @
        else$ S: y5 N: R5 d$ Z2 Q3 `2 N
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    ! N* f, Y* ^+ O# S, h$ n}</P>
    0 K% W2 X/ g  H3 e
    9 @, h/ j4 S4 ~9 b9 e9 X<>
    / L% W/ D) D: u) m* L/ d+ Q% M. H//-----------------------------------------------------------------------------
    4 S) m5 v% G4 ^" A+ p+ t// Name: + m% l2 q7 t8 l. P
    // Desc: 0 r3 Z5 f/ B. d# a5 `1 M$ }, @
    //-----------------------------------------------------------------------------! g* K) f; ^6 p- S
    void CMazeServer::UnlockCell( DWORD x, DWORD y )
    9 K0 Y) ^6 }" l. @  {- h% f{: D) m/ I  ^; w* U
        if( x == 0xffff )# \8 s8 h2 s! s. |
            m_OffMapLock.Leave();
    6 s! o& Z" }3 W3 [    else% b+ g3 u7 P: Z& E( m# c6 s' o' Z
            m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);7 I) l" D- j" ?. w( ^+ p
    }</P>+ ]: V/ b% z  m, K. [) Z

    $ C8 x3 X8 N) B. s# v<>5 }' a/ C$ k% P
    //-----------------------------------------------------------------------------
    * `" j' V4 I; O  g- J// Name:
    4 e3 B+ C' }1 j/ B6 G3 R% M// Desc:
    ' ~) ^/ i1 S% J$ _* p! N//-----------------------------------------------------------------------------4 X0 S- w8 H4 C9 G0 ?  P
    void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )- @. U7 d, h- p* ?+ T
    {
    ) B& F2 Q+ t6 K. f, Y$ v    if( x1 == x2 &amp;&amp; y1 == y2 )
    7 k* \2 t* {- @" l3 s. K    {4 r* p5 S8 I% x$ n5 C
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    * n) r& J4 e$ k            LockCell( x1, y1 );. N5 R5 _, x( }9 g7 `2 R6 k/ J
            else
    2 `( o( c/ A) p            m_OffMapLock.Enter();</P>
    / V& e4 B* {" i- c4 @<>        return;% a+ N4 i- P* k( J
        }</P>
    . a: Z. o8 o7 L2 _' \( F4 i2 W" q! r<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    ; V/ O, J$ e' d7 X! r0 u# H. U    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    / M; h8 u" |4 M! f) Y$ j5 g    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    ' z7 _& X" M/ Q$ v: H- e! B0 |    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>3 N5 Z$ e. }# r3 ^
    <>    if( x1 == 0xffff )9 {: z$ Y6 l  y3 g8 Z: K
        {6 R( x7 R6 n1 U9 T& s
            m_OffMapLock.Enter();, M3 J1 r4 T5 v0 N* R9 Z
            m_LockGrid.LockCell(x2shift,y2shift);0 h# G4 k. S, K) J$ \3 Y( f
        }
    ( J) }9 s8 [6 q7 s6 P8 \: A    else if( x2 == 0xffff )7 @3 l3 ]$ i0 w  h* @# d
        {- ~0 P! C' Q( m8 ~0 p% C8 R# D
            m_OffMapLock.Enter();
    2 h4 F+ _4 U, L        m_LockGrid.LockCell(x1shift,y1shift);
    3 r: B& H" ], f( `$ c; Q    }
    ' K4 R* @+ G0 F: n3 J' d    else
    - L1 D  ?  S& g' q6 e7 Q3 r3 i    {) j  ?! F% M& I6 E2 L3 o
            m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);; P: K0 K; |5 P3 z4 _
        }& d" _) V$ H2 X  T# D! @4 n
    }</P>
    & k  P: i! h/ E+ `$ y* w2 L
    2 E5 q/ D+ |! M. }: }. \# Q$ Q7 ^<>
    : p+ n/ A  P1 u$ I5 C, I0 u//-----------------------------------------------------------------------------( x; n3 [" Z2 w( e
    // Name: ( `9 f# ]* m# y3 Z: x
    // Desc:
    4 J: T( T& N1 X. a//-----------------------------------------------------------------------------% I( |1 S4 {  a
    void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    5 E  F: A* F9 y{- u8 h9 K7 K; w
        if( x1 == x2 &amp;&amp; y1 == y2 )
    * l* l9 [7 R; N# Q    {7 _1 k4 ]" D* W. P
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )7 w6 q; r7 c% d7 H% A9 M! w9 l7 Y
                UnlockCell( x1, y1 );. I6 Z& K* K* w# Y
            else) e7 _. R/ w* V
                m_OffMapLock.Leave();</P>
    ) R9 [- M4 B7 l  r4 B<>        return;' X& _- c" j7 u
        }</P>9 \8 a$ w3 T1 K. p$ k, P3 Q
    <P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    4 X: _9 e( i5 W4 A) u% _# M    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    8 s+ a& u3 r8 N% k  Y/ ~( }    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    9 a* }! a6 [+ b: T1 {  j    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    / B  d. ?: b. `6 ~" H& Z& \# [<P>    if( x1 == 0xffff )# [8 p7 @# C6 c6 u9 f: f) c5 \
        {
    " N  w$ k3 Y; d* R0 p4 b        m_LockGrid.UnlockCell(x2shift,y2shift);
    " s5 W8 d! a  y/ w3 T% G        m_OffMapLock.Leave();
    6 ]# g% F# z) K& ]) q4 G    }; O: Q; E( r4 @
        else if( x2 == 0xffff )
    9 X  {3 {( z% Q  d3 `6 z    {; _$ Q8 i2 h# K8 q/ n
            m_LockGrid.UnlockCell(x1shift,y1shift);
    ; z$ v1 l1 U* @" q. J        m_OffMapLock.Leave();
    ! V. r9 G$ T" t+ R, S    }
    ( ~( m! q$ W# {( D; a7 z    else " c* u0 u. ^. b, B6 ^7 a
        {2 c. {/ B) R4 _# h. K. q- [- Z
            m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
    + u- C, V" ], }5 F8 a( B: t5 F7 t2 Z) @    }( ^0 w+ A8 {9 h
    }</P>& v* r6 ?2 H$ b& M# b% N
    6 N3 w9 B  G8 o
    <P>
    / A! L  c: H7 }$ O+ }) n5 [//-----------------------------------------------------------------------------  w# w4 s1 ?2 j9 e8 N, C. }. _
    // Name: * b. y: I' I/ V. @4 Y4 G
    // Desc:
    9 T& }! V' |! \1 Z, B; g//-----------------------------------------------------------------------------
    $ E6 k0 s  L4 G7 F$ u5 Pvoid CMazeServer::OnAddConnection( DWORD id ); r3 a2 }. T+ a! Q
    {6 Q1 S$ w1 f. U( {0 I( k! m1 N. M
        m_AddRemoveLock.Enter();</P>" I- o( o& d/ q6 K! n
    <P>    // Increment our count of players& P3 O) A4 M% h, L5 Q; j+ o
        m_dwPlayerCount++;3 R6 R+ F& F3 d2 o9 X; y7 g
        if( m_dwLogLevel &gt; 0 )- `. [6 M/ K* h2 R6 B! ]. E
        {, _8 J* S9 @! n8 ^1 [- a' x
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );. ]: h1 ^. P4 E2 G; l
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );" Z" \. N4 }$ w# n& @
        }</P>
    ) ]; x5 U1 [+ [2 Z9 h5 |<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )+ C. t% P9 A' f% d
            m_dwPeakPlayerCount = m_dwPlayerCount;</P>. k# @# J# b" m  z* O8 E* M
    <P>    // Create a player for this client
    ' V! }8 e3 O3 Y2 p    PlayerData* pPlayerData = CreatePlayerData();
    % O: |0 x" I; A6 R, S$ f& y- }    if( pPlayerData == NULL )
    4 ?: j# \& r1 X  _    {8 ^2 P. X" g& U; e
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );9 [* o) {8 Y- t* D. v
            DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );
      S3 m' w5 Y$ d( ?/ v/ W: T  [' p# }        m_AddRemoveLock.Leave();9 p# R: U" z# n/ z% F
            return;
    1 x0 v$ Q$ q2 i4 G    }</P>6 V. k; f3 I& ~7 x* K
    <P>    // Store that pointer as local player data
    ; P! ]+ X/ P7 D    SetPlayerDataForID( id, pPlayerData );</P>4 r. C7 Z8 F0 c5 H3 v5 @
    <P>    // Grab net config into to send to client
      \) {% w; n8 y" |  m    m_ClientNetConfigLock.Enter();
    0 [" w5 L5 j0 D5 g' N* {/ g2 {" i    ServerConfigPacket packet( m_ClientNetConfig );9 _+ _1 \; I/ d- e
        m_ClientNetConfigLock.Leave();</P>
    6 h' n6 P" ]# k* ?1 Q<P>    // Send it; Z' s: a! S# X( ~) a
        SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>- O, p' L! }# b/ A
    <P>    m_AddRemoveLock.Leave();
    / c. g0 e5 O; N9 O( ~/ M}</P>
    6 G3 t/ I' }. O3 }8 i' z- e/ I$ c2 x  B. ^4 m) X
    <P>
    # [. Z! }3 [& r. I( @//-----------------------------------------------------------------------------
    4 |) j  F6 S3 ]- l3 }// Name: , L' _0 g6 W# s! }
    // Desc: 9 P9 i4 {; _+ v' m
    //-----------------------------------------------------------------------------
    # v; g/ P  w) j- E$ ^9 ivoid CMazeServer::OnRemoveConnection( DWORD id )8 n$ l. f/ A& X& f7 t0 b# `
    {
    8 A) l; Y! }/ y$ @5 t0 i    m_AddRemoveLock.Enter();</P>
    * [  z, D% U/ P. {+ l0 f<P>    // Decrement count of players$ |+ i& J0 l+ f  |" |7 P
        m_dwPlayerCount--;</P>+ b& ?0 G2 B  K) Y9 M7 h' u+ C+ Q5 n
    <P>    if( m_dwLogLevel &gt; 0 )
    9 s# @1 w) _8 a1 N5 L; a    {9 n: U/ h1 _$ M% p. D1 D7 S
            ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
    ' y( K0 c" X+ I5 m0 J' J        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );) p! U( S6 S0 `; @/ _4 f8 M9 N1 D
        }</P>. v( J/ O& }+ q+ D
    <P>    // Find playerdata for this client
    & ]  z, N# e# B  w" x    PlayerData* pPlayerData = GetPlayerDataForID( id );
    # _4 r* `  h& M- l    if( pPlayerData != NULL )" P1 N+ B3 x( j& }3 e
        {
    + ]+ I, t7 M. Q' A/ B, q0 R3 t! p        // Destroy it
    - h, Z' _1 l2 O- y' r        RemovePlayerDataID( pPlayerData );
      A: D1 i2 E4 C6 l7 h        DestroyPlayerData( pPlayerData );- K3 E1 \* C+ G( V
        }</P>3 n' M( h5 D" o7 `) a2 \  Y7 m
    <P>    m_AddRemoveLock.Leave();
    ( `) S1 ]# w# A& X7 m}</P>
    6 C" L, B! _0 \9 D7 e$ d: p& L: M& X4 W* n( t/ u. r7 q" L
    <P>
    7 g4 {  P( e  |) i  h, B//-----------------------------------------------------------------------------
    4 g( p" U4 y  A: S/ F/ \7 ?$ p( w// Name: " Q1 y7 O2 T4 O  t4 N) m0 r* a
    // Desc: % N7 o0 n; R3 {0 ^
    //-----------------------------------------------------------------------------
    ( y  C+ O/ O; i$ r+ V% r! dHRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )
    : ^/ D, @5 X' b1 W{
    . y' `7 T2 |; \; C. t    BOOL fFoundSize = FALSE;</P>
    " v! J- \8 \! _+ s1 w. R; f<P>    // Increment the number of thread we have in this process.# P' g. T9 Y) w& V( p0 j
        m_csThreadCountLock.Enter();</P>$ f$ `' O& h+ e# X
    <P>    //Get the start time of when we entered the message handler.; J7 O7 p% e8 t3 ?
        FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>9 A/ q+ P: m, X9 ~& q9 }9 l
    <P>    m_wActiveThreadCount++;5 E# E: U  o$ z0 |+ V3 D/ N: R
        if(m_wActiveThreadCount &gt; m_wMaxThreadCount)# ^# ]; ]# m* T8 F- ~  y1 _9 ]
            m_wMaxThreadCount = m_wActiveThreadCount;9 }4 I5 v7 _0 ?
       
    ' ^0 ~/ `  H9 Z/ c$ i- f  ?. P1 M1 ^    // Calculate and average./ P+ W, \# v- A$ m/ z  z% e
        FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
    2 v- a8 p8 g6 r  s! b+ c    m_fAvgThreadCount += fdiff/32;% v  c5 H) p4 {' e! |$ p/ a% X7 b
        & N2 e% v- [* i" l+ r6 O
        m_csThreadCountLock.Leave();</P>9 F4 j3 Z  z) }6 E
    <P>
    8 \7 C$ U4 m4 h$ s4 N  b    ClientPacket* pClientPack = (ClientPacket*)pData;' O8 Z6 a& i- K
        switch( pClientPack-&gt;wType )
    % j$ k- L4 E+ H/ ^  j+ \, c    {8 `  q3 F" c5 o/ _' n  c9 e
            case PACKETTYPE_CLIENT_POS:
    - G1 @) q- l6 b2 [7 j            
    : v( V  N" U! Y            // Check to see if the packet has a valid size. Including   m! c2 B- q( _1 D5 I9 F
                // the custom pack size.
    + u! z9 @; t" `5 n6 n            if( size &lt; sizeof(ClientPosPacket))+ e& ]% w6 l% N& r1 g
                    fFoundSize = FALSE;
    0 t/ @% d7 H8 q8 k$ w( ?" w4 d( A6 _            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))
    ; \7 m8 o0 N- Q! e; S+ o! O                fFoundSize = FALSE;5 e5 q4 P, _- `$ }; r) h
                else- w  {( }& S; Z+ c8 T1 @& D* I
                    fFoundSize = TRUE;</P>
    0 p0 M/ v( J! m* ?! ^" H<P>            // If valid sized packet, handle the position.
    0 |, ^/ T$ }. c' ~            if(fFoundSize)
    # J+ u- m: O3 P& s( x                HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );
    ; g2 }2 \5 P) Q4 Z9 X' G" ?/ O, P            else
    6 P4 W3 [% ?" m' T8 a0 o4 x                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>6 _8 I. q; l# e# y& K) I
    <P>            break;</P>
    9 d. ~* \# t1 c<P>        case PACKETTYPE_CLIENT_VERSION:
    0 f7 ~  C5 u* ^. i- b7 B2 B( i3 z            if( size == sizeof(ClientVersionPacket) )! J' y2 B- W  D0 |  W
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );
    & \! Z& i8 u- p9 e) Z8 P( _* h            else
    7 Z' m+ s; U# U. @                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );: x; w, C7 ?( P6 [4 E
                break;</P>
    ' k* e; N" f7 ^* r, a<P>        case PACKETTYPE_SERVER_CONFIG:</P>
    0 f$ H' M0 e& C* v  N<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>
    . [! \5 [  i" u/ h- {/ y5 p<P>            break;
    % A; \$ \$ d4 ^: L2 e        default:
    . J1 v$ t1 @5 G- ~2 m/ g6 Y            HandleUnknownPacket( dwFrom, pClientPack, size );4 q, U2 {2 M0 Y$ O) Y
                break;
    , j: F( @4 c! _, ]  y' G$ `9 I    }</P>
    0 q: ]5 D. |0 Y3 M$ x<P>    //If the user wants to hold the thread, Sleep for given amount of time.
    ' I5 T$ _6 n# \1 v& {) r' A    if ( m_dwServerThreadWait &gt; 0 )
    ( G& j% \* D3 M    {
    ' i; L7 M! q$ E) `0 @( P* V        Sleep( m_dwServerThreadWait );
    ' f. w* H3 T) s% X; G4 k0 p, s    }5 B. U9 w, M( ]3 V8 c: O0 N% u( W
        ! b- u" h$ |; r
        // Retrieve thread data for this process.1 e8 l6 F7 z9 B8 Z) e& {
        m_csThreadCountLock.Enter();</P>1 x. W! m/ [2 I, |  z8 ^6 w1 `
    <P>    m_wActiveThreadCount--;</P>/ H. x+ Z* A' {# n
    <P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
    0 r+ O$ E3 K7 t" O) ~5 z8 N/ i    m_fAvgThreadTime += fDiffTime/32;</P>
    0 I/ b! f- C" |* @<P>    //Get the Max time in the thread.1 m8 E) c5 x6 T2 h' Y
        if ( fDiffTime &gt; m_fMaxThreadTime ); b+ D0 t1 [. m; @  e4 a5 r
        {8 B* f. j3 U- b% l" v  g
            m_fMaxThreadTime = fDiffTime;) V/ e3 s$ F; ]/ E
        }</P>5 g9 o# A; C- Y' j9 C
    <P>    m_csThreadCountLock.Leave();</P>( w* a* P  n' a) S( b" a0 D0 y1 m
    <P>    return S_OK;" Y8 ^6 I) {' ^0 q0 D/ t
    }</P>
    7 C/ p- F/ }. B2 w$ d4 B0 Y& K2 G# w
    <P>//-----------------------------------------------------------------------------
    - v% L2 b3 ]$ d  C  R' _- b3 D// Name:
    " n( m. W) J3 B( w' d6 j  R// Desc:
    $ h1 }  v) o; ~0 ?7 n//-----------------------------------------------------------------------------# i/ X; w/ o. u) G) l% V
    BOOL CMazeServer::IsValidPackSize( DWORD dwSize )
    . ]8 u' Q+ {) @{
    + k6 v; G* F8 c    BOOL fFoundSize = FALSE;1 W1 R' w. E- r
        BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;+ f5 T& N( n! N3 a. i; z
        1 f  ?5 d4 q2 S- m
        // Check through the array of valid pack sizes.
    # s; J& T/ q% v( P$ g    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    3 t5 v8 s5 ^  E7 n; d. I, G    {6 z5 @: Y; Y9 V$ ?7 y' P3 M
            for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)
    + \8 _- [. t, b- N6 v        {
    8 u9 U( e' E( L: I, U5 [2 G0 C            if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    - C: {* d( g3 Z, I( Q5 p  X. n: `            {7 `9 n6 f- x  |- H
                    // Found valid size in the array.
    % q9 G2 B0 E; Z- V8 y                fFoundSize = TRUE;
    8 I* n( j) O" r2 H                break;3 D- u' N. `, T+ ]  i- J: M% x
                }# K4 F9 }" ]4 y  Y
                if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.0 {7 c7 I0 A3 U3 J' J0 d6 }
            }
    ; V4 U$ @5 R( N    }5 M* T8 z. T) K% L0 D' h! Z! T
        else3 b+ `  a. D$ d3 I6 n' \  `
        {
    $ F' u! J+ M0 c& J  o. N# T  q, Y7 Y        fFoundSize = TRUE;
      t1 L- i# ]5 ]    }</P>3 x; ?: H! q/ n0 P
    <P>    return fFoundSize;
    ' S3 x# s* ^: `3 h- P& i9 ?9 a}</P>. B$ y) i% {: O% R, H# }; C
    <P>; J$ v3 n! F9 S! d9 R' V
    //-----------------------------------------------------------------------------
    , W, c7 _- H3 [// Name:
    ) X: I! e; H9 b, _: w2 y% U// Desc:
    1 {" o! f& U& h) o* U* I//-----------------------------------------------------------------------------! y  ~9 h  X6 Y0 z! d3 j% ^! e
    void CMazeServer::OnSessionLost( DWORD dwReason ); v) x, p& `& {5 \
    {
    , R( G/ D- v" N. u    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );( ]3 P: x( v4 R
    }</P>
    9 Q5 u, N- z) M
    - L5 \# B, h; k( \& y<P>. j3 P6 _0 N) e1 u' K
    //-----------------------------------------------------------------------------: _/ w; d' _' w0 t1 W3 ~  M3 }) }
    // Name:
    ; u# r! o. p; o% P! r// Desc: 9 K" c6 e0 z* X2 K' {5 c
    //-----------------------------------------------------------------------------
    : X$ e0 _6 N& x) D4 `6 i) NPlayerData* CMazeServer::CreatePlayerData()
    , C0 R2 l2 t- i7 `6 V' L0 R  C{7 l0 @" u3 L8 S8 j
        m_PlayerDataListLock.Enter();</P>- a6 k7 P% b( a" J( e/ X
    <P>    // Grab first free player in the list9 h! t  F8 {- I: ~+ A9 }
        PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>
    2 }9 j$ }  I3 N- Y2 Z4 w0 V# _<P>    if( pPlayerData )
    0 U/ {3 q6 Q8 f- d/ v) e    {0 x2 m' n9 b+ Z* U
            LockPlayerData( pPlayerData );</P>; d0 F" E" r4 v6 [; e2 v
    <P>        // Got one, so remove it from the free list
    4 s0 `5 Q% {% D/ i6 o2 v        if( pPlayerData-&gt;pPrevious )
    1 ^; n2 O) D2 m            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;9 i6 A- H( H+ t. X
            if( pPlayerData-&gt;pNext )
      F' p  Y) S7 W+ z* R            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
    + \( C& v0 O) `. C0 @5 \0 F        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>
    ! Q, q' ?' g: F- j<P>        // Add it to the active list" I) U3 r2 n* z0 G0 w5 w2 V
            if( m_pFirstActivePlayerData )
    ; q" O, H, [3 ~* x            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
    1 Q3 o7 [' p. ]$ \        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;3 y1 E5 n2 `  Z( O' _
            pPlayerData-&gt;pPrevious = NULL;$ S2 V( E/ Y; k, ?
            m_pFirstActivePlayerData = pPlayerData;</P>
    ' i& o4 O! B' H<P>        // Update count of players% d4 ^8 U: t' ~4 g1 u  y
            m_dwActivePlayerDataCount++;</P>
    6 Z4 C; N* K; A9 I* J" c9 z<P>        // Generate the ID for this player1 g7 E: z+ X' a& I" K) G
            m_dwPlayerDataUniqueValue++;
    # W6 G. p: K+ h3 L; z' }$ b3 k5 n        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>. s, ?5 C3 b5 P8 U! t" P( D
    <P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
    . Q6 t- W+ r2 ^& w1 o7 P( {        pPlayerData-&gt;NetID = 0;: E. |( G% w3 C& V- L
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>) n0 W* G  ]! U- g$ d
    <P>        // Insert into the "off-map" cell
      ]7 h2 ~3 @" J' k3 k& {, o( W# _        pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;
    ! T$ Q6 T- b: X. a        pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;/ B! e5 G9 I! t+ I& X
            m_OffMapLock.Enter();. }9 K0 z- D3 o0 B% G8 O' H
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;/ o0 X0 c! j$ W
            m_OffMapCell.pFirstPlayerData = pPlayerData;
    . w; [, B3 L- s  c( L  [& |        m_OffMapLock.Leave();</P>
    - h2 A+ T; z% i& N0 Q# p- ~5 ~<P>        // Mark as active* C# K0 H; \2 A9 [$ y! d8 A7 \+ \
            pPlayerData-&gt;bActive = TRUE;</P>+ e* z0 G/ y  A( f3 t0 ?
    <P>        UnlockPlayerData( pPlayerData );
    9 {2 C5 m+ K. e( T# x' s) X    }</P>9 n9 V" I) K0 _" v
    <P>    m_PlayerDataListLock.Leave();</P>
    5 v0 i+ E, T5 ^8 s6 O# n# ~<P>    return pPlayerData;
    ! Z+ F! Y% s5 _! ]}</P>
    ; r+ ]8 L* i8 r- p/ S7 b
    9 E- p/ Z: |9 P- a/ L<P>
    : T7 W5 o5 L3 t- `3 ^//-----------------------------------------------------------------------------
    / y. i2 B' P" O# H; N' K' q// Name: 8 s' g7 c6 ^# F' V0 ^
    // Desc:
    7 i& ^" f5 ]4 _- w4 _) N  D//-----------------------------------------------------------------------------
    3 g. v1 Z( U4 ^" X$ t( C3 l% ovoid CMazeServer:estroyPlayerData( PlayerData* pPlayerData )  X# @. o5 n) L* H7 o
    {
    , K% F2 w4 D0 g  ?5 V5 q    m_PlayerDataListLock.Enter();
    7 s7 o! p  K' _. \  f& L    LockPlayerData( pPlayerData );</P>; v2 M! J7 a) p; D3 x" c3 B. ^
    <P>    // Remove the player from its cell! I$ C5 b* M8 J( M' ]8 t
        RemovePlayerDataFromCell( pPlayerData );</P>
    / y( r$ p$ j* r4 b' Q<P>    // Mark as inactive$ B$ A- T+ E8 p7 w  t! V+ J
        pPlayerData-&gt;bActive = FALSE;</P>( W' O5 @' e. g1 q. l
    <P>    // Remove player from active list
    # X) }# n7 T- x$ B- v8 Z: W9 M    if( pPlayerData-&gt;pPrevious )) [* Y8 m) i% y+ k
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;* `2 e$ v) C9 h& X4 E& ]4 w* x2 [
        if( pPlayerData-&gt;pNext )  U1 t4 ~$ B8 ]. E
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>( ]# I4 m) n" Z1 k2 g, s
    <P>    if( m_pFirstActivePlayerData == pPlayerData )- e: E; t! Z  u8 ]
            m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P># Q+ B* `: |7 o1 B9 Z& |6 u
    <P>    // Add it to the free list
    ! i% j: a9 L2 T! r6 |1 x' z- t' J    if( m_pFirstFreePlayerData )
    8 G, I+ p' ?! w        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
    1 j1 B( N. S( U    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;9 [4 q) l5 }' z! Y: U. H# v+ \+ n1 S
        pPlayerData-&gt;pPrevious = NULL;6 u+ V$ Y/ z$ ~9 a
        m_pFirstFreePlayerData = pPlayerData;</P>4 G3 x  u& o# [
    <P>    // Update count of players
    8 a3 U# R/ l* p9 |    m_dwActivePlayerDataCount--;</P>- c, T+ a( W/ H3 k
    <P>    UnlockPlayerData( pPlayerData );6 w% X0 g: t# R6 p
        m_PlayerDataListLock.Leave();0 T4 p# ]& ]3 D" [# B3 O
    }</P>/ W: m  r/ p1 ]- `
    " W2 F9 G' T1 B( ~% r0 L
    <P>
    ) m' j0 m' r/ ^//-----------------------------------------------------------------------------
    6 w8 H5 m9 B' u" `& E' P// Name: ( w3 L( X  e! |3 r7 X7 \& i( v
    // Desc: 3 m8 }3 j0 S6 a# V. |
    //-----------------------------------------------------------------------------' c& U# h$ F& b9 ?3 L: S( y# u
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )% `- w, A: B. X- x  K% z% K1 u. j
    {
    " V! ?8 G. z# S9 @' n    // Lock the player/ I; S4 p4 ~/ x: S% k5 J; u
        LockPlayerData( pPlayerData );</P>
    0 X& d4 P  N0 Z- O  M3 M<P>    // Lock the cell the player is in9 C' t0 e, ]# |4 J
        ServerCell* pCell;
    4 f5 l8 X, A1 ~    if( pPlayerData-&gt;wCellX == 0xffff )
    ! a! b5 x1 ?" D3 E; T    {4 |' D$ K( e2 ]% B0 L
            m_OffMapLock.Enter();3 X' q0 d: T' k- ^1 T
            pCell = &amp;m_OffMapCell;
    & Y& b; q  z4 Z- f; s    }! R$ }* J4 D# @, G( k& v7 u
        else
    , L5 [- Y) M9 ^# f% D0 W    {
    3 F$ J# T7 l3 G; ?* R3 R& y" D/ Q        LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );1 S  _' c  s4 @, B5 @
            pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
    0 H. |! A0 _0 s' L7 x    }</P>" M7 ]+ F% L! `8 P. d" F8 O
    <P>    // Remove it from the cell4 ?, l, [1 n4 ]" i; W
        PlayerData* pPt = pCell-&gt;pFirstPlayerData;5 v$ I& T/ l$ i
        PlayerData* pPrev = NULL;
    * Q" s& c1 H5 u$ {1 Y    while ( pPt )
    7 n$ s) Q( P! K# i! X% H: |    {, z- Z2 _+ \) J4 G( p- B
            if( pPt == pPlayerData )
    0 I7 k  s5 E+ u( T* `5 k8 F        {
    2 m( t: w8 n0 ^$ T            if( pPrev )' L8 U9 W& Z' g, X, t, g
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;9 j6 ?1 F$ j' {! Z" V5 |
                else
    : h, T  q3 w1 s& k                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>3 x+ H; G) l, q4 T
    <P>            pPlayerData-&gt;pNextInCell = NULL;1 n1 x5 [4 o7 ]" k
                break;. t! I: a9 L% z5 Z# a
            }
    ' q' p5 m0 p- c6 Z        pPrev = pPt;  x8 f: H/ S3 p4 F" I; g2 f  R  `
            pPt = pPt-&gt;pNextInCell;, o! o0 s; t; J$ b
        }</P>
    + ]. U5 v" v7 H2 ?: k. f) e<P>    // Unlock the cell
    ) [8 F& x) n* K" ]$ A    if( pPlayerData-&gt;wCellX == 0xffff )
    1 W* d; |, o$ e. n% a& J, c        m_OffMapLock.Leave();* T4 t" x7 E+ j+ m7 ?1 |) Z
        else( w% Y4 V, t& ~; L6 }; O
            UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>. E6 e1 a2 `! {5 P; A7 \( a
    <P>    // Unlock the player, q' C) e; [! q
        UnlockPlayerData( pPlayerData );
    - |" I$ Q, B" M3 W! P4 p}</P>! z! `+ y) N+ W+ M1 n5 j
    9 F5 Z7 J- n: j
    <P>
    2 x( x8 I0 j( v* J2 e" [//-----------------------------------------------------------------------------
    % \+ ^+ W( P! a1 X0 T// Name:
    4 \& |1 o! Z. f- d1 E" _// Desc: - M. ^% S& z1 j  f) [; Y
    //-----------------------------------------------------------------------------5 M6 m, j' T+ e5 t
    void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
    & H; a* F7 U9 a( V- @; _1 I% r3 e{
    # d/ _' l0 K& x% V! }& m' B    ServerCell* pCell = GetCell( pPlayerData );
    + C6 l' e0 A3 H1 N& |    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
    8 j8 K- D" Q" Z1 S; ]+ m    PlayerData* pPrev = NULL;- X7 x: p0 ^3 \, r- P
        while ( pPt )
    ) ]7 D0 ]$ u* h    {
    0 l1 ], s6 {' o* g; p+ |7 h        if( pPt == pPlayerData )
      V9 ]8 j) C* e) O% k        {/ E1 K) K7 c! O- R$ m: Z( [
                if( pPrev )
    ) b$ Q- t9 F7 R. o+ O! O                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    / t6 A: G- Q) y% ^1 F            else3 t/ X- t7 ]" L  f; c! n- q
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;
    4 G2 m* l: @- ^$ g  s            pPlayerData-&gt;pNextInCell = NULL;& U. P! X4 }& ]' J  g! B
                break;: N7 G! x) d. H- j/ Y# V6 g
            }) o3 t: c1 R, F
            pPrev = pPt;
    ! r* h9 H8 V( W' |5 p- R0 f        pPt = pPt-&gt;pNextInCell;
    9 M, Q% _% `8 |. y3 [+ u    }! ?1 z: {3 g: ]4 H9 l4 F8 W. U
    }</P>) ]' H( h5 `2 y. A6 M3 S  j! q

    ) d6 z8 W' y, X+ q. a) b; n& a<P>
    / [6 N8 n, Y6 z1 r2 ?//-----------------------------------------------------------------------------9 [: x: D4 Z3 O% l$ P9 \' [
    // Name:
    . T! L( S9 o  ?& V, V// Desc: 8 l$ f+ K) t2 \# D5 y
    //-----------------------------------------------------------------------------
    ) |' l/ q5 c2 {5 F; |$ I" Mvoid CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )
    8 f& z/ D5 m, f{
    + ~* U6 J" O5 y3 s4 A  u' n    ServerCell* pCell   = GetCell( pPlayerData );
    # `% C! `7 Z* @( E" w    pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;. Y) q3 M2 J" H0 o+ ~( o
        pCell-&gt;pFirstPlayerData = pPlayerData;
    2 n) x3 s& X! H1 k9 r6 D$ n" S/ ^( o5 |}</P>6 m* J; x% O3 r5 O' ^
    7 j) v! Y1 [6 r! Q) g& C
    <P>
    ' T! q: S# m, [$ `& r- Q0 ]/ y//-----------------------------------------------------------------------------' e! F$ T3 a/ x: ~
    // Name: 1 F1 Z1 d( s: W" O5 X8 K1 \
    // Desc:
    8 v( I# {: _. O. E& J9 S//-----------------------------------------------------------------------------9 N2 e( M$ t- G, v/ q
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )0 Z3 M% ]) y* U8 {$ Q
    {& k8 G) k- [& V! w- O/ f% r# R+ g
        // Grab player for this client and lock it$ J! I1 a8 p0 {( ^; x7 f: ~9 m3 ~9 }
        PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );
    , l4 ^0 g' E0 B1 C2 u! ^$ u    if( pFromPlayer == NULL )6 L4 k- W6 y) D1 Q
        {
    0 A0 Q. B' }7 h/ N# q" n        if( m_dwLogLevel &gt; 1 )
    % F  r% D6 e" A7 G9 W            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );" S; j7 o& A- ]- v
            return;
    - u7 m6 K5 Q2 ~4 T    }</P>, E% \1 ~' M( w% \/ b8 ?! D9 ]7 G
    <P>    LockPlayerData( pFromPlayer );</P>& G& Z+ e/ K! Q  a8 `
    <P>    if( FALSE == pFromPlayer-&gt;bAllow )
    & I. m* M( I: g2 {2 J1 a    {
    . a: u- |, W9 @        if( m_dwLogLevel &gt; 0 )
    8 m: Y& J; \9 }& o4 u7 S4 Y; I/ Q+ z            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
    9 G* Y/ K, C. V( l! v$ f$ ?+ q& b<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );. g! g# ^" K- ~+ _+ a  l
            UnlockPlayerData( pFromPlayer );! J8 u+ E0 A8 q# n/ Q! z
            return;
    : p+ N6 [1 N) o$ t$ |: _) c    }</P>
    2 }- i: [4 z; q- D8 @  Q7 J<P>    // Compute the cell the player should be in now8 F7 N6 Q# l, l5 e0 v* \5 G
        DWORD newcellx = int(pClientPosPack-&gt;fX);+ Y6 ?2 P3 ^* ^# f
        DWORD newcelly = int(pClientPosPack-&gt;fY);" h5 r' Z" e3 k# D, y
        DWORD oldcellx = pFromPlayer-&gt;wCellX;
    . S; }, K$ d2 _: ~' [6 B9 Q  P    DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>
      L8 G9 W& l% b% A: K& V" V<P>    // Have we moved cell?
    / p( F2 Z( ]& r0 `* \$ D# ~4 p    if( newcellx != oldcellx || newcelly != oldcelly )1 h* a; g1 f. H, j, f% ^, R, D
        {
    ! f9 D  y' d; R6 x4 S        // Yes, so lock the pair of cells in question
    - O; l( k; z3 v/ z* @! k% k        LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>, W- X2 s2 |! B" S  m3 l+ o2 f+ R
    <P>        // Remove from old cell and add to new cell/ b$ r5 k& B: z
            UnsafeRemovePlayerDataFromCell( pFromPlayer );  e6 d( t4 w5 w' G1 u& s6 r
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);0 V1 u7 h/ A6 G: Q5 _0 _
            UnsafeAddPlayerDataToCell( pFromPlayer );</P>( D" y7 P) o8 t7 y) E- s2 N
    <P>        // Unlock cells/ F8 {4 T! B2 y& ]2 f* L) u+ n, W
            UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );. {5 {9 A7 e0 R+ E, D+ M% ^
        }</P>
    ! V. k- v1 c, K( H4 A' P<P>    // Update player position
    9 q% A0 d. v+ r# R    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
    : ?0 W0 I% k- ]* j! B    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    : g. {. d& l  r- L% }( ^/ V    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>6 T0 Y. K- j4 `& D' x# k4 m
    <P>    // Allocate space to build the reply packet, and fill in header
    ; E- L4 y8 t$ M' Z! B0 L    DWORD dwAllocSize;+ |- C/ `* R; F% K
        ServerAckPacket* pSvrAckPack = NULL;</P>
    4 ]* m' C6 ^: n& S- e; u  _<P>    // Begin by allocating a buffer sized according to
    % G- K+ K2 e+ S    // the current number of nearby players + 4.  This will give 2 k$ w3 E9 `. l, E9 U* V
        // a little room for more players to come 'near' without resize
    8 M- M$ j8 a' L" z1 [    // the buffer.5 ^6 X4 |, D# ~7 t
        DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>, d5 p. m! R- g( H& X7 |
    <P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    . ~3 V# N2 L) [! H+ \3 v7 |- c    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );0 J9 e' P" A' R! V- H3 q9 Q+ U$ o; g
        if( NULL == pSvrAckPack )+ m& _  O6 V: Y9 R; N# p
        {  e1 }' ?0 J* w% Z0 R# G
            // Out of mem.  Cleanup and return
    & W! u9 [; T  S) ?        UnlockPlayerData( pFromPlayer );
    3 Z! N% x4 V4 D) i: Y4 K, Y        return;      
    & N' x5 s/ k8 |. i* S+ r    }
    8 p& A6 l3 [( M+ |8 P% M    ZeroMemory( pSvrAckPack, dwAllocSize );</P>
    8 H1 _8 O2 j2 t2 s: f0 y<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);
    - _3 T  o2 A. D9 @% ], V! o    pSvrAckPack-&gt;wPlayerStatePacketCount = 0;
    % T' U. j5 ], r* x! F4 M    PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>4 H9 e5 c! O! _5 C6 N0 w6 j
    <P>    // Compute range of cells we're going to scan for players to send
      G: r/ ]9 ^( h( C0 P/ H. B" E    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;3 i0 G0 `. E$ X6 W
        DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
      r- ~# x: y; e3 ]$ l    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;
    # d7 T4 Z. |# |' r! V; W    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>! W9 {5 L1 U# S) p3 X, H7 w
    <P>    // Lock that range of cells* f) D) Y, \8 w0 Q1 Y9 ]
        LockRange( minx, miny, maxx, maxy );</P>
    $ I! V; q4 A- y2 E: ]+ t; C4 A<P>    // Scan through the cells, tagging player data onto the end of% n# f/ h: v$ d! X! \
        // our pSvrAckPacket until we run out of room
    * G& O! x- @2 b8 |; P: S6 r  Q    for( DWORD y = miny; y &lt;= maxy; y++ )# s; L  e& q! M6 }" ^# p& ~, H
        {
      k+ [8 @+ Y) m6 M: |* P        for( DWORD x = minx; x &lt;= maxx; x++ )" R" \; o) i) I
            {  F  o+ t; _% K: u
                PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;
    , J, X3 c, C  p5 A% F1 z% n            while ( pCurPlayerData )6 ^6 X- j% ?0 A$ C* f
                {
    # F3 E+ Z0 n8 ]4 S2 k$ ~9 C' ]                if( pCurPlayerData != pFromPlayer )
    & H% l8 e8 ~4 p                {
    + r- p+ J7 i+ ~' T. f: j- ^                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )( K% G" U& @& v
                        {
    3 B, M- G: |* ?, F                        // Make sure pChunk is where we think it is
    & @- c! W: h" N+ |( G. [                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>
    2 A  P& g/ P: F1 F<P>                        // There are more than just 4 new nearby players, so resize the
      `+ N* ?) d' u8 h                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
    , Q( `6 Q* S; q% U/ k( s9 v                        dwMaxPlayerStatePackets += 16;8 K6 |  g$ M8 [+ q! C" Z# `+ p
                            dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);' F+ v: A) k' C/ ]% S: P: ?
                            ServerAckPacket* pNewSvrAckPack = NULL;9 c' A: W. i/ a
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );; i4 C; @$ E; Q7 ~; p
                            if( NULL == pNewSvrAckPack )
    . v* B. Y6 d* s/ n- @( Y6 b                        {& m2 E. {: E% h% K9 z; V5 u" @
                                // Out of mem.  Cleanup and return
    % n& F. q# o5 ?* H- y                            free( pSvrAckPack );
    ! @& N# J& N# V9 g6 m; I+ }                            UnlockRange( minx, miny, maxx, maxy );7 {0 ~; d; M( q, k9 w
                                UnlockPlayerData( pFromPlayer );# l  e1 A/ S! ]. A
                                return;       5 t' I* k/ i$ L5 L! r  g
                            }</P>
    , ]( a6 [8 l) Z<P>                        pSvrAckPack = pNewSvrAckPack;+ |. |5 f7 Q8 S, v+ O
                            pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>5 z$ j. O& Y: \" b& ]6 f
    <P>                        // Make sure pChunk is still where its supposed to be  D" `  i. P8 @! a- ~' ]- p$ \5 k# i
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );- v+ O+ N& x- e+ u0 S
                        }</P>! {: R3 u+ o2 Y  {, x
    <P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;7 U6 e1 {6 S: y1 L, X( ~1 G! J
                        pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
    : [1 `- f8 s( u- T                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;
    . N" q7 O9 P: J                    pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;+ }3 d# n5 v) p; Q6 x
                        pChunk++;+ Q# ^* B$ q, `. p  ^
                        pSvrAckPack-&gt;wPlayerStatePacketCount++;
    & V3 X. w+ u3 t9 V0 D# z, i                }) i6 H/ s% u' R
                    pCurPlayerData = pCurPlayerData-&gt;pNextInCell;6 Z! N& f( x& \" _3 {
                }
    3 u2 R; u9 z& E/ P. |3 @# V" d        }. ]2 S/ s: s, W3 P% M* F- x
        }</P>; }6 A; \! v4 X  N& G. Y
    <P>    // Update the dwNumNearbyPlayers for this player
    ) g" i: _' g  W* Y' C    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>) O, |. l( D6 N; W( g* n. u. n$ J
    <P>    // Unlock range of cells
    . [9 X4 M& y" k$ h5 P    UnlockRange( minx, miny, maxx, maxy );</P>4 C8 @4 e4 |7 Z) [5 y, v
    <P>    if( m_dwLogLevel &gt; 2 )1 b  r% p0 O- Y& L9 J) ?% s8 q- Z" [
        {
    3 C( M/ a! ^8 q( Y        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );9 F- {6 S9 L0 ~% A: R, W
        }4 c9 V) ?$ O& J$ x! G* _- x! h% Q) C
        else if( m_dwLogLevel == 2 )
    + p) Y- V, F( R! ^% g1 u. [    {3 C7 J, P4 h' M4 y  {
            FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    7 U0 E( p0 L) L$ c, v        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f ), E1 Q% }& g/ K2 Y! b0 }
            {
    " l  c8 Z8 }8 \6 ~8 j            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );6 ^! g' s8 |9 p0 @
                pFromPlayer-&gt;fLastDisplayTime = fTime;  O5 V" n" S' {& J2 i6 m
            }
    6 R$ p3 b6 i( i# P, r- n    }</P>" q+ Z+ H  T1 o! U" o8 O* H% t, a% C! v/ }
    <P>    // Unlock the playerdata
    9 y4 M' h. Z7 R% ?+ K    UnlockPlayerData( pFromPlayer );</P>% n5 f5 q  r/ u. g
    <P>    // Send acknowledgement back to client, including list of nearby players 1 D# C9 B! j! E" C$ U6 a/ I
        DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));
    # f/ X5 J8 r/ P) B
    , l+ N( [2 c$ K    // Pack the buffer with dummy data.& N1 _- f1 l5 j4 a/ y7 g: i
        if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)
    ' D" f) j$ X) T- V7 P$ i+ m    {
    6 `2 @0 s' C  F: l        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];. s4 p. Y& u$ z
            VOID*   pTempBuffer = 0;</P>
    5 `7 e' g. z/ T+ J: J) V<P>        pTempBuffer = malloc(dwBufferSize);
    % \  }* ?8 ~7 F8 b0 G6 t1 v" H        if( NULL == pTempBuffer )3 Q: n( D3 S3 W8 F1 t3 h9 y
            {
    / V0 R: v% |2 b2 f# [0 m            //Out of memory
    + r" Y/ v' H: T  W$ q0 Y* Z. [) v            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );! J* y3 E2 d) V4 ^: y1 y9 \
                free( pSvrAckPack );
    : X6 h# x3 j% j6 J. V            return;
    - ~" Z4 t- @+ ^& `2 I        }</P>
    . T7 H% R; G; s# C+ l/ Z# E<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');6 {1 r$ x% F0 Q. G# G' V) J
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>+ j& E0 k5 `; q) J
    <P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );3 d( O2 X! ~6 _" L8 L/ `
       
    - u4 \  K0 m6 r" a2 D% B$ P        free(pTempBuffer);1 X- W. n9 U7 @2 q
        }   
    + c! d9 c$ l; N( F0 x" M4 w7 i    else
    0 V$ T. b* O8 N% i( P" ^/ W    {, F' {3 Y, y) H6 w
            SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );$ M2 L5 l7 d- k, ]! \
        }</P>( T" B- r' I& D& e1 C7 p
    <P>    free( pSvrAckPack );</P>
    6 G) j& ~3 a% M" ~+ _<P>}</P># U+ j$ w( Z- r# N8 W2 [

      O( }7 k9 t7 @<P>1 n5 q) G3 `$ {# V
    //-----------------------------------------------------------------------------
    : u& [- l5 S. Z- i) e5 J// Name:
    / ^4 ]6 W6 \7 c% h5 [) S" W6 h: p// Desc:
    7 x- K* m$ p; p8 O//-----------------------------------------------------------------------------5 k7 ~( w; ~6 G6 N# q
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )" x$ z6 w; b9 r$ r( j( ^9 }
    {+ c3 D/ }( l( e
        // Grab playerdata for this client and lock it' ]3 x0 B, l- D% r0 Z8 }0 i
        PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );9 I# [, f, i/ S! G7 m% N
        if( pPlayerData == NULL )
    - n3 ^1 u* k5 ]0 Y' R4 v        return;& T* L/ e6 [2 o( M" G0 H
        LockPlayerData( pPlayerData );</P>
      {( F4 K& X+ C/ Q4 }: Y<P>    // Record the version number ; O) p1 o+ U' u- ~+ l2 ~+ J, L
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>0 ?( u7 d% V# }3 J6 e$ o4 c2 L
    <P>    if( m_bLocalLoopback )# f2 V1 p: c* {; \. j# P* j: K
            pPlayerData-&gt;bAllow = TRUE;
    ( V+ [5 a1 r5 v& P* J+ `    else
    - T9 j5 r. N  e- s: h        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>
    * ~& ~' F8 n4 g7 G: Y! ~1 v<P>    if( m_dwLogLevel &gt; 0 )) @4 i* {) E3 i1 [, z* r
            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>
    ( B2 m6 ]1 f: |5 R. U7 c<P>    if( FALSE == pPlayerData-&gt;bAllow )6 B1 s4 r4 M( Q( l! p$ r
        {
    6 E, _$ w; _" X: X        if( m_dwLogLevel &gt; 0 )
    $ I2 C# q7 R( ^7 r6 q( W( p            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>
    - Z8 t. y: S! |, N5 G, q& M<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );8 F. t8 {2 F- ?
            UnlockPlayerData( pPlayerData );
    1 o* ~/ y- Z* O) W. I        return;5 n4 W! k/ L, R3 V% k0 j0 r5 W0 b
        }</P>
    ! \! t4 L5 h9 V2 P<P>    // Unlock the playerdata
    7 i1 l; Y; c% o: F% n1 B    UnlockPlayerData( pPlayerData );</P>
    % I# B# l8 T1 }6 T<P>    // Send acknowledgement to client that the client was either accepted or rejected
    ' D! @5 T' w* }# T    ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );
    ; X1 q5 D9 r+ [7 y    SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
    $ p7 m; C, t* k}</P>% a: s, D8 k- e6 T- i" C
    . ~2 q; y& T# L% j; u+ o% Y
    <P>  x/ x/ ]+ k% ^
    //-----------------------------------------------------------------------------& V" Z4 G$ {. T- w& M2 n
    // Name: 5 T( Q1 K, l2 w- g, }9 B
    // Desc: ( x: u9 a0 L6 ?8 d9 n
    //-----------------------------------------------------------------------------5 {! }/ i0 g& O  o
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )6 y, U# K/ Q8 ^- o( ]& r
    {
    7 q9 h, x& Q4 i1 f    switch( dwClientVersion )9 s/ N1 g2 S: A/ t; t4 ?
        {
    4 p, q3 E, i4 M        case 107: // only v107 is supported+ l4 w4 u$ O& y9 j* C) z/ s7 m
                return TRUE;6 B1 V* H$ v( _
            default:
    / W/ |( y: R& z, e1 M            return FALSE;
    2 p8 m4 X  k7 L. K    }% }$ E5 n) c, T
    }</P>7 t) E$ k- k' m/ k% h/ H6 t

    + ?* x; h3 s0 c! m0 i0 i<P>
    - w9 H5 X& J1 a1 w//-----------------------------------------------------------------------------' H: P6 a. y& b; E" J& g
    // Name:
    # F' w! L4 i+ S+ c0 Y* o// Desc:
    & |+ P7 e$ R; }! n! `1 S4 I//-----------------------------------------------------------------------------8 ]8 \$ f4 `7 X* f
    void CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )) w- x4 c9 T0 q2 B
    {+ O- r& `. N" K' j- U( _9 h/ K+ ~
        if( m_dwLogLevel &gt; 1 )9 B8 _1 y, A+ B2 r9 B4 `# z
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>
    8 R9 f5 b5 h+ i<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );+ W7 a/ h+ Y6 I) Y% B% i
    }</P>& T% x* q6 q; \9 ^; y4 b
    ( ]7 z2 {5 V! B% \! p* ~
    <P>
    5 s8 Z5 k9 P, m5 {' Z% |) `& @//-----------------------------------------------------------------------------' c6 w' J7 H# X- s$ J1 y7 m8 W
    // Name: . @$ Q! N% N1 }5 s9 v
    // Desc: & {, _8 w: V4 J+ L
    //-----------------------------------------------------------------------------, U' H) P  i" E. e1 Z3 l
    DWORD   CMazeServer::IDHash( DWORD id )
    ( b& b% X4 q: m% l1 Y{0 n$ u' G9 f( ^9 S% k2 c4 c+ M
        DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);
    7 e: V8 j1 s% e/ e    return hash;
    ) ?5 T% i) p, D9 \# O}</P>
    % X3 I- K3 y$ \* b, O1 R8 v, r: Z+ @& V& u" q. L$ C, Q. Q2 p
    <P>9 _; R- E0 @( d  U& }3 E$ k7 u
    //-----------------------------------------------------------------------------* s, u5 x9 \/ L; A) k3 j
    // Name:
    & ?! c8 A! g; A" }! r/ U// Desc:
    3 Y' e9 e2 W5 I/ z1 ?3 L9 x//-----------------------------------------------------------------------------
    ! h% W% ?' S! t" gvoid CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )! P/ ]* @3 j) e
    {
    - c+ R; X# d1 {6 N: f    // Hash the ID to a bucket number" [+ v) L; e- I( J/ }
        DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>/ `/ q. p4 V  t$ k
    <P>    // Lock that hash bucket' t# W% w. r. |- T
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    # Z3 A3 \/ U# b0 A7 O    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    % |" h& G* L4 I<P>    // Loop though players in bucket until we find the right one) O$ |+ q* T8 u5 }7 z. j5 F4 ?
        PlayerData* pPt = m_pstIDHashBucket[bucket];, c$ q) j" w* L; q9 E
        PlayerData* pPrev = NULL;1 D# }: @" X# m( c& w4 ]
        while( pPt )
    * }. z% Y' Y# C" w: R: g0 L    {
    ( J6 S  W& P5 M! y, }6 p( D        if( pPt == pPlayerData )5 g) x. c9 ]: B+ G2 t9 ~. f0 y; u
                break;! O4 o, J: `- \
            pPrev = pPt;) \' H7 Q5 _$ N0 O0 X
            pPt = pPt-&gt;pNextInIDHashBucket;
    - {; m+ q1 P& ~% c    }</P>, z+ y7 Y6 A/ {% c
    <P>    if( pPt ), C& }: K+ u. V0 Z
        {2 X6 E  p  ^7 k) Z* O
            if( pPrev ): b! \+ A- \/ H' K& N) B
                pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;
    & y2 @9 A) g' p) B        else
    . ]$ ^3 B& y- {7 q* |( c; x% D            m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
    ) S5 _) E2 U  i  U% F& p! v        pPt-&gt;pNextInIDHashBucket = NULL;( I4 M4 j) k6 {; b7 S- e; V
        }</P>
    + O% z8 f1 ~6 ^5 r/ b0 S6 I<P>    // Unlock the hash bucket7 E/ ^4 I) o) U
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    * f8 A- ~, b1 a8 ?}</P>: g( j0 x5 X: d$ }6 D4 K, Y

    2 a+ e6 B8 G: W<P>
    # J2 B) y" q$ B" e( m% u7 Q* w//-----------------------------------------------------------------------------& m2 d3 L5 ?8 t* D
    // Name:
    : p7 Z( s1 i6 ]0 i  q1 p// Desc:
    ) N2 @3 P- d1 J- q5 h* w% K//-----------------------------------------------------------------------------; k- \0 d: o9 }# C5 e% D/ a
    void CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
    * q# h' s$ h  `$ M- u2 K1 @{
    , F7 Z& s: _* X5 k$ N0 |    // Make sure this player isn't added twice to the m_pstIDHashBucket[]
    6 F) ^7 C) ^8 G. T5 n( W  b, D    // otherwise there will be a circular reference& o0 B0 R& h8 ~/ r; m
        PlayerData* pSearch = GetPlayerDataForID( id );+ S6 A6 s! a8 }% o& H
        if( pSearch != NULL )4 k! W7 l& F7 |* |3 R
            return;</P>
    - O9 C/ w2 Q1 e$ L/ x' P) Q# f<P>    // Hash the ID to a bucket number
    6 {. G/ U; Y! Z) s9 C; v    DWORD   bucket = IDHash( id );</P>9 w7 h+ ]9 y0 F) K8 I/ w$ A; D
    <P>    // Lock that hash bucket9 |1 F; l* k: C) o& H
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    4 j* C, r4 P' c; u    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>. p+ x  e0 R4 `% j/ }
    <P>    // Add player onto hash bucket chain% \- e2 R7 m, `
        pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];
    * I* z; j/ U7 m! S    m_pstIDHashBucket[bucket] = pPlayerData;</P>
    * s& d+ B$ b: C+ r) l* K3 X9 |<P>    // Store net id in player
    ) d# J* V! P' \6 H5 z3 c" [% U    pPlayerData-&gt;NetID = id;</P>/ l/ h  k/ W6 d7 a. Y( z
    <P>    // Unlock the hash bucket
    % P/ c- K( Q7 t$ L    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    4 d7 w3 E0 l& m3 \3 H: B}</P>4 J- B2 L" v& y
    3 q8 Z3 p; s5 R/ N/ U
    <P>
    6 Q) q# @! F3 R, {# w' ^$ o' _2 E//-----------------------------------------------------------------------------: `+ i+ n$ t# q5 ]0 e  d+ r- K
    // Name:
    3 Q2 x, M& K3 l& C; S// Desc:
    ' P5 y  E+ ^1 O4 i% @( K$ Z6 W& @5 Y//-----------------------------------------------------------------------------
    ( @0 c, z  R- ~, H7 y; j$ q9 kPlayerData* CMazeServer::GetPlayerDataForID( DWORD id )5 h/ s. h& U3 \! J5 w
    {) u+ U* J/ `3 T8 ?" M) X, T
        // Hash the ID to a bucket number  p9 P; O! F8 F" @% f% S
        DWORD   bucket = IDHash( id );</P>1 q" w0 B: L! _) x4 L# I' r. [
    <P>    // Lock that hash bucket
    : Q( @3 `* Z* b1 S2 n2 v    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;7 r( q6 ]  J" J. l% ]8 G( l
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>7 k7 N1 O6 `. P% m
    <P>    // Loop though players in bucket until we find the right one
    8 o6 \/ ?1 ]7 w4 H6 D' p4 l    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    / }; e- _9 o1 r: G, {  h! {    while ( pPlayerData )
    9 n2 ]& z6 D$ n4 ?3 V    {
      P+ E, c( U, y5 f) f" ^        if( pPlayerData-&gt;NetID == id )5 T1 f$ k0 C5 {; J, \
                break;' S' k+ A2 P/ _1 {
            pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    7 A& y# c/ r( A    }</P>1 L& W) w/ W+ y$ @: k7 U! v, E$ l
    <P>    // Unlock the hash bucket
    7 {% D1 Y* _6 o# S0 k    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>' h1 r8 P% y/ @4 ~) u  p! ?3 ?* u& |
    <P>    // Return the player we found (will be NULL if we couldn't find it)
    7 X, Q, f) U+ y( i0 P6 b. w    return pPlayerData;
      U$ m: C- f4 V+ _( E2 P$ Z7 g! i/ ]}</P>& }. j" z) M' N0 e1 Y
    ' u) h" }" [9 G- ^
    <P>8 G4 w* }$ v% n
    //-----------------------------------------------------------------------------
    - V% s* F7 G5 M- Y3 k+ V4 L6 Z// Name:
    9 Q' P; r: I% R) _/ V% L- U9 l$ ^( I! H// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner
    , t# w3 a6 k: ^4 j//-----------------------------------------------------------------------------
    ) L. s  ?  a2 P3 U' Dvoid CMazeServer:isplayNextConnectionInfo()
    0 n! C  t' v  n. u{' l2 q1 E, V' l# n4 S
        if( m_pNet )- @1 `5 o3 j6 ~; T
        {5 b& X/ @! G9 t" O
            // Find the player that was displayed the longest time ago, and display it./ N! L' |2 W  G: a) e/ e3 b! |
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );0 @6 Q. W) U2 T, ]* U( z
            PlayerData* pOldestPlayerData = NULL;+ Z( F6 p+ _" o9 f1 ]
            FLOAT fOldestTime = 0.0f;</P>% i4 a* ]0 H* r5 n7 x
    <P>        m_PlayerDataListLock.Enter();</P>: w6 u; n6 ~  Q4 c  t1 k1 X2 C$ Q/ h7 \+ _
    <P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
    / E% h) l. y; U- @6 t4 x        while ( pPlayerData )! Z/ u; r/ L; @% P
            {, N+ T1 E- @+ ~. V. H9 ]$ @
                if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
    # B6 M0 M! ?3 m! u+ v            {
      T1 X5 z; w  n1 S                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;" X+ N& N2 Q0 `3 n( M" Z0 \. `. K2 y
                    pOldestPlayerData = pPlayerData;
    7 ]3 A; b% G/ k* x            }</P>3 p; z4 D3 K. q' \% A" j
    <P>            pPlayerData = pPlayerData-&gt;pNext;" f; N3 ~) W+ v2 G, c
            }</P>7 r/ z6 v+ v# D9 s& _
    <P>        // Display the player with the oldest CI field, and update its CI field.; B! s) {0 @/ s8 s' c, a
            if( pOldestPlayerData )
    ; U" n! W/ W0 h4 l* Q3 O        {, [, Z1 M) I2 R  e* g, J  g+ N
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );8 |6 {, X# i) H# w7 y% K0 }+ `
                DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
    % L+ Z8 _* D6 B% Y/ L7 ~            pOldestPlayerData-&gt;fLastCITime = fCurTime;
    ' m, ]6 K4 A- ^. E/ t1 j3 ~: n        }! D, r5 g- o1 q7 G3 Z0 |. h
            else. J7 m4 q1 u  k  `8 |/ p
            {
    - S9 Z$ O. A  y) l% V  V            ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    7 e( f' f& ?5 t8 x9 r        }</P>' F3 C% _. E' D  W; r
    <P>        m_PlayerDataListLock.Leave();
    & h0 T/ Z9 E  U    }
    8 Y; ?& a3 b$ y. h}</P>
    5 k  G" A9 l1 a% e* e
    . F4 b1 N7 R& N& o<P>8 B9 O4 }1 n: c2 `2 q* c4 ~
    //-----------------------------------------------------------------------------
      v. q5 ^4 J% ?& U# l// Name:
    3 P0 p( v% A2 Z# P" t5 M$ V$ p// Desc:
    : c* ^- k  G+ U6 E! ]//-----------------------------------------------------------------------------0 F% P1 U# @5 g$ |
    void CMazeServer:rintStats()
    % I! P8 J) n& Z' J{
    : {7 S4 q5 a& g8 X7 I    ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"), ! z6 L& m, g$ f* b5 k
                                        m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );
    : Z9 L( ?* B6 D5 O2 d( H    ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),9 v$ N. T3 s; X  ^! |0 H( a9 H
                                        m_fAvgThreadTime, m_fMaxThreadTime );: `; L" p9 W) z/ r5 l) @  }
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
    1 B0 v  ^( @# B& P5 `: s$ C    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );8 [0 R( D3 N, k5 d6 E
    }</P>
    * {; I! m: M2 w, l) [9 V0 U# p% @: s. \0 r- c( L% y- c
    <P>; u$ \0 Y& t3 m. w) D6 @6 j# C
    //-----------------------------------------------------------------------------: }& k1 m( n  n  E$ {* H
    // Name: . Z; ~0 D, A' x1 l- [
    // Desc: . `9 M9 D7 U. |
    //-----------------------------------------------------------------------------
    - K& [1 i& a* J% C3 pvoid CMazeServer:isplayConnectionInfo( DWORD dwID )' m( w5 U7 a3 @- s/ c
    {) z# Y: w: J/ B" |, j0 q7 J" m
        TCHAR strInfo[5000];) Q. p) N* i1 J2 C/ F* @6 P, U1 X
        TCHAR* strEndOfLine;
    ! G4 L5 @6 ?$ |* T4 B1 ]    TCHAR* strStartOfLine;</P>
    8 D7 J1 b* N7 _1 ^1 |" P<P>    // Query the IOutboudNet for info about the connection to this user
    0 ^$ A3 [( R7 B7 [7 p    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>
    2 P6 q, ~% E  d' y<P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );
    ' N0 Z) s. ]5 {, t    ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    $ P# W& l9 Q# h<P>    // Display each line seperately
    6 U7 _" }2 \0 s. y9 ?, o    strStartOfLine = strInfo;: J/ C" z" |* c0 S; @  G
        while( TRUE )
    8 g) g  ?; Q. u- y/ m    {$ R6 i! e1 T( F; G1 N5 a5 Q
            strEndOfLine = _tcschr( strStartOfLine, '\n' );
    2 E, I; t/ Y! B. ^# T% e* t        if( strEndOfLine == NULL )3 s/ K  h6 ]9 E. D
                break;</P>
    . I; n: P- E/ L- x<P>        *strEndOfLine = 0;
    , p5 ]/ w. P( s# {  N- r7 ^        ConsolePrintf( SLINE_LOG, strStartOfLine );0 u3 m1 ^% [! {
            strStartOfLine = strEndOfLine + 1;
    , S; _1 B. ?: J    }' L4 H. ]1 J; ^+ E2 e+ c/ s
    }</P>6 P' s7 t1 X2 k8 U
    0 i% b8 g% b) Q% I6 e, h
    <P>( j$ T: K6 O1 O
    //-----------------------------------------------------------------------------
    % L/ _, a) |) `// Name:
    $ z4 c# ^4 ?+ m8 t  {# Y( r// Desc:
    0 q8 |  L  w" R* T  d. Q4 b( G//-----------------------------------------------------------------------------
    0 l& v1 f3 Y0 j, G  J$ }) }HRESULT CMazeServer::SendPacket( DWORD to, void* pData, 5 a: ~6 E0 ~7 n5 Z
                                     DWORD size, BOOL reliable, DWORD dwTimeout )
    9 M9 f3 p& |0 O! b9 c{8 q# ^; _1 H. ^. r. s3 O7 d: t* ?
        // Chance of forcing any packet to be delivered reliably
    ; O& W1 Z- N3 m/ o4 y! M    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )
    1 b& p3 H; X6 _! O( z' {8 ?        reliable = TRUE;</P>( f0 o# z2 m8 o3 }3 p( y8 N1 g$ k
    <P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    , k- J% b% w: U( p; |1 H}</P>
    * I, B% B6 L: M. B, H7 \# G2 j3 A1 A7 ]; T9 s. q
    <P>
    3 A, L- H- @' P, l+ Q& [//-----------------------------------------------------------------------------7 @0 j* O9 j! o. h
    // Name: ) U- ]. x! U+ `4 X0 c" W& J
    // Desc:
    ' S: W# E  D4 g/ x8 b//-----------------------------------------------------------------------------
    5 y5 M, ~2 f; w$ N) Tvoid CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )9 ]0 T& n2 `& |) W% h0 u
    {
    3 Y  J4 N9 e  j, n  T& ?    // If we're up and running, then send this new information to all clients
    - ?; Y* j) m  L4 `# K8 d8 g3 R    if( m_pNet )
    6 w! R! Q- H$ `6 y7 b0 H    {# p+ b$ E( C0 K
            //Use the AllPlayers ID
    $ Y" o- K& @8 G! q" z        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );8 V1 r& ^  B3 Y8 U
        }
    + q, B. |# Y- H" U$ C8 G( T}</P>: U- J4 L& K. X" f/ O7 m6 o+ `2 j/ ]1 w

    ) f- j( H& ?1 W1 J<P>
    - I. q* c6 @5 h3 D//-----------------------------------------------------------------------------
    , j* `+ V: U5 q8 R5 F0 J$ H6 t// Name: ! ]" s) x9 B* P
    // Desc:
    * H+ Y9 z- W# l5 ~, M//-----------------------------------------------------------------------------
    & E: d' Z1 ]9 F) b+ ^6 g6 M5 l1 \void CMazeServer::SetClientReliableRate( DWORD percent )
    1 l" r- x/ m& R( c{  D  T* S: W6 E
        // Update client config, and build packet containing that data" W/ D% f+ U( D0 ?6 N* v
        m_ClientNetConfigLock.Enter();
    1 e0 A+ c6 I7 W+ Z; S    m_ClientNetConfig.ubReliableRate = BYTE(percent);
    ! M9 C" [: W; H+ U  L9 E    ServerConfigPacket packet( m_ClientNetConfig );5 c" u6 U% h  ]) `. x
        m_ClientNetConfigLock.Leave();</P>
    4 d, o3 f6 e! z% j. d. f<P>    SendConfigPacketToAll( &amp;packet );: b7 ?  h0 M$ L) r1 m
    }</P>; {9 r" q7 G6 q
    ( i( Q- d8 r, V! ~( {# m3 [2 U4 x
    <P>
    ' O& g! [- f  b//-----------------------------------------------------------------------------3 C8 z  Y9 C6 D" P
    // Name:
    6 A7 F& J7 I3 x1 d% n// Desc: - m# D  x) I* J5 O0 A! p8 O
    //-----------------------------------------------------------------------------
    7 [7 C/ i5 N4 t; c  ivoid CMazeServer::SetClientUpdateRate( DWORD rate )& C, k; z7 m1 ?& Z+ e+ d  r
    {! `7 J) n, L0 t5 r7 R2 c4 m
        // Update client config, and build packet containing that data
    5 ]' I9 A9 j5 _$ L+ `( F6 C. @, @    m_ClientNetConfigLock.Enter();! S% e' }( ~% _: t; F% A% c
        m_ClientNetConfig.wUpdateRate = WORD(rate);
    . y9 H; o" f+ H6 F    ServerConfigPacket  packet( m_ClientNetConfig );
    . }3 K$ D* c: Q+ M1 Z9 J8 X    m_ClientNetConfigLock.Leave();</P>9 o+ Z1 L$ {2 E$ X) q7 f) d0 o
    <P>    SendConfigPacketToAll( &amp;packet );
    8 x% Y$ }8 E9 i: M+ m. T6 L: L}</P>1 G/ N6 t8 O, N
    8 n) x2 e9 F8 N! S" O
    <P>
    & n! ?, D3 C* p//-----------------------------------------------------------------------------7 s3 c7 C5 ]) m# _
    // Name:
    4 C# P  C* X  Q* {# u# u5 N// Desc: : E/ t2 \# F3 Q, m' P) \3 B, M* R
    //-----------------------------------------------------------------------------2 T; c1 ~6 ^! Q: K% F5 `9 G1 u, I
    void CMazeServer::SetClientTimeout( DWORD timeout )6 Q, {! e8 u6 o3 k
    {- L2 Z+ p  ?3 l8 f& s
        // Update client config, and build packet containing that data
    ( w4 G% B$ h2 ]. Z* F6 K! o    m_ClientNetConfigLock.Enter();
    9 e; \/ n) c& |6 B# Z    m_ClientNetConfig.wTimeout = WORD(timeout);
    ) G! v6 M8 f4 V0 T4 a1 d; a    ServerConfigPacket  packet( m_ClientNetConfig );
    ! N$ p+ I! G& J% Q    m_ClientNetConfigLock.Leave();</P>
    0 x% C9 n: y, R) X( _  \( Q<P>    SendConfigPacketToAll( &amp;packet );
    ( u9 R/ q( }, }8 L}</P>
    ! Q) l% `. M1 W2 t) \: j* n+ J1 N6 p
    <P>
    7 u5 Y$ t; D( K" @% |//-----------------------------------------------------------------------------
    2 V; J. p1 v. y) B) R: i1 t# I// Name:
    1 ?1 z( {2 U9 n0 Q- r; d// Desc:   I+ e7 T" D4 ]# A" N- F
    //-----------------------------------------------------------------------------
    % ~" A) i8 p  ]void CMazeServer::SetClientPackSize( DWORD size )* T4 {( K/ c3 p5 B' l# R
    {6 B6 `$ q( \2 |0 _" o- T
        // Update client config, and build packet containing that data
      W5 n  |# z# e1 p1 h6 J' K    m_ClientNetConfigLock.Enter();
    5 B* h" Y  E, }* f1 f$ ]) b    6 X; T% o1 p% V# l. m3 |- g
        m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.
      W% C2 X* C8 n: Q' K/ X8 _! f2 ?    if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)     C2 O" x. A: s# x- t6 D
            m_ClientNetConfig.ubClientPackIndex = 0;</P>( _9 u) F6 n4 H* l! N
    <P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);1 e5 v' Z8 S$ C9 i2 a& b
        ServerConfigPacket packet( m_ClientNetConfig );5 U% t- }, h, g! C% `6 s6 }6 c
        m_ClientNetConfigLock.Leave();</P>- K) o3 _& o; I/ m
    <P>    SendConfigPacketToAll( &amp;packet );" j8 \1 |5 {% v. ~
    }</P>/ [2 U) A7 D9 L. _# p- `

    1 B" _& h  ^% ^( @<P>
    $ b  x4 b, O( P0 E5 h//-----------------------------------------------------------------------------
    $ h" X1 ]2 l5 N  q- c// Name: + R  X  k: P1 J+ f9 M  }- n
    // Desc: * G6 a  @& o9 {
    //-----------------------------------------------------------------------------
    & ~$ w6 t+ Y& w8 e0 P- z/ uvoid CMazeServer::SetServerPackSize( DWORD size )4 I$ [! t. w( Q
    {
    5 W  A& d* w2 _9 l* `    // Update client config, and build packet containing that data/ i* Y$ E2 m& t% W2 v
        m_ClientNetConfigLock.Enter();3 K' Z9 ], V$ ?' I6 N
        8 M0 p8 Q5 `7 s+ s; Q
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array./ w' u( P4 L# K# B: _
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   
    " V2 T2 G& i; @$ f. e        m_ClientNetConfig.ubServerPackIndex = 0;</P>
    % z* ?: _; G+ _- h* l<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);) X! h& q( m# S; E" b
        ServerConfigPacket packet( m_ClientNetConfig );2 F. K  C( Y) S* S# l8 V: O" `: S
        m_ClientNetConfigLock.Leave();</P>
    # ~; C3 P; Z2 Q<P>    SendConfigPacketToAll( &amp;packet );
    " {9 ?) n4 @9 m9 t( C* Q8 V5 \( \}</P>
    0 r+ ]  t9 h7 D6 t<P>
    - u! e' c; e9 d! q( B//-----------------------------------------------------------------------------
    7 B9 T, W8 k3 [* ]- q// Name: ) N3 \9 s" r! x' P) }
    // Desc:
    & x- Y/ d% W. X* b# i  A7 Y/ x//-----------------------------------------------------------------------------6 l# L4 g, e% }' ?( f
    void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
    : w! I! h4 g, w! E4 X2 e: d7 J& ]{
      s* ^* k  ^* V: n7 G% l    // Update client config, and build packet containing that data8 `5 P& N4 n$ V! o6 R4 {
        m_ClientNetConfigLock.Enter();" f9 l; n$ s3 w: s$ X
       
    * P5 _& y$ j1 q% d    m_ClientNetConfig.dwThreadWait = dwThreadWait;
      c8 W3 B+ J0 y1 f& j2 A) Q    ServerConfigPacket packet( m_ClientNetConfig );
    5 s# z5 j& o% H9 i    m_ClientNetConfigLock.Leave();</P>, x0 s1 L+ M/ r" s9 O# k
    <P>    SendConfigPacketToAll( &amp;packet );4 P; V$ e7 \& e- I
    }</P></DIV>
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-8-23 06:00 , Processed in 0.507902 second(s), 51 queries .

    回顶部