QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4163|回复: 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 ?" ]" l, m" u' h( B
    <>// File: mazeserver.cpp2 i) _7 q. C. ^
    //
    ' |+ _% ]- v: T. z1 F4 t/ G7 k// Desc: see main.cpp
    1 c: d* a$ A7 w3 U- c. d//
    : w- K, E% w7 W  |$ _( _// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.0 P  j& D: ^6 I( U1 \
    //-----------------------------------------------------------------------------9 |+ L. {# i+ n$ \" i1 H
    #define STRICT# j) _: C6 f+ q1 Q$ Q4 X
    #define D3D_OVERLOADS
    + B+ g5 ^0 l9 A6 c0 r1 K) B#include &lt;windows.h&gt;
    7 M  \: s$ m% L  X( c: r8 |#include &lt;d3dx.h&gt;- Q8 b+ V. w7 o) K$ l! I
    #include &lt;stdio.h&gt;
    9 Q6 i/ m+ W4 {4 i+ ~#include &lt;math.h&gt;+ I( T1 z4 Q3 G, j
    #include &lt;mmsystem.h&gt;
    / V* S  u$ n. x- E0 {#include &lt;dplay8.h&gt;7 u" o/ S8 y4 @1 E
    #include &lt;dpaddr.h&gt;
    9 r) V4 Z, M" |) t, Q2 b8 E) a#include &lt;dxerr8.h&gt;+ r% t+ P2 m$ ]2 E
    #include "DXUtil.h"" b2 c  f- A/ X4 w4 }" N$ C
    #include "MazeServer.h"
    / a! P# p1 H6 a6 w1 ^/ o+ G#include "ackets.h"
    0 R$ G4 q5 k9 M( e$ a1 z#include "Maze.h"; K; w; K+ n$ x9 k9 Q- x
    #include &lt;malloc.h&gt;
    3 a3 s% {8 o5 P* @#include &lt;tchar.h&gt;</P>' J+ B5 `9 y" |% \, E; F5 |

    ' Z3 O5 j* t7 X<>//-----------------------------------------------------------------------------& s5 b) g9 j: P
    // Name:
    3 W/ F' |) L! t% D) W4 ^// Desc:
    3 ]. w( V6 x6 o' g1 ~3 M//-----------------------------------------------------------------------------" H7 x% j0 o. }4 R" k
    CMazeServer::CMazeServer()4 l7 L' C8 E8 o- S, [
    {
    9 ~" i9 \4 X: a2 v  W    m_dwPlayerCount         = 0;/ J( P( |+ ~8 u7 g- M" u
       
    ( m( u+ m- b8 B3 J7 n/ w8 _6 e2 O    m_wActiveThreadCount   = 0;3 ^0 u9 U2 R, q) G/ ^  G, ]1 w
        m_wMaxThreadCount      = 0;
    - l* t3 R1 d& g! l4 c# A9 T    m_fAvgThreadCount      = 0;; g. r* @$ ~, s8 p$ Q
        m_fAvgThreadTime       = 0;
      \0 s" h: Q( W/ K; m! @; \; _    m_fMaxThreadTime       = 0;</P>; r, {' _7 t/ T
    <>    m_dwServerReliableRate  = 15;9 X$ }( j3 S' _7 o& {9 l  Y3 O
        m_dwServerTimeout       = 150;
    ! H0 o! s; i5 |; m# g    m_dwLogLevel            = 2;
    ! J9 j% G3 T" L3 k    m_pMaze                 = NULL;</P>
    ( {9 J+ V& J* ^8 `<>    m_ClientNetConfig.ubReliableRate = 15;1 |( F, |6 v. ~( _, _! R- v4 t5 x
        m_ClientNetConfig.wUpdateRate    = 150;
    ( g+ y2 _$ ]. Z' F/ Q    m_ClientNetConfig.wTimeout       = 150;</P>& ~+ x: ^1 o/ X2 C
    <>    m_ClientNetConfig.dwThreadWait = 0;</P>
    # b' _  ]+ Y# w: N' X' h<>    m_ClientNetConfig.ubClientPackIndex = 0;
    ' N7 X' i; W2 l    m_ClientNetConfig.ubServerPackIndex = 0;
    ) I* \4 j- G" v+ h) _1 V    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)
    * M* ^- W8 |7 ]7 t" B/ m    {  `- y8 d2 L& [
            m_ClientNetConfig.wClientPackSizeArray[x] = 0;# t: G( b3 @% O3 g! l' W1 q3 R
            m_ClientNetConfig.wServerPackSizeArray[x] = 0;
    2 h% P$ ^2 ^0 \    }; R4 l* Y- A' F- }( u# X
    }</P>
    . R9 m8 Z9 W3 X. z0 x6 @
    ! z: S! Z& T/ `6 F<>
    % s3 H* z8 O2 U5 F) ^! |//-----------------------------------------------------------------------------9 ]# n+ L) n8 u' ]' ^
    // Name: - i) A6 L5 H& d1 q% `2 F
    // Desc:
    $ B3 f% c! {  f; |//-----------------------------------------------------------------------------& r$ V. J( Z7 c" b2 `7 D& @. ]
    HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )
    ) }! T4 D, X. j$ f{
    - ~; n( J- t& l7 j4 L: R$ Y% s! y    m_bLocalLoopback = bLocalLoopback;0 `7 i& c2 E; x& u8 x
        m_pMaze = pMaze;9 x0 F4 v  V0 H6 _
        if( m_pMaze == NULL )( g& O9 I7 e4 c' l) F7 y
            return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
    $ {! V8 z- j1 s" y<>    // Grab height and width of maze$ q7 d, l3 D; C: x
        m_dwWidth = m_pMaze-&gt;GetWidth();' @& V$ R& l  m' Q: H0 h
        m_dwHeight = m_pMaze-&gt;GetHeight();</P>2 d4 ~) ^' h4 M' u& F8 T  b) ^
    <>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;9 `) E/ i3 V6 h5 F. N! m  C: s' B
        m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
    - G* D0 }% S5 T  `% s! U<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.9 I3 ?, l5 x6 z7 ?7 x; ^2 r" ~
        if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )6 z- o) M/ q6 V! Z, T* m* }
            return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );; d5 E, ~: J* n" t% V2 n: \
        if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )
    6 k" c" l! u4 z$ v        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>3 u5 f( M- n2 W, @, c1 U
    <>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;: ^, F+ m/ K+ ~; c6 b+ m
        m_dwMazeXShift = 0;0 a* L% r- C0 B7 i6 K# k
        while ( (scale &gt;&gt;= 1) )' ~5 e& P$ Z% }  {
            m_dwMazeXShift++;</P>% @! i/ Y% J" e' O2 }, \
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;. \4 \+ }8 t6 t% a" k
        m_dwMazeYShift = 0;8 V/ T, \8 E9 E# v1 c" q
        while ( (scale &gt;&gt;= 1) )
    * s+ |) a% r$ t. `$ Z% `' i        m_dwMazeYShift++;</P>
    5 T5 F3 ]% E. U, k2 u6 s<>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||5 A+ c% x, a& y7 r2 G$ [
            ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )# }$ H# Q/ X* N2 I6 m
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>
    1 a4 K: h- m5 {; h6 g+ P<>    // Initialise the player list
    1 t4 A/ G" B% q1 Z$ }4 o( Q+ J1 C    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );3 [# z3 G5 g2 e
        m_pFirstActivePlayerData = NULL;% l9 L8 J8 G4 B% g4 V# w$ }. s+ c9 h
        m_pFirstFreePlayerData = m_PlayerDatas;
    % L- x. P- e0 `% _$ C9 k    for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )3 N( m) q5 A. B- G/ r4 a
        {
    ( D$ x8 H, T* ?: B        m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];* c6 f! s/ o- a6 ~
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];1 {' S! B7 C% C0 @
        }</P>) [- q% Y$ A5 W& `) Y- a: L4 N, v2 K; E
    <>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
    : q. d4 q$ [7 I/ z8 l    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];, X- ]0 ]3 M! ^  i( w4 J, X" A2 Q
        m_dwActivePlayerDataCount = 0;
    , p$ w5 X: V6 ]' g  K2 Z! v1 j4 V    m_dwPlayerDataUniqueValue = 0;</P>" e; A1 D' e' H& Z/ `: ~; T6 c
    <>    // Initialise the cells7 x! J( u$ c  H2 n+ H
        ZeroMemory( m_Cells, sizeof(m_Cells) );  C, X1 G+ w3 g! U5 s* A( O3 S
        ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>; e  ^* n" Q5 ~8 d2 W8 h% t
    <>    return S_OK;, L7 j: e5 {5 W) E
    }</P>/ G$ [: a$ x& o& v* u, L- v
    ; W3 F* X. u# ?  g: g; F1 U; k/ F
    <>
    8 D6 A+ v0 q2 m1 j4 U; V6 u//-----------------------------------------------------------------------------0 H# N6 s- d' j% |
    // Name:   N9 I* v' r3 g3 e1 u0 a
    // Desc:
    2 `/ T+ T: r' J//-----------------------------------------------------------------------------& C& y7 ~# {4 x& u
    void CMazeServer::Shutdown()
    * X- P1 |+ ~% p( i3 x{
    1 R$ F& N' @- i/ h6 T2 }% w8 B+ w}</P>
    % I  [- v  f5 R+ n* ~& _9 X3 O
    * u$ P, `4 {" S7 L% X% R" l$ H) ]<>
    . D  q7 ]0 d$ H% F; E" r//-----------------------------------------------------------------------------5 Z2 g# k! j6 q  U7 `$ m1 f
    // Name:
    - \: Y( X; i5 j% S! Y1 m// Desc: 1 L3 Q# A1 I/ B# |8 W
    //-----------------------------------------------------------------------------
    ' L4 w% y% t$ ^void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    ' k/ U7 Y' y0 i1 a{" _1 s9 Z2 @4 p8 k! p* P
        m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ," {6 s' p$ ^" v3 I" K
                              x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    . I& Y" ^8 f! `) v3 @}</P>& T$ A" m3 n- C4 W) }3 F5 N

    ) {# h0 {* H# T! r% @. D" h<>
    * ~( W. |0 P, W* A. w//-----------------------------------------------------------------------------
    : x" \7 A* [) |% _6 w// Name: ; _* [; [& {9 Y- H+ k* D$ n, b
    // Desc:
    4 Y2 _! |. u1 }$ M2 J' N" J//-----------------------------------------------------------------------------
    : u( z8 F; W: d, c% c7 T  W" Y) dvoid CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )2 B( q9 C+ ^1 m% }
    {- v6 d- H1 C6 j" X. P
        m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    6 A$ [# f8 `2 e& i                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );+ _' S- b! Z9 K9 i$ k" K% U. D
    }</P>
    ; S; N' T! R1 V1 y/ ^' r6 Y# j. n0 C7 @3 R4 O  A# t8 _& M; e' ]9 i
    <>8 o% ?+ k# `! C! m' y! ?2 ^
    //-----------------------------------------------------------------------------
    ; y9 J0 b- V0 H// Name: 7 g9 h6 r9 t& |  ], T& |2 c
    // Desc:
    8 x. x) U( C2 }9 I% q//-----------------------------------------------------------------------------5 X$ k8 V# e8 u( g1 ]
    void CMazeServer:ockCell( DWORD x, DWORD y )
    , _) y) ^  f5 \/ H, G{
    - [' \0 ~) f5 J7 z$ v    if( x == 0xffff )) g. h$ \8 Z* I; ~
            m_OffMapLock.Enter();
    5 H. c; G! |' _    else8 g5 f9 \& l2 W/ F& Q* w
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);% n# c$ e# f: y: Z
    }</P>6 @, W: H$ k: X$ ?0 t4 \4 E
    ( E* \" F) H1 Q- p( V9 G4 R
    <>. D' ]' w! M6 D( t3 g9 X6 I, a
    //-----------------------------------------------------------------------------
    5 D  D. X. M* t* @3 O* m: y// Name: $ H  p$ [4 e, m& @2 h* R
    // Desc:
    ; b" y7 H0 t) ^7 g  L0 q//-----------------------------------------------------------------------------, y) j4 N0 u/ C! [3 A
    void CMazeServer::UnlockCell( DWORD x, DWORD y )
    # ^" k* X+ t; f0 A5 u* h{
    " s% X" V1 |5 i  R# B    if( x == 0xffff )0 U3 \2 H- N8 }
            m_OffMapLock.Leave();, P9 G# [  x) }, c6 \' o
        else7 ^$ e. K+ f8 S5 f' I9 n$ e+ v1 R9 }
            m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);8 N5 ^* t) f/ \9 X7 K& \* `: g
    }</P>
    1 F, p4 O/ r2 T' S
    4 e& g4 ?( h2 g: [<>+ K- s7 f$ N" j5 |7 P/ P5 t. {1 P
    //-----------------------------------------------------------------------------
    : H4 a  t# ~# j3 X8 u# |8 n// Name:
    ( r0 E4 P; G4 ~6 y; S! g// Desc:
    6 J0 Y# |' W+ ~  @, i+ B6 ?) V: _) ?9 @//-----------------------------------------------------------------------------
    9 |$ G7 j% ^! ^void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )/ b8 Z; B4 F2 K8 h( z% E! G
    {
    7 h' \4 x: w. k  ]3 w    if( x1 == x2 &amp;&amp; y1 == y2 )6 L- H2 ^( T: B/ [
        {
    " T, n- X* W' j  o4 K# y1 }* @        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    2 }) h" J$ ^+ c7 Y            LockCell( x1, y1 );  C2 }, O" t/ `
            else
    ) f$ A+ k2 k7 C7 C& I9 u. M, G            m_OffMapLock.Enter();</P>  z  Z; s: i% N# X6 L" P* M8 T
    <>        return;
    ( {- x) \6 T0 E( S    }</P>* ~- N4 ?" |! j* @! ]
    <>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    ) u, F# [2 N9 z# y9 X, i    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;, R; f) F2 F2 y9 V9 P
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    7 x$ H4 e* U& M3 Q. G. Q8 I/ j    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>& u7 Y5 @& `, f1 G! f
    <>    if( x1 == 0xffff )
      l5 d/ B  Q6 j# x! R6 P    {; q" U- n* ~2 q! r  z: ]/ g
            m_OffMapLock.Enter();5 t) r; k6 ]3 s. z! w! a8 q
            m_LockGrid.LockCell(x2shift,y2shift);* Q. D! b! o6 S& O8 `
        }
    & k% I, V4 y( b    else if( x2 == 0xffff )
    * s! a) }+ |$ |    {+ v9 @0 r+ i6 A
            m_OffMapLock.Enter();
    ) \; \" _" `+ x5 B5 q0 ~% L        m_LockGrid.LockCell(x1shift,y1shift);
    7 s1 a" r/ G9 p. D2 M    }
    ! |8 b/ `! s' o) O, }6 W    else " C' N3 U& m- s( M  P) {. q
        {/ d+ Y0 M# [# T: t# W9 L
            m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);6 D% K# K0 k4 @5 @7 i% {& {+ f- c4 F
        }
    ' Z) U5 p. _" ^}</P>
    / @0 u& B5 R/ {) ]! M3 m) O6 F! P5 c/ v
    <>3 o7 s/ D8 e( I) Y* n
    //-----------------------------------------------------------------------------, o( L) X& W3 O
    // Name:
    ; k: R0 d* j* f8 D// Desc:
    4 S6 H5 Y6 s0 {3 z) p//-----------------------------------------------------------------------------
    # f- Q; A0 c( zvoid CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )& f6 R, b6 F3 o; b* n2 b/ f
    {$ j+ o" c2 l, f& P: ]' H) u
        if( x1 == x2 &amp;&amp; y1 == y2 )$ O4 F& [* A. B- ]" w
        {( {* M% K1 k3 L% `
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )% a# \: O0 o; L4 G# r: Q! U
                UnlockCell( x1, y1 );2 `$ U, H) K$ j0 Z( f
            else* S6 {8 O% R' U4 {* g
                m_OffMapLock.Leave();</P>
    8 \, Z# k0 w4 v% I4 o3 Y9 |<>        return;2 o5 s2 ^7 U$ w9 k5 S( t, p
        }</P>% e8 X1 D3 q* [& H  f4 Y6 h4 H, X
    <P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;- H: W, ]5 K3 l! O" h
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;4 Y/ }+ W/ O8 g3 G
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    ( n. y+ a# x+ M" D  {3 Y    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    % x1 e$ y# w5 D! t8 _<P>    if( x1 == 0xffff )
    . o+ h- N" _" z* o+ G    {, D$ s7 z: z( a  V. H
            m_LockGrid.UnlockCell(x2shift,y2shift);
    3 A; F- Y# i  E" `+ S8 C7 D& f' A        m_OffMapLock.Leave();/ I) c4 u; ^' f4 a" Q% h+ F
        }7 l, e$ L5 m7 c7 v% e& y# g7 O
        else if( x2 == 0xffff )" \9 ]! b, E: [6 H/ L
        {
    5 {+ r- x% _7 K8 |        m_LockGrid.UnlockCell(x1shift,y1shift);
    , Z! K0 [( y1 M$ A0 e7 Y3 g        m_OffMapLock.Leave();4 @: v  P+ J) s' S, _: X( m
        }) F. U' F! q2 C7 ~) o
        else 4 f" B+ Y+ U; Y/ P* A) s  _
        {: u" |" ?* L8 h# |$ S. u
            m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);7 z% {/ @4 V( [& T4 _
        }
    ( i9 \7 X; k- Y! X+ {}</P>0 j# w0 r/ q" S( r; [

    $ \  C1 r; N7 P8 Z' k6 I<P>
    0 k. l: X$ g! V+ B# Q  |% Z0 E3 X( y//-----------------------------------------------------------------------------
    ' n# U& k" m& I) ]+ `% Q. h// Name:
    8 Y+ }  S% K, d1 L3 R9 @// Desc:
    . L) n' n4 r: l7 R( E) d5 }//-----------------------------------------------------------------------------
    * w# @+ ?0 A4 J* L) o8 V2 \void CMazeServer::OnAddConnection( DWORD id )
    5 ?5 D* J- R6 c5 S+ [& d0 m' A{) k* H6 p5 R8 k- |
        m_AddRemoveLock.Enter();</P>- q5 B3 q# D7 G# p
    <P>    // Increment our count of players
    ( b4 k1 B' f. }. l! K    m_dwPlayerCount++;
    6 x" Y9 s( y- U% N3 L    if( m_dwLogLevel &gt; 0 )2 T! F/ u0 p: O9 J! r- V' }+ M
        {% f: X9 r) `+ [; w% W
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
    " f' I: q) E: Q6 w( c0 H        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );6 |& v9 `0 h4 J+ f
        }</P>
    $ j; G6 `/ l. _6 s) b# p! e7 |9 x<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    " T; }0 }9 ]/ G' V$ ~/ \+ c        m_dwPeakPlayerCount = m_dwPlayerCount;</P>: y( j6 L& m6 Z$ J
    <P>    // Create a player for this client
    ; @+ L4 H9 w( F7 I$ L7 X' d    PlayerData* pPlayerData = CreatePlayerData();) ^0 ^* `# b# ?( H: @& z6 c- c
        if( pPlayerData == NULL )' Q& ^, H, [0 X8 t- a
        {
    $ }9 z3 v+ E- A3 w        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );) g0 H  S4 \( L% k8 w) S* l8 {
            DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );
    # I% c8 t) w  r% A+ @$ L( i9 e        m_AddRemoveLock.Leave();- j: t7 ]5 e2 T9 W1 W
            return;
    + p. D' @$ V/ i6 C    }</P>
    , Z, K  c# \: S3 g<P>    // Store that pointer as local player data
    ! f* G4 |( M. P' V1 ?    SetPlayerDataForID( id, pPlayerData );</P>
    ) I. J( c; _2 H! U/ T+ L$ A6 I/ B<P>    // Grab net config into to send to client
      C0 i, p; X9 ~/ k    m_ClientNetConfigLock.Enter();& f5 c+ o* s9 D2 \$ q
        ServerConfigPacket packet( m_ClientNetConfig );
    % z( A+ r, J6 D' B* V' h    m_ClientNetConfigLock.Leave();</P>
    ) I8 O6 D& ]. p5 l2 ^  ]<P>    // Send it( l; i) |8 g3 c& Y$ g  |2 f
        SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>' }: n4 h& w+ i9 P7 u. r7 n
    <P>    m_AddRemoveLock.Leave();
    6 Z; C$ N3 a$ M- T2 Y0 D/ A}</P>
    , M/ E% w+ X1 R2 r6 T9 K3 l9 h
    " `; U! _, H3 A. D" g9 }% Z<P>
    ; a- o% u& M( Q//-----------------------------------------------------------------------------
    6 r" f; K# \7 i3 m. {0 G// Name: 3 P+ \# v9 l0 e" x+ r
    // Desc:
      L1 V; A; u* r//-----------------------------------------------------------------------------: |' r; U" f0 {+ L
    void CMazeServer::OnRemoveConnection( DWORD id )+ ]! d1 }* l! v' f7 c& C1 a" l5 n/ h
    {& _! u& e, |. c  V! o& g
        m_AddRemoveLock.Enter();</P>
    0 K+ ^8 k* t9 m+ J5 S1 w0 K<P>    // Decrement count of players* [6 y  j8 s, ~0 p: h
        m_dwPlayerCount--;</P>
    9 V2 U/ ?4 p, I, c& u<P>    if( m_dwLogLevel &gt; 0 )) S" ], C/ U/ T+ {. P) K4 b
        {
    ( K' O- o2 j  ^* @( `. E        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
    ' l- l& x& R" N- Y. ]: s        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    ' l* P* ^9 v; L6 t5 H0 V/ f    }</P>
    $ u. t- t8 a+ R& T1 L+ i<P>    // Find playerdata for this client0 y; f+ W. c+ g" B% {; t
        PlayerData* pPlayerData = GetPlayerDataForID( id );% U. l$ t# J: k: n$ A) G3 J
        if( pPlayerData != NULL )
    $ P1 l  z! u, R9 q. C7 p5 n    {
    : I% I$ I: {! U/ s. `" E9 d. A        // Destroy it
    / Z7 M# v' a/ n) t6 D9 g        RemovePlayerDataID( pPlayerData );
    & P7 r! d( T  E/ S        DestroyPlayerData( pPlayerData );! u, h- G) i8 O5 v- ^
        }</P>
    1 k' O2 G1 s; g6 H/ d( p<P>    m_AddRemoveLock.Leave();) o7 M5 H1 K9 R' c4 I
    }</P>+ t" c$ r0 P' ?4 f4 j; _+ Z
    & j$ c" C$ z& J& u7 O& W
    <P>% L( r( K- \5 w2 E) _( \* O
    //-----------------------------------------------------------------------------' N' M( m, o1 T' X
    // Name: 1 K* _2 Q/ H5 A, ^" I4 h( Z
    // Desc:
    7 b8 l  G- `' \: C5 W" ]//-----------------------------------------------------------------------------
    9 \& M! ~: m5 s, E$ GHRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )# F" f% C8 N% i0 U$ l
    {
    8 A5 q1 T& }( t    BOOL fFoundSize = FALSE;</P>
    + E# n7 Y  R  Z: C8 e: z/ q% `<P>    // Increment the number of thread we have in this process.
    5 \- Y. E1 l0 \2 L! R- L0 Q    m_csThreadCountLock.Enter();</P>: U0 Z! z4 [' Z
    <P>    //Get the start time of when we entered the message handler.
    4 I# k3 k5 K. u+ n% E3 w    FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
    ! l% G' y7 v* U7 m# {<P>    m_wActiveThreadCount++;
    ! T4 u) B* c+ _4 L6 }: j    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)" Q7 C+ }6 l3 @3 J: J9 A1 S
            m_wMaxThreadCount = m_wActiveThreadCount;, ~% A9 V5 G0 F4 h  R3 U
        * G7 S/ t% a1 w6 H8 j( f
        // Calculate and average.( d; ^! s9 a% _5 l
        FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
    + ]! |  [: U% K6 i    m_fAvgThreadCount += fdiff/32;' M0 U6 j  V6 M# O
       
    ' P: f4 x& P8 s: Z    m_csThreadCountLock.Leave();</P>
    ' g& ]0 P8 \* S9 P% _" k<P>
    # T) e5 z) w9 q  H8 ~  c% L    ClientPacket* pClientPack = (ClientPacket*)pData;3 E) a$ t$ M- ]' K: A0 L  p
        switch( pClientPack-&gt;wType )+ Z, U: p+ `* F: B# R. Q( y
        {
    ; V- H6 v0 O& x, K4 Y8 u) E- o        case PACKETTYPE_CLIENT_POS:* W; K# v* v' _; \0 i. \
                
    9 C* `" h7 ?  `' U4 v            // Check to see if the packet has a valid size. Including % H, r7 A- }* [% I6 i3 c& g
                // the custom pack size.+ B$ ^* L: D5 J/ X9 B
                if( size &lt; sizeof(ClientPosPacket))6 `: {" s* r) p: X$ z8 X5 i0 \
                    fFoundSize = FALSE;
    " I; v- p4 j' _            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))
    ( X1 j6 {! w2 t6 j: n* g' n                fFoundSize = FALSE;7 u' m3 P6 d' k) s
                else# _0 p8 [. x. r
                    fFoundSize = TRUE;</P>
    8 O" L  d* p8 m" P! W<P>            // If valid sized packet, handle the position.
    ( n! Y: ^4 q" H            if(fFoundSize)
    5 S0 j1 N$ }; u3 j% R                HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );
    % @4 Z$ e+ P7 o            else& e$ f9 ~8 {0 v# L
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
    5 E$ B( S, M; Y1 \2 T<P>            break;</P>4 v/ [! i' s( m# a( M2 B
    <P>        case PACKETTYPE_CLIENT_VERSION:
    1 A, H9 t! d8 [0 D            if( size == sizeof(ClientVersionPacket) )6 |7 @0 U2 t3 m) x' c9 z3 I2 Q
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );
    0 A+ w- \! b5 f            else8 ~; B$ y9 f  J% B) u
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    * V# _0 G' x: H: ~. U+ {3 D            break;</P>$ j. G' a+ @. P7 V. V6 T% a
    <P>        case PACKETTYPE_SERVER_CONFIG:</P>( f5 q8 f3 o/ w
    <P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>7 w9 r' s7 T& G. J; A  c1 ^7 |% ?
    <P>            break;
    9 Y% c# f# M6 @' d        default:1 `' y/ y0 C$ c: {+ W
                HandleUnknownPacket( dwFrom, pClientPack, size );1 W% W. \* E$ a! e. I
                break;
    + a2 x3 s3 y: `  o0 |8 c5 h" d    }</P>/ h; A2 W2 Q0 g. m& p) j) k  K& V* H) J
    <P>    //If the user wants to hold the thread, Sleep for given amount of time.
    + f2 \: `; }. C, D    if ( m_dwServerThreadWait &gt; 0 )6 Q" n: |4 F' T/ M4 h/ q
        {
    0 I( Q* m% h' Z  _+ f( p" _( c: f        Sleep( m_dwServerThreadWait );
    3 F. _9 M! F" J( h1 o    }5 _7 |% s5 I; f( a2 ?5 r+ n) Y% h
        / m+ O& F( d& P
        // Retrieve thread data for this process.) }: M/ c3 s3 m, G7 a: r: \- u
        m_csThreadCountLock.Enter();</P>, }0 @4 g! L3 P' T
    <P>    m_wActiveThreadCount--;</P>
    * z& h5 P. h& F; f" ]" i! T; t<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
    1 ~- U: g1 s+ B6 J3 S1 G    m_fAvgThreadTime += fDiffTime/32;</P>
    9 G, E9 T) Q0 `<P>    //Get the Max time in the thread.
    : Q: \- d6 m. S) F    if ( fDiffTime &gt; m_fMaxThreadTime )7 [7 E& {$ F7 A$ o9 F
        {
    & L2 _5 u6 W% }  |        m_fMaxThreadTime = fDiffTime;) Q- Y3 j6 r) h* M' }# K
        }</P>$ d& R6 t: b/ j  w
    <P>    m_csThreadCountLock.Leave();</P>
    + h6 [) x+ U5 a6 O) }# f+ V<P>    return S_OK;' @: U! A$ o  a" z
    }</P>! d4 d6 I: B6 X$ ~2 J- H) O

    0 c2 A; Y8 z9 A. b' u<P>//-----------------------------------------------------------------------------' Z- O: n, b8 q
    // Name: ) T' b  I( Z7 P8 F$ W
    // Desc: 7 @1 K" T  ]$ k8 {7 e
    //-----------------------------------------------------------------------------
    , n# V  Q2 `: G2 X7 \( n$ G0 O/ q3 ?4 ]BOOL CMazeServer::IsValidPackSize( DWORD dwSize )  ^9 H2 {$ t) j) n  F; z
    {
    7 u% s4 H# S) d" v! @/ h    BOOL fFoundSize = FALSE;
    ! p9 v7 g! ?/ X+ i( U    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;' b) k$ |0 u6 m) ?2 P% ~8 k; X
       
    2 O1 I, S% s6 b2 \    // Check through the array of valid pack sizes.
      ^' m; |7 h6 _& k    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])  }6 d. i. x- e( h' ]0 C
        {
    ) o3 f3 W, K. T: f# W, n        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)
    3 A2 k) W! y6 T, E: n9 i" f2 m. T3 G        {5 U3 x  H& w& Z: r' b' G" d& \
                if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])& t' l. s+ t! t3 A8 {/ x
                {
    % h; O+ h/ G& r" e1 [                // Found valid size in the array.; q1 O( g$ ^. h* c1 t2 v
                    fFoundSize = TRUE;
    - Y  Z$ }$ A0 [3 Z7 `6 i5 F                break;
    ! u8 I. K+ x% R# b' s            }# b, I' p9 n. M# G
                if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.) I9 v" \& p; ~3 B% C
            }
    8 u, b9 L, W% p3 e, I    }+ {6 ?" b) u# P1 Q2 F
        else
    6 j; x2 w8 U& g$ k3 ]5 K; X! e/ |9 @    {
    8 D! ?# }  E" ?# {- s+ Y2 b7 i7 F$ O        fFoundSize = TRUE;
    0 b, M0 f! q2 ~7 e8 b    }</P>4 a6 u& l  K6 E3 O* x' {
    <P>    return fFoundSize;
    & h' F* q' C0 P% o" l' a- i" T}</P>
    # Q) g# D8 @1 y8 g5 R% a& B7 s3 v; q<P>
    + a' T2 ]0 Z, E, _3 z9 q1 P//-----------------------------------------------------------------------------
    * U2 C6 t7 G1 K& v// Name:
    4 j; H0 `2 d0 ~8 C// Desc:
    . q3 M! O3 f+ E0 H  P7 t//-----------------------------------------------------------------------------0 [" x. v6 G. [" t6 ~: P
    void CMazeServer::OnSessionLost( DWORD dwReason )
    0 |9 q2 j2 y: d1 R{
    - P5 O$ N7 A7 r: u7 ]3 {4 w    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );# {' ]1 W; ?: `1 \% d5 `
    }</P>
    & F) T- P/ |0 w. T+ c) p1 i% L0 X' O
    <P>
    0 G% o; r8 @7 A+ R* q//-----------------------------------------------------------------------------
    5 H! i: r+ P2 j- S( R& k# @// Name: ! r8 Y' b$ ?+ B0 L$ m. W, \
    // Desc:
    $ c! U4 ^4 s  w) O) Q# q//-----------------------------------------------------------------------------
    . s! H& j% w! o3 ]" A0 u, o8 u& uPlayerData* CMazeServer::CreatePlayerData()
    + T/ O1 O8 S" Y* M{/ ^, u7 D8 m, W8 N1 r- E) U
        m_PlayerDataListLock.Enter();</P>
    4 K" A+ a& K- h" H/ m<P>    // Grab first free player in the list
    * G( C. @7 P3 F' j! A    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>( h" j  [7 Q; e5 U% m
    <P>    if( pPlayerData )
    ' p7 s9 s! }( r6 f  @8 K    {
    - h) K% e! I/ n, f+ ?$ ?+ m! U        LockPlayerData( pPlayerData );</P>0 d- A) A  q! i1 c7 j
    <P>        // Got one, so remove it from the free list& C/ o8 b& c: b: g
            if( pPlayerData-&gt;pPrevious )
    / R) ?& @& I1 A            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    2 I% f) }% H# t7 V( J# M        if( pPlayerData-&gt;pNext )- z: T; U3 C: w3 `6 F
                pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
    1 w4 Q* q& H# k0 |        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>
    " _  ?- ]" n* w) I( h<P>        // Add it to the active list0 V2 z/ @2 ]! W9 m3 W
            if( m_pFirstActivePlayerData )
    - o+ J) [' L, ~' g' y            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
    ' O' u% D: j! `: t        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;' S2 y- z8 z8 I/ w- h" o
            pPlayerData-&gt;pPrevious = NULL;; {! s9 M( w( q
            m_pFirstActivePlayerData = pPlayerData;</P>
    1 F: s: }& I. A9 ~2 o<P>        // Update count of players
    6 W0 T2 h+ b& R        m_dwActivePlayerDataCount++;</P>4 M* _0 x' [3 \2 Z' C' S
    <P>        // Generate the ID for this player0 |/ }: x+ y  H4 D6 ^4 o. b
            m_dwPlayerDataUniqueValue++;
    2 h4 Q! w( N9 W" }" b: Q3 z0 w# q; a* @        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
    ( m& O/ F, {) Q5 o1 r3 H<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;- R6 ~9 \3 e1 b  }8 \; ^
            pPlayerData-&gt;NetID = 0;
    ; x8 v; Q$ X8 n- J! J, z6 X0 @        pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>/ ]" l0 D/ I8 O+ z  j, @* Z5 q
    <P>        // Insert into the "off-map" cell2 y+ Q- y2 b1 `/ a. W: w
            pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;( T- j, B& O& @; m
            pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;" l& E/ I0 @& T9 {
            m_OffMapLock.Enter();- M% i: D8 \' Z$ L
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;6 K# n8 W/ a% J$ q
            m_OffMapCell.pFirstPlayerData = pPlayerData;- K5 z) A6 x8 s$ z) h0 C1 ?
            m_OffMapLock.Leave();</P>
    $ n$ @5 K. b5 @+ L4 ^" f" [4 r0 \<P>        // Mark as active
    1 i7 \9 ^; x$ ?+ ]3 t' C& b        pPlayerData-&gt;bActive = TRUE;</P>
    & R$ a- ?( X! F! \<P>        UnlockPlayerData( pPlayerData );
    " B7 u$ G" G, X* c    }</P>7 e- w. U; H" N0 Z
    <P>    m_PlayerDataListLock.Leave();</P>  D0 b* `" i3 B# f1 {
    <P>    return pPlayerData;
    ) v# \* x  U" u" A' _}</P>
    + N" f- s. B3 N; M. |
    & F: B7 Z8 N  i) n<P>
    7 N  j0 f/ u7 K; T/ T//-----------------------------------------------------------------------------: A! |3 f- G6 X' l1 p: c
    // Name:
    6 h) F. T0 h. X5 I( U; [" K4 u// Desc:   \8 I7 Q- n0 Z7 B! I# j
    //-----------------------------------------------------------------------------% \. C8 H/ H" z
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )
    ) u& D4 n9 V1 P& w! F! E+ T% V{. ^% V; e& ]4 N. K. D, l" [8 U1 {# W
        m_PlayerDataListLock.Enter();
    # q+ Q9 S) k) q- _' E8 H7 Q    LockPlayerData( pPlayerData );</P>
    & I5 z4 J1 q$ M" y# u7 C6 }7 A0 j<P>    // Remove the player from its cell& E6 ~# }2 E/ @
        RemovePlayerDataFromCell( pPlayerData );</P>
    & {6 }: `, @0 s. f<P>    // Mark as inactive
    ( l  h  _# T3 V% ]    pPlayerData-&gt;bActive = FALSE;</P>
    2 \" v6 {5 T7 w! {' j% |% S2 J<P>    // Remove player from active list7 \4 [0 j& g- F4 Q* C' M' x
        if( pPlayerData-&gt;pPrevious )" C; K' ~4 Z& F
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    9 ~6 U, r' d2 R8 _# Y    if( pPlayerData-&gt;pNext )
    # n' i( c, L, x$ G        pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>0 u/ Z0 I' }! y/ a
    <P>    if( m_pFirstActivePlayerData == pPlayerData )6 `# h' E8 u) R3 ]& [
            m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>
    0 x4 d; @" v" k- D8 X( J2 Q. U# E9 l<P>    // Add it to the free list
    % ~2 H7 ~# X: i' ^7 j    if( m_pFirstFreePlayerData )
    ; T0 L0 m; X% L6 y; m7 o! S! D        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
    7 Y9 U3 e0 U4 }' k, l) Y8 D0 P0 I    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;5 r3 q( u* C8 s7 \$ N8 B8 g! H8 j" @
        pPlayerData-&gt;pPrevious = NULL;: V5 _- E! a1 T' B, W! g5 l- {- f
        m_pFirstFreePlayerData = pPlayerData;</P>" M: I+ m! ~& z+ a% y
    <P>    // Update count of players
    , C# S" D9 \# z9 Q8 `1 Y    m_dwActivePlayerDataCount--;</P>9 `, |$ m3 B# t5 c1 Y4 a9 X
    <P>    UnlockPlayerData( pPlayerData );- z& v% \2 {& Y$ W5 h! r3 p
        m_PlayerDataListLock.Leave();
    / x1 u( J/ _) h7 ^0 B& I}</P>
    1 ?) w, Z4 M, W6 ?. g$ b' A  T0 L$ y! U- n; Y( T
    <P>
    % q$ q" W$ F  i5 ~//-----------------------------------------------------------------------------5 |, x" H% r+ I1 q' r$ @7 @
    // Name: % o9 g1 k: S7 y6 P  g
    // Desc: 6 l( F/ d5 q0 [: ]. e$ N7 j3 z
    //-----------------------------------------------------------------------------1 q( v1 C' F2 R
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )
    & \* Z' l, k3 n9 u/ Q" X$ F{
    $ Z9 ]+ z1 \# \    // Lock the player
    4 @1 ^! C, \; P    LockPlayerData( pPlayerData );</P>
    8 e2 T+ ?3 @# j! b$ I( M2 ^<P>    // Lock the cell the player is in
    6 [6 Y/ o, o  j    ServerCell* pCell;
    5 i  M, D6 A1 }  E  K( R9 o    if( pPlayerData-&gt;wCellX == 0xffff )
    / x5 z2 D# v4 S! Q    {7 i% R) z. m5 u8 Q+ {. `1 a) C
            m_OffMapLock.Enter();
    . T( i4 v% w9 Z" O& v        pCell = &amp;m_OffMapCell;
    1 q, M1 S( D6 m  K    }
    . N2 b. B3 _9 f3 g    else
    3 `$ ^2 k# y1 ?! N% q    {
    ' h& o4 T9 P# o# P        LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );* E1 I. ]* w- a) t0 R8 n" l
            pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];! Z8 @- W- {, w0 b+ s% Z( G
        }</P>
    * Y' p+ r0 W5 K6 ^1 t3 ^% a0 U<P>    // Remove it from the cell5 V$ n! t: `! M# Z- C2 N) X
        PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    % Q( |5 u3 o$ @* d" P6 I    PlayerData* pPrev = NULL;
    ) p2 h2 f7 }' n6 L    while ( pPt )* o6 ~/ ]+ K( _/ L
        {
    7 }3 S) M' J# f7 s        if( pPt == pPlayerData )
    1 l, L/ i0 T) m2 D7 N+ |# Z- ?        {
    6 p6 Q' o; ?% d% y/ P            if( pPrev )
    ; R- r' ]6 L5 K! D                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    # s* |5 ^( P6 }; N, g            else
    5 Y- E% H, w7 b4 M) d                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
    # {  Y2 Y8 O' h: R" I<P>            pPlayerData-&gt;pNextInCell = NULL;$ B. o3 u/ g. W) s/ d7 g( M8 _
                break;& D+ f' m7 J: t% W5 s& }
            }
    $ L; Y8 L# j- {+ s5 b3 a2 b        pPrev = pPt;
    $ w# y6 e$ \6 E/ L        pPt = pPt-&gt;pNextInCell;9 j6 Q/ s- L  s  l
        }</P>$ |! X5 y+ P' O. \
    <P>    // Unlock the cell
    $ W0 C8 J: [) z; [, L    if( pPlayerData-&gt;wCellX == 0xffff )3 H8 g3 [1 V% o
            m_OffMapLock.Leave();7 t; ^) W- t" v, C0 t
        else
    ( @! _. O$ \7 i5 p( T        UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>! V. U8 x0 Y( W: R: s
    <P>    // Unlock the player+ P5 B; }  n- r) j, h* k; l/ \
        UnlockPlayerData( pPlayerData );
    6 o7 J+ I  y+ ~2 n4 p}</P>
    , J+ D: [% t# b6 j. j5 Z2 H! p/ g& b, p) s% A. a  `0 p
    <P>
    + c* s0 }, R4 [! C//-----------------------------------------------------------------------------6 ?2 z8 h( @, T* _  T( O
    // Name: " a5 C/ M6 X4 a2 i" D( d
    // Desc:
    % l7 f4 q$ T3 [# W& a//-----------------------------------------------------------------------------
    & R8 y; `' _% H8 V; l8 |: jvoid CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData ); D" V  \2 N, \2 D
    {
    ! K- \9 {8 z% m; v9 p' \( e7 v    ServerCell* pCell = GetCell( pPlayerData );; v& ?/ H; \; K6 v# ?
        PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
      h/ n5 n4 A7 |: v* g: x# K* e    PlayerData* pPrev = NULL;
    4 X' \+ @* t+ }4 l) f( @    while ( pPt )
    # g" l- m9 J7 I. z8 ~% i% Z    {  f" z( _+ n2 I: E' F6 k, R$ ~
            if( pPt == pPlayerData )& m' m" Q' s" ?" G; u
            {
    8 r7 q. s( M( A4 G3 \1 |7 q/ E            if( pPrev )
    ; F( N" Y/ A& B) N1 m                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    . w  S3 |8 b# H7 J6 t- U            else. F; U% G9 N7 V) J3 U% z3 q
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;0 o' d& W9 h* S0 x
                pPlayerData-&gt;pNextInCell = NULL;
    & [# R' P! f* A& Z            break;( X( Y0 j( a6 \0 C4 E' c
            }7 H, H* D2 R; W' ?& T
            pPrev = pPt;
    $ @: R5 S6 f1 c& `1 F- c1 p% a( i        pPt = pPt-&gt;pNextInCell;8 A. ?) g8 j- D! E
        }7 U6 s5 X& H3 a
    }</P>
    4 n4 \! J* L# o7 ^2 g' X, n6 w% E
    <P>
    * i; {. T# \( p# _//-----------------------------------------------------------------------------, S/ k  T1 E( h. X, ?
    // Name:
    . z3 t3 W* z8 E* ?// Desc: * {" O- |* L' T) @- e7 f3 g1 a
    //-----------------------------------------------------------------------------5 A8 G8 r% _9 O- I' ]+ }; ~
    void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData ), }5 \! I, ^9 _, k$ D( s# g- U
    {( Z7 ?; c4 r  X8 a$ m
        ServerCell* pCell   = GetCell( pPlayerData );7 q# P3 Y  ?5 T' r& f
        pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;
    1 d8 h& }9 \6 i4 ~8 a- l2 F2 ~    pCell-&gt;pFirstPlayerData = pPlayerData;( l& @6 T9 u1 k9 m' G9 i5 V6 q
    }</P>
    , T6 X; ?. ]# ^7 n
    0 T- v% Y9 k. t6 ?5 f, v5 y<P>
    ' \* M0 r( F. V7 u" X  s//-----------------------------------------------------------------------------$ D- K5 V8 I2 E8 i$ W( P9 K! Q( `/ c
    // Name:
    " Y: {$ g! M) f7 _1 P// Desc:
    / t# C: S6 W9 o% E8 E/ J6 g//-----------------------------------------------------------------------------3 H3 P2 n$ p7 R4 K. m/ n
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )
      `4 n% b) C* @# f6 r5 `2 a; e% p$ ]{8 N! s4 F( }. l8 w/ q8 [! b
        // Grab player for this client and lock it- w* y( ~% D% Y/ q2 K/ h5 M3 u
        PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );
    ! o; q  L' [* g    if( pFromPlayer == NULL )
      s! ^6 t& k) x6 j- o/ ]' ^( X1 p    {! X% w' |; m) D0 C
            if( m_dwLogLevel &gt; 1 )
    ( X& `6 A! e+ x            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );
    4 P# _4 C8 D2 A$ G+ D; C0 T        return;
    7 [  l, e6 |( g  n, v    }</P>
    & J2 L' V. ?# j2 T<P>    LockPlayerData( pFromPlayer );</P>  ?( f$ v/ C. v- m
    <P>    if( FALSE == pFromPlayer-&gt;bAllow )
    9 X; x' h3 h0 Z) g: `7 J1 j) `0 G    {0 h% O' X2 Q* L/ \1 o
            if( m_dwLogLevel &gt; 0 )
    3 @2 M4 o! j/ Z            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
    9 a% j! z/ M" o1 p! `<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );9 {* V1 }( P1 G5 u" b
            UnlockPlayerData( pFromPlayer );
    - b; i8 ~* L* O# b        return;5 @$ q; R& \' L# }
        }</P>
    - X. g7 G5 O, h) Y# X<P>    // Compute the cell the player should be in now! _# L" r4 b  r# C0 j% V
        DWORD newcellx = int(pClientPosPack-&gt;fX);) y6 Q2 N. Y% g' q: {* c( i2 _4 d
        DWORD newcelly = int(pClientPosPack-&gt;fY);
    9 v; j4 w5 a! P! v+ @) v  c    DWORD oldcellx = pFromPlayer-&gt;wCellX;
    1 S" ^% e/ }: E    DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>
    : t. }0 L6 m( U# j& r9 o3 f<P>    // Have we moved cell?* {+ Y7 E' h; \( s2 ?  V' z
        if( newcellx != oldcellx || newcelly != oldcelly )
      k- `) k( b' k' T# W    {5 R1 w& B# d6 M
            // Yes, so lock the pair of cells in question- U; J4 K# O/ i7 {
            LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
    4 F& w% n0 O; }( p+ r- h. d( _- c<P>        // Remove from old cell and add to new cell
    & l. F9 x1 ^9 S9 ~7 O, r2 J1 s0 G! c        UnsafeRemovePlayerDataFromCell( pFromPlayer );
    5 [* b8 x; b/ ~, W3 h5 M+ k        pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    9 b& P; p. b5 h- x        UnsafeAddPlayerDataToCell( pFromPlayer );</P>
    * ^! c6 _! k8 I2 X; U( V<P>        // Unlock cells
    : Z1 y" @# s) r4 N. f6 t0 m) `) R        UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );, Z! f( i8 ?6 x! x
        }</P>
    9 Y; p6 O0 E+ l3 E( p/ b<P>    // Update player position
    , d) q& e/ T" \# n  D% f    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;9 K  m/ Z9 f1 [- ?- ?! b
        pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    1 c- C$ w* c$ i: f5 I8 R    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>& {/ R$ k( E8 Y8 K* f& O
    <P>    // Allocate space to build the reply packet, and fill in header & C  i+ \0 ~" E
        DWORD dwAllocSize;
    ' G* a* F" [& ]# [" R/ s    ServerAckPacket* pSvrAckPack = NULL;</P>
    + K# i9 ^% v# P" l$ @$ j' m<P>    // Begin by allocating a buffer sized according to0 ]8 x/ p  g6 n. M0 |: f
        // the current number of nearby players + 4.  This will give + U+ v4 X7 V+ b7 M
        // a little room for more players to come 'near' without resize3 M" o" T, _  o5 r
        // the buffer.
    ! V( Z6 w3 v7 M/ M7 |6 F! h    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>
    * z" E2 |, ?' m0 v/ {9 M8 G<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);( O+ Z/ M$ s8 I" l+ ?0 l
        pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );& U/ N& Z2 x7 J+ s0 S" s- J
        if( NULL == pSvrAckPack )
    - S1 Q. Y6 z% V# U. n, ]3 \  j4 f    {) A! s1 K1 F& r; @4 d
            // Out of mem.  Cleanup and return
    ! \7 I4 N  `! P1 X# G: M6 j: ?        UnlockPlayerData( pFromPlayer );6 @# ]: r5 z7 h
            return;      
    & m6 ~& N) x+ r( `: U. R    }5 X2 m* v; q8 D" o% T: q8 G+ q9 P
        ZeroMemory( pSvrAckPack, dwAllocSize );</P>
    : ?) w" i: c" C+ o4 ~) ^0 x% n<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);5 _2 p8 ]; A0 t8 b( P( z
        pSvrAckPack-&gt;wPlayerStatePacketCount = 0;/ j) J7 \. |& f; R3 _! L% n' V
        PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>
    9 G! u8 w8 |( O1 ~<P>    // Compute range of cells we're going to scan for players to send
    ; Y( Q8 x; S! x2 |) s7 J5 B    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;9 X& ]) Q5 ]& T# ^# _# d
        DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
    7 A& n- Q, F, \: u  h4 X    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;8 |' n' D8 x) ^5 b' N+ A6 |  Y8 @
        DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P># d# ?2 I3 f7 [. M" E
    <P>    // Lock that range of cells1 J- q& S& _: r% T6 o
        LockRange( minx, miny, maxx, maxy );</P>: p$ I& n  N8 n  S2 I; R
    <P>    // Scan through the cells, tagging player data onto the end of) F% S9 H* v7 j5 A
        // our pSvrAckPacket until we run out of room
    0 C4 s$ p- i0 Y) \    for( DWORD y = miny; y &lt;= maxy; y++ ): d7 T: Z# {/ q
        {8 ^" M1 Y* ^0 l/ Y1 s, ]
            for( DWORD x = minx; x &lt;= maxx; x++ )
    3 Z$ L0 [1 K- z. X4 d* g5 A        {8 i+ Z* \. U0 n# u1 N3 c( x6 W
                PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;$ n8 J$ Q' x% V% g4 X& G
                while ( pCurPlayerData )
    ' C  ~& o8 M( D, u; d            {
    % o$ {4 ^. K4 p                if( pCurPlayerData != pFromPlayer )
    ( V# r) u4 O# k# a  J' y& Y                {
      [- `4 Y2 o4 ^1 V; e$ [- _( i) U; V                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )2 a* @0 t: A8 C1 f, s+ o
                        {
    & g* @  C/ A4 Z7 l                        // Make sure pChunk is where we think it is- k2 m' L3 }% H, U
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>
    . A  v$ D# q% _1 ^' V$ H<P>                        // There are more than just 4 new nearby players, so resize the 9 d' f2 y) X* s* d5 s; l
                            // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.7 P, b/ a7 ]6 a' @- f3 `  }
                            dwMaxPlayerStatePackets += 16;- T$ m7 c9 G+ M9 K* \
                            dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);. B, |; y: s) u5 \* L; ~
                            ServerAckPacket* pNewSvrAckPack = NULL;
    7 u5 T9 [* \, I& Q                        pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    6 u" W& Y$ q& ~) ?+ a0 I& a                        if( NULL == pNewSvrAckPack )
    + j: `& [! T% V* X& B: V/ ^+ Y                        {
    + t# m' f# c! y& b7 h7 A                            // Out of mem.  Cleanup and return; }3 m8 w4 j- z$ k$ R7 {
                                free( pSvrAckPack );
    8 l- `! b8 Q+ |* K, E/ q& }* x) e. h                            UnlockRange( minx, miny, maxx, maxy );
    " f( Z2 a5 G0 U! X1 _                            UnlockPlayerData( pFromPlayer );1 a& l2 L' t3 O0 O
                                return;      
      L* y/ L9 \8 b) L                        }</P>
      g) x2 ~) n8 t, [3 g# e<P>                        pSvrAckPack = pNewSvrAckPack;; ^5 F" Y; N' d/ j6 _- F* a: }
                            pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
    6 V& P- |$ {( L3 k- p- G2 N<P>                        // Make sure pChunk is still where its supposed to be4 }& w# Q" U6 Y7 Z2 ]9 H
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );
    5 s: }! t$ b  Y                    }</P>$ l  D6 H8 {; F7 G) l; r
    <P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;
    % q( l6 k; V4 l* S! b! N                    pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
    1 H7 w% T6 N' w  i1 a                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;
    1 J5 |) x0 y* C                    pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;
    % n% Z$ y) Z2 |/ j& X                    pChunk++;
    & V& R& r. b) \                    pSvrAckPack-&gt;wPlayerStatePacketCount++;
    . |+ m9 f2 l; I5 i                }
    7 m+ _9 t" h/ C; q3 _0 ?: T                pCurPlayerData = pCurPlayerData-&gt;pNextInCell;
    - I  n$ |2 s) E. G            }
    # b- `% }3 e6 G* Z( ?# c        }
    5 j3 ^. v$ w; R    }</P>  F' Q# G  _6 C
    <P>    // Update the dwNumNearbyPlayers for this player! m6 [, ]3 Q* T. j8 B! O
        pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>6 ~* c1 p+ R/ Z& |' ^( I  V
    <P>    // Unlock range of cells
    7 ?' r( x; q) u% |3 ?( ~+ X    UnlockRange( minx, miny, maxx, maxy );</P>
    & B6 o- c! K! X6 l) p<P>    if( m_dwLogLevel &gt; 2 )9 ~2 o' X% D* \
        {
    ; t" X( y8 F* h, p        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );2 T: i% i8 E( @6 N5 R; j# I
        }. B, Q2 \  K& i+ l0 l1 d
        else if( m_dwLogLevel == 2 )
    6 G. L, Z+ _* t- Z$ a! f7 o! u    {
    4 R1 c  m1 s  u, m! N: b: ]% b        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    . o) C( L# |2 C/ P3 L        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )
    , I- r7 |  v% J/ N  r        {* `( P5 t* F3 d. G7 W9 @( _
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );  f6 z7 `8 z* J8 w
                pFromPlayer-&gt;fLastDisplayTime = fTime;
    0 i5 I) B' f* _/ R' D# R        }. U8 _+ P4 ^: {; F3 @: \
        }</P>
    # h( [* m  [' K. a8 z+ x, K' F" `<P>    // Unlock the playerdata2 I9 l; X0 D3 P+ a4 h' b
        UnlockPlayerData( pFromPlayer );</P>
    " h/ Z. D4 s, P5 C1 Z7 p<P>    // Send acknowledgement back to client, including list of nearby players $ @7 a, N& H& {0 T
        DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));
    6 j# F9 ?/ ^( K2 n
    - H7 @1 x) g6 _/ M' e& N9 Z: W6 S    // Pack the buffer with dummy data.
    7 f- U4 l7 c8 H" m8 B8 y    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)
    . ?; s: U  E" \3 h; d$ J    {
    2 d( z- o; `4 N! t        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];" g) {/ n. k7 o& Z" \6 [
            VOID*   pTempBuffer = 0;</P>" o$ s& V- J  b2 e2 {* O
    <P>        pTempBuffer = malloc(dwBufferSize);
    0 z/ H7 F( w: S" T        if( NULL == pTempBuffer )' ~; I: L2 e: m! W8 B7 E, B
            {
      i1 A% J; W) t. j( O; T) J            //Out of memory
    0 M* K! k1 B; P3 q. b            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
    ) q" y2 g; a! P+ p1 o            free( pSvrAckPack );  O: w* x. h4 y, e3 e5 A% k; T
                return;: z# X4 q+ d8 P4 J) l3 q' c
            }</P>
    6 |! c8 e0 ~/ n) x0 u<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');  _+ h) K4 Y7 H8 Y
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>
    4 |! v% D4 {* O% c5 T. r<P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );
    3 T4 x7 U3 c) q' }4 W+ M! X  Z3 c! U   
    1 P& K( _2 t  \7 {: T/ V) M        free(pTempBuffer);
    % O) ?2 L- I5 }0 c8 h0 _# \    }   
    ; V, y  h5 m- s! h6 v6 f    else; T! ]4 s; u  ?4 }" [' C
        {" U! @. j' y+ _" c- r
            SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );: o" R3 D( n5 ]4 T. R
        }</P>
    / y& _9 X# P/ K& }: X+ U/ L<P>    free( pSvrAckPack );</P>
    ( V% c/ d9 ~* Y: f! L$ d" J% v7 J8 R<P>}</P>: }7 w, m( D/ P
    # a5 }6 _( J# e, ~
    <P>
    " f5 O3 W- M/ U2 \# E. `//-----------------------------------------------------------------------------
    " D4 G1 c  W0 c// Name:
      S8 R, q5 d8 g* Y% b' o// Desc: + o( k0 U, k' ]0 q0 P9 u
    //-----------------------------------------------------------------------------
    ! L# l/ I7 x2 j+ j# X* c" ~void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )$ n' p9 o) i  w+ w" q7 L
    {
    ) M" @9 y* a  t) A& ?( U- D    // Grab playerdata for this client and lock it" E" H- t9 Z5 u
        PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
    : Q8 D. G. w5 {" z    if( pPlayerData == NULL )
    0 n& x% B, G1 M& v3 x        return;
    / }" o3 ^3 ^( S( }: f$ U    LockPlayerData( pPlayerData );</P>
    2 ?$ |' n2 K3 |! E; D<P>    // Record the version number 8 O% L' B7 N- }0 H% q" t
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>0 D. t* P  l4 v" I0 D' T
    <P>    if( m_bLocalLoopback )
    # J. ]7 f6 b5 D/ _' y% _& O; o+ |        pPlayerData-&gt;bAllow = TRUE;
    " b3 X; p1 T6 }6 `    else
    4 S7 w( n" O0 g% E, M        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>
    8 Y% ^7 I5 O# N. e. @- ~7 H<P>    if( m_dwLogLevel &gt; 0 )# R& |" ?0 ]5 A! P- G; b- k) ?$ J
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Client version=%d (%s)"), pPlayerData-&gt;NetID, pPlayerData-&gt;dwVersion, pPlayerData-&gt;bAllow ? TEXT("Accepted") : TEXT("Rejected") );</P>
    + b2 E8 I3 t' B( [& x# P  l& z<P>    if( FALSE == pPlayerData-&gt;bAllow )& N: n8 |3 l" ~8 i; s2 x) ~8 @( _1 r5 [, {
        {' }; K% x3 [: p" P7 D0 e  d; X
            if( m_dwLogLevel &gt; 0 )1 K2 v( [, \4 A+ L3 y
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>
    . i  h4 ~6 Y' P2 R2 v<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    3 _/ s3 y% [9 u" z0 X        UnlockPlayerData( pPlayerData );* X. [$ U! V; X5 F/ |7 T. L, Z* H
            return;+ o* k+ r4 S6 m; T) t7 v. d
        }</P>
    % B& t* u( r4 g<P>    // Unlock the playerdata: m5 }4 ^% w% N" w; M. R% z
        UnlockPlayerData( pPlayerData );</P>; e4 }0 K" g* u
    <P>    // Send acknowledgement to client that the client was either accepted or rejected
    . s9 ^- Z2 g* J1 D3 u    ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );% w2 H, a9 f2 S1 e0 ]5 Z
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
    4 R2 Q1 l" u' Y" x; @' Q}</P>
      N0 \) [- M9 ^) E
      `1 M# r7 J0 m, x, m<P>
    ( G" n3 k5 O9 ?4 {7 W3 I//-----------------------------------------------------------------------------$ o* S: e( m% h* y$ ?1 r( s  a4 \7 n
    // Name: 5 F2 a1 A% b3 `- x6 Q, z) f
    // Desc: 3 Z8 Z  l. I  ^# p, F: N' z) j: |
    //-----------------------------------------------------------------------------
    3 t2 i: h8 W$ Z: a2 kBOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
    2 K3 |; L/ u/ Z2 _) P2 Z, W{
    ) k1 z% y; ?- X6 k7 o6 c    switch( dwClientVersion )
    , L, X& P. g5 C6 C2 A    {" _- Z$ G! K! Z. w
            case 107: // only v107 is supported6 i$ k& e0 V/ E& t3 H
                return TRUE;  P% b$ a8 L+ B% ]" t. L1 e2 {0 e& y" n
            default:
    ' T; @& ^) Z; A1 [2 Z            return FALSE;
    # v6 o* \! }# V0 ^% n    }; N( z* D/ S; _, ?
    }</P>5 T  B$ X1 P3 w) V9 L" s- n& D, u# x
    , p* F1 t' R1 A2 v) R$ d* j5 _+ O: }
    <P>
    / r3 ~' S0 |' Z1 L  S, v//-----------------------------------------------------------------------------
      ]" h' |5 y5 J$ [// Name:
    ( s& ]* P" T$ p* e6 q// Desc:
    6 r  T; N. Q5 k+ z9 F//-----------------------------------------------------------------------------( I5 p' H0 T) W& v! ~  ]
    void CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
    8 x% O; Q+ A+ d4 K2 q- i{
    6 X& G& `& C# |) ~  e9 M    if( m_dwLogLevel &gt; 1 )$ j$ C" l; J' ?2 k7 A3 P
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>2 h2 s7 ]9 C" H: n# d
    <P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );- G2 ^! H7 M4 V5 d' w
    }</P>
    4 k9 F5 k: [3 F2 e1 h) x$ {, r$ d0 t- e9 R4 V
    <P>4 g; b5 c- d& H. M
    //-----------------------------------------------------------------------------# F: A7 T0 E/ @  E
    // Name:
    / c: {# J3 g/ x; G- f// Desc: * }' U( h  d( M4 Z% Y3 |. h
    //-----------------------------------------------------------------------------# G9 U6 u5 W7 Y" ^. @
    DWORD   CMazeServer::IDHash( DWORD id )+ B' q9 a4 e7 T" N0 u$ S/ z- g
    {
    0 \  H  M4 U& r" ^    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);
    ' D; i* m1 g# }    return hash;
    * u2 t8 @$ C3 c' x! S. [) }5 r0 [}</P>
    ; Q, c! C' o8 x5 [9 Z' T
    ! y- y  _8 S& v3 h4 g6 V<P>  M# v% U* P! \; x" t
    //-----------------------------------------------------------------------------0 `3 A* k. f4 D: H5 s8 y% y4 c# ^8 i
    // Name:
    & u  G; Y' x" p. `8 A// Desc: , r# y  r, p, g4 b
    //-----------------------------------------------------------------------------
    ( }& V  l# u1 g* w; rvoid CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
    9 Z0 h$ G( p' h  i' {3 X2 x( m{6 R  k7 P# ?; O- U, v
        // Hash the ID to a bucket number
    ( U- M" `# R& \0 [: _    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
    # D6 W" q% y. H: K<P>    // Lock that hash bucket
    + t, K2 E* e3 l# r. H    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
      A: Y. p1 W. T) h1 ~, ]    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    : N, g+ y6 b4 i& ]* R4 J<P>    // Loop though players in bucket until we find the right one: v* a' ~$ a% |5 _. o8 `  ]0 L
        PlayerData* pPt = m_pstIDHashBucket[bucket];# p( n, o1 m( B8 x
        PlayerData* pPrev = NULL;9 A2 @5 [0 Z+ K& ~  T" r2 h7 M( w5 Q  j
        while( pPt )8 _8 G8 f# [! e* I
        {# Z; s) i+ ^9 X
            if( pPt == pPlayerData )
    9 u# q! ?- U5 P6 G) g6 [            break;
    4 g3 o0 @# f' S7 ?8 a# ~        pPrev = pPt;
    # a( a. _: Z1 |$ t, E        pPt = pPt-&gt;pNextInIDHashBucket;7 v5 `& g5 C% B1 R
        }</P>9 S! |+ q5 X! O* E
    <P>    if( pPt )
    7 W! |' Z5 {5 V    {. V, T+ s3 o8 R0 W5 F
            if( pPrev )
    ) c# O* g: G/ m4 g* ]  \2 L. V3 [" l            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;
    % h- p2 C% j% p$ T- {, j# Z% @        else5 K) D) R# H! S" p- h0 |2 ~% X
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
    6 X. S$ N# U+ w, a& F6 E8 j' Q        pPt-&gt;pNextInIDHashBucket = NULL;
    $ Z) U4 g( c- S( f6 t    }</P>  T% j+ I) v9 T- z, j
    <P>    // Unlock the hash bucket& v  L/ Z2 m) R- a' u; L
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();3 h$ y9 Q- u  U, M2 y) p) ~6 D
    }</P>- a  \7 b( t' C! G4 |' m8 f0 K

    ) m' A8 z6 l. V/ x$ I" i<P>  z5 r  p* `  v5 j
    //-----------------------------------------------------------------------------
    2 a. F% t3 N4 g% h1 {& e// Name: ; e" |( ~& F( D. t" x0 ?0 P
    // Desc: # q& o3 m0 }- T. `- s
    //-----------------------------------------------------------------------------
    " c5 Q, m9 K8 o- Vvoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )* i' X' c! ^, K% M) x. J3 [6 K( S) e3 e
    {+ f1 i  p6 ?5 b) S3 q
        // Make sure this player isn't added twice to the m_pstIDHashBucket[]
    1 ?* Y7 u9 ~3 [( N* \    // otherwise there will be a circular reference
    6 V3 o" l4 z8 n& g0 O$ h4 T% J    PlayerData* pSearch = GetPlayerDataForID( id );5 I! t4 x& n, s( E8 ^4 e6 s4 B9 f& g
        if( pSearch != NULL )
    ' c7 r  q5 u# X. u        return;</P># X" r) V! @& d) V8 v) Q
    <P>    // Hash the ID to a bucket number# S9 J1 z0 [4 E) Y9 X
        DWORD   bucket = IDHash( id );</P>3 g+ d$ L7 B' o4 L9 s+ J# Z( @" U- C
    <P>    // Lock that hash bucket1 |$ q% V1 d, R8 x' f& }
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    2 R4 h- g, B9 H* V    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>& U# ~* r+ y# n3 N: }
    <P>    // Add player onto hash bucket chain
    1 Z% s' T# T- X$ w% }' Q    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];  G# L8 `4 N- o6 {8 W. m
        m_pstIDHashBucket[bucket] = pPlayerData;</P>+ f9 g: f6 N4 m: n: _% H! N8 q3 i
    <P>    // Store net id in player
    + ~3 G( ?& D* I: V) ?    pPlayerData-&gt;NetID = id;</P>
    ) G# k' d; o& q% ]" j: T+ z4 E3 P1 J<P>    // Unlock the hash bucket
    9 j7 }, x. E/ ]9 ~3 L    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    ) g" S6 H" y# `. x- c8 O}</P>( M3 D  `% F# k- u$ c$ f

    8 |7 x' M1 M) ^! C) @% |- s<P>, G+ @! c2 e. M
    //-----------------------------------------------------------------------------
    1 R. r6 k- [& X. R7 k7 ]9 H// Name:
    7 M6 C1 g- S3 \2 o// Desc:
    ! K" j" X  L" `# ?//-----------------------------------------------------------------------------, Z7 i+ J) C( I- z, |, Q
    PlayerData* CMazeServer::GetPlayerDataForID( DWORD id ), r2 F4 F( l3 X) s9 z: c& p
    {
    & s( Q& w7 i" m    // Hash the ID to a bucket number& ]. |6 I  ]0 o$ b7 L/ U
        DWORD   bucket = IDHash( id );</P>
    6 O" |* s( ~- m6 |3 V<P>    // Lock that hash bucket
    ! I* [5 M6 v9 [9 h( `# e    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    ! U$ D$ Z# P$ g' j  E    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>+ s- U1 a1 Z: P8 h
    <P>    // Loop though players in bucket until we find the right one! f2 x) H' b, s! u& u1 e7 u/ k
        PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    1 e3 P! F) b  I    while ( pPlayerData )% A2 g; R' f! \, I
        {
    5 L: X1 ?- |, n* f9 D+ G# l        if( pPlayerData-&gt;NetID == id )3 O% _# q7 W/ a# z  f5 J
                break;9 d( O3 ]5 c) i/ Y, `) u
            pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    / x% X- H" N/ e7 L( l* P    }</P>1 v2 r" b) a1 U+ |" I. T
    <P>    // Unlock the hash bucket
    $ v- C6 g8 o( D/ R  m" f2 l    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>
    4 Z" }1 ^4 f$ Y" L7 ^. ~<P>    // Return the player we found (will be NULL if we couldn't find it)/ k8 w. n, f/ M0 m. C, {( P+ X
        return pPlayerData;- u" `  O4 M' M6 T& V/ v4 g8 ?
    }</P>
    * V/ S. M7 b7 r, n: U3 F4 Q( _4 L: q/ L
    <P>
    * _1 m- x1 Z9 v( W/ [//-----------------------------------------------------------------------------
    + ?3 [, C$ G, J6 o// Name: 7 z$ S5 X" u+ ~& c
    // Desc: calls DisplayConnectionInfo for each connection in a round-robin manner5 w5 k0 {: f1 W7 I, Z/ f! l
    //-----------------------------------------------------------------------------' m" x; B3 K; E; H* h
    void CMazeServer:isplayNextConnectionInfo()7 Q. }- @% I4 K1 x  i+ ~6 _7 c6 u
    {
    9 ?! \  w5 |/ r* O! G. g/ q6 i+ r0 D    if( m_pNet )" n$ ?% o) q4 c0 m
        {
    # q$ X+ g7 H0 q        // Find the player that was displayed the longest time ago, and display it./ a" J! B6 G. O: u4 v; q/ L9 k
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );2 Z, h  \3 A$ U2 ?, t
            PlayerData* pOldestPlayerData = NULL;
    " X. J( C+ ~* A9 `! A) b- j' r6 w        FLOAT fOldestTime = 0.0f;</P>! m( @: w* {- z3 O
    <P>        m_PlayerDataListLock.Enter();</P>
      f4 b7 F( g- ~4 L<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
    3 }; n9 M$ T) w; Z1 Z0 U+ r        while ( pPlayerData ); c& l# m4 v4 m) D5 ]3 B5 \8 L
            {; [0 A# }8 S" E
                if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )% k( }% w( c4 \% l% `; I
                {0 s7 S% P1 t3 N
                    fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;
    / T2 T4 [# b5 G2 y' B                pOldestPlayerData = pPlayerData;, y* w3 P: H- e. |- @' P
                }</P>
    ! T/ M; I7 O+ l. k: I<P>            pPlayerData = pPlayerData-&gt;pNext;- D! L3 e" C  c: F% f6 a$ E0 p
            }</P>: v; }  E0 h; q% h- Q
    <P>        // Display the player with the oldest CI field, and update its CI field.
      Y/ E. l$ C9 c* {        if( pOldestPlayerData )$ ]) e, _# I  C# _, _# Z
            {6 W3 n6 _4 V1 D8 f  q8 u9 A
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
    ' K! {* R7 p2 m2 e; ^: d/ _  E            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );9 H" h' U( H1 }
                pOldestPlayerData-&gt;fLastCITime = fCurTime;0 y1 V" e# J$ B  `' V
            }/ x0 S5 B# i1 d, @6 }
            else
    * N" b) [6 Z$ V6 `2 R        {( `$ `; b1 k2 N. e( m
                ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    5 R$ f/ [4 c/ q! C/ s, L3 ~        }</P>
    : k8 M8 K; }, s8 C- E; V- l<P>        m_PlayerDataListLock.Leave();
    ! M& T! K% x/ b- ?    }1 B$ V* f1 I8 N  d$ J$ U
    }</P># N+ @0 S& B7 P7 _

    ! ^* ]; ~! @, D2 M' \6 }) K8 k<P>
    / x& ^6 X  L* L//-----------------------------------------------------------------------------
    3 ~" N* m: g1 ~// Name: 7 |4 b6 n: A# g+ g2 h& {
    // Desc: $ B( D  Z' x2 G; Q6 m% E0 Y
    //-----------------------------------------------------------------------------6 e# {6 @( `+ A# }3 `0 E
    void CMazeServer:rintStats()
    % ^) x4 W) u* {{
    1 t  ~/ W" o! Y; w    ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"), % b  T; i/ J1 D/ {/ Z
                                        m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );9 I) ~/ O. D4 i' Q! I  Y
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
    * S$ O6 ~( @6 Z  |4 d7 S* |% I                                    m_fAvgThreadTime, m_fMaxThreadTime );( i+ u3 K9 M1 ?
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
    2 R  Z! [" B/ A4 k  [  n9 U    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );5 T! ^+ C5 Q  w! }% H
    }</P>
    / `! @4 F- |9 y8 G+ H) C# S
    * f3 A& L7 |7 A( Q  Z6 U1 f5 h  ?' h<P>
    % h' g: v# b/ @% F3 M$ z0 C9 m//-----------------------------------------------------------------------------$ c5 {) d* k; w3 F# C$ a
    // Name:
    ; H4 l! r  P' A0 j* d* a// Desc:
    $ c& q- B' r) t5 Y6 K% L* }; u//-----------------------------------------------------------------------------, L( G; e1 P, y& u4 m7 ?
    void CMazeServer:isplayConnectionInfo( DWORD dwID )' o; {4 N5 m( `, l. a4 N0 d
    {% o$ Q: ^. Q' s8 o0 Q
        TCHAR strInfo[5000];) ~% R/ P1 q! J; g. Q
        TCHAR* strEndOfLine;
    4 [1 Z* l+ T# ^' K0 L! L    TCHAR* strStartOfLine;</P>
    2 S6 Z, p( L. A3 N# J3 h<P>    // Query the IOutboudNet for info about the connection to this user
    / L* Q# Q9 O  f4 _  g" u/ X    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>" ?2 N8 C% |7 r0 T9 Y: p4 O
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );- j# C1 e( {$ P
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    ! t  Q& c1 _5 o# E5 \: T8 X/ M<P>    // Display each line seperately' @5 o( K1 T4 B% ]2 \' s3 g
        strStartOfLine = strInfo;  u& g, b  N  L7 F' G; e
        while( TRUE ): {  }$ L4 ~$ P& `* h
        {5 ^, J$ n+ m0 A# ~) l. c& {  S" b
            strEndOfLine = _tcschr( strStartOfLine, '\n' );- K2 e+ p. g: L1 m- p" a3 v0 [
            if( strEndOfLine == NULL )
    2 f) {7 l  W0 E+ y* _/ U2 A            break;</P>
      x+ a, f% ?2 |* Z4 G<P>        *strEndOfLine = 0;0 H3 z8 j$ k3 Z7 d" T% ~4 j! t8 ^
            ConsolePrintf( SLINE_LOG, strStartOfLine );1 }7 X& H- j" I+ ~0 i* h
            strStartOfLine = strEndOfLine + 1;- W) P( H2 s) S* X9 k5 ^
        }1 ^# j3 S+ Q% Q0 G8 b
    }</P>
    6 Z, z# k) Y/ o* R% F* }1 X( A# v
    / a4 L. f2 h1 t/ m& r$ f4 V<P>& {1 s% n9 y2 s0 n" y8 A
    //-----------------------------------------------------------------------------* d8 O  G& N$ `) a
    // Name:
    , B" d% ~/ B4 q8 m// Desc:
    $ A( `* I" m+ o, e//-----------------------------------------------------------------------------7 B( g2 E* v* C
    HRESULT CMazeServer::SendPacket( DWORD to, void* pData, + K- H, ?; Q9 R$ y. c) P. d, u
                                     DWORD size, BOOL reliable, DWORD dwTimeout )
    * j  w: R' B* b9 P{
    ' ]" O! F5 _0 g4 B! ]    // Chance of forcing any packet to be delivered reliably
    : \4 M+ e; ]! ?9 @. r6 e6 z    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )
    8 t# M/ ~( Z5 W% G6 v* q6 E        reliable = TRUE;</P>: D, C/ C3 _, Y% ~
    <P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    2 a% O/ N$ y+ e+ H) V6 F/ X}</P>- P( [: q. e- ?% b& T8 Y8 e/ v" v

    3 U; d8 _; N% t$ V" F; H2 |<P>' B! G2 F0 b+ g# R7 |: [% z
    //-----------------------------------------------------------------------------
    : e/ T( c' y/ _// Name:
    # W6 g8 _# f$ N( w0 N8 h5 h) W// Desc: : c/ |9 H* T1 h* Q: p6 x, H
    //-----------------------------------------------------------------------------0 [6 ~' i  p( x
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )
    . A, y9 q# b2 z; X- x{
    , M2 b' J# g- Y0 D; p' x( R    // If we're up and running, then send this new information to all clients5 h6 f' \5 [, @' l4 O
        if( m_pNet )
    / Y1 |1 |% H" Q' A    {/ x2 `$ l$ B- s1 ~$ O2 ^' q
            //Use the AllPlayers ID! m3 Y* K& _+ ^+ H
            SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );% q  A9 e) V1 F' Z6 f* V6 W
        }* R: l7 E# _% a$ I. e0 A
    }</P>
    # k2 ]- b0 D8 p* f  Z; v: N2 |7 e. E% X# Z, k: w9 ~2 K. z
    <P>
    9 e/ ]8 n8 V& ]7 r# a( m//-----------------------------------------------------------------------------
    ; \' U) G( `- P- h7 d0 Z// Name:
    ' I$ v1 [' t1 n" M5 A# n. e// Desc: , Q/ g  X) E! q4 g$ @( r% W6 A8 i
    //-----------------------------------------------------------------------------: |" b8 V; e, p1 t9 W' c& ~
    void CMazeServer::SetClientReliableRate( DWORD percent )
    % `# u# N8 p3 z8 p2 j{1 R: ]& B& m/ T! k' G6 q% W
        // Update client config, and build packet containing that data
    5 A6 Q8 E9 E: r- X" ^    m_ClientNetConfigLock.Enter();
    1 _* d8 s" g; N3 Y- J! k    m_ClientNetConfig.ubReliableRate = BYTE(percent);& k" ], E1 L- J5 f6 E& W0 n
        ServerConfigPacket packet( m_ClientNetConfig );
    - j3 P: |) m, m% L2 _: P, b; r; Z( E    m_ClientNetConfigLock.Leave();</P>
    3 m$ W3 }4 Z$ e<P>    SendConfigPacketToAll( &amp;packet );" p# j7 x# j7 Y8 i. ^: C
    }</P>
    $ t. O* m1 T0 v) F2 _# J; [3 z" G- |! G
    <P>1 I! M5 i* I& w: z; r- \
    //-----------------------------------------------------------------------------
    6 l, A4 p3 n$ }// Name:
    . r" w$ }3 W0 y/ k# r+ U* e/ u// Desc: + ?% d4 \- s- x$ y
    //-----------------------------------------------------------------------------1 |4 l5 x: ^1 s; m: i* Q! U- k
    void CMazeServer::SetClientUpdateRate( DWORD rate )
    6 [+ ^; R4 V0 z  A$ r- ?{
    + K; y8 ~* X) q! O- W1 _' g+ e2 Z    // Update client config, and build packet containing that data
    . z; r9 L. c4 j% g    m_ClientNetConfigLock.Enter();  E3 h% m9 c; K: [' B
        m_ClientNetConfig.wUpdateRate = WORD(rate);* Q- K$ d* }, E2 ^1 K/ x+ j
        ServerConfigPacket  packet( m_ClientNetConfig );) Q; x  \5 O4 F$ x, r) |
        m_ClientNetConfigLock.Leave();</P>
    / T; }/ d. p5 P, ^+ S' w: J2 W<P>    SendConfigPacketToAll( &amp;packet );
    % y- E/ C+ P* J# x& S3 U2 R" N! f}</P>
    7 K+ X( @9 H; E1 F& K) ?, W2 R
    ) O/ L* q& C+ c& F" T) `2 s<P>* C9 F  W2 k' O: Q5 Y/ N) `- Y1 ]
    //-----------------------------------------------------------------------------
    4 u' N; S* I/ ^: D8 `- R/ C// Name:
    4 s! s4 M% p4 W. B( z) c// Desc: 7 O6 [. [9 E' q; O! q0 V" W
    //-----------------------------------------------------------------------------
    % }; Z3 n8 {6 t& l# {void CMazeServer::SetClientTimeout( DWORD timeout )7 e( Y# K* ^5 y
    {% w1 ]5 F0 h# C' e: b8 ]+ ]
        // Update client config, and build packet containing that data' {7 r8 ^  d5 K8 u0 \7 l
        m_ClientNetConfigLock.Enter();8 ?' m9 g6 A1 J# l$ X! a* _
        m_ClientNetConfig.wTimeout = WORD(timeout);0 M' g% [, Z9 b. G
        ServerConfigPacket  packet( m_ClientNetConfig );
    ! Z# m2 l* U! f! C    m_ClientNetConfigLock.Leave();</P>
    / }8 @& c8 f4 g$ a+ @<P>    SendConfigPacketToAll( &amp;packet );5 @( G5 i- s- |
    }</P>
    8 Q; h" D0 w3 H" `
    5 Z- _) S9 L. }6 t' q4 b<P>
    : ]3 z- F5 b/ t3 d: F: b6 N//-----------------------------------------------------------------------------1 b4 W- w+ j( c0 y
    // Name: , E5 [, G) X) `  o7 e$ \7 @1 u, G
    // Desc:
    ' s9 v% @% l6 K* }//-----------------------------------------------------------------------------# O6 [1 q- E, j7 u4 W/ ?
    void CMazeServer::SetClientPackSize( DWORD size )
    : T$ W) }. l' L5 F{
    1 T: }1 Q3 C9 v    // Update client config, and build packet containing that data) K3 ~8 F% V" `6 W% l4 Z
        m_ClientNetConfigLock.Enter();# @4 J/ [. E7 T. ?
        9 `: M- [- P7 i& s$ k  A/ n
        m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.
    5 e# |; H7 X) O1 K    if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   ) z) E! ^# {" N7 r( f
            m_ClientNetConfig.ubClientPackIndex = 0;</P>* L* a& _7 f8 b& _  m8 v, T
    <P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);  K+ q, ]6 o  H& }4 p
        ServerConfigPacket packet( m_ClientNetConfig );2 N: M- y4 s. Z: H$ a
        m_ClientNetConfigLock.Leave();</P>
    8 m0 D( K2 u2 u% R<P>    SendConfigPacketToAll( &amp;packet );
    , `& X. T  V; J! T4 Z8 _}</P>
    ! Q. q/ C/ r; Y7 i- u% e+ d; ]7 r( W* c1 B
    <P>( y' K+ u' w5 ^. e" Y/ L
    //-----------------------------------------------------------------------------
    ; }" _8 p: d) f8 _  U( |// Name:
    8 x) [1 Z/ D  E" G( m/ t// Desc: ( R/ O+ f6 [) d" p5 M5 o
    //-----------------------------------------------------------------------------) s1 P! l1 G/ I  U
    void CMazeServer::SetServerPackSize( DWORD size )
    ' x: e* I8 E: c/ I; t4 O" I# ~{6 k8 M% v9 y2 g# S5 S6 L2 V
        // Update client config, and build packet containing that data
    2 b! ~* B' N7 j. s' e- D+ S    m_ClientNetConfigLock.Enter();
    * j- g5 f, E7 V' e5 c   
    3 l% ~8 n% o2 Z0 }    m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.) F+ ^7 }- p& }  r
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   ) W+ }) @  ]+ s& n/ t0 W  b
            m_ClientNetConfig.ubServerPackIndex = 0;</P>* j* t' i  w+ P3 F, B
    <P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);, b& D0 e- \8 L/ Z
        ServerConfigPacket packet( m_ClientNetConfig );
    ( j; R$ Q" q9 D  ]! y8 ^2 X    m_ClientNetConfigLock.Leave();</P>! d, u5 H+ t# X$ R
    <P>    SendConfigPacketToAll( &amp;packet );8 v# y4 f/ _3 Y! N
    }</P>
    1 w$ i9 _6 D' m' y# g: T" I<P>
    % G8 e  ^! r- ~1 V& ~0 N  g2 C//-----------------------------------------------------------------------------) x- e7 \7 t" x" |8 b7 H8 j
    // Name: * b  A3 Q7 J. @
    // Desc:
    5 }# Z$ E0 K* W% Z//-----------------------------------------------------------------------------
    * ?( O! E" K) ^- U' dvoid CMazeServer::SetClientThreadWait( DWORD dwThreadWait )' L: t" _8 I8 O. K& F  r7 [; q
    {
    4 b# v! }1 O6 t0 h1 i4 a" h    // Update client config, and build packet containing that data- o$ l: i7 G, y* M. ]
        m_ClientNetConfigLock.Enter();# @5 h. v! d  P% v, F
        6 M- Z1 G9 Y4 K9 m
        m_ClientNetConfig.dwThreadWait = dwThreadWait;6 g+ i4 x& V0 n+ q/ ]
        ServerConfigPacket packet( m_ClientNetConfig );6 b4 [( Q; s/ `
        m_ClientNetConfigLock.Leave();</P>0 C$ Q# S! M( D: v- K2 d4 C* B9 W
    <P>    SendConfigPacketToAll( &amp;packet );
    8 U6 u" d7 d  e! F4 m( w}</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 14:52 , Processed in 1.225293 second(s), 51 queries .

    回顶部