QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4180|回复: 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>/ `0 S$ n+ }8 f1 g% B1 X- @) T
    <>// File: mazeserver.cpp+ J# T3 Z$ D7 U: q& `
    //' ]1 N6 u' c/ e
    // Desc: see main.cpp
    ! X- A0 F4 K, n/// z' V- c, Q1 r
    // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
    ' i; `9 o1 s( }) @3 N" S% }. A//-----------------------------------------------------------------------------
    - [. Y- R8 F4 C2 m  c8 ~4 S#define STRICT0 D6 Z. u5 b+ c$ m
    #define D3D_OVERLOADS6 H+ l' G/ \" Y+ o
    #include &lt;windows.h&gt;& {" B  b4 f. {
    #include &lt;d3dx.h&gt;$ r( s- {3 p5 T' ?# R" X/ c% ^
    #include &lt;stdio.h&gt;! O0 Y- y4 R  K
    #include &lt;math.h&gt;: z, Y, [' U) R$ B
    #include &lt;mmsystem.h&gt;6 r; I4 K. g: ]
    #include &lt;dplay8.h&gt;( G1 `' B: z7 L. n+ s
    #include &lt;dpaddr.h&gt;
      b' M- x3 v" v# w7 {#include &lt;dxerr8.h&gt;
    . C- G5 M8 Z- Y5 h#include "DXUtil.h"
    / m& L9 t7 I+ ~4 z) }  e( l#include "MazeServer.h"
    0 `, _& O* U! k9 x9 S' r#include "ackets.h"& u5 ?  K! r, @; r' ~
    #include "Maze.h"7 V( A8 I! w( K6 z: X
    #include &lt;malloc.h&gt;
    2 l9 u2 i- d* w. X, k& f/ m) w/ U#include &lt;tchar.h&gt;</P>
    4 S  S. `8 h' k8 W0 _- T  f, h* y# a& h* U5 S8 {
    <>//-----------------------------------------------------------------------------
    1 k, X8 p1 z! T* T( a// Name:
    / b5 o: H- y% `5 I// Desc:
    1 d+ W( B, H- c/ H5 T( h//-----------------------------------------------------------------------------
    1 o' |% {8 {1 V( D9 Q& W, ]- QCMazeServer::CMazeServer()
    : _' W- d! h1 Z: y. h6 F" V$ v# |{
    , ~. P# D! |* W* M    m_dwPlayerCount         = 0;% \0 R. |: E$ W: Q* K
       
    3 J4 D6 z" J) r1 t  d' R4 E* X    m_wActiveThreadCount   = 0;
    1 i# u, G$ p+ P" W& i$ o    m_wMaxThreadCount      = 0;3 L) q7 S6 _% T7 Y$ A7 x
        m_fAvgThreadCount      = 0;
    4 a7 z2 J' p5 t) ]8 ]1 Q! Y2 S    m_fAvgThreadTime       = 0;
    $ y2 d( A* V# \) u! k    m_fMaxThreadTime       = 0;</P>+ z# A/ i4 r: v) D* @0 \$ K9 p3 L
    <>    m_dwServerReliableRate  = 15;
    8 _5 a& Z0 C6 U* w# b    m_dwServerTimeout       = 150;
    ; v% |8 [" p' q    m_dwLogLevel            = 2;
    , `" m0 U* m7 V: x: {3 H1 R! O    m_pMaze                 = NULL;</P>& i. Y% D, u! Q( w- P2 C3 B( W  g0 v/ @
    <>    m_ClientNetConfig.ubReliableRate = 15;
    4 p( C2 r6 R$ L: ]! ~& d' V    m_ClientNetConfig.wUpdateRate    = 150;# d/ T2 m' q- C3 Q, f& m4 c- v6 c
        m_ClientNetConfig.wTimeout       = 150;</P>
    6 W+ B- j; V: c' ~% E0 {+ B<>    m_ClientNetConfig.dwThreadWait = 0;</P>
    ; m! w. o6 a2 w% C* Q, Y; \5 o9 k<>    m_ClientNetConfig.ubClientPackIndex = 0;* P/ e; v# @6 c; t3 c7 a# {  N
        m_ClientNetConfig.ubServerPackIndex = 0;
    4 f$ @: h/ S. L    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)
    1 j; L' M$ h7 `  I    {
    4 k# t* s0 L* Y: |3 e        m_ClientNetConfig.wClientPackSizeArray[x] = 0;
    , f2 _- x. K' S0 u        m_ClientNetConfig.wServerPackSizeArray[x] = 0;  ?; l2 b0 C8 N  m( Z. }0 `1 J
        }
    7 _! q/ e. a2 X9 B}</P>
    5 ~) n" r* K/ D6 s1 Q% ^4 G1 L' x: r" j. A
    <>. R/ d  j7 z: _$ b" f
    //-----------------------------------------------------------------------------* e- r4 M! K" Q: \4 Q
    // Name:
    3 A& A+ _8 o1 a# K9 Q// Desc: 4 E# x. {1 X7 P9 D0 j# B- ^5 k
    //-----------------------------------------------------------------------------$ \  |. R* R& Y; T. n$ m% i! }0 a
    HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )  H3 n! P6 S+ |: _- R
    {
    , K5 k# ~/ |1 r$ w! M7 g3 U; Z8 v* k    m_bLocalLoopback = bLocalLoopback;
    * y3 s5 x/ D4 N' C9 Q/ Z% Q    m_pMaze = pMaze;9 u- ?8 O. A6 y! _7 Q
        if( m_pMaze == NULL )
    ; T9 H7 n) I4 }        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
    2 t) Q  O7 W0 s; M1 q7 J, U+ M- ]<>    // Grab height and width of maze" R9 l& M3 K( w% t6 c! I
        m_dwWidth = m_pMaze-&gt;GetWidth();
    8 e" l# m: v" ^" h* b; \# g4 o( p1 b    m_dwHeight = m_pMaze-&gt;GetHeight();</P>
    ' s  a6 y& u2 Z<>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    7 n$ [# C1 O0 g+ L. m    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>0 {$ P# }  D& a9 P( U
    <>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.7 `# X( R' A9 z9 }! ~
        if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    4 }$ i7 K% C5 }5 K) }- p1 e        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );, a! v( e9 H7 z
        if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )
    0 H  r1 `9 O% y6 x7 q- o% P# u$ h& W        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
    / T# Q2 d4 I+ \+ v1 @% S, b<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;2 s! I( |: _$ n" a# r) q
        m_dwMazeXShift = 0;/ H1 N* B; w6 Y: o% X- n" z& A
        while ( (scale &gt;&gt;= 1) )- \  g) U% r6 R, c' I
            m_dwMazeXShift++;</P>% I4 z! e- `! A
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;+ ^, Y2 w8 j. T1 q
        m_dwMazeYShift = 0;
    . _3 K; l5 X& l2 s7 d7 Q& k    while ( (scale &gt;&gt;= 1) )) K; o, D# J/ |3 S
            m_dwMazeYShift++;</P>3 R. w, r% B# a
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    4 e; z; b7 g7 S+ k9 ?* a        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )$ a4 Y4 y5 t% b- ]; M) Z! F4 I
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>! s3 S6 v; ^& c
    <>    // Initialise the player list
    3 L/ a0 s* a" B' J    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );$ }7 E) z/ K! _) v) U, Y; V6 b/ b
        m_pFirstActivePlayerData = NULL;* x0 ?3 }7 r6 a9 m: O2 n
        m_pFirstFreePlayerData = m_PlayerDatas;
      s0 i3 ]4 R6 W. D5 W9 G1 |6 [    for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )/ b6 B* K! ]& ~( y. T
        {
    ( V7 p0 U$ k3 m- d        m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];
    9 f% Y% D0 @- {! [5 D4 L$ Z0 V/ \        m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
    - h: M$ F3 `5 C& }. S) r6 M1 H7 n& u    }</P>
      o; d6 B: M5 t/ @) A8 H<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
    4 C# ]- j3 K: e    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];* R7 L2 A5 K; F
        m_dwActivePlayerDataCount = 0;
    / X3 D3 |9 l5 `" v/ Q    m_dwPlayerDataUniqueValue = 0;</P>
    5 L1 u7 W5 \% k9 e2 y" R8 i<>    // Initialise the cells  n3 K9 l+ i. R6 X
        ZeroMemory( m_Cells, sizeof(m_Cells) );) y1 Z! A, O/ u1 I% V
        ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>
    % h1 W7 ?) w4 G! x! y$ j<>    return S_OK;6 A, r8 Y; x0 L! H
    }</P>
    ; V5 n) a4 D8 f+ |( L9 z
    7 q& n) D( a' A<>" p% w) q; b% G- P5 h! P
    //-----------------------------------------------------------------------------0 U" A# D7 \. i4 O0 J0 k) x- {- S
    // Name:
    6 a' p+ r8 n3 B* C// Desc: & }" u) D: u8 Y, N& l5 C2 L
    //-----------------------------------------------------------------------------
    0 v' S# e  h* r% z4 d/ ^6 r3 F) Tvoid CMazeServer::Shutdown()
    : p2 y6 Y' @- D" u) O1 q$ L( q# m{" n/ E4 v  J7 E) M% t5 i: Z
    }</P>
    - N/ M8 j2 y4 p. X1 [4 \, x4 h- @% a; F( r4 H5 H2 E
    <>
    : i& e, Q) \: F) O//-----------------------------------------------------------------------------
    , e$ |7 Y, Y$ L3 n" C4 Y( n// Name: * Q" [$ Q3 ]: t; w
    // Desc: + k& ?8 j+ l( J' H
    //-----------------------------------------------------------------------------# R  q, P# w* z# N2 g
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    ; v* F; A! Q% M0 a: w{& Z# I4 F" Q% h" n  J2 f1 Q1 j
        m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    / n% m7 k+ B9 e/ Q6 r0 y                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );. f4 @9 o- t% T3 x5 J7 K
    }</P>
    9 _' P6 c$ E9 F7 ~0 t: A* |# S- d5 p1 e1 {. d6 a
    <>5 z) X9 Z; ^! \
    //-----------------------------------------------------------------------------5 e+ {& \8 ~+ m% m
    // Name:
    ' |( q, o) m6 |0 b* R// Desc:
    3 P+ v/ W/ A3 B! ~) P& M8 M2 k//-----------------------------------------------------------------------------, |7 f. D5 R" e4 Q. O/ M
    void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )/ j# M8 `. C& P( R% J
    {
    8 [( Z# t" x7 D: Y! d8 U    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,: f' q) D* o7 b& w
                                x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    4 c% @# q& e  q/ r}</P>
    . f1 u% q  t! H; s) l; @3 `# V
    <>
    ( |+ @$ G7 A3 u  V9 s' b; M//-----------------------------------------------------------------------------( X' T, ~+ l3 t" v. A
    // Name: ( X# R2 n) g6 Q4 y
    // Desc: ( g) t5 J% ?/ c1 c# M
    //-----------------------------------------------------------------------------/ X1 I/ r0 ^1 N7 \$ l) x. r( i
    void CMazeServer:ockCell( DWORD x, DWORD y )
    - L1 w% D' S, W( H7 v{
    + C, W1 d1 _) v2 [% m    if( x == 0xffff )" H4 m' Z# t* l3 U
            m_OffMapLock.Enter();
    * t* f" L1 G/ \: f  l    else' [/ Z0 s( F  q' ~7 h) ]- s6 X
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);0 b5 T7 s  G9 e$ i3 S2 l
    }</P>
    . _& u3 h0 _+ o. v  `
    $ d) `# E5 b$ L<>; y6 i  l/ x: s( o+ d& n, ?
    //-----------------------------------------------------------------------------
    ( `  V4 ?$ Q, `% l- \// Name: # n% }" y! c+ B) o; \; ]; {
    // Desc: 5 v+ l: a) F2 S2 \1 [
    //-----------------------------------------------------------------------------& ~3 r, S8 ?" A+ k% B
    void CMazeServer::UnlockCell( DWORD x, DWORD y )
    ! v/ i- l$ X. {5 q, N! k{6 R. U+ l& I( Y# D
        if( x == 0xffff )
    1 Q: U7 q: k4 u9 B" b# w$ Z9 ^        m_OffMapLock.Leave();
    : \' |" f6 u9 ^# E$ r    else
    5 \  ?3 F! l0 ?7 @7 N+ r        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);" J' O8 w2 A* n% y' m) ]
    }</P>" I$ r# u5 V: \# g0 A& q! a( f

    $ d( p8 A$ }: k% ^<>) w8 {: Z3 \1 J4 `  S! C; U
    //-----------------------------------------------------------------------------
    ; R# _4 [& H5 x3 g9 L5 v- e// Name: 3 ^& ?# ^1 i9 X) B5 a& K: q* r
    // Desc:
    6 ^9 w. n9 W" i7 l//-----------------------------------------------------------------------------
    8 C6 P" k6 M' C5 Fvoid CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 ); P4 r$ a. H/ S
    {
    ; w7 C/ i4 t4 P: ?6 e; O( U( w    if( x1 == x2 &amp;&amp; y1 == y2 )
      K* N+ w# b: f  [/ h    {
    % S+ [* u* ]) R( N/ v1 T) X        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )3 Q# r& _! C" I- d' T/ W1 w) M
                LockCell( x1, y1 );
    " f! M, {  u1 K+ a& `+ p( Z        else1 U" Q0 X! T, K' ?# V5 f8 V
                m_OffMapLock.Enter();</P># R5 V2 s# U7 |$ S) k3 b( P
    <>        return;
    ! M( H& v; v( P" [0 C% ^8 h    }</P>
    $ T0 R- {! v: ~' O4 j<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;& b7 |0 \# h1 P. K
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    6 x% Y. Z8 p/ u1 f5 i/ _, L    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    % k1 N. O- Z- {# }& T5 E5 {    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    ) B5 D/ a+ o) A* [9 Y<>    if( x1 == 0xffff ); i- ~* b; A, S1 Y7 `
        {5 A2 q6 s4 e  g
            m_OffMapLock.Enter();
    1 J$ ^! |+ j, D% ?: [        m_LockGrid.LockCell(x2shift,y2shift);% N8 i' g' I: L
        }
    / c# R+ m# M1 C0 d  {( e) t0 {    else if( x2 == 0xffff )
    ! w$ p7 U- o3 `    {
    & J3 e+ w: g. X5 y1 Y( ~* g        m_OffMapLock.Enter();" Z0 H2 r/ S9 Y/ h6 y7 U4 Y! g
            m_LockGrid.LockCell(x1shift,y1shift);
    9 D: g7 G% i; `: e    }  Y% e+ Q" ?$ o" z3 E
        else
    : t% S7 b/ C% \* g# D    {
    $ J1 U2 u! s9 T. a        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);# U' t7 F$ ^$ f" M0 m
        }
    * G% M( L0 p, x1 a}</P>$ g$ V! v% g. N; n$ w

    & X. {- S, T' Q) j( A<>5 c( n) b$ [7 j) q
    //-----------------------------------------------------------------------------
    / [& z- t. w1 G, ^. [8 x/ _// Name:
    ; T+ e0 T4 ~' t$ U! r8 ]$ Z6 n1 o// Desc: 2 p! I4 l3 Z/ a" ?. n  k' M4 v4 k# Q
    //-----------------------------------------------------------------------------
    $ k7 r8 J, H2 ovoid CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    7 M6 Q/ T7 B* ^+ X4 s, D5 c, ^{- b* m8 J' H7 C+ A* T9 q
        if( x1 == x2 &amp;&amp; y1 == y2 )$ X$ e) Q. ]7 h6 g3 n% t# Q, O+ O/ C
        {. \9 B0 r( X' i3 U9 P2 i9 }- z
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )* F# L4 r$ W' O4 r! W5 Y  W8 t. J& O
                UnlockCell( x1, y1 );/ F. j: o4 Y9 R4 J! L- i- ?  k
            else; ^' Y% I8 \  G( @8 e8 R; W6 u
                m_OffMapLock.Leave();</P>7 o0 L4 e! S* `) n- q# d: p! z
    <>        return;- h9 _5 Y: j4 p! {) ?
        }</P>6 {8 o6 Q" Q9 a* ?
    <P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;9 D) B2 X* e/ U- N3 h) k
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;, @+ r8 [' |' U+ q
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    : x( I% F& q" o$ q+ ?    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>' Z; p+ C" ?/ R& l
    <P>    if( x1 == 0xffff )
    4 Q* z& t$ m+ l8 r9 a    {
    & e* V( k  {( O8 g  P, l        m_LockGrid.UnlockCell(x2shift,y2shift);7 O& `: ^/ F. S2 o
            m_OffMapLock.Leave();  k) q' I# f, z; |6 W, r7 u
        }
    5 `! _5 J. _$ w1 ]/ M5 v: [    else if( x2 == 0xffff )
    ) s: H# U" f5 O' _6 [7 u    {
    # K8 W0 E% ^, i        m_LockGrid.UnlockCell(x1shift,y1shift);: J! s+ n. \0 ^5 v! g* [
            m_OffMapLock.Leave();8 r+ Y" \% ~4 O. Y
        }6 F1 J& M, o7 }3 v3 ]2 x% P
        else 0 U) n4 n( N. u2 P( b! ^7 g+ G6 U9 l
        {
    3 ^' H( V$ f: A  y6 z0 L0 N" s0 h        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
    & a0 g! q' i# ~/ C( [% \  o- R    }, P. }- a- x' h0 o% A1 N( i
    }</P>) l8 k1 p( O9 e  t7 _$ W
    9 B/ L8 K) N+ T- k2 x& Z( t# f
    <P># E- ^7 F8 `, r  P5 c  l  y
    //-----------------------------------------------------------------------------
    + ~% H/ Y& G& t+ u// Name:
    - s+ k9 ?8 c; ]) t; O+ G// Desc: & Y! O* y5 X1 B3 d
    //-----------------------------------------------------------------------------
    1 X; B+ ~9 y0 Jvoid CMazeServer::OnAddConnection( DWORD id ): o# U$ b- w( e+ P- c/ s5 c
    {$ i# r6 G3 c5 Y& K: P4 d/ ~
        m_AddRemoveLock.Enter();</P>
    . E- f- k) X) ^+ ^# {9 o8 u0 _2 I, f9 n5 ~<P>    // Increment our count of players
    ) V- X8 c& V7 Q8 k' p    m_dwPlayerCount++;* N* |) M* P# N; }1 }  z( m3 z
        if( m_dwLogLevel &gt; 0 )0 h, [  f7 ]" ?
        {+ b  Y8 F( ^- F' c% E" t
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
    * `) p8 P6 o8 I7 i2 o8 f        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    5 e6 f* s# g+ x+ C1 V9 i( F; G    }</P>
    2 f  N3 G/ G0 `* o& M, u<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )$ s; H# ?! q% T8 i# Y6 A% I
            m_dwPeakPlayerCount = m_dwPlayerCount;</P>/ A! V2 m7 L- Y8 K& a" n2 a" W
    <P>    // Create a player for this client
    ( ^( [+ o' [* ?    PlayerData* pPlayerData = CreatePlayerData();# j' z7 F3 D7 h- i
        if( pPlayerData == NULL ), q, I. q1 f% L
        {
    : A7 \8 F1 e+ _        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );* v# d3 Y/ w+ o: g; s4 E; Q4 O
            DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );: m: B' \' S8 ]' r5 Y
            m_AddRemoveLock.Leave();
    ; I& n7 N; W4 I" M. K. K( E; ^: H; D        return;- J* B8 E) j" ^  K9 X' U6 `0 C; s
        }</P>- z/ l, P: c2 b' J
    <P>    // Store that pointer as local player data
    * P; n$ ^$ t( H8 [    SetPlayerDataForID( id, pPlayerData );</P># M: h5 p3 p, z& n: Q* E; d/ q: D( p
    <P>    // Grab net config into to send to client4 H; F. t/ @- X+ `% k
        m_ClientNetConfigLock.Enter();* f+ i4 s! _% i1 B' `6 M
        ServerConfigPacket packet( m_ClientNetConfig );
    9 [8 }, i" N( L    m_ClientNetConfigLock.Leave();</P>
    , y. h- f* A9 |! W<P>    // Send it0 _- G8 @0 T2 P
        SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>
    ( b' C/ N5 B# a7 E; `7 q0 u1 z<P>    m_AddRemoveLock.Leave();6 m7 v3 s9 l0 R7 Q1 K' \
    }</P>
    & ]" l: K' _+ w' s! b. y" J7 a/ W3 K$ p0 x: N  l' j/ o+ M1 e
    <P># e( y% t+ G) h
    //-----------------------------------------------------------------------------" E5 G4 o( t% ~+ w# o
    // Name: % M2 @# y# W2 d: e! {/ A  i) u+ {
    // Desc: ! h2 \! z, X5 |+ l7 l
    //-----------------------------------------------------------------------------
    $ I& Q" l$ k5 A& }3 V* Pvoid CMazeServer::OnRemoveConnection( DWORD id )7 C2 ?6 `- }3 _8 g7 l1 g
    {7 I1 m/ N$ D2 h7 I. P
        m_AddRemoveLock.Enter();</P>
    7 M: H0 k" ^+ P# H) o2 ^<P>    // Decrement count of players0 Q8 H0 u- A& @9 a
        m_dwPlayerCount--;</P>
    / A  n. _$ n3 ?) ^% z/ q<P>    if( m_dwLogLevel &gt; 0 )+ |- n" c+ h  S% h/ D: C; U. {
        {: h$ T. j' k$ A& j9 ?9 d1 T
            ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );- ~  ?) w$ F, o
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );+ V9 O/ r; z% Z( D. s: [4 x4 ]
        }</P>
    1 S1 a* M! }+ ~  y9 w- R<P>    // Find playerdata for this client
    9 `% E& O9 h% b2 A    PlayerData* pPlayerData = GetPlayerDataForID( id );4 t  C) G* `6 b) T2 s
        if( pPlayerData != NULL )' ~7 ?) ~, e# S7 ?( x; C/ |0 c1 S
        {
    , o' m; o5 l% |& W4 ^        // Destroy it
    % v6 D/ N* w1 D0 L        RemovePlayerDataID( pPlayerData );; G7 S  x- \; K" ?! z
            DestroyPlayerData( pPlayerData );1 U% k' W" {! J
        }</P>
    * n' R1 R* q& Y7 m( b9 ]$ n  ]<P>    m_AddRemoveLock.Leave();
    ; k* T" u3 ]+ o+ L# I}</P>+ x" o+ D" t1 m
    * d& I% h5 P) O+ I
    <P>* M& w) C1 H6 }+ C  D
    //-----------------------------------------------------------------------------6 l* E2 s, S( ^$ K
    // Name:
    8 T9 {( o, s5 a9 X* c// Desc:
    $ X3 I& I6 |8 a9 `//-----------------------------------------------------------------------------
    ( ~; z9 W5 [5 R4 M- K+ CHRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )( u/ j+ |0 b4 \5 S& E7 `1 A4 e
    {
    0 V) f3 J- ~1 X    BOOL fFoundSize = FALSE;</P>5 z: f( X3 @! k1 Q1 U; b; N# k
    <P>    // Increment the number of thread we have in this process." K+ S3 M% d! H& |
        m_csThreadCountLock.Enter();</P>9 r8 Z& m$ [3 z7 {* a
    <P>    //Get the start time of when we entered the message handler.
    - U1 X3 z+ D/ }- ^( f, T    FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
    6 f! _, I# c8 P7 ]' x9 d<P>    m_wActiveThreadCount++;$ b5 o1 t0 o1 m( Z9 p# e/ t
        if(m_wActiveThreadCount &gt; m_wMaxThreadCount)1 [4 w; F; V* ^1 D! F! ~' z! l
            m_wMaxThreadCount = m_wActiveThreadCount;
      Y; j7 D3 u  ?! }( g' `   
    / q& o5 y! X1 g( C5 I    // Calculate and average.
    * s' y  T! ^0 n& K    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;# y2 e  M- w' [$ l; W: d
        m_fAvgThreadCount += fdiff/32;, |, u" Q- _5 U" t/ D" R& r
       
    6 S" v: I0 i3 h6 {& {6 o; y) I    m_csThreadCountLock.Leave();</P>
    % U$ O0 K' i8 |1 B' Q7 [<P>
    0 C9 W1 r; {& s    ClientPacket* pClientPack = (ClientPacket*)pData;
    ! n9 e! q7 L% I; N    switch( pClientPack-&gt;wType )
    % G& n" E6 [, B    {
    & U* z* X9 z0 y2 r4 s' }        case PACKETTYPE_CLIENT_POS:8 L5 K0 a. t. S% n+ N
                ' @5 P( n6 |9 i3 r
                // Check to see if the packet has a valid size. Including * b0 u; P3 h. Q  K3 Y6 F6 r
                // the custom pack size.* r8 f& ~7 A: r) H- K: M" ^
                if( size &lt; sizeof(ClientPosPacket))
    9 N) a/ t/ p, o8 E                fFoundSize = FALSE;
    9 F* v) @0 x6 c            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))- M3 ~3 ?- }' ^3 D8 r" J( ~
                    fFoundSize = FALSE;7 d. V; P' W" j
                else
    4 s! Y0 b4 M8 @6 v                fFoundSize = TRUE;</P>
    8 o& U/ U) I# _4 q1 z7 r<P>            // If valid sized packet, handle the position.
    ( L! ~8 K6 ]9 Z3 m, M' L8 `: G6 V            if(fFoundSize)7 E! C2 W' S3 E5 r
                    HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );
    5 }& t: [+ |* r0 k, P9 [6 z! @" `            else0 h/ E( {( g8 P' k
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>7 E' Y# u# t2 A9 x& I. M
    <P>            break;</P>9 B2 E* H& U. n8 t- T3 _
    <P>        case PACKETTYPE_CLIENT_VERSION:  ?5 M/ ~; X1 t! P
                if( size == sizeof(ClientVersionPacket) )
    ' m  K; i) d; t7 z4 c( x                HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );  X  G# a5 j! F+ g" v
                else+ n7 B  Q+ `: ^7 m
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );" p- e- r7 a% X) j3 [* `
                break;</P>+ B3 v. p6 G! }+ N! y  v
    <P>        case PACKETTYPE_SERVER_CONFIG:</P>
    2 B8 B+ N" A/ u, L<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>6 ~/ {: y! B& p* y+ G& T; A7 ^' V: b
    <P>            break;
    - e: `" m0 E3 b. O1 l! R2 z        default:
    & h( ^" h% k6 ^$ h' ^+ L8 {            HandleUnknownPacket( dwFrom, pClientPack, size );& h: w; w; m' f- h# \( B& @
                break;2 S( m* T6 ~. B0 {
        }</P>8 D# B. I+ F% ~
    <P>    //If the user wants to hold the thread, Sleep for given amount of time.
    * f$ x9 C4 I" v  f    if ( m_dwServerThreadWait &gt; 0 )
    1 t( o! q; E/ z6 e; |, q    {- ?' M8 I5 g6 f9 ]: u5 x
            Sleep( m_dwServerThreadWait );
    - [- [1 R2 y5 ?$ ?/ u' E4 i) [    }
    % |  a4 Q9 ~9 u! p5 `7 K: M   
    , k8 w+ |- t6 U% d, B5 A    // Retrieve thread data for this process.6 }" c' W3 M4 G* B* A/ K$ D" j
        m_csThreadCountLock.Enter();</P>4 W! T" Q1 i* e8 o# y
    <P>    m_wActiveThreadCount--;</P>$ Z, u3 e8 h; w5 K" ]6 I+ ?. X- ?
    <P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;3 ]5 R- B% s  ^& E
        m_fAvgThreadTime += fDiffTime/32;</P>0 g  c! t4 i  G& X
    <P>    //Get the Max time in the thread.
    , \, g. z5 k2 g, b    if ( fDiffTime &gt; m_fMaxThreadTime )
      |, c. A( x, Y2 g7 g6 B& j  [6 E6 }    {$ }1 g3 J0 M( ]& c: v
            m_fMaxThreadTime = fDiffTime;% n  N2 d2 U: _6 j
        }</P>
    0 u+ q/ B  @" I& c7 u<P>    m_csThreadCountLock.Leave();</P>3 m5 }0 s8 r) _1 V; Y1 [3 L8 X
    <P>    return S_OK;  d9 t4 y) j# Y( U
    }</P>
    2 p- V( ?3 K) p% x
    . q% h7 R  _1 q) @+ z  O<P>//-----------------------------------------------------------------------------
    - c% [) [" Z. V. W- \// Name:
    6 j* O. o' m% \! c* i! B// Desc:
    * _6 j5 Z- y' s3 u0 Y//-----------------------------------------------------------------------------
      V2 i" c- u6 k5 }BOOL CMazeServer::IsValidPackSize( DWORD dwSize )+ N+ k. }6 d# f( y, q
    {, L8 u8 G1 M! U  p8 A- o* j1 H, H! }
        BOOL fFoundSize = FALSE;& A- }8 `5 U9 W: H' P/ I
        BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;
    & Z+ h" W! B: `* e- _   
    ! o$ j/ ~% P' @7 o5 [/ g$ l    // Check through the array of valid pack sizes.
    2 o3 f, D, i6 c    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    " s4 G3 ]! [7 [9 S' C& q* p% T/ d    {' z4 k$ @& j1 M1 A. y7 N5 Q5 q
            for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)
    ) f4 U. y& @4 I" _9 K        {- o$ _1 z% U% C8 Q
                if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    7 F7 N5 o* P) U. a            {% y. R- g, y# b6 [
                    // Found valid size in the array.6 A/ f- a/ H/ [
                    fFoundSize = TRUE;7 x0 o! f" q' O- ?
                    break;
    & b4 ^. |' W$ K. Q# y3 m' M) M            }
    % u$ Y2 M( p! L6 e9 q            if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
    6 ]4 V+ q8 W6 k! X/ D        }
    % a+ R* V& q8 R5 |. W5 d    }& K' y( e  X* `5 b3 a9 C3 {: a
        else& u  g: d1 }- c9 ]
        {; v: b( P! X; w& [1 W/ N! `
            fFoundSize = TRUE;/ u0 {; S) A9 i& p& W! q
        }</P>1 D2 S; p7 c9 U. Q3 p
    <P>    return fFoundSize;
    # @. R, Q1 W: R) Y" |}</P>
    1 R4 Q( e* j  M1 V2 `# N# T<P>" ^# P" S  ], s/ u0 D5 n1 k
    //-----------------------------------------------------------------------------& K2 j4 @% j! T2 v  U9 F4 w. l% K
    // Name:
    4 R/ M8 P: a6 O! |  Q6 z// Desc:
    & ]& Z! s' |/ y5 c//-----------------------------------------------------------------------------5 a$ h2 w: K! X$ n! V9 q
    void CMazeServer::OnSessionLost( DWORD dwReason )
    6 i' q: s2 b" m/ y( U: N# g& _7 o: C, w{
    ( U3 q. F, C- ~) k    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
    4 J. x& e2 \  x5 g}</P>
    # u5 ^. A, w  Y( y1 i
    1 z4 I( k: ?* K  W, M* _<P>- R1 u. `5 I; @4 U4 z) D
    //-----------------------------------------------------------------------------
    ( I  K& I4 N/ P: T! Q// Name: - B+ x- ^2 A: z& \( S7 A
    // Desc: % [- v. ?1 M6 ]
    //-----------------------------------------------------------------------------: m4 A) ]$ D. `& q' W1 Y
    PlayerData* CMazeServer::CreatePlayerData()
    4 v: ]! r( K2 Y8 N* M' W  o6 f, X{
    ; j1 H1 B7 J6 v7 D' p    m_PlayerDataListLock.Enter();</P>$ f  B" O( H4 c  @6 u$ N# p  ~
    <P>    // Grab first free player in the list
    ' \7 }) D6 `3 c: z    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>5 Y5 G% q* X: {
    <P>    if( pPlayerData )
    * @8 |7 U& l3 b* @8 _9 t    {
    + s5 x2 I; Y' y        LockPlayerData( pPlayerData );</P>
    # I- r; d  \, V! x$ y: ]# U<P>        // Got one, so remove it from the free list
    ( d2 K2 p6 _/ k$ s        if( pPlayerData-&gt;pPrevious )& r3 R& h$ U# Q6 K& y
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    5 l  N, J5 P! i7 `7 x: t7 t        if( pPlayerData-&gt;pNext )
    ) s. X" a4 m' k# l7 a            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;' X, N' b0 v- A* r  i' |7 u
            m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>
    0 m3 T7 l* R( S3 D, I. h% w$ P<P>        // Add it to the active list
    ( g/ E3 W5 H+ u4 S( D        if( m_pFirstActivePlayerData )
    ( n9 K2 }* D' d: p1 C+ _            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;# Z) `6 m, s0 C
            pPlayerData-&gt;pNext = m_pFirstActivePlayerData;
    . w( c% m6 O+ |7 Y" e        pPlayerData-&gt;pPrevious = NULL;+ M! P% N$ D4 `$ _3 a( T& z! q  ~# d
            m_pFirstActivePlayerData = pPlayerData;</P>8 |0 v8 v2 X0 R/ k4 P
    <P>        // Update count of players
    9 D' ?! s" m( p& o0 t4 Q        m_dwActivePlayerDataCount++;</P>1 _1 h7 j/ }! q3 G
    <P>        // Generate the ID for this player
    3 r  d: g7 j* X        m_dwPlayerDataUniqueValue++;
    6 D/ M! [# x- f6 b6 t5 e) `) V3 d        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
    : z+ e0 P: V' i0 `' o, K6 P<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;1 o9 d8 z# _6 g5 s7 G! G
            pPlayerData-&gt;NetID = 0;
    . L; e4 ]0 F- q, r6 O: {        pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>
    4 Y# _& I% K; t# W1 V3 k( a5 j<P>        // Insert into the "off-map" cell
    0 A. q1 I& t9 w2 ~  {/ e        pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;
    7 j2 p( _! C& c0 z6 t# T) z        pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;9 l0 ^; C: c7 ^; c! Q6 F
            m_OffMapLock.Enter();* K* P. E* l; U
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;
    2 K* _' Q9 d+ g  ?5 Y  e+ _        m_OffMapCell.pFirstPlayerData = pPlayerData;
    ) W9 \9 w% C/ H. _        m_OffMapLock.Leave();</P>2 l' H: \& a( M) W3 c6 P
    <P>        // Mark as active
    ' X5 }% Q3 G" Q5 B        pPlayerData-&gt;bActive = TRUE;</P>
    $ s8 T& U& u/ S+ j<P>        UnlockPlayerData( pPlayerData );" k: P6 }' R$ J+ R
        }</P>$ S; }9 O, O% N7 n* q/ [
    <P>    m_PlayerDataListLock.Leave();</P>
    3 p/ M) v& l5 X; ^/ F<P>    return pPlayerData;
    2 n# D! v) Q2 |* M" b" u  Y}</P>
    3 s5 s4 a- H) g1 c' ]3 D/ @: w0 f; N! a" v
    <P>
    5 W' J% B' F& C  b* I9 ~//-----------------------------------------------------------------------------
    & H- J6 s/ g+ `. E6 d// Name:
    * _6 F0 p1 W4 B3 D// Desc:
    # h8 ^4 W* o" i+ @# ~//-----------------------------------------------------------------------------
    & ]! c# w; r0 A8 S* ~# Y# q' avoid CMazeServer:estroyPlayerData( PlayerData* pPlayerData )
    ; K8 A* `$ ~! w, A5 w9 @) P$ c* Q" _{
    + k$ @6 l) ]. c$ r- ^& ~5 R# K    m_PlayerDataListLock.Enter();7 Y/ t, ~: l) r' ]
        LockPlayerData( pPlayerData );</P>7 I3 P# U; N7 v
    <P>    // Remove the player from its cell5 X& S4 e! A9 L" ^; u4 u) z# z
        RemovePlayerDataFromCell( pPlayerData );</P>; V3 D0 d0 {' J8 G# ^* Y! Q
    <P>    // Mark as inactive8 F. W4 X6 c# I* y7 M4 b; g: L8 a& b
        pPlayerData-&gt;bActive = FALSE;</P>1 U' r, t4 N% C  L; A
    <P>    // Remove player from active list5 e9 u5 k& y$ J% F; u/ g4 a
        if( pPlayerData-&gt;pPrevious )  ^. h% m4 z5 g2 [! n- I6 l% }4 ~
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    / c6 J1 M; H: P1 F    if( pPlayerData-&gt;pNext )" t4 }- ^$ G: A9 x, ~+ Z5 Q8 \) n
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>7 A" {' P( `! B* R0 r
    <P>    if( m_pFirstActivePlayerData == pPlayerData )4 J0 L4 }) g/ ^
            m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>
    5 l1 K; ^8 r3 x* o+ B1 J<P>    // Add it to the free list- O: k; H1 S( C- J0 A
        if( m_pFirstFreePlayerData )- G6 g1 u& i, J5 i
            m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;8 k0 t3 I; P& N( U5 l
        pPlayerData-&gt;pNext = m_pFirstFreePlayerData;
    0 ?9 ^4 z' W" q. b: L  c    pPlayerData-&gt;pPrevious = NULL;
    5 c8 ?1 Y4 e1 |& Y+ l: V( [    m_pFirstFreePlayerData = pPlayerData;</P>
    8 o) h7 n' R( ~0 I! H3 h<P>    // Update count of players) ^( B8 W0 q  [, X2 Q; m
        m_dwActivePlayerDataCount--;</P>( j: S1 Y& n7 V& E  Q  J7 U  Y9 l
    <P>    UnlockPlayerData( pPlayerData );
      [: X' y: @  S7 w' @    m_PlayerDataListLock.Leave();
    # w- a' m  J$ s, D# Q# Y}</P>
    2 \( k7 n7 w1 @" e% d/ ]* g
    0 s  h0 z/ l7 R6 f  m. _/ H/ F, ^<P>
    - i! W4 }1 k; M2 m4 h1 k0 s0 ^//-----------------------------------------------------------------------------
    ! b1 i! h/ b4 s4 M// Name: # N  }/ q+ `* s, L
    // Desc: # n" F! J6 }& l: M
    //-----------------------------------------------------------------------------* g7 w; s! E1 V. L7 K, u( g1 [
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )
    , s# A/ B! G4 M' {8 `# d{
    1 T! \! W8 n+ A) j, I    // Lock the player
    5 Y, o4 A2 S% B$ v- d: E    LockPlayerData( pPlayerData );</P>
    - k7 {" v0 T# A; V& ^<P>    // Lock the cell the player is in
    * g& }- y0 o' [5 w# X8 N    ServerCell* pCell;
    / h! s6 ]7 g# Y4 u) W- z    if( pPlayerData-&gt;wCellX == 0xffff )
    # s9 R/ g, o! G/ J    {$ A4 E2 L: \# }' v5 t- j
            m_OffMapLock.Enter();# L4 T+ ]& c8 ]! f4 a
            pCell = &amp;m_OffMapCell;
    4 v: y% a" _: a$ |; {6 }% M+ F    }
    ) G* S- t& I$ _, x+ D    else" k- ^3 X; k; }4 l2 ^, ]* w  R
        {  _. K' Q5 F( H
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );- J4 p# |1 C! I6 [; L+ z) e
            pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];8 i5 u6 b* M# E* v. O' e
        }</P>! c% m, p/ C" |; d6 X. t6 ?
    <P>    // Remove it from the cell
    - N  b- j8 J/ J7 x! b, ^& z% a    PlayerData* pPt = pCell-&gt;pFirstPlayerData;0 j1 j7 _, q; U* J
        PlayerData* pPrev = NULL;0 c& Q- s5 `' `$ Q) G
        while ( pPt )
    2 F) ^& p4 ]5 H8 L/ L1 \7 ~    {
    7 A: X& c, W* l, P( d! }/ I        if( pPt == pPlayerData )9 X! ?+ Z9 k$ C7 o# z
            {! b0 i' l/ s5 _
                if( pPrev )
    6 b: B9 Y; a. Z  n& q                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    % ^) a) b  B1 N  y8 I" s: j            else: `. }7 g* K& V. D
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
    ' |& L( u. _; \: X& z1 |<P>            pPlayerData-&gt;pNextInCell = NULL;0 E  l- O: P8 v. }0 [# c
                break;
    6 P2 X8 ]# S/ m- R8 d5 U        }6 s; a, R4 b+ U- f$ {3 W: V
            pPrev = pPt;( N( O$ M( i' l) q8 @2 K
            pPt = pPt-&gt;pNextInCell;
    4 D7 }& m5 V2 {) f    }</P>, ^5 W" J, Z. ]3 a4 k: ^3 ?
    <P>    // Unlock the cell
    & H; F4 V! e6 X/ ~; Z    if( pPlayerData-&gt;wCellX == 0xffff )' i. H: C' k: B& r) F6 E6 l
            m_OffMapLock.Leave();
    " o9 }1 e( w; _0 ~( T3 c    else4 M# V6 B4 W+ D9 A: ~1 ?' h$ U
            UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>! _: ]! \% V5 @7 o; k
    <P>    // Unlock the player4 x$ o. @1 W% K2 k' d
        UnlockPlayerData( pPlayerData );
    9 q3 P5 r2 V3 g) @$ g% z) `}</P>7 T+ W9 u- Z4 T# `# o

    1 M' A0 f' _. F<P>4 Q; _3 c& n( w' S
    //-----------------------------------------------------------------------------& t9 ]8 [5 f: E  i" t5 A% S( X& ]
    // Name:
    - {( Q7 t7 z; w: s% J5 L! ~// Desc:
    $ H6 g4 _; E/ b' j$ F8 w//-----------------------------------------------------------------------------
    + r  V' d' `4 R* n2 x6 q: B$ Gvoid CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
    1 D# F( G: T6 A2 {( u& @& t" I{4 K" C4 y( X) K
        ServerCell* pCell = GetCell( pPlayerData );! y& l8 Q+ |5 Q1 Q) ~: b
        PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
    ' x. \9 Q% Z9 R% _: T& B9 p6 r* Q    PlayerData* pPrev = NULL;; X+ M9 U; B! `6 `% _4 W& g
        while ( pPt )* _" U9 m: A$ p- ^* i: X. |9 {5 R$ A
        {/ B9 x! [) A4 c, l6 K# E! m4 e6 _
            if( pPt == pPlayerData )- v9 m7 P% U' Y5 [, R* M4 d
            {/ I4 I9 f$ t1 T
                if( pPrev )
    " @0 I1 W6 P8 ]. E( O* a                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;, T6 T( [; m' P/ F% ]1 o" S
                else
    , }7 r  R1 t1 m# {* ~% T5 {$ e                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;
    # o$ F" y7 p2 g* D5 ?            pPlayerData-&gt;pNextInCell = NULL;
    7 |3 F+ _8 z2 ^# B5 `- _1 [1 x+ E            break;6 e  K; |+ |1 _2 w/ x) Q+ E- E9 Y
            }
    / m' F+ v! o/ k$ A! J# |$ b        pPrev = pPt;4 c! Y8 V, c6 T: C% T' [
            pPt = pPt-&gt;pNextInCell;- O0 n& W* M) N
        }! A6 L! L: D2 h9 _* m
    }</P>
    2 u/ @# k. R- k* l1 }  d5 J5 j: Q, S$ Z0 J
    <P>+ T) O" H) \, q6 d
    //-----------------------------------------------------------------------------2 Q5 j3 w8 @/ s3 g
    // Name:
    5 I/ h6 v8 F* O% O  @// Desc:
    % N6 @- g, V7 x$ B5 ?: }+ s//-----------------------------------------------------------------------------& O, G7 y( U. r1 _4 M
    void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )8 a6 L) J2 O$ W4 [1 `6 M" D- R
    {  l, w8 O" _" h  K$ x, M; u+ Y8 J
        ServerCell* pCell   = GetCell( pPlayerData );3 I$ @; n7 o5 Z5 j6 W, b( U0 z
        pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;
    ( w7 ]) g2 [+ X- J- J0 Q    pCell-&gt;pFirstPlayerData = pPlayerData;
    4 y! p1 h! P3 @' G& S9 j: _}</P># y8 n8 a# x; O" u4 o

    , h* r3 z: [0 ]: B! D<P>
    * |. v# Z% @5 u! b6 Z" ^//-----------------------------------------------------------------------------
    ' Y$ A( U, f+ W6 D& e// Name:
    $ b0 p' D, n8 m) m% V" U* \6 P// Desc: 3 j& M/ s5 t: \. f( I" j: o
    //-----------------------------------------------------------------------------% b$ `5 e0 C" i$ J
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )0 a* E/ z; L. l3 K  [) \) y' Y, o
    {
    % L* Z3 c; i* v# P    // Grab player for this client and lock it( y9 B" v/ n) ^- C
        PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );  h+ l9 Q3 k$ q6 W  P8 |
        if( pFromPlayer == NULL )
    " K/ w' E. }; L+ M/ d1 k    {
      u  p" ]# B6 C8 c* ~2 ~3 D        if( m_dwLogLevel &gt; 1 ), B+ g: R4 a9 I  ]# Y
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );
    3 I% N* a3 g8 U$ L# q2 \( W        return;7 I8 Q  |2 g% j5 M& y: J) B
        }</P>
      p3 H3 [) ~& |( H) M) X7 H<P>    LockPlayerData( pFromPlayer );</P>" c+ O6 A6 E; m1 d% X
    <P>    if( FALSE == pFromPlayer-&gt;bAllow )4 {4 V$ \+ E/ x3 S: p* `
        {9 w- J2 e, \2 }" o8 b
            if( m_dwLogLevel &gt; 0 )8 l1 N  P6 \0 q
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>  n  m2 b2 |- V
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    % F" ^$ O3 T7 v5 h2 ^/ O1 L        UnlockPlayerData( pFromPlayer );
    * t+ P1 @9 _; \% V/ N        return;
    ; T7 A, A9 S1 P    }</P>. \( Y2 X1 |# [
    <P>    // Compute the cell the player should be in now2 \% h5 F8 j3 X# g
        DWORD newcellx = int(pClientPosPack-&gt;fX);
    6 `9 f" h  o- E! Q1 W) w8 @: Y    DWORD newcelly = int(pClientPosPack-&gt;fY);7 o4 g" F: m. o. T; O7 v& A3 z7 d
        DWORD oldcellx = pFromPlayer-&gt;wCellX;
      n5 l8 h7 p/ I8 z% y    DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>- ^0 N( f" g8 \1 y! h  j9 v/ @
    <P>    // Have we moved cell?
    . U! W1 _# h% K" ?    if( newcellx != oldcellx || newcelly != oldcelly )* p7 b- K3 k% D# T" T
        {" q: Q/ D/ q- L; e* y  H! }
            // Yes, so lock the pair of cells in question
    ) v! [1 l5 V9 ?5 I" W9 Y        LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
    1 D3 }6 |+ z- K<P>        // Remove from old cell and add to new cell, O! q$ G% k5 g. h2 z
            UnsafeRemovePlayerDataFromCell( pFromPlayer );& z/ S4 O& M# t4 Z, F) p7 y
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    ' ~0 R  P/ ?  A& T  a0 {5 _        UnsafeAddPlayerDataToCell( pFromPlayer );</P>1 @6 n* _1 v. t7 x8 D# r
    <P>        // Unlock cells4 v" T2 T/ y8 a1 P* u
            UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );
    & }' s8 x* E1 ?    }</P>9 J+ u% l4 ~- {' p. P
    <P>    // Update player position9 A7 x: k/ v6 O% {6 {; s* u. d
        pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
    4 A6 o2 l3 o; c" e$ p# b6 I    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    ! {& I( H2 h8 a    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
    $ e0 G! A$ U) _- X" }. x; G" Y8 E<P>    // Allocate space to build the reply packet, and fill in header ( G9 ]: \7 z" A/ }7 C# n
        DWORD dwAllocSize;6 S9 @& Y: b' O% y3 j, Q% ~
        ServerAckPacket* pSvrAckPack = NULL;</P>2 O( a: j1 g. K% x
    <P>    // Begin by allocating a buffer sized according to# [! I# Y" R0 t
        // the current number of nearby players + 4.  This will give
    9 e# x5 R7 i3 A5 V2 q5 z; y) {    // a little room for more players to come 'near' without resize3 @* W. p% O' {. K5 q- \; R
        // the buffer.
    " `+ ~$ b8 X% ?; C+ P' c: w    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>
    ( [$ n" L  I+ l* D; V! Z, y$ {3 S1 m2 x<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);+ T' l' U- Q- F' K
        pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    ! R" c5 d- h+ l5 [    if( NULL == pSvrAckPack )+ d* u1 \1 F* p) L2 A; b5 I5 _1 u
        {
    ! a1 X4 a! q# [+ Q        // Out of mem.  Cleanup and return, N6 Q4 g& t& l+ X9 O, I# M1 s! A
            UnlockPlayerData( pFromPlayer );6 p* m3 r. N5 V% o% E: P
            return;       0 _; @3 n6 K4 y8 L8 e& E* k! |. J
        }
    : Q  U, ?$ ^& u  R! `    ZeroMemory( pSvrAckPack, dwAllocSize );</P>
    % R2 H6 @; x9 T# s<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);, a2 T5 P& w1 O+ j7 c0 X0 W
        pSvrAckPack-&gt;wPlayerStatePacketCount = 0;) G1 Y$ \4 R: z( |6 D7 y
        PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>
    : c+ y2 u1 M! N' r# V<P>    // Compute range of cells we're going to scan for players to send
    . s) s8 b$ a$ v& L3 @: ^0 p    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;
    . ?5 N9 K8 @6 y# f3 T" E3 [    DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
    + g1 Z+ }9 h2 Y0 D, e    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;$ U& e& f2 p) C/ Z; |' r7 m
        DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>* c; Z0 D# r( P& P: ]
    <P>    // Lock that range of cells7 A9 Y2 ]  _; [
        LockRange( minx, miny, maxx, maxy );</P>/ B. u. h1 B; ~2 F
    <P>    // Scan through the cells, tagging player data onto the end of
    - z: ^+ v; ^4 B( B( j% a    // our pSvrAckPacket until we run out of room
    5 A, F# D! R6 o8 O    for( DWORD y = miny; y &lt;= maxy; y++ )9 K* `+ X: F( A/ x" X0 c* R" Y3 h
        {) d$ j) ^+ F/ `
            for( DWORD x = minx; x &lt;= maxx; x++ )
    8 r. }! _; W" r: }* R, l" ~        {
    9 q) n5 E! {8 |. U6 {$ Q( C            PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;
    - ]6 b. s! q, p6 ], x            while ( pCurPlayerData )
    " E" z1 ?. d$ F8 ^5 B1 e            {
    3 Y( r# H0 r! m6 |0 T8 j                if( pCurPlayerData != pFromPlayer )
    . D( Z7 f/ t) r) r2 l5 p                {7 m; L+ H' M# q, m$ y1 R
                        if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )
    9 N- \# J9 w4 t, b6 ~# x3 J0 R                    {+ t$ z) w1 N0 Z& [  i0 ]: Y
                            // Make sure pChunk is where we think it is
      o$ o: y: u6 x7 \/ F                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>
    2 `8 A% V& c( _: n<P>                        // There are more than just 4 new nearby players, so resize the
    4 S- R/ p( `* Q% G1 m- K( D                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
    # Z2 i. Z" C1 m% B  I% ~                        dwMaxPlayerStatePackets += 16;# I$ J7 V: ^/ [
                            dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);/ z6 |/ I! _0 ~) v5 l/ z( c
                            ServerAckPacket* pNewSvrAckPack = NULL;
    ' H. t, D; e; l# Z* u/ `' J% C                        pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    - ?) n" d* v* z# Q                        if( NULL == pNewSvrAckPack ), e+ g" h: o" Y6 J1 {: D
                            {- c; i- o8 H& q7 F
                                // Out of mem.  Cleanup and return. A4 m0 i1 y: I# @7 C# d( g9 ~  e
                                free( pSvrAckPack );2 {. k6 B& `. Z  x1 Y: L9 U; D: j
                                UnlockRange( minx, miny, maxx, maxy );
    & c% V' [# j/ c) [! I( k                            UnlockPlayerData( pFromPlayer );
    : Z  C! U! D" o                            return;       & I' ]$ J7 o, v! ^/ E- X+ A
                            }</P>7 x  q  {& n- ~* ~, H' w1 V- L
    <P>                        pSvrAckPack = pNewSvrAckPack;* S2 g) E' A1 A) q, f
                            pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>: @: }- B/ Q+ Z3 t9 m
    <P>                        // Make sure pChunk is still where its supposed to be
    3 ~, h4 c$ D' ?! a" L2 F, G                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );
    / `. Z% F7 [4 w' {$ j3 T% Y8 |                    }</P>% n  j5 b7 B' I  t' W
    <P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;5 J3 J* U3 t% G2 c7 {1 r3 S: u
                        pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;3 J8 J7 X- S* b* {' y
                        pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;, v0 Y' i% o. V
                        pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;" y& F1 f" f$ C9 j
                        pChunk++;. j" F" Y1 U- L
                        pSvrAckPack-&gt;wPlayerStatePacketCount++;
    4 m& ^% {" R0 G, G, O* X5 K. w  @                }# \3 ]& W- B8 g0 g+ t
                    pCurPlayerData = pCurPlayerData-&gt;pNextInCell;
    ) Y" g( y6 q4 ~1 }# T1 H5 Y            }
    7 r7 U' r$ {$ A6 B        }1 F+ }0 k8 t' ^. E* W
        }</P>
    ) c% c! i- u; L<P>    // Update the dwNumNearbyPlayers for this player
    / z' I6 b, t/ Y    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>
    7 U; i  }0 c" x! J* A# d<P>    // Unlock range of cells
    " q% x( p, N6 E( E+ h7 d    UnlockRange( minx, miny, maxx, maxy );</P>
    0 ?& t1 z. r. T* ~6 j5 P<P>    if( m_dwLogLevel &gt; 2 )  {9 J, W, g" A- ^6 Z, m
        {* g) Y( m: @' y& T2 I6 Q
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );9 T. T+ F2 ]' \% d8 l! ]+ [
        }0 z; B' ^9 O3 Z; Q; m! B
        else if( m_dwLogLevel == 2 )
      {0 e! V9 G% Y  Z) i) |/ s' M0 e    {
    3 l$ _  P$ l0 z1 i        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    8 Z% [- |! U) K& {; R        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )
    + F9 B; q* B4 I# W        {
    ! h. P  w' j+ O" `; h7 g( p/ h            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );9 w8 ~, a% U* k- t" C& K
                pFromPlayer-&gt;fLastDisplayTime = fTime;
    $ E8 ?4 s7 t' h, f        }
    8 L  b& ~! U# a3 m5 k" x& p* Z    }</P>
    6 D' }9 ^# g2 H. X* H9 j<P>    // Unlock the playerdata7 p4 K2 F- R, |" P
        UnlockPlayerData( pFromPlayer );</P>
    4 s0 ]" |& x+ z9 v, [- x9 g<P>    // Send acknowledgement back to client, including list of nearby players ) |  c, ?  k9 V; i$ }
        DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));
    0 `' A) z$ C8 ]5 j8 K# I! S" v ( a+ e$ K+ A" X# s( K
        // Pack the buffer with dummy data.+ F% G' \+ R+ L
        if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)$ N2 O  p( n4 w/ G3 g: s. U
        {
    ; V, }' k+ ^, l- Y7 a        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];
    ; T) I$ R6 z& b( D! p        VOID*   pTempBuffer = 0;</P>0 f' D' _, F6 i
    <P>        pTempBuffer = malloc(dwBufferSize);9 L: [3 \/ N+ [& Z3 ~
            if( NULL == pTempBuffer )
    / Z+ U) b9 r- H$ Z- v) y" ]        {
    ; h+ R1 s* X# K+ j+ i8 Q            //Out of memory
    7 w' ]& B! ^: c+ r' K            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
    : q' u  X" e4 X3 L; e, T            free( pSvrAckPack );! ]9 N; u; F# Z1 v4 |/ E
                return;
    ' I8 M  B& Q3 n% {9 p$ F- h/ V        }</P>8 r! {- _4 k' d" }' I- C
    <P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');
    ( x6 Z$ X  a* a4 s        memcpy(pTempBuffer, pSvrAckPack, acksize);</P>
    ) g& j! r& R! B, v- d# }' b5 j<P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );
    4 s8 S1 M  L: N0 F   
    2 Y# P: ?$ j* ?$ d' W        free(pTempBuffer);
    - R1 C+ a4 |- E, f    }   + i# C1 f* u& Z4 o, x
        else# q% Q+ J( }: V$ x- C7 L0 L
        {6 I( M3 A) f* O% Q: j- \4 c
            SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );' g6 c7 b$ N* b
        }</P>
    & |3 v" g0 |; z6 _2 w2 @<P>    free( pSvrAckPack );</P>, k( o( u/ f' u
    <P>}</P>
    8 g" }' n& Z$ y3 j$ F4 i
    ; I0 S( y; o1 I. H, J<P>
    5 u, c/ j, u7 q//-----------------------------------------------------------------------------
    7 x+ i2 N9 M! U" Q7 G& d// Name:
    0 \( }6 c% U; F4 J- z! K, S4 C/ S3 ?// Desc:
    # o% o! S; d9 n! \//-----------------------------------------------------------------------------
    7 U5 f; U. K. i& N, I/ evoid CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack ); Y5 R) D3 P: \
    {
    1 N; Q/ [0 C. s& G    // Grab playerdata for this client and lock it
    ( l' {$ k/ c/ f  [$ c+ q9 V    PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
    ) U( |( a( k8 q; O0 E+ p  Q    if( pPlayerData == NULL )1 E( d! d' z- I2 M8 L* X3 t/ {
            return;; z- C, O9 [; I2 n. @0 Y
        LockPlayerData( pPlayerData );</P>' v6 J2 L# k' f# M
    <P>    // Record the version number
    6 V4 B. V  ~2 f+ V- p3 Q; D& v    pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
    - G; h% E2 `' W# ]7 g2 e; O<P>    if( m_bLocalLoopback )
    7 T; m. h! T* t4 z; W+ L  b        pPlayerData-&gt;bAllow = TRUE;  p' U. ?7 Z! J4 S- k+ }
        else
    * l  f0 ^, p  p' G        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>! a0 [4 Q2 k5 l: r. N6 t( h8 C
    <P>    if( m_dwLogLevel &gt; 0 )
    " O0 A, d- L* Z) e3 r        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Client version=%d (%s)"), pPlayerData-&gt;NetID, pPlayerData-&gt;dwVersion, pPlayerData-&gt;bAllow ? TEXT("Accepted") : TEXT("Rejected") );</P>
    ' p9 W1 x0 K$ D5 s# q+ s5 l' i2 k& x<P>    if( FALSE == pPlayerData-&gt;bAllow )
    5 C1 T; V1 B  z/ F    {
    1 ~; ~- D9 ~, A        if( m_dwLogLevel &gt; 0 )
    1 Q8 }" \) d0 |; o$ [0 h8 |6 [            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>, \2 a$ v8 C/ {! P7 [6 @/ Q9 d1 J
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );/ ?7 r$ }2 o: }: u+ u
            UnlockPlayerData( pPlayerData );- `  G, N6 V8 o9 m
            return;
    , X, M, `5 E& T' r' ~+ ]    }</P>8 u+ {0 P& I& x5 R/ ~! y
    <P>    // Unlock the playerdata1 E( _4 r2 K# @0 P
        UnlockPlayerData( pPlayerData );</P>
    7 c( ^% \+ x  d) b) n" {<P>    // Send acknowledgement to client that the client was either accepted or rejected
    ( H% Y) [+ V8 ~% v  _& J    ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );
    1 e/ I8 {1 }* j. Z! r    SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
    4 W: Q( W0 S' i6 U}</P>! [+ T$ m  ~; Z3 G% C

    7 W, m$ n! F- N! A3 w<P>+ @4 {2 b) M9 [( [
    //-----------------------------------------------------------------------------2 ~3 [# ^6 W9 N
    // Name: ( }0 D; O) O; _7 g- k$ [
    // Desc: # ~6 b0 _: B' W4 m4 c1 K  X, D8 p
    //-----------------------------------------------------------------------------
    - q8 }4 L: T, ?BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )  W/ H5 r: C7 X7 m2 ?
    {
    8 M0 c# X: d2 k+ E! o- W; v7 ~    switch( dwClientVersion )- a9 M8 s0 w1 v$ c
        {
    / {+ d6 X- L# a5 C        case 107: // only v107 is supported
    : B9 x% Q% J" ~6 z            return TRUE;7 k& J5 n4 p' w. F) f0 C
            default:
    ' ^1 P6 A8 F; q            return FALSE;
    6 F9 R& m# P- R    }7 y& k! b: m6 u2 G
    }</P>4 b$ J3 m' k8 p% `: w2 O/ H

    9 c3 |* K& n8 J; i<P>: [6 f% B, z" X$ x/ a5 e7 Q2 j
    //-----------------------------------------------------------------------------
    1 d( ^3 h  C3 k/ f( M. Q4 A// Name: 4 \3 U. v) q( o- n# M2 r
    // Desc:
    ) a# S: ]) D/ c  x; X- L1 p) T//-----------------------------------------------------------------------------
    ! m' u2 I' U- |9 ^% U5 Yvoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )1 W+ j, z+ a: n
    {
    8 h/ `6 J, f. C0 H    if( m_dwLogLevel &gt; 1 ). v4 A' L% K2 E* Z) x
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>$ q5 @1 v  {- z- [2 P
    <P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );) I# p5 @: |# [4 R2 u
    }</P>3 _% A; M/ z0 N( d9 z. J

    2 p: {: V& J1 L& W& w<P>
    3 U: |6 |0 j2 S0 L1 F$ f; s; r//-----------------------------------------------------------------------------. p8 l5 }1 b) m/ t
    // Name:
    " O3 l; }8 j# o' ?& c& t( W// Desc:
    " M: e  Z" s* K/ a& x8 g2 [//-----------------------------------------------------------------------------; g7 N0 s  r: R5 Y1 S6 ]% X: n+ z; L
    DWORD   CMazeServer::IDHash( DWORD id )# h/ ~9 |8 Y5 j
    {
    , D/ {! G0 y) m    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);
    3 N4 S4 e, A4 c. D5 q    return hash;& _, M7 Z0 [; `8 x4 I8 K& h
    }</P>1 n- r1 C% q4 @# J7 w* `, n
    & Y' M; b* q# z3 ?
    <P>6 ~8 H5 l( B; H9 z" c
    //-----------------------------------------------------------------------------
    1 g% _" g8 K  z// Name:
    " s) E/ d9 [. S; l9 m// Desc: ; V/ l) H+ ]" x% A0 `6 H/ s
    //-----------------------------------------------------------------------------( ^: T2 d! j4 [
    void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )8 k6 H1 H. u/ ^3 v) }* o
    {) o7 d4 Y* h# U& D' X/ q. N: v% l
        // Hash the ID to a bucket number! {1 a' D' f& d, @1 {/ y- J  K
        DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
    , G3 |# P( I0 n; U6 E! z& S' v<P>    // Lock that hash bucket; `0 K! |- H8 [# |
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;/ o) h7 w* H9 ^  |- o
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>% J9 e9 D+ W& R* V% H! Q3 I
    <P>    // Loop though players in bucket until we find the right one
    " j3 Y( W$ c% o9 ^6 c    PlayerData* pPt = m_pstIDHashBucket[bucket];, R; A( A/ F) F) f1 f
        PlayerData* pPrev = NULL;
    2 M2 w0 c- w' o% S' Y7 p    while( pPt )6 u2 q+ l- i- z* D
        {
    3 o% ]9 U$ r; P7 p1 c. g        if( pPt == pPlayerData )
    9 X0 C0 _$ |( ^, z6 ]/ C            break;. _$ c: k. {* M5 i# M  i8 V
            pPrev = pPt;5 N6 e. ~5 a2 g; T* G2 x
            pPt = pPt-&gt;pNextInIDHashBucket;
    6 S( m& t2 |1 I. _- ?    }</P>+ G  w1 X6 t1 }  I- a; l* ~
    <P>    if( pPt )6 a$ Q2 B* R/ x& `4 N' a: k
        {
    9 L: E' b+ g4 J        if( pPrev )
    - a3 w4 C/ Y" z            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;
    * I3 Q( W7 H+ R/ {4 A" l        else
    ! n; p% J- S) G            m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;. k1 u6 J* y& O# Z& F' R% c/ m
            pPt-&gt;pNextInIDHashBucket = NULL;) J6 ^4 u( Q$ X  m
        }</P>
      P9 w. S; S* U- E! U<P>    // Unlock the hash bucket
    ( Z" o4 @* M$ H/ X: u    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    7 ~6 g% Q, Z1 A2 A. ~: ?}</P>
    9 R5 i: _7 l! G9 A4 S  _: I, _3 t0 p- h/ S; a7 H% _! S
    <P>
    % M% y  w5 j' V) t1 L$ Z//-----------------------------------------------------------------------------8 a4 X9 v% e( I/ H
    // Name:
    2 y! o6 v- c- y  }- I# b' T  c// Desc:
    ' `# I* e" W  J/ f//-----------------------------------------------------------------------------
    $ X+ y% U. f% Y, T4 X, Uvoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
    & T6 U  T/ n5 f$ |9 y9 u7 D/ G{
    0 N$ t# V1 k; i( L9 u$ b3 k* c    // Make sure this player isn't added twice to the m_pstIDHashBucket[]
    , L: @5 M) {; G1 Q    // otherwise there will be a circular reference. f4 p* K0 V- N% g( x4 Y: s
        PlayerData* pSearch = GetPlayerDataForID( id );
    9 U6 H; G8 _1 U7 h    if( pSearch != NULL )# b: z& A$ z( e# ~; l0 \& D, Y
            return;</P>' w3 O; ^5 Y1 e. {, u5 o3 A
    <P>    // Hash the ID to a bucket number
    : o1 K( D3 Z2 w    DWORD   bucket = IDHash( id );</P>
    ' M& f* B5 Z8 @) |<P>    // Lock that hash bucket
    $ Q$ W7 [( y* J4 Z; P8 m3 }    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;9 P# X, Y+ ]. \- w4 D
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>6 ?' x2 O! v0 q& {) E
    <P>    // Add player onto hash bucket chain- F0 C5 ?8 E6 F0 H; E0 h
        pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];
    : r4 z* d$ n- k    m_pstIDHashBucket[bucket] = pPlayerData;</P>
    6 J$ P  {! S0 Q( e* _<P>    // Store net id in player
    5 n# f4 B# ^- r$ I- N    pPlayerData-&gt;NetID = id;</P>! N" l/ q" G0 E( h' D. i/ i
    <P>    // Unlock the hash bucket
    9 ?& V1 z+ ], A+ p. j' W0 t5 }; }' X$ D    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();( g; A8 _& M$ t) X* }- ]
    }</P>/ @8 @# V0 A- W8 ]0 x! D/ [

    ' i1 n2 P1 C  l- N/ w/ b<P>8 F: s' u. G& v/ B1 Z
    //-----------------------------------------------------------------------------
    ( B5 o( ?" b( i// Name:
    , F% G& ]1 C8 l+ M- T  n$ x// Desc:   D& ]. C& z' z2 z
    //-----------------------------------------------------------------------------7 `3 i9 F/ D) R6 d8 \7 I, }
    PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )6 I* N) }$ @* Q' Z+ q0 Q
    {" [/ U( o2 R& C4 |
        // Hash the ID to a bucket number5 |, J( f4 w+ B6 N9 ]5 t% e) I
        DWORD   bucket = IDHash( id );</P>
    0 }3 K3 [' P( |" \<P>    // Lock that hash bucket
    # t' x( k1 O0 y* r. z    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
      U+ [6 V/ _3 E9 g    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    4 }2 s4 M' B# F! q<P>    // Loop though players in bucket until we find the right one$ o/ O/ a* ?) z8 C' G$ p0 y
        PlayerData* pPlayerData = m_pstIDHashBucket[bucket];: `' ?- U! G+ E! \' u( B6 Q# w
        while ( pPlayerData )2 g5 e& W7 r6 o  U5 P6 G* C+ j2 d4 |
        {3 g" p# J( _) b! x) t! X
            if( pPlayerData-&gt;NetID == id )
    ; G* M3 G# h' `3 W0 w            break;1 X) `$ L; |* v& d  {# s" Q
            pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;6 l6 C# W  K$ q" R9 [% M$ E/ @! H9 x
        }</P>
    + `6 d6 j. j. [1 m+ f0 O! G<P>    // Unlock the hash bucket
    : Z3 n0 U1 L6 V$ Y2 v. @% s8 P' Y    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>
    7 ?0 Q4 e. `8 I! X<P>    // Return the player we found (will be NULL if we couldn't find it)
    ( @  v* \/ ~9 [. G3 V: _' s    return pPlayerData;
    / G: i0 x9 M3 G9 j# @5 M; m5 _9 j}</P>
    4 i# G! k. i# @! g  {. o& m
    , M5 Q8 Z% K1 f) u( Q$ c. T. a<P>
    ' a8 T9 q' P4 Z9 E) T//-----------------------------------------------------------------------------5 B& R1 p2 ]4 Y
    // Name:
    % k$ G( w( f, F. r' ]  c// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner
      b) i- y9 e$ l" @5 ^//-----------------------------------------------------------------------------8 _: O2 B# j  j7 T
    void CMazeServer:isplayNextConnectionInfo(); U4 b: {+ q8 U# B4 g
    {9 H/ E1 L' Q1 Y; N/ x6 h% d2 s  p) L6 {
        if( m_pNet ): L$ U& v& d$ l
        {
    0 l0 g  r! Q, `        // Find the player that was displayed the longest time ago, and display it./ u1 m% J& |6 ?. E$ O1 m; K
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
    # l/ X; p* z. M+ B: h        PlayerData* pOldestPlayerData = NULL;
    ! v/ n2 L9 V; v" J        FLOAT fOldestTime = 0.0f;</P>, Y1 O8 K2 T6 j& y9 h& B/ ?; g
    <P>        m_PlayerDataListLock.Enter();</P>
    7 Q" h6 x4 L/ c; I/ s1 l<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;% V& w/ h6 d: A* ]. x; e5 [
            while ( pPlayerData )
    1 D1 u' h: X  ~+ B( B        {
    $ x5 l0 }$ Y: r: i( h9 }% T            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )& Q2 K  v9 g2 ~8 X  U; X+ L
                {
    " p; ?* c2 B9 Q7 |8 O# @9 p9 {8 H                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;) d* W- k/ V: c) d/ Y/ Y# j; Q
                    pOldestPlayerData = pPlayerData;9 k9 X' _1 l/ n3 n" Z% @( z& z, N
                }</P>
    ) f$ A+ H8 K$ Y2 H1 y; y. R<P>            pPlayerData = pPlayerData-&gt;pNext;; L# v( B! ~: ^  o, m, F- y
            }</P>/ M' _5 [3 A4 Z
    <P>        // Display the player with the oldest CI field, and update its CI field.* r: F, J+ E/ y4 P" p# X7 L2 c
            if( pOldestPlayerData )" \. F$ J( O3 I1 `9 a+ U
            {
    ! _0 V2 Y1 i8 i4 _1 j: U! z            ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );! J; |* f6 E* q$ w* D% ]
                DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
    & B2 t' R: @+ c4 U/ f" D7 d4 }            pOldestPlayerData-&gt;fLastCITime = fCurTime;
    / y# c6 @0 _4 b8 B5 r5 {. q        }
    1 Q' Z. `& C( \. i7 H$ P7 u$ K        else
    3 ?$ o3 L* x4 W9 T" h6 }        {
      `% C1 U- H: U! V- g$ G3 r3 V            ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    % O' H8 \& ?- H8 O- @        }</P>3 H2 U) i# S, p/ C
    <P>        m_PlayerDataListLock.Leave();
    4 r' X$ t0 x  |7 U: d4 q    }; D& ]  |% p. t6 ]
    }</P>( A9 b- q1 ^  e1 O$ Y0 d' m
    6 M3 ^: [2 S  C) W& j0 A
    <P>
    . u2 p9 M* W: P7 u! _( l4 n2 ]//-----------------------------------------------------------------------------* j4 }" I) ~4 i' H5 \
    // Name:
      x7 L5 U9 i/ J, ]( {// Desc: 7 N" m3 Q* ~% D
    //-----------------------------------------------------------------------------
    / e2 a: s2 P, a0 M* Lvoid CMazeServer:rintStats()& d+ R, H* x6 N/ I. w
    {
    8 Z9 |$ Z5 t6 I/ h; ]    ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
    2 \# d0 Z" l0 b& e9 Y                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );
    ( O) _/ K& a1 u! b    ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),: m5 ^% u4 u& C* P
                                        m_fAvgThreadTime, m_fMaxThreadTime );- q) H. y% ~9 y
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );  V. N6 {+ ]. _9 j
        ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );$ f5 @/ G' k! l7 p: D
    }</P>' Z' h/ q  |8 \4 z; ~4 o  O

    ) C7 r  M. d  S( y4 A<P>! w$ j) b/ D, a9 L" C4 k
    //-----------------------------------------------------------------------------1 b  B! h5 p: U4 T% x$ r$ s
    // Name:
    2 {1 x* h: X- {0 _8 L2 ~2 o! e; a// Desc:
    % a8 \9 l) C0 G& Z# E  H//-----------------------------------------------------------------------------5 ?# @- o2 D2 U* _/ D- Y; L3 [
    void CMazeServer:isplayConnectionInfo( DWORD dwID )4 t( p0 _: @, q* L, t
    {% d( v. C2 l) _
        TCHAR strInfo[5000];
    , p( \, n% Z* c7 }  P1 B    TCHAR* strEndOfLine;/ Y3 h/ S* L# \, Y
        TCHAR* strStartOfLine;</P>
    ' `' z: B- b  L<P>    // Query the IOutboudNet for info about the connection to this user
    4 F4 ]7 c4 O/ D! ]7 l1 ?, i3 l. d    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>" ?7 x0 f! g8 J% Q$ k+ y
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );
    ! y; i9 H  B# D% c9 J4 ^0 e. R    ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    1 p( F  ^( t9 v% g+ Q<P>    // Display each line seperately
    9 d$ K; H7 s! H0 ^$ S    strStartOfLine = strInfo;
    $ b8 k* L, e+ L    while( TRUE )
    * `- b! e% E, s: @    {- y. b# k. w* c4 e* [* O
            strEndOfLine = _tcschr( strStartOfLine, '\n' );
    $ |/ z' m2 n; H2 ?1 `2 i; C/ J        if( strEndOfLine == NULL )* t4 N# E. V9 K( }- ~+ k1 F+ m, [
                break;</P>
      C/ I' s+ m7 m) f" D/ x; u<P>        *strEndOfLine = 0;
    ' Y* d5 S% u$ q6 N. e' G        ConsolePrintf( SLINE_LOG, strStartOfLine );
    4 R- X7 x" U6 @( L1 Q. K: L        strStartOfLine = strEndOfLine + 1;3 ~4 O# q* T0 D  M* ^) K
        }
    0 H. }/ j2 E0 _7 Y9 H- D}</P>
      n8 F) G! H  j+ ]. K& Q. D1 M% J8 l. U/ {7 W. p$ s+ g  C' s
    <P>
    ; I) s/ ]: e$ V2 G/ m//-----------------------------------------------------------------------------  x; t2 c  a% E% R8 E, R0 g( K1 K3 I& C
    // Name:
    3 A8 m* p- z! M( D// Desc: 9 _# T# b) C9 Y% Q
    //-----------------------------------------------------------------------------
    ! X& X. r& J5 Q9 JHRESULT CMazeServer::SendPacket( DWORD to, void* pData,
    ' ]$ \! c; ?) ]8 n1 k* r" F                                 DWORD size, BOOL reliable, DWORD dwTimeout )
    & G8 Z) G5 E5 T{
    9 ^: `; ]2 Q  G3 W    // Chance of forcing any packet to be delivered reliably9 X; m( F. M' Q. M8 O
        if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )/ v: T6 L- G  _# N
            reliable = TRUE;</P>
    4 F" l* g6 S; `9 q<P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    - S6 I2 z1 t1 L}</P>
    5 z, F/ n. y! y* d" q5 H2 r% w0 F. L
    <P>3 b+ C/ o- q6 |- ~8 D
    //-----------------------------------------------------------------------------3 ]& f( q+ C7 F, Y+ P, {5 U5 t! n
    // Name:   O, {* N# u" v  L7 l) l
    // Desc: 4 y( a& v% J6 u/ y2 s$ j2 H
    //-----------------------------------------------------------------------------$ m( W2 b! r( r' P" B$ u8 q6 x
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )& K) o& V4 [' Q
    {
    7 C- j* Z% Q! R6 W/ ~2 {- S    // If we're up and running, then send this new information to all clients
    . I( t( h8 J6 V$ F( g    if( m_pNet ): M) z% J/ N  K" V( u' r
        {
    / X+ u$ e- |* e; [0 p' D        //Use the AllPlayers ID
    6 ~4 \; w4 W, G        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );
      N! x, I$ z/ d    }6 g7 @  o2 C# ?$ g0 @, `. h, ^! g
    }</P>+ S: r2 H( _3 }  b9 k

    & `: R% Z4 M! }. ?. P2 R7 |<P>
    7 }& P4 ^* k6 D3 B" N! y//-----------------------------------------------------------------------------' d3 x8 _* x% g2 D2 ^% S3 a
    // Name:
    # c0 v2 H, q. F, p' s6 w4 \& z3 E// Desc: 4 M1 \+ `1 q: d9 d; b8 s( C
    //-----------------------------------------------------------------------------' `, t: t! f" \4 l# T
    void CMazeServer::SetClientReliableRate( DWORD percent )
    5 |, i9 F) x& m/ Y, v{
    " g  h# w2 z$ b3 F2 d5 A; h; e    // Update client config, and build packet containing that data
    ) O& w6 G: T1 n1 W( L    m_ClientNetConfigLock.Enter();2 l' ^) m1 r4 e5 e5 d
        m_ClientNetConfig.ubReliableRate = BYTE(percent);# M2 g- ]  D! P
        ServerConfigPacket packet( m_ClientNetConfig );
    $ ]. e/ v9 B) q7 V1 o5 l    m_ClientNetConfigLock.Leave();</P>
    3 d& e2 v+ M7 x# H4 t<P>    SendConfigPacketToAll( &amp;packet );& c* J8 A, H2 B+ y! k) Q4 C" q
    }</P>
    ! q7 b9 e6 w$ G
    7 y9 q( K! ^, i<P>
    - B2 s( P, ]; V( ^$ c7 n! T//-----------------------------------------------------------------------------
    " d  n- v+ \" N7 l5 o# V- r// Name: $ }- D: E& d2 Y$ e4 `% A. C# e+ p
    // Desc:
    " i* c" y2 z! \8 Y, G& Z; ~9 `//-----------------------------------------------------------------------------
    2 X' R4 I& ?+ z# Zvoid CMazeServer::SetClientUpdateRate( DWORD rate )" J$ @7 v& O' a, u' R
    {
    0 o  s$ J, W1 m! ?- Z% w    // Update client config, and build packet containing that data
    & S( ], }$ _1 J0 [7 K    m_ClientNetConfigLock.Enter();
    ' t( f7 v) I6 a$ H  `    m_ClientNetConfig.wUpdateRate = WORD(rate);
    / _) {; J7 A- c) Q& a3 o    ServerConfigPacket  packet( m_ClientNetConfig );
    ) B- a  s9 |* Z    m_ClientNetConfigLock.Leave();</P>* n+ n1 M& e) l
    <P>    SendConfigPacketToAll( &amp;packet );9 x: b& s8 \' v9 Q0 q; `* K% X
    }</P>) j. e# o$ X! R* j6 \

    ; @) l' p& i% s8 O<P>
    % @) q  d, f* }- G0 _' O. v, ?//-----------------------------------------------------------------------------$ j6 E# e+ {* F6 X, M
    // Name:
    ( a7 ]- u2 R! Y* `' v// Desc: / z1 q4 d' Y5 k- |
    //-----------------------------------------------------------------------------
    2 X/ n9 s- o0 r" Mvoid CMazeServer::SetClientTimeout( DWORD timeout ). c% v% q+ z. ?+ l' J# n6 l
    {* e( h. R. C- E( o( n4 G' |
        // Update client config, and build packet containing that data
    : f+ ~6 i4 M8 p1 a    m_ClientNetConfigLock.Enter();
    ( X0 w: ]- V2 n    m_ClientNetConfig.wTimeout = WORD(timeout);
    : k. I% `5 ?) k4 P+ z( j8 @2 O    ServerConfigPacket  packet( m_ClientNetConfig );! x7 D* w- N* K! y% ], T  f- |
        m_ClientNetConfigLock.Leave();</P>
    6 J9 @/ U9 M" A( C<P>    SendConfigPacketToAll( &amp;packet );4 U4 e0 L7 S+ P
    }</P>
    3 ?5 Q6 J$ k, c; F3 \
    3 P# E3 k" k1 @6 p- l8 ^<P>
    6 t( o, J( D$ {: S3 _: K//-----------------------------------------------------------------------------8 e$ i4 k) p+ r: l( i" n/ }
    // Name: ! u7 S: M7 s- [2 U$ B
    // Desc:
    $ H$ n) L7 o" @. ]7 F//-----------------------------------------------------------------------------
    / D1 g$ ]& _/ R7 [, Vvoid CMazeServer::SetClientPackSize( DWORD size )' v7 E/ f' b! s. b: ]  i8 i
    {1 _! v7 @) K' Q% |. u
        // Update client config, and build packet containing that data
    + [1 K: K& g" _3 h' P    m_ClientNetConfigLock.Enter();
    4 ~% R5 y0 f  e) t2 M5 i; W+ [   
    - N8 _/ X1 c3 Y    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.
    1 k+ c9 U5 l, \, @    if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   & t: L* w/ _! v
            m_ClientNetConfig.ubClientPackIndex = 0;</P>
    6 ^  L9 _. h8 ~" x3 D<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);
    ! ?& Q5 Y1 `& Y' T# E    ServerConfigPacket packet( m_ClientNetConfig );, S) p" ], U& e* d6 V7 Z
        m_ClientNetConfigLock.Leave();</P>6 e4 M8 C1 r- |- c0 _: h4 J9 E8 Q
    <P>    SendConfigPacketToAll( &amp;packet );- G% Z% t/ T" `7 V. Z/ j3 J+ U
    }</P>3 m" V  p' ~& b, E! K
    + @; B3 y6 n3 Z3 m0 m  g
    <P>
    - w$ W, U! v" g% _* X- W7 h//-----------------------------------------------------------------------------
    # F. a: S9 P3 N& Q  S  f9 y; B( R// Name:
    1 T3 O' l5 G  O! s// Desc:
    ' X* Z! s2 ?# ^7 [9 X( z//-----------------------------------------------------------------------------' B7 `: O# I* ~+ M8 x9 o' h' q4 l3 Q% k
    void CMazeServer::SetServerPackSize( DWORD size )$ j1 t$ m0 v0 ~; L% n' R5 v' E& p
    {3 Q& g, T- w1 g* [: c3 C
        // Update client config, and build packet containing that data. ^/ v3 c5 N- J  s+ p* T0 w! o' H
        m_ClientNetConfigLock.Enter();# M" ^/ p3 r3 j! ]
        / G( n5 c& M( ^3 u
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.8 W/ a( R, l3 t- b
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   . S/ j. d# W. L8 j
            m_ClientNetConfig.ubServerPackIndex = 0;</P>- O4 u3 j* Q- U2 Q6 }
    <P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
    # T$ r- x8 e; v0 G/ e! n: t    ServerConfigPacket packet( m_ClientNetConfig );
    ! G+ ?7 h2 m. R. \: p+ P1 I    m_ClientNetConfigLock.Leave();</P>
    # X# _# ~: E$ k5 X5 I& R& ?<P>    SendConfigPacketToAll( &amp;packet );
    ' A" o1 `# Z9 E}</P>: x1 M& j5 t3 ^: [1 T( N, k" x
    <P>; E* d# Q, C( }
    //-----------------------------------------------------------------------------
    6 F2 G- Y; d: ?3 g$ w0 o4 j4 u  l// Name:
    ; R, b) y+ Q* I) S9 B// Desc:
    1 h& d1 Y! c3 X! J' a. ~//-----------------------------------------------------------------------------
    + c, y0 X7 q# W% Uvoid CMazeServer::SetClientThreadWait( DWORD dwThreadWait )3 |) n- [( [5 S4 k8 g. s( y; q
    {
    , u# n; b0 O. e( E& z9 I  g    // Update client config, and build packet containing that data
    , S  X, v1 c6 N5 Z    m_ClientNetConfigLock.Enter();- N% y1 E) Z# O4 N: }
        ) I# d6 v# F1 n& I& O: Z
        m_ClientNetConfig.dwThreadWait = dwThreadWait;
    ( W8 J+ d& x& f# z5 ?* ]    ServerConfigPacket packet( m_ClientNetConfig );
    1 r/ g& x' W& _0 T& H. v9 |/ A& j- M    m_ClientNetConfigLock.Leave();</P>
    7 }: X7 A! n! z! c+ L<P>    SendConfigPacketToAll( &amp;packet );2 p5 K/ }/ P# u9 U; K& e- |
    }</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-11 12:59 , Processed in 0.365549 second(s), 51 queries .

    回顶部