QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4160|回复: 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>
    - H& P" b& h8 e' ~<>// File: mazeserver.cpp  B: D) Q& H+ q* E* ?1 x* u
    //7 @; m! Z5 {6 _" [3 q* s
    // Desc: see main.cpp" S& O; ?4 ]9 `! S$ B
    //
    ( z4 N( F5 t; F. ?9 N! [0 ~// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved." s- P+ {" A" O. f2 K  Z; R$ l$ [
    //-----------------------------------------------------------------------------  q' q9 H: {7 \- V
    #define STRICT8 r# C+ M6 q7 @
    #define D3D_OVERLOADS2 T( @& C  H( Y1 c
    #include &lt;windows.h&gt;& S) @2 U* s2 P: |$ Q  j
    #include &lt;d3dx.h&gt;* T0 J' U6 v* o
    #include &lt;stdio.h&gt;3 l# J/ [/ i6 H
    #include &lt;math.h&gt;4 n9 a6 R  U9 W( O' y& s
    #include &lt;mmsystem.h&gt;
    & y4 ^' `$ I) ]8 R9 ^/ [+ o+ o6 [#include &lt;dplay8.h&gt;; S9 L4 P. J/ F4 i
    #include &lt;dpaddr.h&gt;9 @$ J" U' a( l! {: [. C5 ?, f
    #include &lt;dxerr8.h&gt;
    7 @( P5 i% l- e$ x* P#include "DXUtil.h"9 u2 r8 }3 a9 q9 N6 `- o
    #include "MazeServer.h"( S* k2 I" n/ S6 v6 |& l7 v* M
    #include "ackets.h"0 b' w$ t2 `  L2 I
    #include "Maze.h"
    8 }5 `; w* y+ e1 J( d* I9 ?#include &lt;malloc.h&gt;7 v; ^/ V1 t( }
    #include &lt;tchar.h&gt;</P># C3 I9 X5 Z# H2 e
    5 Q6 e8 H. S) |. e; y
    <>//-----------------------------------------------------------------------------/ D( _1 q3 C& x, X. I
    // Name: ; o2 M( k- n+ W' e1 W
    // Desc: 5 i1 u/ W6 S$ ?/ u
    //-----------------------------------------------------------------------------
    , v3 q4 u! ?9 J; \4 b" T9 m  ~. J# zCMazeServer::CMazeServer(); ~& k) {- _( z
    {0 t* z6 \5 o+ L% k( h
        m_dwPlayerCount         = 0;
    5 ?9 W! o2 O( ]% a# U. }  D    1 h4 u$ a6 T' f
        m_wActiveThreadCount   = 0;
    : E# o7 c$ u% ?, f6 Z5 t    m_wMaxThreadCount      = 0;
    0 Z  [6 M) m9 x: C; L    m_fAvgThreadCount      = 0;
    ) A4 j6 F- F2 S+ @  Q1 U9 s    m_fAvgThreadTime       = 0;1 Q& G% g! ?+ T0 g" K2 G3 p
        m_fMaxThreadTime       = 0;</P>+ c* B/ |0 {1 ^2 ]/ w& I
    <>    m_dwServerReliableRate  = 15;$ i) q5 s. A& j5 X. q9 f/ q
        m_dwServerTimeout       = 150;" o9 \- k" [5 ?% P2 H
        m_dwLogLevel            = 2;# K3 E4 E' F; b/ E/ U; D
        m_pMaze                 = NULL;</P>
    $ _: V% j& Z: F; m0 c<>    m_ClientNetConfig.ubReliableRate = 15;; l# O, d; S. y! d
        m_ClientNetConfig.wUpdateRate    = 150;: W1 w0 ]& X' C0 G( \. `9 i
        m_ClientNetConfig.wTimeout       = 150;</P>
    ' w. ?& O0 }; _, B9 v* U1 q, ^3 [<>    m_ClientNetConfig.dwThreadWait = 0;</P>
    ! }$ Z! m; u9 P<>    m_ClientNetConfig.ubClientPackIndex = 0;4 `4 r% i+ s0 u4 `
        m_ClientNetConfig.ubServerPackIndex = 0;
    & h$ @( @4 X) l* j2 x) p1 s! h    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)
    % C9 k2 t5 [0 W* y9 Q    {
    ( r+ K* Y. ]- \5 B4 ]; h2 e- ^9 q        m_ClientNetConfig.wClientPackSizeArray[x] = 0;* ]& X! p# p8 D) l
            m_ClientNetConfig.wServerPackSizeArray[x] = 0;
    - N: A" J6 M9 ]5 H0 |: n2 q    }) m6 M' z' i: G- \! s
    }</P>1 i. ]) U1 V, Y- G% `1 N) V( N

    5 l! S2 q3 a7 l" |' Z  H<>
    1 }/ z- O+ e# r' i1 J//-----------------------------------------------------------------------------! B' f& b$ p3 I% k& Y9 a0 o
    // Name:
    - t% w3 G; V8 ~( G: T' P8 {% A( M// Desc:
    . `* T+ n, V9 I& o' I//-----------------------------------------------------------------------------3 t8 z( G- K3 B! y4 L" z
    HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )
    + r. Y; ?9 f. ]4 z' R) _{
      m2 X, P+ u4 D7 B' \& Y: n    m_bLocalLoopback = bLocalLoopback;
    ! G; l9 V0 J) X0 r+ Z    m_pMaze = pMaze;5 F: u6 O* W/ l4 s
        if( m_pMaze == NULL )9 ~: d, Q: |7 _
            return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>0 j  s) Q, f  [' {" e6 s
    <>    // Grab height and width of maze0 m1 n1 q% e8 ~4 Z, s% f4 y
        m_dwWidth = m_pMaze-&gt;GetWidth();! Y# J# S7 r9 e9 u+ x
        m_dwHeight = m_pMaze-&gt;GetHeight();</P>6 ?4 g% C" G% [2 z5 @. r
    <>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;9 H* Q4 D& p7 j
        m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
    * c( V- U- U' T7 A5 c- R" r<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.
    ' \  S: v" B7 W0 i    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    * W" \5 f5 y7 {* H) A! F        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );4 X& K: P" D8 {* e* |
        if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )+ N% [& E( B* E/ |( H; C/ i
            return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
    8 @4 r$ N9 ?  }# F3 e: G<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;
    7 w9 d4 {7 h0 C( J    m_dwMazeXShift = 0;+ J' H8 e6 C, ~3 O- V. [
        while ( (scale &gt;&gt;= 1) )+ d0 q0 j* U7 F8 C" f& ~
            m_dwMazeXShift++;</P>
    3 U2 M. p7 K2 u5 W$ E- e. ], b<>    scale = m_dwHeight / LOCK_GRID_SIZE;( R; F+ L  d! a8 l' G4 ~- v
        m_dwMazeYShift = 0;
    2 g( I  V/ [& u, ]- f" E    while ( (scale &gt;&gt;= 1) )
    + k7 S; {; v& T1 M& y* k; K  t        m_dwMazeYShift++;</P>/ |3 @8 ~' o6 s9 Y
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    ( N0 z+ v$ \% S5 ?        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )
    7 N2 |& Z0 E( C- M$ \; w. q        return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>6 \% w  g2 q- _+ V
    <>    // Initialise the player list2 u  V  u& |! {' c
        ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );
    * d! Z2 N) }: C) X! \    m_pFirstActivePlayerData = NULL;
    9 l) D$ e0 U  N7 r3 v7 w    m_pFirstFreePlayerData = m_PlayerDatas;  T! C: @+ k( a
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )
    * s9 ^- A7 R" l6 a7 x" }    {
    ( V7 h! ~+ t2 v6 A) h8 x4 y( O- H        m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];
    5 @0 G3 m- a4 I: ~4 u5 [        m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];) `; ?; {: F2 p- Z
        }</P>0 j0 U$ e6 m) Y! r* {" y
    <>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];- u% R' }" h5 ?( f2 l
        m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];8 I' u) V3 G4 N5 ]% z0 G% B
        m_dwActivePlayerDataCount = 0;' h& T. N( P- X
        m_dwPlayerDataUniqueValue = 0;</P>
    * r4 f3 L/ u" n<>    // Initialise the cells
    + @: Q8 x! e8 y1 U' W0 f/ a2 W    ZeroMemory( m_Cells, sizeof(m_Cells) );
    ' t. r2 ^: H& F8 w+ B) m: b+ f    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>
    / ^9 J; V- }+ @9 G  {7 h, G<>    return S_OK;
    + A8 t3 s- o# F+ O4 Z, r$ Y/ X8 ~}</P>
    1 x+ x4 V/ J" V: K7 a$ \& B+ A: ^6 m! }( ~& X8 X
    <>" O; H$ H$ `! V! C( ]
    //-----------------------------------------------------------------------------# h  G  @3 {1 S, E$ M( _0 Z: B. Y
    // Name:
    " P3 E9 j1 [% h) w+ I! F// Desc: 7 K# F; x5 h2 h- v- E
    //-----------------------------------------------------------------------------4 J0 f" H2 W4 G6 a0 l4 i8 i
    void CMazeServer::Shutdown()
    9 w* a% o% C6 \, B, w$ R& J{9 Y% l' o; i1 E  K' Y: c
    }</P>  e. ?* ^5 ^7 |; Z/ b
    7 L$ O* F: o- L0 P, r4 R
    <>
    4 N& O5 Y6 b# a2 |" u//-----------------------------------------------------------------------------! W4 F! M8 i" V, h2 ]8 c7 c
    // Name:
    . {$ O5 T8 V! m// Desc:
    2 }. M3 Z" u6 n2 n& ~% ?//-----------------------------------------------------------------------------& u6 Z' z% v- q9 ]' b, j
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    . [( \7 u- R! L( J1 D- Z* t{
    ; D* t$ l" ^' p& u# x    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,2 m6 ]- g1 a8 m$ |, Z
                              x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    " ^- n  K' I% r; h}</P>
    ! A4 @& x+ P: x( @; C4 i% G* c
    ; C  j8 Y) b, G* s9 u& u6 s9 p# `% n<>1 q1 T, q8 J$ t. G+ C2 E/ U5 ]
    //-----------------------------------------------------------------------------
    9 A. j5 W  F3 w9 B" D// Name:
      A3 R( Y9 o) j" y// Desc:
    7 Y4 n1 f! C2 K7 J2 \, h0 g0 R9 }//-----------------------------------------------------------------------------2 Z3 T/ c/ W1 @- F* X7 @
    void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )( \. O" q+ b; g# k
    {
    0 I, l; g/ q) L8 ?    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    " o) D" w7 k9 c8 H* @2 y                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );1 ~. u& z) ~, X
    }</P>+ g7 ?7 [, F+ L+ f; n: n) t0 Y
    / H1 ?. s( i* D4 a" i
    <>1 \3 V' g" Y" q: ?
    //-----------------------------------------------------------------------------
    ) W  n: z% [1 r7 P4 i2 k! o// Name: 6 F! u# k: N- D3 |5 B( \- x( B0 j
    // Desc:
    * ?& e8 \: d- M& H; B  L+ o! y//-----------------------------------------------------------------------------  w+ ]  N7 K& B( E- W
    void CMazeServer:ockCell( DWORD x, DWORD y )
    $ r+ j9 h; n( f{" E* A: E' g: u$ ]+ x* f5 W* p
        if( x == 0xffff )! N: ]  L; _8 u
            m_OffMapLock.Enter();
    % \; `9 [3 {' m& X    else
    1 h4 O3 N; N- O  E, s; o/ L4 Y        m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    * Q1 s0 ?) w; l$ _}</P>
    6 s$ w) L4 Q- J
    9 v- i' S9 \8 j% _4 j! C9 I. L<>% C, p! `0 ?& {6 u* S) k3 x0 U# `
    //-----------------------------------------------------------------------------+ @9 A) M9 c% H" h3 y
    // Name:
    6 C' j8 v6 b) ?0 J) V/ q6 H// Desc:
    4 m0 \" T+ K% L//-----------------------------------------------------------------------------
    ' {0 c4 B  w7 U6 z2 R3 X5 ovoid CMazeServer::UnlockCell( DWORD x, DWORD y )+ @* |1 q1 x; m; ]7 U' Q
    {
    / x" X; A& n  I    if( x == 0xffff )9 P$ v/ A1 u1 Z3 J& W7 I/ W
            m_OffMapLock.Leave();
    0 \1 m; ~: R, o6 D; |7 S- @    else
    + m' {7 A# R& V; I% E! I        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);" R6 e/ V! j& Q: H; A9 @5 U
    }</P>
    + @, A/ e  z- z) E
    # `' T4 V3 ~1 l0 G3 R% a<>% [1 G9 j- P& j" i* A
    //-----------------------------------------------------------------------------! h( Z+ Y9 J  o
    // Name:
    2 |' a9 L& M# a* _1 ]% E! U" ]8 m// Desc:
    1 D* Y; d$ a+ t, d//-----------------------------------------------------------------------------
    ! b% ~% G. I: ~6 [" Pvoid CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    + r0 D& q3 r* ], y6 y{
    ) k6 ?( j' j, ]  y! b. h5 S" Q    if( x1 == x2 &amp;&amp; y1 == y2 )) R  H" Q8 {% C$ y6 ^0 v# [
        {
    0 R) g; i4 D7 Y        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    0 I. H5 D7 c6 ~; S4 Y            LockCell( x1, y1 );
    ( G; n$ [' u& _% J        else( I" Y4 M% b7 D. ~' T
                m_OffMapLock.Enter();</P>7 Q& N+ O0 |( s
    <>        return;
    ; ^' @8 H1 k. x9 F! l' }$ V+ b    }</P>4 B, ?- r% o% g+ V( @8 m% y
    <>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    ) Q$ U4 _8 E3 h2 i  e9 Z9 w, e    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    $ U( g+ G9 b, w    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    4 x1 y; Y  N% v    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>; t+ w$ _. h$ K
    <>    if( x1 == 0xffff )
    % @- C! u8 ]# z8 X( G    {* F7 i0 `4 [1 z6 Z6 V
            m_OffMapLock.Enter();! z  ]& K  V6 [, V) Q
            m_LockGrid.LockCell(x2shift,y2shift);! W( P, ]. i" t1 j6 S
        }6 S7 L2 E, l. Q. `) Z% U
        else if( x2 == 0xffff )% O8 F2 F# f; c6 Z8 v
        {% ^- a$ p; Z! Y8 a% N- u3 A
            m_OffMapLock.Enter();
    ; ?" p  {9 w. w& G5 ^% F        m_LockGrid.LockCell(x1shift,y1shift);
    3 s3 w, N6 \, z! l+ J2 t% w+ d    }
      u& u) _* f7 T3 H, |( l( b    else 6 t! c3 }7 o* n- s- t7 C
        {
    + `1 K; }/ P: R8 t! w3 ?        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);5 @3 \0 W- W- I  K. i" s, U
        }9 Q- W, S3 w0 t7 x
    }</P>
    ' F8 E0 R3 z; l; Y% _& J0 m1 [2 ]# J3 I) V
    <>1 P% ~2 E2 B' \4 R! t: _1 K
    //-----------------------------------------------------------------------------
    ' ]6 Q' O$ l4 q7 L0 o& @/ {// Name: 5 ?) f  \4 d* r! r2 p- \
    // Desc:
    7 ?0 P3 p- s3 E+ Q' R  q//-----------------------------------------------------------------------------
    ' [8 `6 D6 |6 H/ f: x& o( C& I0 t- ^4 Yvoid CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )! `3 R3 ^/ Z5 @; E" l: |+ {
    {+ N5 b( O$ M) Z. w1 n$ ~5 r2 U
        if( x1 == x2 &amp;&amp; y1 == y2 )
    ' g1 c) i2 l/ r" o/ D; j& L4 R    {
    5 K( |+ N9 R: R9 d% \8 K. G6 H0 {        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )7 [: ]2 l8 r  ^0 f" J6 Q
                UnlockCell( x1, y1 );
    * v, y3 q! d2 G2 }        else
    9 K: p6 k* `) ?  V& @- n  U+ u            m_OffMapLock.Leave();</P>. ?/ Y: u1 J: k1 s* b
    <>        return;/ W: P! n3 m4 G
        }</P>
    , |8 n' K, h0 @% F6 k<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;5 R6 M4 S3 H% P
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;: P* Z& f4 O$ T* U. Z4 s  B( S
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    ; @) m. {1 {/ x4 Z4 w( O) G    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>& O4 U8 y( l1 C$ L/ o
    <P>    if( x1 == 0xffff ), }, H1 _, u! {
        {# F+ c4 s" G4 J( X
            m_LockGrid.UnlockCell(x2shift,y2shift);
    $ Y. K$ M% |3 q7 M: L        m_OffMapLock.Leave();- m! x  p! Z( }* ~2 P1 x: V3 l
        }
      u  v# y' N8 t* F- h: j+ ~3 `    else if( x2 == 0xffff )
    1 v2 \: o0 h. J0 Q* A  T0 Y0 Z8 N/ |& E    {8 _. V; t) i% L6 f5 o7 ]
            m_LockGrid.UnlockCell(x1shift,y1shift);/ {8 y9 A; k; D0 _+ ~
            m_OffMapLock.Leave();
    : i' n: J$ H. A# Z1 H6 u    }, F! T- s& n4 R) x7 X9 h
        else
    % D! A7 `! k& e" D: s, y5 `3 L    {
    " K. e1 s9 z; F6 u/ }( r        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
    ( e) Q0 M! ^& J    }8 N8 G8 e( l2 O6 V/ q$ q% h3 r' q# v
    }</P>4 X& K5 ^) w2 O% d% ?: y7 g

    , e5 D4 T7 ~, ?" J+ S# y- \: a! m<P>/ O8 Y8 t5 w% {0 q: K8 N4 a
    //-----------------------------------------------------------------------------
    4 W  W: Y0 m4 e8 j// Name:
    3 K* q1 C. S$ ~" X* C7 s: M, v9 G// Desc: ( t3 Q& N9 ^2 c" p1 |
    //------------------------------------------------------------------------------ P6 v. g8 `- V" C' C
    void CMazeServer::OnAddConnection( DWORD id ); \/ `' K4 D% z" K4 i5 s3 I
    {
    . p7 M4 l& s6 r7 w0 Q, L    m_AddRemoveLock.Enter();</P>
    6 j/ T& W. g, U5 f9 R<P>    // Increment our count of players
    6 \5 e6 h3 h/ l; q    m_dwPlayerCount++;
      Q; d9 D" K; u9 s- e    if( m_dwLogLevel &gt; 0 )& G( A4 g& l6 ~- T9 Q9 ]2 j
        {% E- w  v0 g  F' ?# V
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );/ @- [& q/ r% f
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );# N7 @; r; G3 ^/ }) r3 h" J- d- V* I
        }</P>
    * M3 j! d- s3 q; C' R' B1 h<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    8 f+ S8 I' h: v" K1 M( t0 t# w        m_dwPeakPlayerCount = m_dwPlayerCount;</P>. W3 V0 Q- i( O. f$ f
    <P>    // Create a player for this client0 E( J: F9 K" \, G% T4 V9 @) N- Y
        PlayerData* pPlayerData = CreatePlayerData();
    3 H! l0 t& j7 J1 U# ^% I4 I0 k    if( pPlayerData == NULL )/ p  u+ I5 B4 U; w+ v. ]
        {2 @+ A: s! J! N- Q! ?
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
    4 ]8 w, K6 b) E, v        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );) ^& X! x3 C; K% Z5 }# a) ]% z
            m_AddRemoveLock.Leave();/ q' |% u/ X2 ^0 X  a
            return;* R5 l& W$ U* K/ n
        }</P>7 I7 K) l, {; b. F
    <P>    // Store that pointer as local player data' v# Y, V8 T, m6 I* u4 }$ J% K
        SetPlayerDataForID( id, pPlayerData );</P>9 C$ u5 r0 p- O
    <P>    // Grab net config into to send to client3 ^6 x2 |1 M6 ^3 Z3 H* R, K
        m_ClientNetConfigLock.Enter();
    0 c/ m% f, A  q  X$ S  v    ServerConfigPacket packet( m_ClientNetConfig );- ~) I+ o3 t9 U* @/ w" {
        m_ClientNetConfigLock.Leave();</P>$ g- [$ g, w/ h) y
    <P>    // Send it' B8 E/ Q! J1 w* S) U7 k
        SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>$ o) P* \( o/ J+ u) w* w5 Y
    <P>    m_AddRemoveLock.Leave();
    0 H$ N5 o/ }& r! A8 A}</P>
    % I; R1 h9 b3 r& u) M8 _6 C" O0 q) V9 O. ]# e$ D6 U) A
    <P>
    " T) I9 H& M, R//-----------------------------------------------------------------------------
    ) K7 H# k& z0 d+ R; Q  g8 A9 H- _8 ~// Name: 5 ?& k: `1 |( W$ H% \. G" ^
    // Desc:
    ( a. J1 f7 {8 M* b5 p//-----------------------------------------------------------------------------: e/ F9 Y( O* u/ D; ]) m! @
    void CMazeServer::OnRemoveConnection( DWORD id )* Z9 J; z  D! n' e7 ]+ r! N
    {
    7 I4 K" N3 B* E; Z    m_AddRemoveLock.Enter();</P>
    9 q9 d9 m4 c/ a1 i% _! w8 Q<P>    // Decrement count of players
    3 E' }1 k/ g+ n4 e    m_dwPlayerCount--;</P>* V/ M, m; r6 T, Z. T! k
    <P>    if( m_dwLogLevel &gt; 0 )
    , v/ k; c3 R. e2 }! v    {
    ) T* C. S8 m& }; j) J2 z* ^( f( R        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
    / Q  J& v" O9 m7 _5 b5 y6 |3 F        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );4 t: c3 C4 M7 u5 z) b. L
        }</P>
    7 G1 ^% f# Y% W3 W$ m' t<P>    // Find playerdata for this client; p. P7 k7 N( s, m: s/ M4 d
        PlayerData* pPlayerData = GetPlayerDataForID( id );+ p" g( k+ Y! |  Q: e6 T
        if( pPlayerData != NULL )' t& T4 ]- _: X' a3 b, Q1 ~
        {+ d$ j/ w( v9 U7 s+ N: T
            // Destroy it
    , z/ Z+ E- K: h3 b* t        RemovePlayerDataID( pPlayerData );4 X7 C# x9 M+ l0 W5 F
            DestroyPlayerData( pPlayerData );; i' m* y8 ^) b/ \& N
        }</P>& d! n  t# k9 \5 ~# ^! q
    <P>    m_AddRemoveLock.Leave();
    0 O' T! c; d! k4 H% d2 Y}</P>
    9 W7 l% q  e  M, b& y1 n! Z- ]9 c; o( v$ f- V3 ?; k% s9 i$ G" T
    <P>; f0 Z  y8 ]0 k6 e) ^4 p: O( h
    //-----------------------------------------------------------------------------
    - M. f1 J0 X/ W1 o6 ?' R1 E// Name: : a) Y2 E$ w( T# r# p9 m, E
    // Desc:
    8 V) J6 v2 J! B* j5 m5 K2 Q: h//-----------------------------------------------------------------------------
    ' B, e! I0 u8 E3 YHRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )
    % c8 h% K: X9 x8 E: T: u0 g{
    0 ]! A* l& q8 H$ f    BOOL fFoundSize = FALSE;</P>+ I0 l7 P5 V) H: ^( Q
    <P>    // Increment the number of thread we have in this process.
    6 o& O4 A6 O7 v  b    m_csThreadCountLock.Enter();</P>
    1 v7 I  U' p* k! d<P>    //Get the start time of when we entered the message handler.$ K( _3 e3 o( F) f+ a
        FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
    : O! O) x1 `! _; C0 t4 X<P>    m_wActiveThreadCount++;
    4 i) [1 b: @& f. i    if(m_wActiveThreadCount &gt; m_wMaxThreadCount), T5 p2 s2 @, t! W9 A
            m_wMaxThreadCount = m_wActiveThreadCount;6 z: |/ `: c; ?% i* l3 h
       
    . ]3 @8 Y7 \. e$ M" U    // Calculate and average.
    ) A2 m+ R( `$ r! r! p    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
    5 J- b- W5 ]8 @6 f    m_fAvgThreadCount += fdiff/32;5 k: b' g5 p  Q; i; w7 J
        ! S6 L6 N3 t( a9 f% q
        m_csThreadCountLock.Leave();</P>8 M" h+ U' W* M, A
    <P>; K/ \2 c) c! `9 Z1 a
        ClientPacket* pClientPack = (ClientPacket*)pData;5 ]' i) z0 P# w. [& T6 B
        switch( pClientPack-&gt;wType )9 L/ d  ?% U* m) B: s  T) z
        {* l% |3 |' V& r" t  f& O8 h. k/ O
            case PACKETTYPE_CLIENT_POS:
    # _! M4 a) a' X            
    * T7 y9 j- H6 W% W# I            // Check to see if the packet has a valid size. Including % H- R  Z# q- f
                // the custom pack size.
    & F1 e0 [) L9 V1 }9 t% _            if( size &lt; sizeof(ClientPosPacket))
    - a- B- w0 @# @                fFoundSize = FALSE;
    , m4 ?/ Z" n" m            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))
    . E6 `) Y' {# c' ]                fFoundSize = FALSE;0 P+ U& Q3 @6 e
                else
      C! _3 p4 _! q                fFoundSize = TRUE;</P>2 O! F8 ?4 d& Z, X! b# ~0 z
    <P>            // If valid sized packet, handle the position.
    5 H" A( u) h& A. n& x7 o6 I            if(fFoundSize)
    ' H5 T' N, R9 S7 e6 D                HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );: T3 k. Z. J6 J. ^& B3 \& X
                else
    ) @8 ~0 g. |! z" {                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>% x2 ]& L- v8 A8 _: s
    <P>            break;</P>
    ; Z, \, z7 ~7 v3 a% E! h' q/ [, [. _6 V/ J<P>        case PACKETTYPE_CLIENT_VERSION:
    8 \" \4 p1 @/ \" X- r5 i# [7 J            if( size == sizeof(ClientVersionPacket) )( p6 q7 h7 c4 q) b4 m( E
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );0 h3 ^0 X8 N! C7 d7 o
                else3 ^$ x0 N& A) ]/ x2 l8 B! s
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    9 m' v: E; t  i0 D            break;</P>  p9 V' [7 L. k
    <P>        case PACKETTYPE_SERVER_CONFIG:</P>" J& W* o% a/ i0 i4 c) }5 o
    <P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>/ t6 V. ?# I( m. D5 C$ D9 W
    <P>            break;2 V# E2 z4 |$ J" m" ^$ m5 f
            default:: C; N1 O; S4 l+ P8 x% C
                HandleUnknownPacket( dwFrom, pClientPack, size );
    / F9 J) |2 u- m. q- H0 ~            break;, n# {8 J! k3 J9 q
        }</P>' n- g, o8 f& |  X+ h* `* X! b
    <P>    //If the user wants to hold the thread, Sleep for given amount of time.
    ) R/ T. q& d$ o    if ( m_dwServerThreadWait &gt; 0 )
    5 o# G7 e& ?( X5 q% N7 m- s    {& q7 J7 Q7 f6 C4 n+ `
            Sleep( m_dwServerThreadWait );
    * z$ F+ J2 M7 ~7 |    }+ A# S/ Y* _$ M- v( _
        2 |  o  k8 O: T9 Y
        // Retrieve thread data for this process.
    1 ?/ Q% n/ A/ F    m_csThreadCountLock.Enter();</P>! S7 _- u( W! M
    <P>    m_wActiveThreadCount--;</P>
    + G. Z+ c$ d. g" k$ a<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
    ) d+ e( }5 O& c$ g) [    m_fAvgThreadTime += fDiffTime/32;</P>
    0 ?0 i7 T: s; h$ U5 `<P>    //Get the Max time in the thread.; [) p' F  K( j2 O1 T4 V
        if ( fDiffTime &gt; m_fMaxThreadTime )+ z7 o# Y7 l, h5 P- p: B) t( P6 p5 M
        {
    / O3 _& [4 c% {& m        m_fMaxThreadTime = fDiffTime;
    ' x7 u$ O, Q+ W8 f    }</P>; g" Y( M3 a; {$ O( e
    <P>    m_csThreadCountLock.Leave();</P>
    : C5 m& [/ W$ Z8 w6 ]<P>    return S_OK;  O; ^* l4 O- }9 O4 t
    }</P>1 m  O* H( x- c4 x2 @

    - \' _; [2 }1 d8 ~. J) S<P>//-----------------------------------------------------------------------------$ E+ H5 J+ b/ c! ?+ W7 e; u
    // Name:
    ( w' }2 v0 N, v- R// Desc: ! X0 _' [% W5 s& z) w+ A
    //-----------------------------------------------------------------------------
    8 O. v8 e+ A3 x2 Q; x8 G% D+ T  Q) TBOOL CMazeServer::IsValidPackSize( DWORD dwSize )! y0 Q& ~4 I. f# @  s, w. r; D" [
    {
    & H( ?6 B) T- J8 u, ]# r2 C    BOOL fFoundSize = FALSE;
    ( P3 \2 w! S: u9 ~* d! L3 h6 ]    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;
    $ z. d* {: z+ U! k! X) j    5 }7 }$ Q" S& h% d/ _9 o
        // Check through the array of valid pack sizes.
    - S$ R5 E1 i* c: Y# @  D0 p! a    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation]); I/ O3 S0 B9 c! C5 G. z7 A
        {
    - o5 u! b$ s0 d/ [9 m" P% V        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)
    0 o  ?- S* s6 x; ~* c% R4 I- R        {
    2 U, ~1 \% N0 P& b            if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    - A% D8 Q8 O7 }            {# R3 r( `1 K; f" _2 M
                    // Found valid size in the array.
    , B1 l' A& Z. u/ D/ P' H0 X. h                fFoundSize = TRUE;# s) {* D7 O/ c: I+ _7 Q5 x/ l
                    break;
    2 l7 o. R( ]1 e$ L" `+ X1 [& Y            }, H- x5 n6 B) x9 A
                if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
    4 f" Q: M, Y1 C+ C6 _+ |$ e        }
    : @" M* V8 D4 M' q    }% @  i3 w. h; E8 R
        else
    ( s6 r6 L% [- |5 S    {
      ?' a7 A1 I. ]/ F" n9 ~        fFoundSize = TRUE;
    8 z8 v  T+ d! F/ u3 Y5 F    }</P>
    : A3 Z; a1 E6 R; ]% ~<P>    return fFoundSize;1 x$ u4 l0 z/ x% u  H
    }</P>
    1 ]; Q( K* ?: x- d& {8 h<P>) \- O0 G& _; o
    //-----------------------------------------------------------------------------
    $ o7 f" Z' s# a6 |// Name:
    ! [) L; H) B  H$ z// Desc: 3 `5 i" m( q! O
    //-----------------------------------------------------------------------------8 C. X- ]$ b: \  ^3 W
    void CMazeServer::OnSessionLost( DWORD dwReason )
    ) L7 M! p  A8 X1 ]) D; I* X& T{0 _) J( S9 M$ }& N4 y: u0 l
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
    & Z1 J- w$ x. l- y}</P>
    * n: n& v9 m& P. @; l% H
    : E" b! D! X0 e$ b+ n<P>  N+ H6 Z8 Q5 F' J' n9 o. P
    //-----------------------------------------------------------------------------
    ' b5 N5 _  ~0 Q// Name:
    4 J/ J" W# S/ ?1 Z+ u, m0 I& R5 w// Desc:
    # w- g# \( Z" A& k$ S0 d2 a//-----------------------------------------------------------------------------
    4 ^7 F. q: m- d5 [+ b" q! l5 _PlayerData* CMazeServer::CreatePlayerData()
    7 G  m/ i- o; s6 W& n2 w' T{
    0 a. R! |6 j! s. k4 _: ~, v    m_PlayerDataListLock.Enter();</P>! i( e, _1 d) [
    <P>    // Grab first free player in the list8 T7 `4 t8 K' p  t
        PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>/ C. d/ C$ A1 u; S
    <P>    if( pPlayerData )( h& z* y* [1 s8 N5 G
        {
    , ~4 t4 C1 K( J' z9 N8 y        LockPlayerData( pPlayerData );</P>
    ) S  u3 z6 f0 V0 v6 a* V0 [<P>        // Got one, so remove it from the free list
    ' J" u' H% i* ~& w        if( pPlayerData-&gt;pPrevious )
    + L3 d5 z4 S( \* S3 E$ q. p2 |            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;6 P# T) H* f: t. k6 e. Y( w
            if( pPlayerData-&gt;pNext )
    # [0 V2 f7 C, j9 I            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;0 @. j. J1 `1 T2 M$ [2 r( }/ s
            m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>7 @$ s( O, f0 \' b, |" s& T
    <P>        // Add it to the active list4 v( h9 p1 V5 \$ q  d) _
            if( m_pFirstActivePlayerData )
    ; Y; d( o+ S) D2 G  m! \            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;* K% O, o/ A# O% p9 H
            pPlayerData-&gt;pNext = m_pFirstActivePlayerData;9 h) ^5 N1 T# r7 i
            pPlayerData-&gt;pPrevious = NULL;0 n% _. Z  h# M3 o7 j8 L
            m_pFirstActivePlayerData = pPlayerData;</P>
    ) c* c; m' X  k% \<P>        // Update count of players" u. `9 }0 H9 G+ W7 W! w+ Z
            m_dwActivePlayerDataCount++;</P>
    ' r* C; ~9 R6 t' {<P>        // Generate the ID for this player, U& r4 [$ r6 W* ^8 h
            m_dwPlayerDataUniqueValue++;7 E. x) Y: L3 I$ }* I
            pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
      @  ?+ ?' u1 S& I& I. u* G" ^<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;2 ]1 T& M3 O# d1 i! g: E, G
            pPlayerData-&gt;NetID = 0;
    % K6 M- w$ z( [1 F  i        pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>
    ' C7 I) W+ R1 q, U6 j( j; L<P>        // Insert into the "off-map" cell
    - o  C$ c/ d, j& K        pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;; x3 L+ _$ j0 V1 ~8 M; G% J
            pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;
    # N. j# ]: _0 \7 |        m_OffMapLock.Enter();# Z' F' ?9 D+ P
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;4 s. r4 d1 n. V7 ]. ?
            m_OffMapCell.pFirstPlayerData = pPlayerData;
    1 P2 B+ o2 ?4 n0 r0 K( U4 ]        m_OffMapLock.Leave();</P>8 l/ o5 l! v7 M; \3 Z
    <P>        // Mark as active1 Z  c8 M6 N3 h/ s7 [
            pPlayerData-&gt;bActive = TRUE;</P>
    " o; o+ O" L- g  t' l3 u<P>        UnlockPlayerData( pPlayerData );8 m/ |( v+ n- P; L5 b# R6 a( S3 x
        }</P>
    7 P4 N$ N7 S: B5 ~4 ?% b! n<P>    m_PlayerDataListLock.Leave();</P>
    $ o) A0 M  P1 ^9 }4 _" x0 K' B% _' j: g<P>    return pPlayerData;
    , X8 R( J/ I" a. G}</P>4 l& e! }6 T/ I6 k8 W1 U1 V6 ?! I

    0 W  K7 }0 H; M) m- W0 k6 c<P>
    9 L+ @6 |& l* Q//-----------------------------------------------------------------------------  J1 a0 f7 H# x/ U8 E2 j
    // Name: ; `; M4 B2 ]$ N
    // Desc:
    3 p% D+ ^& H* l1 Y//-----------------------------------------------------------------------------
    8 T+ c2 J5 |5 p$ B5 Yvoid CMazeServer:estroyPlayerData( PlayerData* pPlayerData )4 d4 h' }  C  Z& T, D/ x; ^4 ]
    {
    # M4 U6 u% ?$ R# A' e$ W& f2 `    m_PlayerDataListLock.Enter();
    4 }( |5 m4 }4 N4 H    LockPlayerData( pPlayerData );</P>: A/ o4 j1 i/ Y, G+ a7 [2 R
    <P>    // Remove the player from its cell
    1 C& Z* U+ E+ l* N( W: O2 o    RemovePlayerDataFromCell( pPlayerData );</P>
    , j3 O) v' D; {6 c# s<P>    // Mark as inactive
    0 d) ?# F/ o8 p! x4 q- C    pPlayerData-&gt;bActive = FALSE;</P>
    - d2 {* d) u/ J) P0 y( p, c<P>    // Remove player from active list
    * R* G8 B+ q: |" N. Z7 P& r( ?- P    if( pPlayerData-&gt;pPrevious )# ~4 e: r& g& |* n0 j
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    , c2 q- ?/ h7 d& B  `8 Q8 Q    if( pPlayerData-&gt;pNext )
    % A0 S% q* j: y2 W! T! q7 l        pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>
    9 L. a, j( N- v2 h/ ]: }( j<P>    if( m_pFirstActivePlayerData == pPlayerData )
    2 R; j; \9 U& }+ T$ O        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>
    / |1 I* p" s4 I5 p  C5 _0 m<P>    // Add it to the free list
    , S% [; H- M* B    if( m_pFirstFreePlayerData )
    6 z. w# h! K+ \$ _1 R        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
    9 E' ^0 s8 ], X" e) q& W  U1 C    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;
    % D9 [8 ^7 Q7 L* g, Q- B, O    pPlayerData-&gt;pPrevious = NULL;3 I8 ]4 {( q  x
        m_pFirstFreePlayerData = pPlayerData;</P>
    5 Z3 o6 @, f& P! a<P>    // Update count of players
    5 A$ ]; x2 B$ t    m_dwActivePlayerDataCount--;</P>+ r0 ^  f6 m1 P6 \4 \+ M, i' B( s
    <P>    UnlockPlayerData( pPlayerData );1 Z/ v0 H2 [. A0 c' k
        m_PlayerDataListLock.Leave();
    - R2 {% U/ P+ T3 o8 k" t2 B/ L}</P>
      y1 M2 T' y) I5 O0 H) E5 ~9 k" ?
    / E- Y9 X+ _- b' _/ G% Q<P>
    9 Y( o% b& a1 O+ u7 I1 j, i3 y//-----------------------------------------------------------------------------( ~0 M& r# i8 m. C. G
    // Name: ! p/ y* Y2 r2 N' r
    // Desc: $ x1 @9 M! L. Y) j( M1 v
    //-----------------------------------------------------------------------------2 `9 @3 J' G. U! k" R( g" F) t
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )$ D" I& i( r- |0 y; Q. c
    {% M5 j+ [/ d, W  t, {; N2 q0 a
        // Lock the player* z% q+ [7 ~# x1 I; Z) F0 C
        LockPlayerData( pPlayerData );</P>
    , q4 a! t% O0 i; E! V3 E<P>    // Lock the cell the player is in. j6 q! j. ?; T
        ServerCell* pCell;
    1 l- g  k* h8 p1 u$ g    if( pPlayerData-&gt;wCellX == 0xffff )' \, D/ J9 \6 B$ t2 l: H
        {7 g# O8 ]- f  p5 }+ ?7 s
            m_OffMapLock.Enter();# ^- ^0 H. x/ c0 b  G0 Y
            pCell = &amp;m_OffMapCell;( x) d" E) q$ o! q' r2 w8 w
        }
    $ I4 Y- p7 z1 L6 {# ~+ F. U    else
    1 I, G  q) P" R) p) D( ]. c: ]' y0 ^    {: h2 i; m1 ]+ s  Y5 x" S
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );& i+ |0 C3 {! z' }3 t
            pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];6 [' [& B- ^. f/ m& B. h% ^
        }</P>* `/ r( y+ L; R( f5 s" {$ E. M
    <P>    // Remove it from the cell" R; g7 J* d( k. R1 `  Y% o
        PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    7 y9 h6 [0 U, `# l    PlayerData* pPrev = NULL;
    9 L1 q+ u! Y. _/ Q$ ^( c    while ( pPt )1 ?$ u) x! o2 x: a- d2 H
        {5 Y! o3 n  c$ d  u" L6 f! Z8 `5 w
            if( pPt == pPlayerData )" }+ U. D: C+ B4 N; l1 [: s7 v
            {5 j& v& j/ R5 b, Y2 N8 |1 X6 L
                if( pPrev )9 [' ^5 q# \! b/ z
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    * c, a' P# o9 H& ~# {$ N            else
    6 J# H$ _& }. O# c2 `                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
    - x; h" }  k, S( D/ ]<P>            pPlayerData-&gt;pNextInCell = NULL;
    ( p, l; m. ]. ?4 o( U            break;
    # B$ I8 Z+ N+ b5 H; r6 f        }1 J; U( S9 l1 w- B: t- Q
            pPrev = pPt;
    & b  K" ^) ^: k* [3 _! |7 A        pPt = pPt-&gt;pNextInCell;
    6 C: k0 ^% l4 r% ~$ N    }</P>
    + L- n5 O- l& U% Y# A<P>    // Unlock the cell% j; t+ q9 [; C. A: e8 b
        if( pPlayerData-&gt;wCellX == 0xffff )8 e; ?( ?; @  L: y: K
            m_OffMapLock.Leave();  i2 ~3 G& l$ I
        else
    , w5 B. Q1 U0 P  w: S. r        UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>
    . i" R3 o, j% }1 Z6 h3 V" X; n<P>    // Unlock the player
    ; _8 M7 l" |" X' H+ M8 [    UnlockPlayerData( pPlayerData );1 i4 _+ G* K- }6 F8 H! a, P
    }</P>) l& z2 [4 [, U; M) X* {

    8 l0 Z3 L2 `' ?: t/ ~5 ^) l$ T& q<P>
    $ f9 R) ^8 w- x" Q' ]2 y4 F& {' v//------------------------------------------------------------------------------ o5 ^6 _; N' e; }7 p3 U+ o- q% m
    // Name: 8 t4 T' I9 F0 u' T( _4 ?
    // Desc:
      d0 m1 ]6 `* h! l, h' r( G) U//-----------------------------------------------------------------------------
    # n7 c# H' L: d, b3 q7 e* b& nvoid CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )7 r7 y0 v  n7 e0 Y9 x8 ]" I
    {
    9 f* O& B- |3 b, P: E0 a    ServerCell* pCell = GetCell( pPlayerData );+ T0 G: k! Y) ^- e
        PlayerData* pPt  = pCell-&gt;pFirstPlayerData;/ v; n1 d' m; a0 r/ |* N
        PlayerData* pPrev = NULL;# P" u% E1 e3 J- r8 x
        while ( pPt )! r1 v: }" c# v* |+ S8 H* B6 Z
        {
    $ K2 ?% C- {( r/ F: J        if( pPt == pPlayerData )
    9 n' y" ~1 e- X4 W. D        {' K% H2 `8 ?" W! p6 }" K& n
                if( pPrev )% h5 A( o* x5 u- X; U" L0 ?
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    2 I4 y( P. e0 z/ M8 o; T2 i            else, B) U, _; l( K5 c$ O- h
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;
    ' C1 W0 L$ p  t3 }, Q' C1 J/ @            pPlayerData-&gt;pNextInCell = NULL;
    8 _3 i* f9 F4 t            break;% m/ k7 y+ A  `6 I9 w% U! I
            }! D% C& o4 T/ @9 a2 J5 B
            pPrev = pPt;
    7 @; ~: G" ~1 w+ E( Z        pPt = pPt-&gt;pNextInCell;! z, G, W* ^! _) W+ g
        }' D# m/ t6 ^( z& @; |. b
    }</P>+ y3 g2 z4 L. ?: |" s- s4 N

    1 S! {/ D7 W: R6 u0 s0 J. R<P>
    , O; R, Q# M3 O0 |//-----------------------------------------------------------------------------3 d: a5 B" a% A
    // Name:
    & ?: E% T- A8 F1 Q# W  ?3 f: [// Desc: - l' @# [0 {; ]7 |+ l6 {9 N5 z* [/ B
    //-----------------------------------------------------------------------------
    7 o. S! j" K9 K; S% Qvoid CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )  s& [  f4 t! x$ p( N; q( n, k7 P
    {+ ]" H3 R- v% F' E, C
        ServerCell* pCell   = GetCell( pPlayerData );# T% c2 f3 }# g4 A. [# t" h
        pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;1 y0 Y/ g% t4 V
        pCell-&gt;pFirstPlayerData = pPlayerData;
    : e: ~# f5 W9 t* a}</P>
    ( d5 l' _( w, i+ _- V' S4 ^- K3 J7 f8 ~1 \9 V7 {0 A
    <P>1 Z( U( ]- K0 w2 x" A4 e* q: v
    //-----------------------------------------------------------------------------
    ; W9 D1 I, N7 G! M! L// Name: ( }/ L4 v# H0 k1 G: `& N1 C
    // Desc: $ s* L  c* Q4 e1 n7 V1 |# G
    //-----------------------------------------------------------------------------& k: o9 w+ I# U2 \& e
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )
    ( v3 h2 m) T8 ~: H{
    9 Q% ?+ ]4 X- t" i* n    // Grab player for this client and lock it5 O' k  n1 m5 N! o
        PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );5 d' \9 S0 [3 Y3 [& z: T3 m
        if( pFromPlayer == NULL )
      ?! q  s/ I6 J% @! P    {
    5 `) J9 c+ _: l7 W2 |" G; `: k6 x        if( m_dwLogLevel &gt; 1 )
    7 K+ y6 L9 O9 e; }! t            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );
    ' H4 G8 ?" c( ~, _        return;
    7 A1 A8 A9 G% m4 s    }</P>+ k; V  W8 y, }# P, |
    <P>    LockPlayerData( pFromPlayer );</P>
    ' l; Y% s7 E% }. t<P>    if( FALSE == pFromPlayer-&gt;bAllow )/ l1 d/ Y1 u& c
        {
    # Z, B( ^3 O# S: i% M. Y* Q        if( m_dwLogLevel &gt; 0 )5 O) k5 D! A5 w. @
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
    5 l" y+ G/ i6 u, w* f<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );5 @5 T* C& |& W! u. N) L; |
            UnlockPlayerData( pFromPlayer );
    5 A, Z+ {& {- i; }1 w6 W        return;& E6 P% Y/ C& `
        }</P>3 e, S4 D0 a" T: W9 X
    <P>    // Compute the cell the player should be in now
    . V! Z3 f5 s, d% H! q    DWORD newcellx = int(pClientPosPack-&gt;fX);
    5 Z+ X4 s2 @/ [' [4 q    DWORD newcelly = int(pClientPosPack-&gt;fY);
    3 o/ E7 ?! l! w% a7 L2 i, k    DWORD oldcellx = pFromPlayer-&gt;wCellX;# H1 d: L6 v4 b4 j! V7 Y
        DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>0 E- f% {3 N" f% P! b
    <P>    // Have we moved cell?
      D. |# S  T8 r, Z    if( newcellx != oldcellx || newcelly != oldcelly )8 H4 }1 r. d- F. k/ l0 h- w8 y
        {
    ; S9 e( ?3 G% Y2 I9 K' u/ x1 z        // Yes, so lock the pair of cells in question& R- ^6 W5 U4 a% V) C7 C# ^
            LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
    ' Q0 Y2 c4 Z  g- G& h$ ]<P>        // Remove from old cell and add to new cell
    ( x0 _) [+ n/ S& ~! c        UnsafeRemovePlayerDataFromCell( pFromPlayer );
    , t2 L+ e" ]; x. Y        pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);- ?; ^: p& v2 @0 E
            UnsafeAddPlayerDataToCell( pFromPlayer );</P>/ G* e' v- l7 h7 e( E5 [$ Y9 X7 c9 b
    <P>        // Unlock cells) Z: T0 ~4 g1 G1 I
            UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );( r( U0 B1 H2 a- D- _" d
        }</P>% u% {; I$ ?& ]- M
    <P>    // Update player position' K) ~, N* j) }" j% g
        pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
    . l5 y, D8 o5 O    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    2 e1 o9 m# e0 k$ e3 f    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
    / @6 j) H& E6 H8 A<P>    // Allocate space to build the reply packet, and fill in header 4 Z3 F% Y  x7 U; J* q3 D) B; |
        DWORD dwAllocSize;, N0 b/ b0 l" S  L- c  T' r/ O
        ServerAckPacket* pSvrAckPack = NULL;</P>
    4 G- E# \" G- T8 x$ n$ E2 z<P>    // Begin by allocating a buffer sized according to. T; P7 b2 o$ v9 @$ P2 J9 D5 @
        // the current number of nearby players + 4.  This will give + H, I% F; h4 Q: c9 `' J
        // a little room for more players to come 'near' without resize, f& B+ t! H0 \- r2 j) l
        // the buffer.
    ( {& I- g7 F! i1 y% }, d9 k    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>1 X3 k, \: T) O! U) d7 n" b
    <P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    ! v& r/ o) v" |/ e    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );' ?  B$ p7 L' ?: V
        if( NULL == pSvrAckPack )' o  D* M( S2 J  C6 a4 ~
        {
    3 I$ c( l( n3 d' w8 g! Y        // Out of mem.  Cleanup and return
      L, A$ d/ t3 U6 w8 K3 J        UnlockPlayerData( pFromPlayer );6 x7 a" C% P7 K3 o
            return;         S7 s( r( w2 s3 \1 Q( q6 d
        }1 v* j. G4 K: R
        ZeroMemory( pSvrAckPack, dwAllocSize );</P>" }, X7 E0 x  U- f) `6 K2 B
    <P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);
    2 |2 e* A5 C; N: c6 H    pSvrAckPack-&gt;wPlayerStatePacketCount = 0;' I) p  H& J0 l4 r- h* i2 l( v
        PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>2 m3 h, [: i) H8 S, ~
    <P>    // Compute range of cells we're going to scan for players to send# D1 ~6 B- ?8 ?
        DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;
    : n2 C9 }7 ?4 F/ ?2 k    DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
    % f8 Y0 }8 k6 k  Z0 @    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;
    . x+ h$ f9 m% a4 U1 b    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>4 _. h% l% [* u; M: \, O' n+ ?
    <P>    // Lock that range of cells$ S% M' D. z8 g$ c( G# L
        LockRange( minx, miny, maxx, maxy );</P>
    9 T9 Z* R: V: A# h9 P<P>    // Scan through the cells, tagging player data onto the end of2 s% k. O6 Z" r; ]
        // our pSvrAckPacket until we run out of room
    * M4 T1 L, D+ E    for( DWORD y = miny; y &lt;= maxy; y++ )
    0 F2 `1 f% D9 L( K1 j( B    {
    . i( P( v# j/ a0 d9 |  E4 ~        for( DWORD x = minx; x &lt;= maxx; x++ )
    2 j. l6 e8 a" H/ |        {2 C1 w8 W5 O+ B
                PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;" Y- g9 C( D: B2 [
                while ( pCurPlayerData )
    * e2 f; V+ b3 M8 S            {
    ; |  M# I! H: o- Z0 \                if( pCurPlayerData != pFromPlayer )9 E' V; B. L3 U1 k: [
                    {2 H" a% W4 @) N' j3 |0 J, W. s
                        if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )
    & i4 W8 S3 K( I% ]- M                    {) m4 A/ |* [- ], w# ^! S
                            // Make sure pChunk is where we think it is
    3 |( c; m, l( p                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>. Z! C6 x7 T0 D7 D7 R. I
    <P>                        // There are more than just 4 new nearby players, so resize the 7 Q! r  ?" E7 z, ^+ G3 A* b8 x7 _
                            // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
    ; r8 H4 @, Z4 r+ s2 s  ^                        dwMaxPlayerStatePackets += 16;0 E2 V7 b5 Q+ [" R
                            dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
      S1 O  \2 G1 p) {  r# L5 W3 H7 L" Y! R                        ServerAckPacket* pNewSvrAckPack = NULL;! o9 R1 I! w( b- p+ r& _5 T
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    2 C2 |5 U, P  m- V# @0 {+ v' I1 c+ }                        if( NULL == pNewSvrAckPack )' L: |8 S8 V7 G6 L! ?, J
                            {
    0 s( j/ r; F4 e7 [* u% ]                            // Out of mem.  Cleanup and return3 m1 s, h+ t% W: _0 G( ?* G
                                free( pSvrAckPack );
    6 T  _. S' @1 ~9 Z& D                            UnlockRange( minx, miny, maxx, maxy );- j& Y" s4 h% o/ H6 l( i
                                UnlockPlayerData( pFromPlayer );; H( u/ q$ B9 W( @' n
                                return;      
    & I0 Z5 Q8 @3 q% G  o                        }</P>' p, i8 Z3 P5 ~( @# T. T
    <P>                        pSvrAckPack = pNewSvrAckPack;
    & w  G4 P  H: P+ q4 w7 j                        pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
    * n- }# ^% i. {- p* V5 U5 ?2 w7 u<P>                        // Make sure pChunk is still where its supposed to be% A! L. l, n9 Q/ {- F
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );, ^* i- y: T* {' O
                        }</P>+ K" p, ~& v1 y: u
    <P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;
    / I+ r9 o) d0 R6 O0 A5 z- l                    pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;2 _. W8 _* f& M; \9 U' C6 \
                        pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;# X, D& c: Y+ I/ a( i& `" M
                        pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;
    & F) D5 r6 ~6 s. g- j2 i. T                    pChunk++;% }/ V2 |2 o9 A
                        pSvrAckPack-&gt;wPlayerStatePacketCount++;
    4 |( F) j( `$ K( C  R; A8 P" F                }' `* B* q. |* m4 j7 K9 S
                    pCurPlayerData = pCurPlayerData-&gt;pNextInCell;
    % Y5 R1 J0 [, L% G3 W+ F4 b+ S3 k' s6 c) j            }
    3 R5 I% g9 G; k: W        }
    4 F9 J; S, m# [4 L    }</P>, X- Z: S; Z# i% b* m
    <P>    // Update the dwNumNearbyPlayers for this player, t$ J2 p& [  {. j, e
        pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>2 y$ o. n/ N* W5 s
    <P>    // Unlock range of cells
    $ V- d  R6 u# i) B9 a  ~    UnlockRange( minx, miny, maxx, maxy );</P>, _0 X4 c: q7 v; }7 O( b6 q9 j
    <P>    if( m_dwLogLevel &gt; 2 )
    6 o* J# a7 Z: \& L5 Y, _/ F    {* R5 ]* k/ X/ x6 s5 \6 l
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
      O% B/ |4 D0 q0 o- A) P6 u    }
    / X1 H, Z& k4 T  j/ C$ L* d    else if( m_dwLogLevel == 2 ), d2 s5 d# k/ H0 _3 g% @0 ]0 [
        {
    4 E& J' x, G/ G! m7 H: I        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    / t" u% P( l8 I& B        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )
    * e4 E) D3 f. M2 i7 O- ?        {
    ; v7 @' k  C/ c) j, [7 U5 J: g            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    / {; Q8 N: R: p5 v4 N. |            pFromPlayer-&gt;fLastDisplayTime = fTime;% ?( \  W; m% H- ^, y+ k4 a/ x% B
            }# C/ L; H1 [3 @
        }</P>
    * o# _! ]4 W/ P+ P% J- q<P>    // Unlock the playerdata
    $ e  K0 B1 \! S9 A/ R    UnlockPlayerData( pFromPlayer );</P>4 D% g. `7 \+ i' w/ d! D- H: @
    <P>    // Send acknowledgement back to client, including list of nearby players
    . X$ t1 P4 P8 C" O    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));) l/ d. O4 T# ]- z7 u6 ]
    ) F, ?- ^4 P2 ~! {- O2 e8 X
        // Pack the buffer with dummy data.
    6 H, C# `+ V! d+ U    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)3 w9 x4 |( R4 Z7 ]
        {$ q% _" D  O0 g7 k) v/ `0 l
            DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];. w# M! }% c" j( S8 ?- ~% `0 j
            VOID*   pTempBuffer = 0;</P>
    , [$ P2 \( B  M) z2 @<P>        pTempBuffer = malloc(dwBufferSize);, b' F) r! W1 N* @
            if( NULL == pTempBuffer )
    ! H: V; r/ E) X$ r$ W' i% y1 ?: @0 w! P        {8 w- J/ {$ g: |# {7 r! l7 R0 q
                //Out of memory* N7 A. y$ n% I% @( ^
                DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );- h; |, R5 b3 K: v/ ?! q
                free( pSvrAckPack );
    ) c5 V' H; O  n2 Y            return;6 }" U& H" U* D
            }</P>5 T( [& c1 ]" p
    <P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');
    ( ^. n/ t1 |% {4 ^2 w: n; a        memcpy(pTempBuffer, pSvrAckPack, acksize);</P>6 p3 Z- h, j5 j/ p" {: m8 P
    <P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );% m2 d* u  x6 u( }2 f; E- W5 m: q
       
    % X! l+ [5 j0 s. \        free(pTempBuffer);
      U- s! M5 j$ n+ W# H    }   
    5 m3 f* j+ o2 D6 @    else5 u# O+ O+ F6 ]5 x
        {& Y* t3 Z! J; ~( S# o( K, |
            SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );
    + Q4 c: p* S/ [( p. R5 h    }</P>
    2 B8 d" g7 i) d3 \0 |! ]7 ~: W<P>    free( pSvrAckPack );</P>
    ) a% A  I8 ?" ^<P>}</P>
    - M/ }# B' s" L7 O. }, ^$ `! p, v  ~' p0 y1 q6 v' ^
    <P>; _& e& R9 @0 h) ^7 }" }" _
    //-----------------------------------------------------------------------------
    ) U3 F& P+ i0 _6 P/ Y0 o5 f  j// Name: + U) t. @# D: g$ w9 d1 U1 \: E) D
    // Desc: : @+ u3 R3 Z5 [8 t* \8 Z1 _$ U$ B
    //-----------------------------------------------------------------------------
    : I: ~) Z: ^5 k- ?) H+ gvoid CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )! w# b& L. s8 A* M- ~
    {
    . r/ q$ E) F' G8 W0 w    // Grab playerdata for this client and lock it; R* [0 g# _7 O( o* J: H# b& l
        PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
    $ Y8 `2 a: Y) [    if( pPlayerData == NULL )
    $ o; I' }- f- [( W; j/ n. z6 C        return;* S9 }: F& X0 K7 C) }- H; q
        LockPlayerData( pPlayerData );</P>
    + E' d6 U, p, N0 r% J( C<P>    // Record the version number , m1 Z0 P6 b' G' G+ ~4 w+ `
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
    $ ?. l) a3 B' H, W7 H<P>    if( m_bLocalLoopback )0 T0 ?! ?( F! @( D& I
            pPlayerData-&gt;bAllow = TRUE;
    ) I& E+ G" R/ ?  ?% ?3 e    else1 G' E4 r9 j# P4 S$ q
            pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>, X$ N$ t2 m3 y
    <P>    if( m_dwLogLevel &gt; 0 )" A1 X* D. x5 j7 ^' \# |9 Q0 K
            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>
      O& p' w/ ?& }# W6 V, }<P>    if( FALSE == pPlayerData-&gt;bAllow )
    . H: M: K/ K3 Z2 F7 C    {
    , R8 Y2 O: a1 F% `0 |        if( m_dwLogLevel &gt; 0 )) b) W  j4 q* D! w
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>
    8 B  u' Y( r" s8 C6 ]9 R) S6 a+ ~7 K  e<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    # l) `4 P6 N3 S        UnlockPlayerData( pPlayerData );
    + Q% g9 J  E* u! u0 T        return;
    " G: F9 p2 g$ F- ^    }</P>
    / X: F3 T! B  Y4 p9 @* l) w+ ^<P>    // Unlock the playerdata7 j9 X% |( i/ i) E$ `  c( p4 V7 ?* @
        UnlockPlayerData( pPlayerData );</P>
    7 n' f* y+ ]; J( u& n<P>    // Send acknowledgement to client that the client was either accepted or rejected
    3 f2 Q8 E2 R8 U4 M0 `3 F' k    ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );
    6 Y/ L# t& H2 h* Q4 n2 P' O4 A; t    SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
    & I& g+ f# h; v: w* G+ T}</P>/ V% a, @3 x, A
    , c6 c4 j9 ]; n; [, C
    <P>
    9 o; h- S. z! W//-----------------------------------------------------------------------------$ Z7 }* W5 r1 H# H9 ^3 h$ r
    // Name:
    ' ?4 B$ k) w' e& t// Desc: 9 c- K$ u- Z7 P, ]8 e% T
    //-----------------------------------------------------------------------------
    9 Q, v+ L( j5 u# Y8 ~BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
    ; [. s. S" Q- [' x6 k+ i' T1 }{
    : ~& P2 s% s* |6 e0 b0 b    switch( dwClientVersion )
    7 I5 L6 j9 d  E    {
    . q; i  h  Y. G# [, I3 q        case 107: // only v107 is supported
    / f, W' ?& u  ]4 i5 z$ L; K! l+ V            return TRUE;0 e! o" V: w, [. g) h7 T1 y! n
            default:! k( A2 |  A- p9 i
                return FALSE;
    " V. Z, ^1 _# @, _5 h& @* M    }
    5 d# Q7 ?  K. S, A" n) U/ U  D}</P>: x# s2 e# i4 t3 d
    1 A6 j, S- O4 o* k
    <P>
    ' n0 i  n  {7 L8 i8 o//-----------------------------------------------------------------------------6 f; [+ R# F% H2 l
    // Name:
    5 ^- i) X  D# j- i/ r  |/ N4 d& G// Desc: ! m/ ~4 \, K3 l1 X/ o0 _  C
    //-----------------------------------------------------------------------------
    & w9 o0 d* c  E( z1 j5 p4 q  Pvoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )0 G/ Y; _/ h# A6 F6 A
    {0 _  G* O, A- @3 T* \8 g! {' u
        if( m_dwLogLevel &gt; 1 )$ T7 q2 t; v9 v/ i
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>
    5 X1 H) f9 z6 X+ N3 [! c<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );- ~# \2 S" E* V% ~* E3 l
    }</P>
    0 e8 j$ D. i/ x+ u
    + r4 c. {' V" n( }+ ^% E$ z- m<P>
    - J6 a; d% M* I- B! Q. \/ l" z//-----------------------------------------------------------------------------! Y9 Y7 y7 }! n) I
    // Name:
    + u4 A, t5 F1 i7 z* \0 h// Desc: * L4 U5 {/ }  y  q: Q- C
    //-----------------------------------------------------------------------------
    " W/ A( K# e2 y& d  ~- [9 c' cDWORD   CMazeServer::IDHash( DWORD id )
    0 s+ B0 [6 Y+ l, a( E{4 H9 L( @  P1 c
        DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);% ~9 S& P; D7 h  K8 K- y
        return hash;! z; Z8 B  u4 H" i  q1 Q
    }</P>- q6 s3 G, u) N. s1 E- I, A) l1 |: b4 g
    ) d+ d0 W- J" e+ G& R' O
    <P>
    & m9 E* Q! m! r//-----------------------------------------------------------------------------
    8 x+ `* f1 _. `* h# ]8 a' G// Name:
    1 S2 }" t0 X' S// Desc:
    5 M; \) C7 |3 Y& H9 @4 S//-----------------------------------------------------------------------------/ L; }3 \1 H2 _5 i/ t3 h/ _0 x
    void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
    8 @% h# v8 I! Z  R5 b3 u{& N3 H  R" y) X# b5 _: p
        // Hash the ID to a bucket number# X% t- g" ^* W& |
        DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
    ) Z; Y8 N+ v/ V% p7 \6 G$ l: T0 ]3 F<P>    // Lock that hash bucket
    + e8 @9 f- e5 s. ?    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;/ T0 I3 i' s$ `' u* n
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>0 L( z. X0 S- W. p4 x" p
    <P>    // Loop though players in bucket until we find the right one
    : V8 V# k- a) r, o6 p' b    PlayerData* pPt = m_pstIDHashBucket[bucket];
    , g5 t" ]$ s3 H) X& m    PlayerData* pPrev = NULL;
    7 ?# k$ H/ D  |! w" Q- u    while( pPt )
    % O0 [, S6 h( a( p' @/ _5 [& V    {* |0 _8 Y$ W% r
            if( pPt == pPlayerData )* a* Z# k, H# \+ _" d
                break;
    , e2 F; A) Z3 C9 G4 i        pPrev = pPt;/ ~" v/ ]! _2 y( z
            pPt = pPt-&gt;pNextInIDHashBucket;
    # h* C- a( o  N- k* ~    }</P>
    4 M% y; `( S9 w! |% U9 S# f<P>    if( pPt )# ]* b: D5 w# @. y& J# y
        {
    + r9 Z. S: B! P7 v$ y        if( pPrev )
    + K3 R3 {' ^1 v( r8 f  g; y# i0 Q+ j            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;
    0 I, ~* s+ c# N9 }1 H& y; |1 S        else# w) `% g& g5 X* L9 A- r; `- Z
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;0 ?: t$ J' H; P: w; ?
            pPt-&gt;pNextInIDHashBucket = NULL;
    9 J, d: i1 _: S  g0 Y9 U/ z1 R    }</P>
    / x3 ?* I% G' d<P>    // Unlock the hash bucket! o' I- j5 V, R7 U' o
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    ! u+ f0 Q6 W7 R/ K}</P>9 U# f! p1 M* B% d. k4 e) i: B
    & e' G* `& }2 m. m6 b; w
    <P>
    $ z- k) n: F' @$ O//-----------------------------------------------------------------------------9 P! l) ~& c' g2 t
    // Name:
    , n; M- N3 E" P! r  \5 ]// Desc: 5 R0 j) h2 {" w0 I
    //-----------------------------------------------------------------------------
    ! |1 u- ~* p4 v" \6 d  u2 b" bvoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )6 {& ?+ q7 V/ U; N6 d% Y) K' J1 P
    {
    , Z% v/ x& l0 |& f: p! [2 r% ^    // Make sure this player isn't added twice to the m_pstIDHashBucket[]
      P) I! P! [( u    // otherwise there will be a circular reference( L8 K$ m/ P6 j8 T8 |
        PlayerData* pSearch = GetPlayerDataForID( id );$ \( {5 ?+ P; h% e2 y
        if( pSearch != NULL ), \: G& ^' E3 p7 B4 P
            return;</P>
      z( n$ W; `  _( t0 u8 q# M<P>    // Hash the ID to a bucket number
    + M$ ~! Z1 e7 h& ^- }    DWORD   bucket = IDHash( id );</P>
    % y- W9 A9 ]( o5 g: W  ~" d1 x<P>    // Lock that hash bucket) G9 S' H# e9 l1 @, s( Z, v7 A
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    ' @" V: k; `: ?2 n8 F    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    / K# W$ k+ N* ?/ c<P>    // Add player onto hash bucket chain
    5 A( q8 E2 _# }5 ]+ l- p    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];* X9 u/ {. t$ j" Q7 c1 p' d
        m_pstIDHashBucket[bucket] = pPlayerData;</P>) v1 g# r6 E  m
    <P>    // Store net id in player
    7 J# y. [& C( X. b& ]( i    pPlayerData-&gt;NetID = id;</P>( P8 `+ S: l8 Q4 q( ?$ D% Q* \
    <P>    // Unlock the hash bucket  q3 M0 @7 _8 [* z  ~# E  o) ]! |" _
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();) r% F! G! G; U  t- h1 n
    }</P>
    & N+ j! p% ^; x- b  n* J( A7 k& \. I) F- o) ?1 |0 D  j
    <P>
    6 T* n, r0 |. r' g//-----------------------------------------------------------------------------! n) X6 l1 T8 N8 p0 Q! P
    // Name: / T+ r; D$ [# d* i8 j
    // Desc: * s+ o2 q+ x3 e: ?& u* ]. S  S
    //-----------------------------------------------------------------------------
    * D! l! q1 k7 iPlayerData* CMazeServer::GetPlayerDataForID( DWORD id )7 f, @- ]  C* }: j$ ?
    {. j* {$ R$ S0 d1 n
        // Hash the ID to a bucket number
    , [& I* H4 ]9 m8 O    DWORD   bucket = IDHash( id );</P>
    ( }0 W6 O& `' w<P>    // Lock that hash bucket
    ! j. X8 d! f1 w+ U" P# d# {    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    ' D! v) a9 ~) u% E    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    3 @4 Z4 x6 g9 E4 U2 O4 K<P>    // Loop though players in bucket until we find the right one. j2 f, ~; A  ]$ }3 H- o
        PlayerData* pPlayerData = m_pstIDHashBucket[bucket];- ^7 Y6 S2 C- ^( c. e: N. r
        while ( pPlayerData )
    : a. p* }: C6 z$ a+ w    {
      |3 i, M$ q/ @8 y        if( pPlayerData-&gt;NetID == id )
    0 V' Q) k% e5 l4 d& h: \            break;
    5 q" V3 K8 E( M: V+ H- q" T# Y        pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    : Z( |; W% N- i, ?! ]    }</P>
    9 A. }( X+ O9 c/ ~4 y<P>    // Unlock the hash bucket" k; F2 A4 {7 `$ y2 D- `4 ]$ }, }
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>: o, t9 F+ o0 u5 M, Q# h
    <P>    // Return the player we found (will be NULL if we couldn't find it)
    4 j) v: Q+ Q: a    return pPlayerData;- n# R3 w! z; c+ X4 O
    }</P>& I) `! \4 y4 S& g3 U' s

    & ~8 c0 g' s* {/ f* r  [6 E8 _7 _<P>
    7 D& y  I0 I  O* J0 b2 W' Q( j//-----------------------------------------------------------------------------, c$ e, P4 M, J0 ]7 @0 x9 x
    // Name: ; d! Q8 A) z1 w5 g( t$ ?8 N6 G
    // Desc: calls DisplayConnectionInfo for each connection in a round-robin manner4 J% a) h# P% Z$ U0 n* X
    //-----------------------------------------------------------------------------
    2 s0 g) f! @+ [void CMazeServer:isplayNextConnectionInfo()9 l3 z3 o- h4 d1 q5 h
    {
    ( {$ K3 h' \4 L6 n; e    if( m_pNet )- i+ g  f. ~  o! ~+ G0 w
        {& p* l- A" Y' W6 z
            // Find the player that was displayed the longest time ago, and display it., k7 W4 M+ b- P
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
    1 J7 g  D" X& ?8 J2 l7 L1 T  u7 D# M        PlayerData* pOldestPlayerData = NULL;/ h2 Z& q  q5 u4 \8 P! A3 S* D0 `' L
            FLOAT fOldestTime = 0.0f;</P>2 Z8 j7 b2 \+ v- r5 }& r
    <P>        m_PlayerDataListLock.Enter();</P>3 A1 q1 c- Q5 y$ d
    <P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;' e5 L6 W- X7 x8 _
            while ( pPlayerData )
    ; t1 _* K- b, i+ X/ ?        {
    ) [# y" t% ]9 |0 r! t& _            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
    , l2 z. s. k0 M+ U9 Y! a& O            {3 i' @" P$ W0 n0 q# z0 }1 ?  `
                    fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;( S8 u1 q3 G+ l" a' ]. |
                    pOldestPlayerData = pPlayerData;) N# ?; w& T( m7 Q
                }</P>* K9 E! H: q6 k2 E% o0 g
    <P>            pPlayerData = pPlayerData-&gt;pNext;
    3 N4 b& v& [7 f2 W' ]  e0 g2 f        }</P>
    8 T2 k& i* M# |- D$ R' W  A+ k<P>        // Display the player with the oldest CI field, and update its CI field.
    + W; S$ u" n/ O! D' @* T+ x% h        if( pOldestPlayerData )4 X8 ?: v/ V. c1 U, }5 K
            {& M: @' I1 V. C5 p' K& q
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
    9 b0 Y  l( x3 |0 W* U) {            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
    # ]1 r' X5 k% d$ T& T" B            pOldestPlayerData-&gt;fLastCITime = fCurTime;# k& [7 `: w' M  c
            }: \' Z: t; [) a( q" ^2 n. Z
            else9 c2 W5 t7 E" F. a; |
            {$ \5 ^- Y9 [$ o
                ConsolePrintf( SLINE_LOG, TEXT("No players found") );6 q( P: ?* r( C. L, c! c* n
            }</P>
    , r" a" S/ o! k' F- A! R! ^<P>        m_PlayerDataListLock.Leave();. o/ s$ Z1 P; e5 w  ^% f
        }9 o: \* `$ K1 p. B$ {
    }</P>2 z% h$ J9 H- T2 n! O: Z

    5 e8 w8 m5 |; J) x7 d9 x<P>& ]. h& ~, }3 g- ~! w8 z
    //-----------------------------------------------------------------------------
    ; p. h. }! Z9 ~// Name:
    " r$ z# ~0 c" E. p5 F% I( w// Desc:
      Y) j3 k7 `$ B3 M* D* d9 S//-----------------------------------------------------------------------------
    9 f/ q  d0 O, v3 n& Pvoid CMazeServer:rintStats()
    " s" s- c& D6 z; U% k- @{. I6 D7 c, ]. T2 {( O3 U, s
        ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
    $ j3 J  V" ^7 e0 D! l# x                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );
    7 O$ T0 K0 {) V& ?! x    ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
    + k6 p; U: @$ A" a/ e! M                                    m_fAvgThreadTime, m_fMaxThreadTime );8 v- I  k( w& b  |/ i9 ~; f# Y# w4 }
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );( H6 i+ Z# V/ K4 k# D
        ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );- `4 P9 s$ L, z
    }</P>
    $ u* Q5 ?7 X9 U! d
    # g: A5 D% s, G( K<P>
      V6 I, F' r9 d. z6 X! U0 h//-----------------------------------------------------------------------------) V4 r( y3 u4 \) F- I
    // Name: * C0 [7 N( D% U* P
    // Desc: 0 Z9 D" Y: E$ |( N1 Z
    //-----------------------------------------------------------------------------8 ?; H: I; _$ a3 D
    void CMazeServer:isplayConnectionInfo( DWORD dwID )
    ) V8 J( @% y& X( `{7 g' h2 D/ {$ `: w7 G9 m
        TCHAR strInfo[5000];
    & x; ^# R' z* t- s! }. M    TCHAR* strEndOfLine;( ]9 X5 n2 o! u
        TCHAR* strStartOfLine;</P>8 K8 g* |' c7 ]$ `" O
    <P>    // Query the IOutboudNet for info about the connection to this user- O7 p* c$ w/ f
        m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>8 p- Q% }: h9 F  |" t# g
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );9 {  e; Q6 \/ p8 j, }' H$ P: z
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>) j; e4 r$ L/ r% a. A) R
    <P>    // Display each line seperately
    # Y( e3 L& a4 w1 X    strStartOfLine = strInfo;
    & T+ T2 O! z6 c( T    while( TRUE ); S( E/ F* o! ]9 N
        {
    + u4 O3 \; V- {6 J, B( B        strEndOfLine = _tcschr( strStartOfLine, '\n' );
    2 b$ [* I$ \5 }6 ]% t: u        if( strEndOfLine == NULL )
    2 I+ p+ Z) T$ h* p0 ]            break;</P>! N% @9 _2 t: b3 F- g: D' i
    <P>        *strEndOfLine = 0;/ P+ w4 ?5 G. A8 s4 B
            ConsolePrintf( SLINE_LOG, strStartOfLine );/ w$ n& D9 ]" k
            strStartOfLine = strEndOfLine + 1;9 S0 G; j( w4 H. J. p& C
        }5 \/ g: v, J# |9 I
    }</P>" C$ ?  Z  }; A. Z+ f1 v

    ( ^  X3 E9 X8 l+ _<P>) |" w* z# r9 k( k0 W: p# g
    //-----------------------------------------------------------------------------
    + U: q9 |  x" }2 F$ l// Name:
    7 }. Y+ h6 i0 U+ o- ]0 c# r// Desc: 4 ?" @$ C% X8 v, J
    //-----------------------------------------------------------------------------
    * b! a. Z* {6 ]8 x2 PHRESULT CMazeServer::SendPacket( DWORD to, void* pData,
    1 r! o1 f; c, _3 N8 u- ]. t  d0 b                                 DWORD size, BOOL reliable, DWORD dwTimeout )
    0 y: o( J- s2 H1 _1 _{. T( @4 Z9 a1 O0 d1 h
        // Chance of forcing any packet to be delivered reliably
    2 g. [' \5 |) U+ [5 R0 f    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )7 {" \  O$ ~. ~/ E
            reliable = TRUE;</P>; K4 D4 C$ j9 h, a, d0 q7 X- q
    <P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    4 ~# j# B# S4 A, l1 C2 e/ ^/ V}</P>
    # |8 ]7 q8 Z, J8 s  E, ^/ w$ L( q
    * V8 Q" t- x$ F  {! i$ }<P>. ~. G; @9 D1 h
    //------------------------------------------------------------------------------ S6 H" C+ b- Y
    // Name:
    , l& q9 W) E8 [: U$ s// Desc:
    , j$ |) K$ `$ C7 J% q* v//-----------------------------------------------------------------------------
    1 O# ^( {! g9 |void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )
    + c6 y  l) ~& `/ W{$ d, D8 `6 q9 v$ Q& E& Q. p& H
        // If we're up and running, then send this new information to all clients
    % q+ k0 R5 i1 ^/ f, {0 G) r  B    if( m_pNet )) k0 ?1 o, \( ^* G) W
        {
    4 I! ]' e# A8 p0 C( m0 D        //Use the AllPlayers ID( @5 i; w1 S+ U. x
            SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );' R( S4 P4 V) U- B
        }
    : @  }* p0 n3 t" ?}</P>
    ( }2 Z9 ?/ e  F  b( M5 f
    ; K. B* K( z3 U# [<P>4 y( g: D( G" Z/ R
    //-----------------------------------------------------------------------------& O! d* f/ O' V; L% h
    // Name:
    $ l; x8 j) Y0 t5 w1 H// Desc:
    + J) W$ R7 A: G+ _5 c, X3 Z//-----------------------------------------------------------------------------
    - I3 G. Z3 ^& v/ P0 D" R. Rvoid CMazeServer::SetClientReliableRate( DWORD percent )( m2 V1 l8 u9 N1 O; O- E
    {0 H: a, V% ^$ c+ \7 b7 b
        // Update client config, and build packet containing that data5 {' M$ k. k% D& U# s, p3 J/ f
        m_ClientNetConfigLock.Enter();
    # D# `9 C) S1 Z& y    m_ClientNetConfig.ubReliableRate = BYTE(percent);
    4 ^* y* H5 q" D/ W. f& |% R    ServerConfigPacket packet( m_ClientNetConfig );+ v  y/ V/ p, u1 W
        m_ClientNetConfigLock.Leave();</P>
    / d8 U: V0 ?% A7 F<P>    SendConfigPacketToAll( &amp;packet );
    : h' i0 p9 O) C3 t7 _}</P>
    6 J' _2 Q/ _3 P- P& K" K
    - Y/ `. b5 ~, Q; D$ K* u<P>
    3 z+ h5 d9 Y% i# v//-----------------------------------------------------------------------------. f4 w  ~5 }2 _+ B- S2 n6 ~
    // Name: : z7 C% O2 B9 O" r* l' q8 v
    // Desc:
    ( J- D1 z) q4 n0 Y0 ?4 W  E3 d7 Q' q//-----------------------------------------------------------------------------
    " j/ z1 q' o( u4 _2 m( Z2 x* Cvoid CMazeServer::SetClientUpdateRate( DWORD rate ): h8 ^7 K+ E$ a# {
    {0 O1 X4 \! R1 y9 F( h/ B
        // Update client config, and build packet containing that data
    ; y/ f# `) m" q6 u    m_ClientNetConfigLock.Enter();9 }! C7 N. _5 @  ~7 c# R* a; D1 z0 g
        m_ClientNetConfig.wUpdateRate = WORD(rate);. x9 g- ]' S9 y
        ServerConfigPacket  packet( m_ClientNetConfig );3 u* Q  h5 ?& M, P$ L2 Y
        m_ClientNetConfigLock.Leave();</P>- }( ]6 S3 p9 V) E0 ~
    <P>    SendConfigPacketToAll( &amp;packet );. z4 u3 z( i4 k$ R
    }</P>8 T. E, ^# ]5 ?9 R: o0 r

    % m+ P. ?+ ~( M<P>
    + X  f  q# o5 n/ M//-----------------------------------------------------------------------------
    & c9 {6 J8 \& v) P2 u- \5 G// Name:
    ( ]5 C* U- ~4 F// Desc: 5 _2 O8 y; @4 {, z) I8 G
    //-----------------------------------------------------------------------------
    % A! b( L1 z% _1 g/ d8 ^+ Dvoid CMazeServer::SetClientTimeout( DWORD timeout )
    3 F3 v+ o( {' Z6 f) a{5 v9 A( f8 A! X+ f1 a1 K$ [
        // Update client config, and build packet containing that data8 w" |( W) W3 ?, U4 ^
        m_ClientNetConfigLock.Enter();
    + R, }! g2 y, r" `4 F) n    m_ClientNetConfig.wTimeout = WORD(timeout);
    4 H: \( z% D. C' H  k6 b    ServerConfigPacket  packet( m_ClientNetConfig );' O2 v: F$ I" K; N
        m_ClientNetConfigLock.Leave();</P>
    3 \9 W% O. h0 K- r$ A<P>    SendConfigPacketToAll( &amp;packet );, h8 n: M7 P# ^
    }</P>  H' L; H% U$ w- ]/ _2 I( Y) @
    ) [' {  D. ?6 i; p
    <P>
    6 i0 [8 i4 P3 k7 f/ w//-----------------------------------------------------------------------------" N0 T* O. n2 t! T4 ~# e, _
    // Name:
    + K: I' D8 b8 C) I1 ?; Q// Desc: - G, u" ?) ~6 c6 D: S
    //-----------------------------------------------------------------------------6 o! H7 v- o4 W- y1 T
    void CMazeServer::SetClientPackSize( DWORD size )
    : B/ ^8 ?$ @4 H1 }{
    ( |; E1 ^$ g! j; U, I0 H% P    // Update client config, and build packet containing that data
    - d' O: [1 j5 ^% z# d, ?- E    m_ClientNetConfigLock.Enter();
    ( L7 [6 S6 }2 j: g- f   
    6 ?7 Y7 f' ^4 z4 s1 H    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.
    2 U5 \3 c  V, D) e$ E2 m+ |    if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   
    ' J6 L4 z( G! x, I2 t" t        m_ClientNetConfig.ubClientPackIndex = 0;</P>, x; Q* q& g% W  N% V, i
    <P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);: M& M3 s& K7 \4 g1 ^# S
        ServerConfigPacket packet( m_ClientNetConfig );
    ( L' D0 G) |% T- L) F4 x9 p    m_ClientNetConfigLock.Leave();</P>1 k( z/ U: s7 K7 ~0 G* m5 H  Y
    <P>    SendConfigPacketToAll( &amp;packet );9 u! P( Z6 V8 D/ q  U: F
    }</P>
      x, ~+ b2 L1 B5 k
    9 \, h) }' D  M. l<P>9 i, U8 }5 [5 y
    //-----------------------------------------------------------------------------
    ( b! ]8 A3 e& S9 h0 Z// Name: ! Z3 R0 E# J) N0 G+ h- Y  l
    // Desc:
    0 h; a4 z- h# M9 W& m4 L. o//-----------------------------------------------------------------------------
    ; [2 P' b6 H% Z# {% }7 u5 yvoid CMazeServer::SetServerPackSize( DWORD size )8 N& L; j: U; Z9 v' D# }
    {" w; \6 e) @, v
        // Update client config, and build packet containing that data
    ; r$ Y+ G9 C+ v7 n    m_ClientNetConfigLock.Enter();
    ( x. t" W: p2 v0 F    ) W7 {' x" j- a) x
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.
    ' _4 [9 n+ z8 f' v% t    if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   
    , x' E) ~  a5 i1 J5 G        m_ClientNetConfig.ubServerPackIndex = 0;</P>
    ) A' I1 k$ G* n$ O4 V<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
    " u1 m; A( G6 S" g- T# Q    ServerConfigPacket packet( m_ClientNetConfig );' D  Z. M% J  G, q1 T
        m_ClientNetConfigLock.Leave();</P>
    ) Y2 c9 R- ~  f* d9 Y- B# r4 v<P>    SendConfigPacketToAll( &amp;packet );
    0 b. Y9 l8 a/ Y. N! ?2 {}</P>
    / d6 R/ s7 N& O. _' e% P: w<P>  e& F0 `% m/ m" x/ {/ g" F- g# B
    //-----------------------------------------------------------------------------
    ! B6 M- p  M1 [2 H3 [; x// Name: ' S: D% A7 w5 X
    // Desc: 6 P6 R. I+ R- [$ `' P; F/ u7 x$ q9 |
    //-----------------------------------------------------------------------------
    / Q6 q* g& ]3 Mvoid CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
    ' L& S5 \* p9 U{; `( [0 @; Y. L9 K) \
        // Update client config, and build packet containing that data
    ( b# Y' X4 M! J# l! C    m_ClientNetConfigLock.Enter();
    + Q. b! a! O/ @    7 ~$ p- y4 }: a
        m_ClientNetConfig.dwThreadWait = dwThreadWait;4 o/ S8 g) J  N* b  i8 D" c: i/ I1 q
        ServerConfigPacket packet( m_ClientNetConfig );) Y' A# V" X3 B" M9 |
        m_ClientNetConfigLock.Leave();</P>
    3 S3 x6 M9 V$ M5 T<P>    SendConfigPacketToAll( &amp;packet );
    0 T" e! m1 O+ C# i: ^$ r" ]; N}</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-4-10 03:16 , Processed in 0.390120 second(s), 51 queries .

    回顶部