QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4182|回复: 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>
    & `1 s2 R: L$ d2 f5 A, P<>// File: mazeserver.cpp
    , J, k$ t" }+ I2 M2 ]//2 [$ w6 h' w" e9 M# l8 v/ \
    // Desc: see main.cpp, ?9 K  A6 G6 }* [$ T
    /// I7 s$ K4 M) z' Y& Y- h0 B) H
    // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.$ y3 c  @; {* k
    //-----------------------------------------------------------------------------$ Z- k  Q& K3 R6 T) I+ x
    #define STRICT
    ! y3 e; m5 M. f7 f% _! V#define D3D_OVERLOADS
    4 K# `* P0 G1 W8 Z% H' T+ {#include &lt;windows.h&gt;
    . V! s; j7 k0 J4 O) s8 u#include &lt;d3dx.h&gt;7 K6 C5 c, o) o( t1 T; O( P: Z3 C
    #include &lt;stdio.h&gt;
    * Z) J4 A5 c( R#include &lt;math.h&gt;
    - w' a- `7 X* x& i, y  ^6 F5 s#include &lt;mmsystem.h&gt;: G3 r0 o8 Y6 U1 O2 \, |
    #include &lt;dplay8.h&gt;
    ) J8 k+ ?/ r; `: {7 Z* u6 Y& ^#include &lt;dpaddr.h&gt;6 }, a5 w8 P! L9 f5 y# V+ l3 ?
    #include &lt;dxerr8.h&gt;# N" e. {+ U6 }) P4 Q
    #include "DXUtil.h": Z8 R( d6 Q9 j+ u$ ~& k
    #include "MazeServer.h". d" L# U( `0 R( I
    #include "ackets.h": }; q" a  L% E7 D( [# a' p
    #include "Maze.h"
    / ]* n0 L1 t2 q) c; h( x8 H7 E#include &lt;malloc.h&gt;
    5 w  @" q; T+ n$ w6 N. Y#include &lt;tchar.h&gt;</P>
    9 ^" i6 p% e" }( i
    / O9 h" M- D3 N5 L<>//-----------------------------------------------------------------------------
    . {. T3 J) j9 l- t6 E// Name:
    ' V# h( F) p# A  R: f// Desc: ; ^' K* Q7 i% E2 u/ c/ U# q
    //-----------------------------------------------------------------------------7 k0 v4 o3 I+ j' b9 K
    CMazeServer::CMazeServer()
    8 J( k0 ?4 a' E( o" d% {( Q+ b{
    % z& L/ V. x" _, O, \" y( \0 m    m_dwPlayerCount         = 0;
    : T% S; t8 T7 f% Q7 L1 T! s2 m4 H' z   
    ) }7 O: e2 H" N5 Q9 @$ K    m_wActiveThreadCount   = 0;6 [6 q( Q2 E* T2 L2 W
        m_wMaxThreadCount      = 0;
    0 _: ]4 L1 L3 e% J! h    m_fAvgThreadCount      = 0;  P8 {% d3 N$ V# K  r  Z* L6 V
        m_fAvgThreadTime       = 0;$ t1 u8 q; d" o+ Q
        m_fMaxThreadTime       = 0;</P>
    $ k4 {( c) A! m<>    m_dwServerReliableRate  = 15;, R$ F! o1 R3 @. h9 o
        m_dwServerTimeout       = 150;
    % n7 }" c0 p6 I6 v7 Z. s    m_dwLogLevel            = 2;! h1 p9 u2 R+ R, x- \' Q" H! ]9 v
        m_pMaze                 = NULL;</P>
    / a3 @2 _3 w; n+ R/ b1 B; |. \<>    m_ClientNetConfig.ubReliableRate = 15;
    & u1 F( n! @5 l/ x$ N6 ^    m_ClientNetConfig.wUpdateRate    = 150;
    & B- j1 ?1 l3 U5 J& W1 X0 s    m_ClientNetConfig.wTimeout       = 150;</P># U# p. l0 }/ E: c
    <>    m_ClientNetConfig.dwThreadWait = 0;</P>
    " L; z# a  `6 }1 x% k0 H<>    m_ClientNetConfig.ubClientPackIndex = 0;
    % Z0 J$ e$ ^, ]9 w! {  O& j    m_ClientNetConfig.ubServerPackIndex = 0;
    7 [; ~+ W% q, c    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)
    ' r% o6 i3 J1 M5 @1 B- K' C4 }    {0 ]2 Q# p3 J+ [; M& a2 M
            m_ClientNetConfig.wClientPackSizeArray[x] = 0;2 \6 N+ ], a! A1 T6 g; M9 D9 }' ^( G
            m_ClientNetConfig.wServerPackSizeArray[x] = 0;. k4 V! ~* r6 n5 M/ P1 f
        }8 I$ G  l9 w9 g! Y
    }</P>6 o* f2 L% K5 W. [

    $ ~) i4 ~3 ^$ Y* h( u) R7 E$ ^<>
    " A2 x' |: A( k: e//-----------------------------------------------------------------------------/ u' d! c. b5 F1 e- m
    // Name:
    . G) l( D0 p8 X) R5 X' G// Desc:
    7 ~# K6 g) ?% ]7 H- f//-----------------------------------------------------------------------------
    * L: }3 m. M, H: t+ q8 FHRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )) J; e: j0 {/ g" s( R
    {
    0 C! c, z7 E8 q3 Z( r    m_bLocalLoopback = bLocalLoopback;
    # U8 a* H0 I: H* C    m_pMaze = pMaze;3 I8 F5 G1 `% n* T
        if( m_pMaze == NULL )
    # c- s" Y# Z4 O6 P5 K, n1 o4 A        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
    % q1 B; r9 i7 Y' Y1 n6 ^/ ]) U<>    // Grab height and width of maze1 h' t' y! l& }% d  Y
        m_dwWidth = m_pMaze-&gt;GetWidth();( @  I+ u+ s- T7 x/ C. R4 ~
        m_dwHeight = m_pMaze-&gt;GetHeight();</P>
    4 O, \' t& P! k" B; D* }<>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;) R* A) O& M8 @& X+ N' ^  y; J
        m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
    . x6 T0 f0 v" s. m6 x( X' S" j<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.
    ( m' Y! I6 J8 G2 i! z7 S2 [; ?& s    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    1 L$ k+ z- v) g# T5 o4 ?        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );; v, v$ O3 R9 M, x6 V
        if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )
    : _! n& G: M: n0 _        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>2 c, t; W! o5 a  Y4 E
    <>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;
    1 p: z6 ^; Z. x    m_dwMazeXShift = 0;
    7 R6 ?+ L/ x5 m    while ( (scale &gt;&gt;= 1) )
    ( l5 b* U3 T; o3 P* T7 r; P3 U% `        m_dwMazeXShift++;</P>( w+ x- q' P& f- J; S
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;
    7 \( c/ \7 z0 C: _3 y    m_dwMazeYShift = 0;* [7 N# E  [. i6 O
        while ( (scale &gt;&gt;= 1) )
    8 v2 G) V' ]- k! B7 I        m_dwMazeYShift++;</P>: C4 Z7 p$ ~2 r
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    & B. ~' g6 y* r3 ~- Z, x        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )8 A1 B+ H4 V* M( S6 r
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>
    5 _' z3 Q# \! M( l& L' |1 L" D<>    // Initialise the player list
    . D7 W6 R4 o6 F& W' ^" ^    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );  d/ |7 L& w+ k4 L
        m_pFirstActivePlayerData = NULL;
    . [% b9 p. M& s# f, F9 p" b; J- }    m_pFirstFreePlayerData = m_PlayerDatas;4 e3 z% M$ y! y* Z2 \
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ ). w, T% P& ^* I
        {
    * E; S% u$ c; h0 b        m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];5 @( Q# G. y* H
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];) p1 g% o0 @8 y
        }</P>8 b/ ^+ x2 I5 S& j9 [* Z! n. D, `
    <>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
    3 Y+ |: B2 d/ r; V' {3 g0 H    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];
    3 }1 n9 r& d" k, d( n& b    m_dwActivePlayerDataCount = 0;, J- E  }& x/ o
        m_dwPlayerDataUniqueValue = 0;</P>
    & T) r, Z9 D9 {6 K0 l) l$ }<>    // Initialise the cells
    2 n7 @* a: r9 }* S    ZeroMemory( m_Cells, sizeof(m_Cells) );
    & W" }4 d; ?# r' a  o  |- ?3 ]. H    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>7 L9 M; {5 j$ B: ?( N; D: B! z
    <>    return S_OK;
    - `/ w, _! I+ P) K4 V& k1 A}</P>: b6 K4 G7 X7 O4 U0 V4 F! Y
    0 s+ w6 T: l4 h; j3 |  s
    <>
    2 j4 [% B6 Y% l' X% k//-----------------------------------------------------------------------------
    0 j5 I8 p! Y* C  A5 z// Name: ' h) Q0 D* u& B
    // Desc: * t2 H' J$ O7 }  g; |
    //-----------------------------------------------------------------------------! M2 l& E7 C2 K' T- q& z6 \. l
    void CMazeServer::Shutdown()
    / x/ B3 G; M+ G# R{
    6 Z, H% M* K, U& _+ [% a$ t# e' n}</P>9 B* L" {, b' `+ G

    ( j" T/ a* y1 ]1 s. E0 G% j<>
    " a2 e0 U- w" v8 D//-----------------------------------------------------------------------------
    9 a) m+ C! l) Z% \4 y& s! U8 d// Name:
    9 b! r9 S+ `& ~& k* o, U: d" U3 b3 a; e// Desc:
    $ _( g+ j5 D2 r5 o* r+ J) G! h7 X//-----------------------------------------------------------------------------6 j! |8 o  h: o, w9 E0 T
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )4 Z9 o, Z# G7 m+ M9 j! g
    {& y6 I* E6 m/ T& r" F
        m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,2 i4 j1 V. F7 j' t+ j
                              x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    3 E! E# X/ ^7 H- d}</P>
    , k0 U3 c2 b# e2 k* R5 [4 b9 S6 L/ M7 K% C
    <>
    0 j4 k1 i5 u. B- d//-----------------------------------------------------------------------------' y* f' W" Y8 r7 h) y5 E( b5 W
    // Name: ! R9 K% f5 u8 l& R" l# C: e
    // Desc: ; H1 K5 r5 ~* c$ O/ i
    //-----------------------------------------------------------------------------
    . f, j; P6 N3 u  l$ H# \! U9 f3 n2 evoid CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    ; \% E3 t" g4 ?4 X7 i{
    $ Q, F' N+ k) h* h1 [    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    / X6 I3 s3 U0 L3 d3 t                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );3 Q3 k- ]  A$ @$ N2 J' N( \: w
    }</P>! d% C$ m1 _- ?

      [0 p' B5 H. \/ Y+ G<>: S4 I* O) Y/ B# n9 P
    //-----------------------------------------------------------------------------
    3 B: o! P8 s9 T* `: |1 o// Name:   m, b. M% X- V
    // Desc: 9 u. B, y: @2 Q8 u( o4 z/ v
    //-----------------------------------------------------------------------------
    1 `% K0 g' a1 Q/ f  Ovoid CMazeServer:ockCell( DWORD x, DWORD y )
    4 v% H0 b$ f- l3 f( T# z3 e+ p2 g{
    ' s4 f. a3 r9 s. z1 }3 T$ ?, B  Z    if( x == 0xffff )
      r- p, J: Q( G3 \) y, Y        m_OffMapLock.Enter();4 H* I3 M. }+ E6 E7 V
        else
    7 `5 s. ^9 M4 p4 A$ ]+ j3 H        m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);" f: c& U+ x% P8 X9 Y6 T
    }</P>& Q2 R1 H2 }; g( j

    ' q6 ]+ x; K4 }<>
    # g. X& r* P$ c  r//-----------------------------------------------------------------------------1 I! Q8 y* R4 W1 h2 A. r: G$ r
    // Name: . S( w+ a  Y1 y& V
    // Desc: ! T/ w. G0 N5 [
    //-----------------------------------------------------------------------------2 X3 Q+ S+ r) ]5 R) n
    void CMazeServer::UnlockCell( DWORD x, DWORD y )8 p4 _* J1 r% f- H" f
    {
    ) N4 Y, }% E2 W$ Z; I9 o    if( x == 0xffff )" ?2 R; D2 p; M$ ]* {) y
            m_OffMapLock.Leave();% A/ I8 E( K5 I$ H" `, [1 @' p1 L
        else( i( P; D! V3 z3 n
            m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    ( L( g: a2 }0 _; ~}</P>
    0 D* }6 S0 T  V6 I/ R+ n8 S# `, [6 s  [' E
    <>* ?, [8 N2 i  _2 B1 @
    //-----------------------------------------------------------------------------% u5 d, M( h8 `- r/ c$ e& q
    // Name: % W& F; l% X, U
    // Desc: 7 ]* a: P1 W  ~( w6 _0 N) Y
    //-----------------------------------------------------------------------------/ `/ l3 k5 K( W
    void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    % w$ j, [: L0 H6 w5 K! r{
    ( u$ X7 f4 n& u* t    if( x1 == x2 &amp;&amp; y1 == y2 )
    6 I/ \6 E$ W* m7 r    {
      D( T: g& p4 V$ `        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )& ^$ d5 N& d# z" G* J2 Z3 r
                LockCell( x1, y1 );
    9 E- Z' E" w1 s# `        else. s/ g0 {, {, G. Q2 ^
                m_OffMapLock.Enter();</P>
    9 Y4 U% [4 t  _" K6 x, G3 f<>        return;
    7 U% g( B) }+ q# U0 X' h% S" N    }</P>
    $ B" u- u. Z8 Z<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;! ?5 r. y( J5 c' c; y
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    5 w6 |5 \* O+ E% ~    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    ' y' j( h& [( ^5 g    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>& _2 q+ E( A1 o# j* A4 N+ ^
    <>    if( x1 == 0xffff ). n, K5 s9 q) ^9 r' Y' |
        {
    8 s! P. K& T: d2 @+ c% X        m_OffMapLock.Enter();
    - k' d9 s. N  G6 V3 O5 z, @* G        m_LockGrid.LockCell(x2shift,y2shift);
    ; u8 O3 ^0 s2 H4 R- R) r+ c& e    }
    + y, ~% F+ e  b' N* g7 T1 [    else if( x2 == 0xffff )
    ; y# T$ t* f" p6 ~, D3 n1 ?    {
    3 j7 B2 D, e4 X        m_OffMapLock.Enter();, O  G" G' T" J; c  @. m
            m_LockGrid.LockCell(x1shift,y1shift);+ M' N2 @- N  M1 s# H9 j
        }8 z! h2 `% V. O! n" F' X
        else
    2 s2 s0 n6 F+ g6 G    {; n. v9 C# Y/ M2 \5 z: `+ g
            m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);, A, j. E) _  @  H6 C
        }5 C4 k1 W+ y$ }/ a7 w3 h
    }</P>
    6 f1 `& z" x' b
    / g' F0 r% [& C  E. G9 R* j<>
    % c1 l  W* Q4 f- e; s//-----------------------------------------------------------------------------3 |3 C9 h! V6 @7 s4 k5 z
    // Name:
    8 l4 R+ @2 g! m4 _2 @5 f" U7 j// Desc:
    & b. W8 z1 P% X. I. M3 q# m//-----------------------------------------------------------------------------
    - \$ u9 i: z2 B6 n- Bvoid CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 ); b$ @$ V6 c: r
    {: V, a) W$ g( X" r
        if( x1 == x2 &amp;&amp; y1 == y2 )
    , _) V* i; U7 ]$ `3 X8 g. d/ ]    {0 E- E/ W! X) ?  G& W
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )9 S( P: _/ t2 T8 [' m% g
                UnlockCell( x1, y1 );+ g4 h6 {0 C1 W0 Q4 }: ?" d
            else' R5 t# P4 h. v! c& ]$ F! d2 P
                m_OffMapLock.Leave();</P>8 I% S7 P3 V5 u3 J' T4 Q5 Q, l
    <>        return;
      {9 `9 s/ |" E+ O: N# `3 K! ~% T    }</P>' ?/ r/ }) l, n5 K8 y
    <P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;  t( [# P! }1 f, P
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    3 T7 I, M- u7 Q) ~+ J    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    : y" I3 @" u+ e    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>- k, y$ P. W+ u* }9 t$ |/ V
    <P>    if( x1 == 0xffff )5 A  Q& g3 w7 ?" O7 ?! d. I
        {
    2 J) w, G( |$ o' B0 P+ C        m_LockGrid.UnlockCell(x2shift,y2shift);
    , J& P1 h* E0 x1 n- j        m_OffMapLock.Leave();
    * u1 A% Z/ S1 L- v, [* X0 N    }
    - O; `/ h* `- O    else if( x2 == 0xffff )
    4 W' Q+ |( R. i1 X7 [    {
    6 w) m$ \1 o9 [        m_LockGrid.UnlockCell(x1shift,y1shift);# k" @. |/ k- k3 h0 s' s! W& J
            m_OffMapLock.Leave();. }- v* M1 ?. Q1 R
        }  n4 G8 s& I+ e2 Q- l7 t9 H. s. t
        else
    3 J3 M% ^+ M: x/ Q    {# b" G" q; u" |% z9 n
            m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
    1 }6 q: A8 _6 m. H    }7 k6 m& T% t' z3 U
    }</P>) w9 k8 Y; S2 D; r4 `  y/ Y

    " M% j: H0 b( j2 |; i. t<P>7 i% F$ z1 n1 X  A# F; K
    //-----------------------------------------------------------------------------
    ' V; Q( N$ h' Y// Name: 0 c2 f3 K' D6 p6 X* |0 r& C: V0 ~  h
    // Desc:
    0 X# X9 W# N* D& T) y//-----------------------------------------------------------------------------$ u" \# u0 d# U7 R& m. m
    void CMazeServer::OnAddConnection( DWORD id )& ?( A) _+ v% w* S
    {
    : y% Z6 r0 E' b; \& K" J, B    m_AddRemoveLock.Enter();</P>
    0 C9 d& r. L# V<P>    // Increment our count of players
    # v" M- [+ }& W/ E  }& I: e+ L    m_dwPlayerCount++;7 g: y% L" \% }! q  V$ p+ Q
        if( m_dwLogLevel &gt; 0 )" G4 ~3 s" a0 C% R4 L  @
        {- b* o( a) K' Z( b4 S' d8 M  |
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
    ( w' w* C) A8 g( p/ t        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    0 ?' ?- y1 q' X    }</P>6 [; k. n' @! w  p9 Z; {8 i% v
    <P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    % e3 ?# Q, E) v8 j0 R' A        m_dwPeakPlayerCount = m_dwPlayerCount;</P>
    + P! Q2 |0 ~5 H/ x. c9 ?3 z6 b, `<P>    // Create a player for this client
    ( F& `5 u/ E+ M+ a    PlayerData* pPlayerData = CreatePlayerData();
    8 o& g. l) j+ F    if( pPlayerData == NULL )
    ' [! B$ Z4 S9 y1 P7 s* w* X9 H! P  A% b    {' k4 _( _1 W! ?: t$ e
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
    ; q5 A/ m  y, L  i5 o$ r7 Z; x  Z        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );6 l5 A/ x1 v0 P9 U# S5 ~7 f: m! f
            m_AddRemoveLock.Leave();
    ) `6 r3 O: Z; I% b( f- G" h        return;3 v, }+ r+ i/ o5 d: K/ \) T, t
        }</P>
    % N6 ]+ T8 f) Q' l, G<P>    // Store that pointer as local player data
    2 a  n" j4 V1 E- J" F5 o& K& r    SetPlayerDataForID( id, pPlayerData );</P>% z) M5 B# [6 }( Y, _$ Y8 b; `/ f
    <P>    // Grab net config into to send to client
    ; m5 S0 \  d. Q$ g1 E  y! l    m_ClientNetConfigLock.Enter();4 I/ X( C8 ]3 T2 x  P2 y1 A/ I3 W6 L
        ServerConfigPacket packet( m_ClientNetConfig );; q( i: _+ T4 N; w" N. I
        m_ClientNetConfigLock.Leave();</P>
    : f; [7 [, d4 s  w. Y<P>    // Send it2 e! p, a$ o: _1 P$ @
        SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>
    7 \% t& u0 `6 |# A3 K+ k<P>    m_AddRemoveLock.Leave();
    3 J3 z% `0 N0 q. o}</P>: P# H) x. J) g9 W4 H% E2 U$ G
    . `7 [1 s/ e/ r! a
    <P>
    " U$ Y; n- [0 s; o( v//-----------------------------------------------------------------------------) e/ g% y* i( B4 ?, Y( Q  w3 j  Z
    // Name: 9 P* W; A9 ^3 U/ \8 C2 ^
    // Desc:
    ' Y$ h$ `, U; h, @, O0 i$ E//-----------------------------------------------------------------------------
    " L( L* n# Z0 x" Yvoid CMazeServer::OnRemoveConnection( DWORD id )4 D1 J3 ~3 X7 c
    {
    5 |1 B7 d* M  R' a* c: v7 b    m_AddRemoveLock.Enter();</P>+ c4 g& K" l- W" i
    <P>    // Decrement count of players
    2 e& m) j- U' W    m_dwPlayerCount--;</P>
    ' ~- ?2 \+ h+ z& X7 G" |<P>    if( m_dwLogLevel &gt; 0 )  j0 c0 g1 ]( S- R+ _0 x! r7 Q
        {6 _% \0 F! h% F+ q; y5 _7 f% r1 A
            ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );' b# H# L8 k, j  |+ W- X0 Z
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    ) Q& U3 L7 B/ u    }</P>  r( h; Z6 v! F7 V! I
    <P>    // Find playerdata for this client+ d5 {5 Z4 K* C: c' q5 I, {
        PlayerData* pPlayerData = GetPlayerDataForID( id );
    4 L+ A# R6 L! Y8 C6 v4 x    if( pPlayerData != NULL )  W  C: v7 Q7 [1 M
        {
    & G0 C' v  U# N4 b2 w% n7 l# ~        // Destroy it9 h; @. ^4 e) c
            RemovePlayerDataID( pPlayerData );" t& z# q  E! n8 T7 O
            DestroyPlayerData( pPlayerData );
    ' [+ a7 [' o8 E. Y    }</P>( M2 X9 J- c9 R$ F3 W
    <P>    m_AddRemoveLock.Leave();
    1 r) r: f3 s1 J( O! U7 M% B) M6 P}</P>5 E, k2 U, h; @7 t- o  E3 A' Z4 r

    7 V$ w/ x/ G+ t9 `1 V<P>$ U! j* P% L, @! Q# n. I. F
    //-----------------------------------------------------------------------------
    $ }5 @( `- x) _0 b( p// Name:
    / h# K. B: H6 p# J& t; h0 E9 \  z// Desc:
    * ~/ X% H- T! A# H//-----------------------------------------------------------------------------! Q% n; ?7 f9 v3 `; m
    HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )- T/ E! [% B% y, R$ S2 G- F6 M) F
    {4 @  A, O* [) S
        BOOL fFoundSize = FALSE;</P>
    2 `, X0 _2 ?0 ^' t4 F  Y  d" M+ D<P>    // Increment the number of thread we have in this process.8 Y* z8 d  H: L
        m_csThreadCountLock.Enter();</P>) D" o" z$ R8 M- N9 R* ?8 n4 i
    <P>    //Get the start time of when we entered the message handler.
    # k* G+ r' c+ b* i  Q$ a- b' T7 D& e# T    FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>% C; D. s2 b, z9 \2 j9 s& M
    <P>    m_wActiveThreadCount++;
    0 S) t! x! {7 f    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)- V8 O1 ]9 C: Z5 T
            m_wMaxThreadCount = m_wActiveThreadCount;! M0 Q# w4 w1 z
       
    ) Y- Q4 C$ [4 Q# B; k+ v! r# ~: k    // Calculate and average.
    4 s* O8 y- w' R6 E) l' e    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
    % E  A7 b: d' \" {& ~8 }    m_fAvgThreadCount += fdiff/32;( S" [. U; O$ r& h0 \% w+ s
        & N3 g  e9 i3 F
        m_csThreadCountLock.Leave();</P>
    ' g9 Z  W( w; q, Q9 l<P>3 a: ?/ X; u( ]+ U, J5 T
        ClientPacket* pClientPack = (ClientPacket*)pData;
    6 W9 ^" H0 j! [    switch( pClientPack-&gt;wType )
    % L3 w- s% Q0 K+ P    {1 a/ {) e  i* R: @3 Q- ?
            case PACKETTYPE_CLIENT_POS:: S% X, Q% Z7 u* Z
                
    # M: W4 {& w! w5 b; F9 R            // Check to see if the packet has a valid size. Including ( b4 V$ O% B$ l, P2 [! Y* P; I5 h
                // the custom pack size.
    * [  Y! {. `" p: e- W, b7 ^- [/ @            if( size &lt; sizeof(ClientPosPacket))
    " i. Z8 G( E* m) w- y4 d                fFoundSize = FALSE;" N: y  m( |# @6 M- P
                else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))+ J$ p* l' n! m- Y% S) S$ x% Y
                    fFoundSize = FALSE;
    0 a/ o1 x$ ]% f2 X, x            else# U' Q$ q# a  l0 L8 ^
                    fFoundSize = TRUE;</P>+ g5 O% p. n7 f
    <P>            // If valid sized packet, handle the position.
    ( O" B% p+ `$ h% f            if(fFoundSize)
    ! s6 V0 f/ L4 I) l" j% S6 z/ E                HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );0 _+ G9 u) x& v/ \/ a
                else
    3 j3 r  _0 v2 S. @& U5 l2 e3 ^                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
    5 g% u4 `. L! c( c/ k8 K/ p6 ~<P>            break;</P>
    - Q' M$ c) e3 T+ D  O<P>        case PACKETTYPE_CLIENT_VERSION:
    + }1 L- K  `* |! L* s, R3 p            if( size == sizeof(ClientVersionPacket) )
    - a* N2 g. F( J% R+ e  G9 t  B                HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );  e2 W, Y8 U! T
                else  E0 j" _9 u4 j. |9 M
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    $ Z# [3 M$ X. h4 \0 Q& H( b            break;</P>% _# K* t* [, w5 U* l* Q) E
    <P>        case PACKETTYPE_SERVER_CONFIG:</P>  Q7 w3 R8 r$ ^) a- Z
    <P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>
    . F, @3 ]# G2 O) v) T8 N- Y<P>            break;" ~6 _. {. j1 @& y6 P/ i- h
            default:% ~- X& ~) j; K9 s0 K. e, |( S( x" N
                HandleUnknownPacket( dwFrom, pClientPack, size );+ }, _& H) M% D; A+ W8 U) _
                break;
    0 g* Y8 y+ i5 h" n. u) i- ]( O- S    }</P>
    # B5 @2 Q3 j( J& N<P>    //If the user wants to hold the thread, Sleep for given amount of time.
    $ i: W, y1 b$ R% v. M$ l, T: t    if ( m_dwServerThreadWait &gt; 0 )7 n; j: z. z: `7 [
        {* h+ B( ~) B6 j) W: f$ h
            Sleep( m_dwServerThreadWait );
    ( O$ h" q( S- K3 [* g* w) V    }7 L7 D1 e- F8 T
        " N- ?9 Z/ Z$ R  U
        // Retrieve thread data for this process.
    ! e4 `  Y5 Y; v9 s    m_csThreadCountLock.Enter();</P>: C) d8 [& B, Z6 m/ c( }7 P
    <P>    m_wActiveThreadCount--;</P>' t7 F5 k6 ]7 P2 k
    <P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
    9 Y; r5 r- f8 M/ s    m_fAvgThreadTime += fDiffTime/32;</P>
    & o; `1 ~( F6 L6 E2 D: F7 ~8 _<P>    //Get the Max time in the thread.
    - ?7 B2 q4 G! Z# l, R" o    if ( fDiffTime &gt; m_fMaxThreadTime )
    # m. E+ H- @) e$ [; |! n1 S    {- Y: f6 d! }# J% l8 E) \/ d
            m_fMaxThreadTime = fDiffTime;1 l# P3 o$ D# J+ J9 @
        }</P>6 n3 |+ Q& _+ S. v; p7 v0 X  g
    <P>    m_csThreadCountLock.Leave();</P>
    . u% E1 p) V, E! f* h1 w; h* s<P>    return S_OK;
    ! s, E6 P) K1 x}</P>" C; P# L. ?  z3 M( D2 l8 `; b( w
    ' a7 t: T! S" {: e
    <P>//-----------------------------------------------------------------------------" d* a6 d7 s4 |2 d' F  R% o9 z$ {1 z- m
    // Name:
    3 L& U2 e) Z! _! b% ^7 M// Desc: 8 a" p& J( v) ~2 Z5 D; h" |
    //-----------------------------------------------------------------------------
    " N, U( ?$ i& @2 h0 Q3 TBOOL CMazeServer::IsValidPackSize( DWORD dwSize )8 X# G; y( c+ v2 V/ U) d# T7 C4 M
    {6 `& v7 q$ M5 Z; [" G* F
        BOOL fFoundSize = FALSE;
    % M0 ]* S% e8 p% m$ G7 U    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;
    ; V' w/ A6 w) N9 L   
    & s3 i0 ~' ^% O: Q. H* S0 i5 n6 X" S    // Check through the array of valid pack sizes.
    & S9 l6 E5 ?3 j! b    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])( C2 M  Y6 I) l" @; X! q8 x" _
        {
    % i" V/ M- f" t( m# N  e+ W$ e# S        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)
    7 P# i" ^/ w6 o7 P; L3 r        {: j) d7 b6 n  P; \- F
                if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    ( X1 ]) e: l2 I            {; m  o, x! q! d6 i5 Z! N& |
                    // Found valid size in the array.& m4 m2 r8 P* ]& o
                    fFoundSize = TRUE;; w$ l+ h9 `' P
                    break;
    + x( G& u7 l* L$ c) S1 R            }
    - @+ r9 ~- o# }9 |            if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
    , @9 T/ ]: ^0 _1 g! ^( H, B5 H        }% h5 q6 s5 @9 @5 _- a2 E" E! n2 p
        }6 r8 D8 W! Z- p' S$ X
        else6 K! }3 |8 `! }' r* \' o
        {
    ' w) B, A$ Q# w, |9 j' |+ @9 k        fFoundSize = TRUE;2 y. _% u+ }) N1 Y3 U8 s3 i
        }</P>
    ' A3 Q4 v" ^+ ]<P>    return fFoundSize;/ ~1 U6 R6 D, o* n& ~, _
    }</P>
    7 d/ k8 e2 _# Z) i; d! D9 j6 U<P>. J, P& f0 d$ i5 a
    //-----------------------------------------------------------------------------
    + b) t3 R: e% T) ~( t// Name: / v; e. @" W$ D: [" _8 @# j( Z+ `
    // Desc: . I6 W3 }$ M7 J2 F+ c1 n1 X
    //-----------------------------------------------------------------------------
    4 ]  K/ t: l+ w' Q, Jvoid CMazeServer::OnSessionLost( DWORD dwReason )
    0 t- t$ R! W3 `6 E0 P8 F$ Z% z{
    4 x1 M, c) A6 O. i, c5 F5 y    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );2 g5 u& E6 Y1 z3 ~- T+ r* j
    }</P>
    $ I1 g6 `( V, w1 ~; w. u0 G6 H" \) |: h  v+ @6 h+ Y$ `
    <P>
    1 k$ |( Z  B2 N* K//-----------------------------------------------------------------------------
    2 \* B, T" F" y// Name: 3 ^& ~! `+ K4 E1 P
    // Desc: & x8 w' B  P' g  z
    //-----------------------------------------------------------------------------% {  o4 m4 W, {
    PlayerData* CMazeServer::CreatePlayerData()
    % F( ~3 ?$ \" S& }  b& U{
    ' A5 x  V6 Z7 ^! a5 {" Y8 I- L% B    m_PlayerDataListLock.Enter();</P>& p; r& s  D3 H8 q( k; V$ A
    <P>    // Grab first free player in the list
    1 E7 b. z2 r  G, I, \* ^5 g% o+ `    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>) j* ^9 j# ^3 j/ g  B# G2 m5 j
    <P>    if( pPlayerData )
    $ j0 ?8 A# M" J+ X& l+ P& U    {, ~% C/ K9 j2 B( k+ u
            LockPlayerData( pPlayerData );</P>+ a: J2 _6 m$ P' z4 K
    <P>        // Got one, so remove it from the free list
    2 j7 Q3 ]3 J6 h# ~4 ]1 K# R        if( pPlayerData-&gt;pPrevious )4 U/ G; h% U2 E' h2 a3 f
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    % i5 T3 |* u1 q4 f. L        if( pPlayerData-&gt;pNext )% f! ?! F7 J& b: T+ F! [3 k
                pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;6 P1 K( f8 g! u# s4 |- o  l
            m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>
    + F# b2 d6 t- O" S8 C<P>        // Add it to the active list- n  p: R! w+ k
            if( m_pFirstActivePlayerData )
    - t4 Y( T+ U+ I/ f7 V            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;6 D8 H# x+ n" d4 J
            pPlayerData-&gt;pNext = m_pFirstActivePlayerData;/ Z  i& W& D% B; l$ J
            pPlayerData-&gt;pPrevious = NULL;
    3 X: E( E8 L8 V- x! M1 V4 |        m_pFirstActivePlayerData = pPlayerData;</P>1 X3 ~: `* e' A4 `
    <P>        // Update count of players
    : G3 e; [8 }( N0 ~4 ^        m_dwActivePlayerDataCount++;</P>" L' N% G' Q0 d) P
    <P>        // Generate the ID for this player
    4 u+ v+ e7 W: b        m_dwPlayerDataUniqueValue++;
    5 \& D) p9 y2 P3 F! }0 z        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
    - {& c1 A, z: o8 m<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
    $ e, x; L8 x! m$ d) L4 c        pPlayerData-&gt;NetID = 0;
    8 X5 C8 B$ i3 S1 Q  g3 ^        pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>
    8 U4 N4 P# h! c3 K( P8 Y6 o( E: `( r<P>        // Insert into the "off-map" cell$ B  z7 ~* P% B  ?
            pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;
    0 _) R( m' U; T, N        pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;# B9 Z( i2 ~' h7 Q2 f
            m_OffMapLock.Enter();+ V; C/ o' T4 y. L: Y3 g) H" c5 T
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;
    2 n6 ^4 P" b2 J. R        m_OffMapCell.pFirstPlayerData = pPlayerData;$ Z2 J0 b! w; A8 D6 [
            m_OffMapLock.Leave();</P>
    8 n% N! u/ {+ {1 R<P>        // Mark as active4 `4 ], [6 R0 D5 X) T0 {; ^% W' I
            pPlayerData-&gt;bActive = TRUE;</P>3 [' e' Y+ c' L' I2 G& T
    <P>        UnlockPlayerData( pPlayerData );
    ; M2 v2 g" ^; V1 U* l3 V3 h8 B# g    }</P>/ H- D! y; z& l8 I
    <P>    m_PlayerDataListLock.Leave();</P>7 G8 N2 w6 O. u" n
    <P>    return pPlayerData;
    # f  |) m" [. P+ A0 ~" z4 T}</P>/ I0 H6 z% o0 @8 Y0 ]1 }1 B; {

    - e8 N4 y' b. `1 K) i<P>1 A! o; r9 t: p% d' v
    //-----------------------------------------------------------------------------# ]  ^6 M* {' Y' F. I5 v
    // Name:
    ! i) w( x9 M) z0 ?3 C// Desc: . i0 u: [! N1 R* t+ I- E5 H
    //-----------------------------------------------------------------------------; E$ A$ E; c0 Y2 k
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )0 ^# O# k2 c* e2 U( p8 m& _1 x6 G8 @
    {  G: S8 L. e3 ?# G
        m_PlayerDataListLock.Enter();
    1 g  B0 E: Q. a) t0 m    LockPlayerData( pPlayerData );</P>% ]" o7 [3 t4 o7 Q0 c; h2 {# J" N
    <P>    // Remove the player from its cell
    2 x8 j2 l5 y' I5 {, v* N! ^7 g    RemovePlayerDataFromCell( pPlayerData );</P>
    3 x  R7 t0 W6 o* [" r8 N<P>    // Mark as inactive6 Z, l( v4 O9 K* I& A
        pPlayerData-&gt;bActive = FALSE;</P>
    # X& k  ~! i6 k3 F4 V<P>    // Remove player from active list, @# x- ], @, a. q; I  U! @' }0 k
        if( pPlayerData-&gt;pPrevious )# z2 j# R: [9 i% Q1 A& M
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    , _; n, K, c, M9 t, i( h  q    if( pPlayerData-&gt;pNext )2 B7 ~, @/ Z" S6 D" u& j7 a9 D
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>* l/ Q+ k5 R  U1 `( Z5 Y
    <P>    if( m_pFirstActivePlayerData == pPlayerData )
    * S# g$ e* k6 X, D        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>% ~  L+ N1 p! w, t" M0 b
    <P>    // Add it to the free list3 f& K5 ^) l" R% g' d' ~* w4 P
        if( m_pFirstFreePlayerData )1 B2 p; K3 r% F1 F
            m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;0 k1 B4 M/ Y) F; ?5 A5 Y
        pPlayerData-&gt;pNext = m_pFirstFreePlayerData;; y2 N! ^8 j* A
        pPlayerData-&gt;pPrevious = NULL;
    ; h, W! Z" O+ c1 G# L. b, N8 j4 H    m_pFirstFreePlayerData = pPlayerData;</P>+ n2 d, ^/ D* l, S
    <P>    // Update count of players
    * F" Q! H: [. Y. |& c    m_dwActivePlayerDataCount--;</P>- _5 {9 v$ ?+ u9 q, D5 N9 m; W7 a
    <P>    UnlockPlayerData( pPlayerData );: d7 c  z: |% d+ l" y
        m_PlayerDataListLock.Leave();$ S( I) k, @( m9 b' q( H5 e
    }</P>
    " G6 a. ^& n! f) Y: x6 X  _+ {4 s; l1 k4 X
    <P>
    . Z* M0 X7 {  Z5 p8 n//-----------------------------------------------------------------------------
    1 }: ~2 O! J- a4 }6 ?; T8 I// Name: $ }) T& \7 s. t4 h6 r( k9 W
    // Desc:
    # ?; r7 }0 ]. f9 Z/ S//-----------------------------------------------------------------------------, x; Q  I- T, r$ A
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )3 s! w; F- K5 j9 d0 p, c
    {
    , J: o0 I. R* \' u* ?4 m5 K* }    // Lock the player( v+ I% J4 U! n
        LockPlayerData( pPlayerData );</P>
    , g5 m: |1 B! o- T' }. U- o<P>    // Lock the cell the player is in- P1 V8 H6 Q. M4 m% z7 r
        ServerCell* pCell;6 S/ V* p! K4 S( d9 p
        if( pPlayerData-&gt;wCellX == 0xffff )+ A% N! O  p* @- G# V' `$ r# _
        {
    + j/ b$ P3 j: E* y' z7 B. ]; ]0 P        m_OffMapLock.Enter();. f$ e$ O0 ?3 u. [
            pCell = &amp;m_OffMapCell;7 S* `  M* F7 v1 H
        }7 p/ w* Q$ x# L1 `" E9 z1 u) [, H
        else
    9 R& u7 v3 J( i) P6 k    {$ w9 H) G9 P& S' ~0 g* i) ~
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );
    8 _9 `, G+ i6 E" O8 e; n        pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
    3 x. w+ k: S- P, Q0 A    }</P>
    ) L' L4 k; f% o" l9 |<P>    // Remove it from the cell
      u  Q' E6 M0 Z6 r) k1 h! v1 L' S    PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    * u& C: r3 t, a/ ^6 H- R3 A' j2 _( A    PlayerData* pPrev = NULL;- F# s3 Y1 V. g# Y9 F/ J, y5 z. h
        while ( pPt )
    . O& Y4 y+ W* c# k5 Z    {
    - U# B+ Q- d" K- B        if( pPt == pPlayerData )7 x2 k- I; n2 q+ A; d: S' ^# O/ m& v
            {* K  ?7 D7 t, z( s
                if( pPrev )
    $ e0 ^  @- t, u- u$ p                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;8 n- b" {$ x5 M
                else4 F# E5 R+ X5 u
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>, S& Z; F: Z/ K4 k: y  m& H
    <P>            pPlayerData-&gt;pNextInCell = NULL;* U; ~7 X1 ~7 ^9 v
                break;
    , P- [! M. }7 I# F3 m' {$ v        }
    , d1 w/ d: R. L9 o4 d        pPrev = pPt;
    6 v. M) U* X. k2 z        pPt = pPt-&gt;pNextInCell;5 A$ R) k- [& M
        }</P>8 x8 R6 t% L* F7 r; U7 q$ E1 h' H6 \) [
    <P>    // Unlock the cell
    ! e6 Q7 A; G) I, k5 ?9 I    if( pPlayerData-&gt;wCellX == 0xffff )) F% A1 d. ?9 P" J* I7 ~
            m_OffMapLock.Leave();  B" ?' {$ e$ L; Y9 c3 b2 e1 _# |( n
        else7 N4 }# L9 R# J8 ~
            UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>0 b& b% [/ @6 f% c  ?6 F
    <P>    // Unlock the player" o1 V; c4 |; A, [& r2 z
        UnlockPlayerData( pPlayerData );3 j# }6 F) Y* A, W
    }</P>
    / f0 D" b) G+ E$ I* d; l7 T, S, T5 {+ T) f( \4 [( T" _) ~
    <P>
    ) l8 m6 I2 a8 B/ C4 N, n8 a) J//-----------------------------------------------------------------------------
    4 _5 v$ K' x8 y& E4 ~* O8 U" q// Name: % K! c7 x4 e7 ~7 l8 [3 G# I- N; ]1 N  W
    // Desc:
    ! K: _* \# X% L( }7 T0 C//-----------------------------------------------------------------------------' ~1 p$ l$ [0 g; |: \
    void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )/ s' \2 h& _. G! _+ Z( V& l* e
    {
    3 I9 x( p$ P7 k    ServerCell* pCell = GetCell( pPlayerData );! Q: \6 _) H, O1 z- [9 M, A$ y
        PlayerData* pPt  = pCell-&gt;pFirstPlayerData;2 ^7 j4 d1 b6 F: G# T1 U: p) g! e. W
        PlayerData* pPrev = NULL;- l; }) Q7 E. R2 a" L% S/ c6 U
        while ( pPt )
    & W8 \. p1 t! v5 G  F8 X    {7 I2 h5 J+ h. g; p4 p& Z1 V
            if( pPt == pPlayerData )
    ' |5 A! y* {, e7 F. K: ?% X( B        {1 O$ h) }: J/ d# p3 `) U7 t
                if( pPrev )
    ' V, F1 e$ Y7 u% \1 s                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    7 J+ L, m' K7 A5 d, ^( _4 `7 x            else2 j% H6 ^8 [2 m5 i+ e5 k- Y/ I7 P
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;  d4 y: r- h2 Z4 J$ P
                pPlayerData-&gt;pNextInCell = NULL;
    : O1 E: d& H8 ?. `/ f+ U/ i            break;" ]7 D# L  Q. U$ Z% ~; J: Q) _
            }% L% V8 C" k; L4 U8 m& N
            pPrev = pPt;9 N6 b  M& A, g( i; M3 L
            pPt = pPt-&gt;pNextInCell;
    / Y. a: T7 j) C8 X    }1 ~( y$ H- s7 @$ O# X7 I
    }</P>
    4 Y/ Y; U; S$ m; c$ D& \9 M; |6 n
    # W. ?3 m( J' {* G, D<P>/ [* [9 I8 \; v0 R
    //-----------------------------------------------------------------------------
    $ @5 [7 I$ u, r) F& ^// Name: & x5 C9 Z/ `( v5 q4 s2 J
    // Desc: , n( i3 I0 I- i
    //-----------------------------------------------------------------------------& J6 y" O+ Z: u' U; W
    void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )3 j$ ?7 z$ J" D8 ^$ C4 t% X
    {- Z( M, Y9 z1 A% L9 L* x
        ServerCell* pCell   = GetCell( pPlayerData );
    ) G: ]3 i3 i, L1 _+ ?. |    pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;" I! O6 G, {: q8 V/ J% K
        pCell-&gt;pFirstPlayerData = pPlayerData;
    4 |. U( v8 ?6 J4 Q! u$ K}</P>3 }0 n' T( @1 U/ Q0 {. A, M( L
    8 e: ~, E! Y- d6 a: V$ M) h( o
    <P>
    8 i' |# g' |+ q& A! P//-----------------------------------------------------------------------------0 b/ o; R" c$ H( u1 M4 m
    // Name: . C) F+ _7 S" x8 J( e) H
    // Desc:
    : V: {; V: E3 b9 b//-----------------------------------------------------------------------------  l" D% T. E6 v, R
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )
    9 i9 z5 l- O, B: f  k; G{
    : z9 e; d7 o! V8 T    // Grab player for this client and lock it+ W! g# s4 ?  F/ s
        PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );
    7 b7 a+ d6 Q0 Z# s' ^4 v1 U# P( h    if( pFromPlayer == NULL )
    # P( D2 F' I3 y6 Z( |    {3 v0 Z& n8 b2 e; j
            if( m_dwLogLevel &gt; 1 )
    , A! t0 T: D1 ~1 ~% d# Q            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );
    $ y. f" u. Z! G. F        return;  u% Y* ^& u( m5 O. y2 }
        }</P>4 u5 w# e: N- Q# A4 y5 G
    <P>    LockPlayerData( pFromPlayer );</P>
    5 B( r# _3 t0 |& y6 B: a8 n5 }<P>    if( FALSE == pFromPlayer-&gt;bAllow )# x% o7 x& W% H9 D" ~4 p
        {
    . O9 z% b0 c% |$ M) F8 u7 {+ ?        if( m_dwLogLevel &gt; 0 )
    5 T( S( R( @) r            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
    - S9 u3 v. w% {<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    ' t1 f$ E: ?. n* [7 K$ n* X7 f        UnlockPlayerData( pFromPlayer );4 Q. \% ]) Y0 e% H; n2 S
            return;
      q. _% |; f) c+ O% Y: l    }</P>4 b  O1 i0 u$ u
    <P>    // Compute the cell the player should be in now! D, J% O9 `% ~/ e/ a4 O2 E
        DWORD newcellx = int(pClientPosPack-&gt;fX);+ X* i7 X- W( y
        DWORD newcelly = int(pClientPosPack-&gt;fY);
    ! K7 P) O; X1 F! r, Q! u    DWORD oldcellx = pFromPlayer-&gt;wCellX;
    , U3 p; j: y0 r3 [    DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>- i- ?: x9 v# f/ g$ h
    <P>    // Have we moved cell?- e( {. Y% g* n& ?% p
        if( newcellx != oldcellx || newcelly != oldcelly )
    6 N  z: |$ G" E/ f    {
    , c' l- w: k0 @+ D8 ]5 x* f        // Yes, so lock the pair of cells in question* l, O; Y( Z, v) T: X
            LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>8 y1 ^; ^2 L' ^; o7 `
    <P>        // Remove from old cell and add to new cell
    / ?, H% f1 D, G3 j# U' c0 h8 N        UnsafeRemovePlayerDataFromCell( pFromPlayer );
    4 a( w1 |9 X2 z% W        pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);" i; ^7 p. O4 x- W) m! s+ U8 z' p, V
            UnsafeAddPlayerDataToCell( pFromPlayer );</P>( o5 q6 B( ~6 J$ s: {2 M
    <P>        // Unlock cells5 i4 J; g2 u, v# ~# i
            UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );
    " x9 [! E3 G# G& ^: Q    }</P>
    * E8 |! b% P& e2 l7 ]1 o2 f. \<P>    // Update player position/ B6 K5 y7 j+ I
        pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;, Q- s* m  I0 g! b
        pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    ' L& d  K5 m) H( `( r5 G    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>. s5 N1 X0 d# u! s3 m
    <P>    // Allocate space to build the reply packet, and fill in header
    $ S6 V! i& U2 G: ?    DWORD dwAllocSize;
    ! ]/ X) b" J, [- L" `    ServerAckPacket* pSvrAckPack = NULL;</P>6 `1 u" r9 i0 b/ s) V; q# M
    <P>    // Begin by allocating a buffer sized according to
      }! P1 ?6 R2 K9 G$ y    // the current number of nearby players + 4.  This will give 1 k$ Y7 A, M$ K% \
        // a little room for more players to come 'near' without resize
    . f. J. n8 `. Q$ |6 ~& Z3 `    // the buffer.
    9 d+ m7 _3 u0 j  G* M    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>$ ~: P# Y; D. `# v( }% u4 z$ G
    <P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    4 u3 q- e& Z! G' T! U0 ^    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    ' i2 O7 D% [4 f# _. g  T- r    if( NULL == pSvrAckPack )
    5 _# V; }* J/ k1 e: ^    {
    # y  w, b% I7 X8 |- T$ T        // Out of mem.  Cleanup and return6 z* I0 Q7 }2 ?5 G
            UnlockPlayerData( pFromPlayer );" ]$ r- _3 g- v) U0 c( J, I( S
            return;       1 b! Y6 o* _# s+ m
        }
    ! [3 C, ^+ i9 ?    ZeroMemory( pSvrAckPack, dwAllocSize );</P>3 h* y$ H" e2 D7 |9 `5 |) L$ `; t
    <P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);0 o- M: R9 r7 q0 W
        pSvrAckPack-&gt;wPlayerStatePacketCount = 0;
    0 y7 {) w& y' \0 E. ~1 j    PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>
    $ n. m" s" m( p) H1 z<P>    // Compute range of cells we're going to scan for players to send
    4 S5 L* ~- {7 q8 r& O( h    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;
    ) }4 o5 h) v5 o    DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
    2 E/ j% w8 h0 I' L+ O" d5 q    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;
    / R) z+ Q& N0 {$ c0 V  k    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>2 g$ c" g, k* o" y8 A
    <P>    // Lock that range of cells
    * m" ~7 ]" W$ q8 w& D" o: m9 p6 f    LockRange( minx, miny, maxx, maxy );</P>
    4 x& B5 N& x6 |% b4 T<P>    // Scan through the cells, tagging player data onto the end of4 W" f& w( M6 p" C9 h
        // our pSvrAckPacket until we run out of room& R1 s" Z0 D8 E* O; b" U8 ~
        for( DWORD y = miny; y &lt;= maxy; y++ )+ v+ `9 m9 |8 s8 u7 k: p
        {
      v/ k; L% V  q        for( DWORD x = minx; x &lt;= maxx; x++ )7 i& r1 \5 E" L9 l1 ^% |+ n
            {" B$ k# m0 ~9 W0 y" U5 C1 |
                PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;
    4 V) @7 ^/ v* t/ |9 F( l1 k/ K            while ( pCurPlayerData ); `% k6 t$ g, t3 r
                {
    9 P+ L. R( E) l4 C                if( pCurPlayerData != pFromPlayer )
    - |! p, k8 ], s7 {                {
    9 Q/ E: V8 A  s& Z! @9 `( k                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )
    5 z3 N$ n' N! N! a: s6 {. R" @                    {" \' Z) ^& X" b( e3 S
                            // Make sure pChunk is where we think it is
    5 j$ Q$ {) W0 x1 w8 G  R* H                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>
    . c+ r* u8 f/ s7 k2 F" |8 A& Q<P>                        // There are more than just 4 new nearby players, so resize the
    0 v6 E+ o' Z7 X: x                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's./ k9 O% u0 B( g: ?; _( S# x
                            dwMaxPlayerStatePackets += 16;7 N$ ^; ]& N* o1 D. r
                            dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    ) x7 L9 q# E, {                        ServerAckPacket* pNewSvrAckPack = NULL;1 a0 c/ ~) J# A. q  l
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    ( A2 b7 Z, [9 W% }                        if( NULL == pNewSvrAckPack )
    $ o# B1 x" a! F                        {
      |0 L0 X, R" d. O. A& I                            // Out of mem.  Cleanup and return
    + ]! Z$ x/ s) Q0 ?                            free( pSvrAckPack );
    , K( n$ w. I  M0 p# ?" `                            UnlockRange( minx, miny, maxx, maxy );  \: J4 v) h8 F% G) e
                                UnlockPlayerData( pFromPlayer );6 J# T% y4 H  F+ w) c3 ?. d5 n4 E
                                return;       6 e& X) |9 p8 B. a
                            }</P>
    : Q7 @5 P) |! L" u% L<P>                        pSvrAckPack = pNewSvrAckPack;% W0 L( [% q! I5 V) h
                            pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>8 Q5 \8 G0 x! h6 J3 d0 ^
    <P>                        // Make sure pChunk is still where its supposed to be
      t: v* o$ s" [2 ~5 V  n* f                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );
    9 H/ R, T" F' A, l/ {/ t/ ]# w                    }</P>, b1 K% K5 U$ e: I4 I* R
    <P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;# _% w% J* Y, |" x( ^
                        pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;) [9 b- G4 |1 ~& O4 m, B$ x
                        pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;
    2 K& ^) W2 a1 K; a  h                    pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;
    4 S7 K7 E5 L. z) @                    pChunk++;. J% N& V, H0 O( Z
                        pSvrAckPack-&gt;wPlayerStatePacketCount++;
    3 |1 y: |* A0 a6 z                }) V% H4 ]1 t0 Q8 y3 G& U
                    pCurPlayerData = pCurPlayerData-&gt;pNextInCell;8 H) G) u+ h% _
                }+ ^3 U0 o' o# h) N
            }
    ( [# [8 ]0 I) r2 c- t# x7 `! ~) O$ Q  m    }</P>5 @* B. ^$ s, Q' R. v* f$ D
    <P>    // Update the dwNumNearbyPlayers for this player
    % r- P9 ]- {, E' U% z0 Y+ S% \3 n    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>, f8 `9 a5 f' }* ^7 r" d
    <P>    // Unlock range of cells$ @8 I+ R! y  F* D5 ]; ~. L
        UnlockRange( minx, miny, maxx, maxy );</P>- h* p$ C- [' d: _/ ]/ H* X- F2 k
    <P>    if( m_dwLogLevel &gt; 2 )
    ! k8 b: [! C1 Q5 ^    {4 N- p1 p3 W9 e1 T$ ]
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );( S6 s7 ?4 c) x, i
        }5 R  A, `2 m$ k0 t3 _) p
        else if( m_dwLogLevel == 2 )  N& }5 b! l: H, [9 u$ h7 L
        {- _5 p, d8 N$ y8 ]
            FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    # c1 g& U3 _3 e4 c        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )
    . x3 N2 g# X: b/ w5 Z        {
    & W' R7 x1 b3 w            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );, |. X' B6 d6 @% n( R
                pFromPlayer-&gt;fLastDisplayTime = fTime;
    2 N; ~- P$ a: U: Y/ l- a5 O        }
    : A, Z" T' w5 v/ H    }</P>
    + E3 E) y6 L  G+ j5 ?<P>    // Unlock the playerdata/ j8 N& R" ?  e! z  h  {
        UnlockPlayerData( pFromPlayer );</P>
    ( E" F' I1 k/ s0 q, X, Z6 k<P>    // Send acknowledgement back to client, including list of nearby players
    ; h) V& B  M" {3 B7 ?5 j    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));2 f4 c! k4 D" B) B3 {% R/ |
    - ?0 ~" P3 J7 Q: `7 Y- k, I7 W  M
        // Pack the buffer with dummy data./ Z) V# Y/ G' t) W
        if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)$ g1 Q  J; I; f+ T0 ^; A
        {
    ; k3 C7 g0 R4 f        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];
    + b3 Y) _$ `8 e$ \        VOID*   pTempBuffer = 0;</P>  v5 G) w; a3 Z8 `- `$ q
    <P>        pTempBuffer = malloc(dwBufferSize);; O# o8 s/ I9 k% Q( P
            if( NULL == pTempBuffer )+ D, r0 S/ _3 `
            {' M. ], d2 J" s% b0 |9 \
                //Out of memory0 M# s7 W: _2 Z# K* R9 Q
                DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
    , M6 p7 o7 o8 b            free( pSvrAckPack );
    2 A. Y4 A( `4 ?% E+ ?            return;. o( T; x. H3 J9 q* z6 d
            }</P>. Y% k9 i+ h' D4 U  }7 P; \4 h
    <P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');: m" a! n. P. F2 |# h
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>
    9 p; g. D) E6 X! r2 `! Y. Z( s<P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );. H3 P. N. D2 Q" C" P* g) v
        ; p1 k3 l' V& y- z  K
            free(pTempBuffer);
    * a) l0 }: m* i0 \* n5 n    }   - T; n4 s* K/ L3 H9 b* V
        else
    - w# K& a1 M( M5 ?, p$ b    {6 f4 [1 N$ g" a
            SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );7 }9 W: n" R% V# ~3 b; j. `: h
        }</P>
    4 |' f% e# [4 K9 t; l. Z<P>    free( pSvrAckPack );</P>
    ; O8 W* `! Y5 |6 w2 F/ p<P>}</P>6 p+ s+ j+ D+ E! K/ U, R  D; z4 J
    1 F" j  Q. Z# R) E4 J1 R, U1 a
    <P>4 \) [  j" Z! d  K, \) x3 [
    //-----------------------------------------------------------------------------3 a6 t  w9 }3 }1 ?' }
    // Name:
    2 [3 X, o: v  Q7 M// Desc:
    8 ^) U2 m! e, }, \. w//-----------------------------------------------------------------------------0 A$ Z+ i5 _! m% M& B( S
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )2 w: J2 y3 e0 s, C! v/ H, T" s! N( D8 X
    {& @8 {. n- Y( K0 H+ @: ~
        // Grab playerdata for this client and lock it
    ; T" m, S/ l7 C; m2 J9 `- q+ [, _7 y    PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );+ B% m$ Y8 P; {% \1 F; A  h. x. H- |0 {
        if( pPlayerData == NULL )1 R" q9 y7 J6 g0 J8 {6 s
            return;
    : ]& F9 c% ^; z4 q8 M' L    LockPlayerData( pPlayerData );</P>
    # ?0 j" c* ~& R7 g$ q" [3 c" @& I<P>    // Record the version number 4 r3 [5 a! F; H0 u( p
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>, [  M( L9 z) B( j$ B2 O
    <P>    if( m_bLocalLoopback )) T5 ?3 V+ a: U: C, J" b
            pPlayerData-&gt;bAllow = TRUE;
    ' j( k/ a4 Q# u9 g    else1 F" @# g% I; A$ G- z
            pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>; [& g; m& h( V% M$ G% }, T3 F* C
    <P>    if( m_dwLogLevel &gt; 0 )
    . G8 K+ Z" @) p; n) Z% h        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>
    , K6 ^3 K+ `: N<P>    if( FALSE == pPlayerData-&gt;bAllow )/ a0 S( I+ k; q8 r9 W! o
        {
    ; o$ l+ O$ w2 l( @/ V% S        if( m_dwLogLevel &gt; 0 )" i/ \" h$ Y( ~" u/ _
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P># G" x9 ]9 I/ d7 ]( i) K
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    . K  r2 W( u3 w* N! O9 C        UnlockPlayerData( pPlayerData );
    * F9 w" t+ }( D$ R% f        return;1 C5 t6 Z+ O4 i4 G
        }</P>/ Y. h+ ?7 b2 s: a, m2 l
    <P>    // Unlock the playerdata- X( I  ?( O( ^! w3 e! ~& X
        UnlockPlayerData( pPlayerData );</P>
    3 j7 i$ F4 U( E+ O<P>    // Send acknowledgement to client that the client was either accepted or rejected4 y/ \1 {8 V7 O( W4 P( t/ W
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );( r+ ~9 n4 P2 g2 {: a
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );8 e0 j' z8 j5 b0 Y9 u/ b- n
    }</P>
    : ^% W6 b# u1 ^# M+ ?' M' {$ p. b1 |2 W+ Q0 t3 ?  `$ P
    <P>7 O! [) N. L/ L2 O) `* f
    //-----------------------------------------------------------------------------
    & s8 t& {8 c& j2 j7 l// Name:
    9 J2 ]4 N3 C3 P3 [! \4 A// Desc:
    % C: u6 _# x7 r//-----------------------------------------------------------------------------
    ) `, A( h. p- v4 N, v: k; B5 {BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )- C4 Q( e3 D; b* G+ C
    {5 e  t. ~1 V! X6 k4 X2 o+ v% C
        switch( dwClientVersion )6 r: L& I5 t# J8 n5 b5 s/ k
        {0 H2 i7 }2 Z) x
            case 107: // only v107 is supported
    : T" Y' T; e5 K5 k9 o5 ^            return TRUE;
    $ A. b- |( M/ `: F% g+ ^        default:
    * F, q6 s5 w1 @& w  x) p            return FALSE;
    2 g' x1 J+ Y* [. L. D0 \    }
    7 l, S' C! q' l}</P>
    " S$ u! y8 f8 O$ j' Z# u6 _/ [3 i; r1 {
    <P>) F: ]0 a4 l( `, a+ R. o( k
    //------------------------------------------------------------------------------ i) ^# i5 e! {; M
    // Name: * F% T3 S+ n7 m2 I* F/ h/ X9 M8 I
    // Desc: 4 ^  ?0 ~% [9 `' V1 U! }
    //-----------------------------------------------------------------------------
    : n# n5 y0 Y: f' \7 ~  Mvoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )! M( D) O- q+ J
    {
    . d# L9 M7 A- y2 _    if( m_dwLogLevel &gt; 1 )
    - g* D0 W# l4 E) J        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>9 P  g0 |7 C2 _
    <P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    9 a2 r: B8 _( e3 _$ z}</P>/ y6 Y6 R- u+ z
    ( t- |* H6 ]$ ?# \. |
    <P>% J# U/ C, p- f4 K5 H! ?! N- ?4 t$ ~
    //-----------------------------------------------------------------------------
    3 s1 L1 H; r9 x// Name: # B. i7 A* J% Y+ j
    // Desc: 6 o" \% u- S# x# \. p
    //-----------------------------------------------------------------------------
    * O7 Q. `4 g& ~' }DWORD   CMazeServer::IDHash( DWORD id )
    1 |2 T0 n# z' P' m2 Y! I' j" Y{
    0 N0 y9 b' X- |    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);
    + ~! G. F. m! h7 k    return hash;
    " w1 x8 c) ^# v( q}</P>; H7 @: u/ {; z6 K$ O, s

    4 H8 O* g7 F/ ?4 d<P>
    2 j* X. e( L6 \" _) K- W# e//-----------------------------------------------------------------------------
      M3 u; F& Z( H" e2 b# L' G// Name: ' p4 ^4 P3 }* G9 H# k: `$ g
    // Desc:
    : H; M' n& b0 r% m//-----------------------------------------------------------------------------$ l) @2 g2 {/ s0 H: \4 S
    void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
    % z! K9 N( l2 o' ?/ |{
    + ]7 w( D+ V. b    // Hash the ID to a bucket number3 g+ p4 Y( @) _3 I& D& v: n
        DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>+ s- Z7 z* X( z% \
    <P>    // Lock that hash bucket% d" A  ~. w2 I7 Z% J2 X- @
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;0 ~4 O9 G( [+ u* u. r& {4 i
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    9 x" W! V5 F5 b+ C; F<P>    // Loop though players in bucket until we find the right one
    # @8 Y/ w' a7 H# u    PlayerData* pPt = m_pstIDHashBucket[bucket];. ]- H4 i; J# k8 C
        PlayerData* pPrev = NULL;: l/ g0 c  d3 E+ {6 C& d  C5 f
        while( pPt )
    ; M7 {0 S/ [5 o! y0 q' V: z    {9 i; N& Z# x) A. a+ g$ ^3 A
            if( pPt == pPlayerData )
    # i* W1 F% g, U8 e            break;
    ) W0 W) J6 g8 U$ T5 T5 E$ c        pPrev = pPt;
    $ T& `( u8 U1 N1 C) _        pPt = pPt-&gt;pNextInIDHashBucket;9 H4 u/ l+ O/ B
        }</P>
    / @" ], B6 z/ e, Q; Z7 U3 W<P>    if( pPt )9 V5 ~" r+ N- {6 w  }
        {
    4 T4 n) T2 u) X3 H/ X        if( pPrev ): S. e0 K$ ^) E+ i6 V
                pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;
    1 Q7 A" M' B# I6 \5 b+ V+ n        else
    + P1 {: D  T3 M5 E7 Q; u( ^+ M            m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
    ' M7 W+ T! _" T4 L1 t: J) _2 G        pPt-&gt;pNextInIDHashBucket = NULL;
    ; a4 K, o) N+ z. _' G4 D3 e. c    }</P>9 G) i3 Y& U$ H. B
    <P>    // Unlock the hash bucket
    9 ]: N7 O* n" u* M* O0 ?9 L4 @5 E$ e    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    . p2 k: U; M/ M: \0 W8 L( P}</P>5 F- F6 c/ \1 m

    8 D$ p. U7 O+ ]<P>+ d) `7 F7 H3 F3 L0 ]" p
    //-----------------------------------------------------------------------------
    5 e, j2 U# m. {* Q' s" W, ?// Name:
    8 h4 ^* j+ L1 k$ E2 J// Desc:
    % p/ f0 Q; T- S//-----------------------------------------------------------------------------9 x; t# w( V- f  g( L: [  ?
    void CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )! T) h# d4 F6 y0 n1 b/ d
    {
    " v, W* \( A1 _    // Make sure this player isn't added twice to the m_pstIDHashBucket[]
    ) c9 y+ d8 \( k% S! A( R+ i' k    // otherwise there will be a circular reference0 J" {. G  S: q; w# @
        PlayerData* pSearch = GetPlayerDataForID( id );$ P/ T9 X- z  Z) r
        if( pSearch != NULL )" P2 I- Y/ O3 s
            return;</P>
    2 x+ l) i3 P2 P% u6 L( R7 L& w3 V<P>    // Hash the ID to a bucket number' v4 b' ^0 W! m; B  Z& K) y
        DWORD   bucket = IDHash( id );</P>
    4 Z* i1 L+ b7 i7 |, }& b; i- X1 b<P>    // Lock that hash bucket
    6 G# Q8 G1 e  u4 [    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;4 T  z" x, T3 f" T# `; d( F$ f
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    ; G+ B) x6 \& Q. ^- z: p<P>    // Add player onto hash bucket chain* I  k) _. b( j1 U4 }
        pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];0 m4 A% P' d. ~* g$ |
        m_pstIDHashBucket[bucket] = pPlayerData;</P>
    # V/ c: G( P# g! f/ N8 c+ B4 O<P>    // Store net id in player5 K2 C* Q, R! `% M0 v
        pPlayerData-&gt;NetID = id;</P>
    5 y  X4 Y* j5 x1 I9 a6 ~<P>    // Unlock the hash bucket
    / z0 L0 J4 U' m# c, I4 l! |    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();6 V  U) }. k( h6 c: C- o
    }</P>
    " Z0 a6 X& W) S( M& t7 e0 D  p' h; d3 H+ R% s# s: m
    <P>; [. Q1 F4 H7 H, ?- v% @2 ~& ~: Z
    //-----------------------------------------------------------------------------4 W) G( A+ m5 E) U6 x
    // Name: % P) z/ u+ t/ E
    // Desc: ( U) v: N, _, H. M0 F: C" V
    //-----------------------------------------------------------------------------) s4 @. i7 B0 M8 y3 n) Q' a  E
    PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )
    . G5 I# o# _" p/ N! q1 x  z{
    5 P2 f1 C; a. X' z; v7 u# h4 b. O    // Hash the ID to a bucket number9 h7 d, U/ X/ ?" c8 z6 _7 v
        DWORD   bucket = IDHash( id );</P>! f5 s" z! Z/ p6 Y) ^0 j
    <P>    // Lock that hash bucket
    / g0 Q" K, |) j5 F( s+ D    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    ( O$ G8 O8 l& X$ z    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    4 Q: w& H* W; Z<P>    // Loop though players in bucket until we find the right one; K: {, p' R2 n  I% X
        PlayerData* pPlayerData = m_pstIDHashBucket[bucket];  y' G$ s5 B7 Z0 \
        while ( pPlayerData )
    ' @0 m: P* |1 h    {
    - r4 ?- X1 d9 A, S7 q+ J0 F        if( pPlayerData-&gt;NetID == id )5 c8 H  K& v# E4 t. i& A
                break;
    3 u* a9 N# ~4 e/ n, O        pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    4 ?- L, n  M) s# B$ T. ~    }</P>* `) F/ [" T# g0 d( e6 g( S
    <P>    // Unlock the hash bucket) K% y' V' g3 N& N
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>' o( n3 I' @6 d1 X( a
    <P>    // Return the player we found (will be NULL if we couldn't find it)
    7 J9 e7 u$ N, y    return pPlayerData;( s& U$ s6 |& n" f/ {
    }</P>
    7 Q2 w: h" g: ~! b
    * L' t/ P: R' ^( B<P>7 w: Z3 o( r# [7 u  ]5 n
    //-----------------------------------------------------------------------------
    4 y, D& A1 W2 [6 s// Name:
    . x3 ]6 Z, h: W0 ]( C- i// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner9 l) Q1 k9 k) o/ B& y% G) u* R
    //-----------------------------------------------------------------------------! c8 T$ l. }# ?5 i
    void CMazeServer:isplayNextConnectionInfo()
    : w( A: L- @+ J# _0 ^, r{0 ~& R2 o6 L4 a2 r2 F. R: h
        if( m_pNet )6 `3 I! _% Y$ z$ ?' v# K
        {$ w5 F8 `3 z% B1 O+ ?' z& o
            // Find the player that was displayed the longest time ago, and display it.% d& N9 d# ~4 ~% B
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );  _) w$ c' H+ r
            PlayerData* pOldestPlayerData = NULL;
    0 d0 e* [+ g0 I8 c4 Z# \        FLOAT fOldestTime = 0.0f;</P>, W4 G- Y0 M+ @2 c7 ?
    <P>        m_PlayerDataListLock.Enter();</P>
    4 J( h7 w/ F9 d7 x+ p3 S2 u" b<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
    4 ]. m3 |7 O5 v+ h1 S        while ( pPlayerData )# F0 K( v; D8 M) R2 t; v3 ^; w. B
            {% e; V. x* n& }7 ^" Y/ |/ L+ N* @! o
                if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )4 h$ f% r( P: f+ n# n9 [) d
                {0 Q/ q3 z7 a7 @. W4 G/ `
                    fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;& K7 O% J9 ?2 T# e- }- g6 p9 r0 @
                    pOldestPlayerData = pPlayerData;' g" P) h  K/ {, F* D7 y
                }</P>
    7 H- S( \3 e' o% f  X<P>            pPlayerData = pPlayerData-&gt;pNext;
    ( e8 E0 {3 G$ l. ?/ @* f        }</P>
    9 Y( @4 f: {; I7 G<P>        // Display the player with the oldest CI field, and update its CI field.3 q# E. ^* w7 o- b, f4 ]0 o) M
            if( pOldestPlayerData )
    2 Z" `/ m  M" A! M) u0 O) M        {
    ! I' i2 \# `; D            ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );; }& b. c2 R7 |# e
                DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
    & x0 y( K! y5 Z            pOldestPlayerData-&gt;fLastCITime = fCurTime;
    $ C; k* v9 g4 J- v# R/ ?        }
    8 u# O$ s; a. o9 i  ~        else
    8 ?/ E1 |- I+ g/ v& \0 V: v        {/ ~% ]+ J# N2 K! l& s
                ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    - i1 w" G, z9 P        }</P>& g3 }& d8 j7 ^7 y
    <P>        m_PlayerDataListLock.Leave();
      Q! c: U/ w" ^- ~3 m, a    }
    ) F& B) t, t% m) I& e}</P>9 i! W& x% o/ V( }2 ?  [) V- e

    3 e9 H! ^. N: D4 z<P>
    " n! S& f& P7 L6 i//-----------------------------------------------------------------------------
    ! ^/ [0 }/ p5 q// Name: 3 A( S% f9 @% p; w+ L- ^
    // Desc:
    6 s8 ?/ q& ?# n) t; l//-----------------------------------------------------------------------------# {3 v4 c6 K& U% @7 V3 N
    void CMazeServer:rintStats()3 `2 a( {8 y( S9 k$ p% M# ]
    {/ @4 O1 z: c3 A! ?/ K# q
        ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
    / y" A; _8 P: N! G7 T; W                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );
    3 H, m* `: R! b( q! a' K/ l    ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
    ' g( P- Z! _; {# v) E! Q                                    m_fAvgThreadTime, m_fMaxThreadTime );, P) s, S+ ~; ?, X
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
    " N1 t) Q- v/ g: p    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );
    " X/ o: j5 L# Q, g  r$ E9 H! ?}</P>- T5 V. h$ D7 B1 @7 u! i" H9 e

    , d- C$ a0 W' u0 d, N<P>
    2 d% B% A+ V: |8 D//-----------------------------------------------------------------------------) P$ ]( {6 s3 l! x9 ^
    // Name:
    3 H3 t# n/ e6 F4 j* J  m. W// Desc:
    9 n; f2 Z8 \5 {% E//------------------------------------------------------------------------------ z( X$ n( ]% X" x/ G) b; K
    void CMazeServer:isplayConnectionInfo( DWORD dwID )
      U. e3 j. u* f{
    8 e; O! X+ }0 U3 i% \    TCHAR strInfo[5000];
      @' U1 Z& i# [) A; z( v9 d    TCHAR* strEndOfLine;
    6 B# W( D1 E2 A    TCHAR* strStartOfLine;</P>
    4 K* q" V% ^8 e# h4 l<P>    // Query the IOutboudNet for info about the connection to this user! P# I9 X; a2 B( P+ R3 M
        m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>
    , e9 o1 O$ |: t2 s3 d) `6 {<P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );8 I8 G7 o4 ^# D3 e  H7 j
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>3 B) ~  F$ s' X4 F1 Y. ]3 @- h
    <P>    // Display each line seperately' N8 N6 t6 l1 \  m* e
        strStartOfLine = strInfo;
    ! d; \  R! M1 T/ |$ J    while( TRUE )6 a7 R  v- B& i* W$ j
        {! ?, g6 }" N. o" a1 g
            strEndOfLine = _tcschr( strStartOfLine, '\n' );2 h2 l; A* `# }, Y: S
            if( strEndOfLine == NULL )3 s3 r; K. O( [/ L; r$ h( j
                break;</P>
    " C: u2 |- _, }8 [<P>        *strEndOfLine = 0;* \$ ]( j" `2 u; e! c1 r3 O
            ConsolePrintf( SLINE_LOG, strStartOfLine );% y. l" q% N  E4 ]" G+ [
            strStartOfLine = strEndOfLine + 1;/ V' A; g2 @6 G. z
        }
    5 E% Q1 @; @% m! N2 n}</P>
    3 M- A% L- k/ r
    " q1 M9 n) S& E3 x  w" {3 C- m<P>/ N( t- E" o3 i1 C7 Q
    //-----------------------------------------------------------------------------/ |: R0 ?+ J* j! N4 C6 o/ c
    // Name: + _+ ], p3 F0 N
    // Desc: & I& j0 r( r  d) R- W
    //-----------------------------------------------------------------------------; w) {2 U9 x( J: t
    HRESULT CMazeServer::SendPacket( DWORD to, void* pData,
    6 K. Q* z* H, J- u& X/ p% P                                 DWORD size, BOOL reliable, DWORD dwTimeout ); f3 l# }, O2 _, v- P4 T
    {
    4 }: ^  Z" b7 }9 s+ v) e6 i    // Chance of forcing any packet to be delivered reliably
    ) W: p2 h% f5 ?    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate ): Q" h4 |* z) E
            reliable = TRUE;</P>
    7 |# i! C- J5 Y* U, r" F<P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    # `- P! }; ^2 K8 t8 B! _* o) h}</P>
    $ @% S, d' m2 P, k( ^5 d# N3 U: [7 K
    ) @9 U3 i. s( i6 e, w<P>% Y0 }, r+ O, g7 F
    //-----------------------------------------------------------------------------
    3 d& |+ f1 Z3 M$ E+ O// Name: 3 J- g# Z* h, y7 }: m& v) g
    // Desc:
    3 q% ]( y( `! M3 A//------------------------------------------------------------------------------ _! B0 u4 P- a3 l
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )* q7 @1 X7 h4 A; Q
    {4 l! A# V9 R$ B1 j
        // If we're up and running, then send this new information to all clients
    ; _5 V5 E" ]9 o    if( m_pNet )! o- w: k% C. L/ _# Q9 `6 ]$ D8 B
        {. }3 ~/ n% B/ d9 |* k4 R
            //Use the AllPlayers ID
    ; ]3 T- ?( E2 ?7 E: w        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );
    $ z; i- z6 U; D1 Q8 U9 i    }6 ?$ u7 J. {7 v% o- t' O: `) |
    }</P>7 U2 x% S: l6 m0 }# c2 |: e

    / K' p! L5 v/ H<P>5 M; K+ l9 |+ w* o) k+ D7 F9 K
    //-----------------------------------------------------------------------------
    " q8 I  U; x2 P. p. o; v. K// Name: / G* s0 d& I8 h) C( J- t
    // Desc:
    6 I) z+ O$ R" D) ~//-----------------------------------------------------------------------------
    , F4 A$ H  Q* b9 V: p" qvoid CMazeServer::SetClientReliableRate( DWORD percent )
    $ o! y9 \) M/ a3 Y. X# I; ]" N5 K{
    , b+ x: n( l9 x% V. t' ~1 F    // Update client config, and build packet containing that data8 u; O+ F0 @7 N
        m_ClientNetConfigLock.Enter();8 w2 L9 @7 [& E$ w1 x/ N- A2 f
        m_ClientNetConfig.ubReliableRate = BYTE(percent);
    ( S7 e3 V; F+ G# n  S( m    ServerConfigPacket packet( m_ClientNetConfig );7 y1 P/ [" I( [; w5 z3 J# n3 ?
        m_ClientNetConfigLock.Leave();</P>
    ) g" t+ `% c2 h) n<P>    SendConfigPacketToAll( &amp;packet );
    2 p: N3 k4 [) Z8 K2 u4 U}</P>
    0 `/ W5 O/ J: q+ y5 Y& @
    & v1 L6 y; v- h<P>) Y5 y9 U& e# A7 D& q/ S5 N6 j
    //-----------------------------------------------------------------------------' Q* f' K' E/ d7 @! _9 z
    // Name: # ?- r7 T# W$ N  S5 z# {' h9 V
    // Desc: 8 Y" n5 d  x# J+ {- a
    //-----------------------------------------------------------------------------
    1 K* W! W) G7 a- e0 C! j# Avoid CMazeServer::SetClientUpdateRate( DWORD rate )6 y7 H* }2 g- V- L8 a' K; M. t4 |2 h
    {
    : p2 h9 b9 S! Y- ^, W, u+ p    // Update client config, and build packet containing that data: h+ s: q2 Q' j0 Z# Z% C
        m_ClientNetConfigLock.Enter();
    ) j- z; c. B9 u4 i' A8 y    m_ClientNetConfig.wUpdateRate = WORD(rate);
    9 b6 o" T& ^# |9 M4 ?* B( t    ServerConfigPacket  packet( m_ClientNetConfig );# P( W# T, a5 i+ O3 I% _
        m_ClientNetConfigLock.Leave();</P># x% \4 ~' N' F/ `
    <P>    SendConfigPacketToAll( &amp;packet );5 ~( h2 z4 |5 R! o
    }</P>' i$ d+ }4 }! Z* p. Q% D- q
    0 }( n0 u4 C2 g9 X
    <P>. v. r! ^9 E5 Z) T. f1 }( |
    //-----------------------------------------------------------------------------
    ' z0 w1 g# a: r* ^: [// Name: ( v9 f( j* I6 X# T# e$ r( ]0 C
    // Desc:
    * b* ]. f8 w1 {# C9 i//-----------------------------------------------------------------------------& q" W6 O6 y) F1 i- v& F6 b
    void CMazeServer::SetClientTimeout( DWORD timeout )
    ! ?, G* Q( ^8 ^7 N! }* u: X# o{
    - l7 W3 m) l$ v0 E' \: h3 p3 X" z' C    // Update client config, and build packet containing that data
    ( z1 f8 J+ e& L3 Y# k    m_ClientNetConfigLock.Enter();- w) C- m5 V; [
        m_ClientNetConfig.wTimeout = WORD(timeout);* g8 b5 |: \  R% j; l: w
        ServerConfigPacket  packet( m_ClientNetConfig );
    1 m: R, H" J8 N0 A: X# U% b    m_ClientNetConfigLock.Leave();</P>
    ; V# ~0 ?* d7 K5 i- q, q4 ]: m+ k<P>    SendConfigPacketToAll( &amp;packet );
    % }5 n" _* P. L  U0 ~8 W  s' ~}</P>; }& O. Y1 P3 P7 e- [$ z: k

    ' d- B/ A- T% y<P>  \" p" Z( _. w8 D! F0 @
    //-----------------------------------------------------------------------------
    5 I# c) ~9 R9 c7 P8 `# `! b// Name:
    ' r5 _7 \) d% u( r! t// Desc:
    7 @6 g2 w* D+ j. D//-----------------------------------------------------------------------------
      F2 V- _7 k5 g: ~& R4 [void CMazeServer::SetClientPackSize( DWORD size ); m" R$ Q! s( H6 g4 |% {! C
    {
    ; i% ~9 K" X! F& [1 K- b    // Update client config, and build packet containing that data
    & q# `( q/ v7 M    m_ClientNetConfigLock.Enter();5 `& e! ]$ W! D( L1 z
        8 s: h6 M" M9 y* K
        m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.
    7 b- j0 H) ?& _& q1 j    if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   ! T4 z* k1 p8 L2 z, ~: h9 _
            m_ClientNetConfig.ubClientPackIndex = 0;</P>( z9 b0 m3 p# d, Y. ^- t
    <P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);
    ! V) |+ ]3 @" @* i& q, V" T    ServerConfigPacket packet( m_ClientNetConfig );" _% o, j' F! `! Q; b; }, \
        m_ClientNetConfigLock.Leave();</P>. w6 R; o1 b* e" ~
    <P>    SendConfigPacketToAll( &amp;packet );
      h# \$ \" l3 ?# \$ D}</P>
    9 n; E; V: n5 Y1 s( e
    8 I5 h6 @: \$ [' A6 r- v3 b<P>
    / Q* U. }7 s  L* `//-----------------------------------------------------------------------------! ?! c2 k! r+ [. o$ U4 Q1 I% q
    // Name:
    1 C8 K- y6 p. v1 }% ?8 Y// Desc:
    ! i4 z; X3 J! V0 N" b% H, p4 t//-----------------------------------------------------------------------------; K1 s) _5 E: t, C  [
    void CMazeServer::SetServerPackSize( DWORD size )
    7 t/ I. E4 T* l{
    ' D$ ?+ [0 o% ^/ G    // Update client config, and build packet containing that data; [. F8 \" N7 [3 ]* x
        m_ClientNetConfigLock.Enter();
    7 i7 X9 j" a" a& D# q3 G, }    * v; m8 a' W. L
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.9 W) \3 ]  b& K1 ?' [/ v7 G8 z- ~$ X
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   
    - p" ?* {4 u" e$ N0 m& L4 q" @' |( o        m_ClientNetConfig.ubServerPackIndex = 0;</P>- `8 i7 M2 Z* Z% ~0 L, N5 Z
    <P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);. S1 [$ z2 C3 T$ O6 V, ~
        ServerConfigPacket packet( m_ClientNetConfig );/ b& i6 y/ O* N; i7 a
        m_ClientNetConfigLock.Leave();</P>
      Z% _; I$ m9 a9 ]  `& z<P>    SendConfigPacketToAll( &amp;packet );1 R1 d# C+ x. ^8 z3 C
    }</P>
    4 _0 U$ i( @; }( N<P>
    - X% j5 ^  U9 D2 b# C  X8 p//-----------------------------------------------------------------------------
    " d' e6 Z; K  U" R: ]7 p( V// Name: 3 E  _! s5 l% f. A
    // Desc:
    8 e, D  s2 R4 I" L' [" I//-----------------------------------------------------------------------------, C  @3 ~: Q" f6 ~
    void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )+ v" c6 @* X# T7 E. y
    {" ?) F: O' d2 q) Q2 V% y5 F
        // Update client config, and build packet containing that data
    ' h1 K" d3 e' e7 u. ]  S9 G& ]    m_ClientNetConfigLock.Enter();
    + J- o# ^. g! P& u( V    2 o; {2 n- l+ Q
        m_ClientNetConfig.dwThreadWait = dwThreadWait;
    ! y9 y8 m$ w* ]- M9 D) q    ServerConfigPacket packet( m_ClientNetConfig );( c: [7 p  H' J4 U
        m_ClientNetConfigLock.Leave();</P>/ P/ I2 c- G  Q; S3 H) E2 ]# W
    <P>    SendConfigPacketToAll( &amp;packet );2 |, C: @# j. v, T! N, G; F
    }</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-6-12 06:31 , Processed in 0.546486 second(s), 50 queries .

    回顶部