QQ登录

只需要一步,快速开始

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

[分享]MazeServer源码示例

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

1万

主题

49

听众

2万

积分

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

    [LV.10]以坛为家III

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

    群组万里江山

    群组sas讨论小组

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

    群组C 语言讨论组

    群组Matlab讨论组

    跳转到指定楼层
    1#
    发表于 2005-1-31 11:52 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    <DIV class=HtmlCode>
    ' ^1 X6 G( U9 r$ j: {$ D<>// File: mazeserver.cpp
    % g. S  h& G- g( [( [" P$ Z# a//
    & w. ?4 K) B8 w. V: i2 @$ b, r// Desc: see main.cpp; e* C+ b" w8 ^8 F/ _7 t
    //) y: C+ r1 x% M9 e$ r
    // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
    + l) Y/ ~3 @, K3 S- E( Q//-----------------------------------------------------------------------------
    6 J& I" a( I7 h; A  E% {#define STRICT
    ( b, X+ v5 Y9 {! h0 \#define D3D_OVERLOADS6 u* s- g8 J/ A- Q! z; e
    #include &lt;windows.h&gt;
    0 K8 J& j7 w+ B6 p2 `8 o3 @5 c#include &lt;d3dx.h&gt;
    / t4 I# `' j+ F" K# V- A#include &lt;stdio.h&gt;
    6 g7 V' D+ I* j4 j3 ~& @* o#include &lt;math.h&gt;
    + d# V# ^' L2 d#include &lt;mmsystem.h&gt;
    8 k! u" t6 ~/ k: ~9 f#include &lt;dplay8.h&gt;
    / f, c! y2 D, }1 s6 q) {; q6 I#include &lt;dpaddr.h&gt;: e' r7 r. G4 H. o& a/ \5 T
    #include &lt;dxerr8.h&gt;$ {3 j$ s- i$ e& Z2 q" A
    #include "DXUtil.h"1 K* ^: G3 M9 X' P
    #include "MazeServer.h"# \3 `: n% m, g
    #include "ackets.h". K$ ?2 g( h3 o2 r. d5 y% f
    #include "Maze.h"
    . ?* ~/ Q3 W9 N6 F4 w; t: ^) f#include &lt;malloc.h&gt;8 X; o+ H9 }; s, J# m
    #include &lt;tchar.h&gt;</P>
    0 z2 r( c8 H" H7 J7 ]
    0 U% |& L2 R8 z2 O<>//-----------------------------------------------------------------------------
    5 K1 T" C  Z- T6 n* T  E$ z// Name: / \! q, _& V9 F) r' ~1 l
    // Desc: 5 {) k$ r" H( r1 ?) E2 l
    //-----------------------------------------------------------------------------( U3 c" S; d. D
    CMazeServer::CMazeServer()
    / @0 X, G  \( @4 F{  y7 R# ~) f5 M) a
        m_dwPlayerCount         = 0;
    % s0 j6 x3 U* p) V9 i) K; u" D: H   
      J3 \8 B3 E/ z& U8 A1 z    m_wActiveThreadCount   = 0;7 k4 i5 {2 f4 @. u  l
        m_wMaxThreadCount      = 0;! F3 F  K* Q: i$ Q0 [+ V
        m_fAvgThreadCount      = 0;; t8 Z4 T/ U& z$ r7 |7 O9 d
        m_fAvgThreadTime       = 0;+ b: j! N' P6 ^
        m_fMaxThreadTime       = 0;</P>
    $ i4 F0 x* D( d' D<>    m_dwServerReliableRate  = 15;
    , G$ N) d# v& Y  `7 {    m_dwServerTimeout       = 150;
    / o( k# C- E3 W+ i4 z- F    m_dwLogLevel            = 2;& `; |$ C$ Z, T; ~: r
        m_pMaze                 = NULL;</P>. a4 I, i4 ^: _) t0 p+ W3 O9 T8 O
    <>    m_ClientNetConfig.ubReliableRate = 15;% E+ N( v. M+ t! W, P* ^4 i1 J
        m_ClientNetConfig.wUpdateRate    = 150;
    8 R0 O5 x! G) `    m_ClientNetConfig.wTimeout       = 150;</P>9 j, z3 X# K' X' c: H9 T
    <>    m_ClientNetConfig.dwThreadWait = 0;</P>; [0 y4 }* u" n0 U8 Z% W
    <>    m_ClientNetConfig.ubClientPackIndex = 0;2 {, ^6 I; Z4 K5 \
        m_ClientNetConfig.ubServerPackIndex = 0;8 m( Q0 c9 }9 X, R5 D3 _; {
        for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)
    ; `2 j* @5 ^+ B/ ]; A3 ?9 {% O    {5 x" a6 W  q3 |
            m_ClientNetConfig.wClientPackSizeArray[x] = 0;3 y1 F9 w* @! T" D2 [7 @
            m_ClientNetConfig.wServerPackSizeArray[x] = 0;% r9 P8 Z+ ~7 ?$ s2 v2 E% L
        }/ ^7 n! ^0 w6 V' S  q9 V1 X
    }</P>
    & M, y9 C3 J9 {4 V. n3 T$ W/ D/ M
    8 p: P  N4 s# K6 z% V1 O1 r<>1 W0 F- @. R5 }( W/ k, j) ^
    //------------------------------------------------------------------------------ l# M% e& s# z% q
    // Name:
    6 V/ n) B+ h( O0 ?% v// Desc: ) Z! b/ g' d$ ]) R2 ]6 [! z# z7 D
    //-----------------------------------------------------------------------------3 x- T$ ^5 {$ _* P5 S; {7 f7 q$ d
    HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )$ {/ B$ J$ W( I1 p0 U/ v
    {
    % S* Q. Q1 q1 g2 ?% O2 j) c    m_bLocalLoopback = bLocalLoopback;
    / s! X) x: A+ g' s5 N' B- h    m_pMaze = pMaze;
    7 h# W0 J" E/ d* J& i    if( m_pMaze == NULL )! H3 S) T& L# u; [4 {
            return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
    " i7 d, L8 i, g6 E<>    // Grab height and width of maze
    9 c3 j" Y% G4 h    m_dwWidth = m_pMaze-&gt;GetWidth();
    & n( V+ c* u" M/ Q/ b    m_dwHeight = m_pMaze-&gt;GetHeight();</P>: g1 [+ ~: o8 U5 x
    <>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    1 x  C- V: g1 H! F' g$ ~    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
    ! b+ m- }2 w. R8 C2 [* w+ s<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.
    % g: x. ]6 k  J9 }9 G    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    - F' \( }: d! S3 F        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    & N6 D2 y) S* \* U* W6 \    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )
    % D, m) M  l# \% l( {5 H        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
    * s- w$ }& U* c( u<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;7 `2 B* q' K5 V* W. M! l/ V
        m_dwMazeXShift = 0;
    7 ?* J4 j  \# K' D, r, I5 u    while ( (scale &gt;&gt;= 1) )
    . g- ~8 X/ m+ o. Y        m_dwMazeXShift++;</P>/ ?9 u; U, a" @1 g
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;8 ^6 @& W1 R8 H! ~+ [
        m_dwMazeYShift = 0;
    " I/ N" O! L+ a0 F& B, b    while ( (scale &gt;&gt;= 1) )
    * i; s$ j4 N4 i$ _        m_dwMazeYShift++;</P>
    - g# C( u) P' i- d<>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    . Z0 T8 ~" t9 z! j7 E        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )+ b% y( [) e2 B: [* |& w! ~
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>
    ' v. x: ?8 t9 m; W( c8 |0 H<>    // Initialise the player list
    6 [( ]5 y0 E' P) D$ c2 E    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );; g3 |8 K1 s  f5 Z3 o
        m_pFirstActivePlayerData = NULL;# ^6 I2 D- \: _; A
        m_pFirstFreePlayerData = m_PlayerDatas;
    + p( H& ^( A& [! y    for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )
    $ f4 }! B$ w2 n$ ?    {- _% B% x+ J) {7 g% z+ R+ u  i3 o
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];: R( d  |# O$ r; f
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];. I+ v* ^( |) n7 a3 R" `. k9 q
        }</P>
    / H6 i) ~2 R* ?<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];, `$ T! r  y1 Y8 H3 X$ L8 M5 S
        m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];
    7 s2 D5 {  k& a$ D/ C$ }  b    m_dwActivePlayerDataCount = 0;
    7 ]; \# W: s2 C: p( G9 j) j7 t( @    m_dwPlayerDataUniqueValue = 0;</P>
    1 F+ [2 k! ~0 y: X3 w# g5 ~3 y<>    // Initialise the cells
    - f8 E% ]" `5 D) o' r    ZeroMemory( m_Cells, sizeof(m_Cells) );
    + q. ^( e$ T9 k/ O    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>9 `& u4 P# [: {) c% r% U( ~8 ^
    <>    return S_OK;9 S0 [" x' {+ Q/ M3 D& A
    }</P>
    1 e4 J! g1 n( Y7 A5 v% [( Q) X% m: c
    <>
    & n% p+ Z* C/ ^- @. p. e# n, L//-----------------------------------------------------------------------------2 ]  B+ k4 S% z0 \/ f3 e" q+ ^
    // Name:
    7 b. E3 K* Z4 d  A2 c/ c8 O; T// Desc:
    6 A% s% ]: R& G! Z) l, k6 [* t//-----------------------------------------------------------------------------/ I- {9 h8 ]# E- [/ q
    void CMazeServer::Shutdown()2 S: e! y, V. B6 a; m; _3 P) v/ }
    {
    ) `2 B/ V" Q8 z1 I, m3 H" r+ x& E}</P>2 T- E1 Z" h7 {8 b6 L2 a1 K6 M1 r
    ) t) y& F: v% L3 G" k6 O6 j: q
    <>/ L* v& z/ m* _
    //-----------------------------------------------------------------------------
    : O! O4 Q( n, `  V# ~// Name: * c7 f- G+ z- @; R
    // Desc: ; G! z- A& [. S+ ?8 P  ?
    //-----------------------------------------------------------------------------$ n& l' @3 z! Y) `
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    / b" S% I! n! _& m( d6 ]: I{
    : q1 ^7 F" [( T$ }, D    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    5 y# v3 R( T& d' a8 }                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    0 Y" _; E9 H- `" o& U2 b8 j}</P>
    7 X$ K3 R8 y+ c" F" S# S( A' V. ~4 I1 Z6 M: e
    <>
    . a- l! P/ Y' D2 c* _) u//-----------------------------------------------------------------------------
    & r+ f4 l  I8 N// Name:   G, J$ s( ]" }7 F
    // Desc:
    ; R1 I  O) R" X//-----------------------------------------------------------------------------0 `: X, `& t2 K. b/ M' m- S8 K5 N
    void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )3 j% ?/ }& U# H' u) b5 W. a
    {
    0 w+ f; D5 H. x) s! Q) z    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ," D. N6 I; `4 T7 q# [& [
                                x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );9 p; `, ]7 P! U7 o$ \3 Y' P
    }</P>
    + b: }' v9 W0 G( I3 U3 u: O. `2 t* }) W. o, Y
    <>
      S2 t  Z: |$ q8 x" J//-----------------------------------------------------------------------------/ @! D2 U+ Z1 {; ]
    // Name:
    0 ?/ A" _3 F5 _9 i* f2 f+ s" ~) k// Desc: 9 C! k& N3 o7 z) u7 g: n- F8 N
    //-----------------------------------------------------------------------------
    ( |( x0 S: B  X" m: E% svoid CMazeServer:ockCell( DWORD x, DWORD y )% u+ `# Q" f3 s$ w: v$ ?
    {
    ) F2 n0 E" a5 _8 x& i/ D2 u0 Q    if( x == 0xffff )
    6 {/ d" Q4 Z" H' q. @        m_OffMapLock.Enter();
    . s4 K# `  z* [    else
    6 ^, n1 ~- m- D) b  z) H' R        m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);8 k. L4 d+ x7 R, o
    }</P>
    % K+ m$ D" H0 q  p3 Y# R- G
    ( y" x; _+ a( I<>
    ! R' i% u7 E3 g//-----------------------------------------------------------------------------
    + j6 J' b4 j( [0 B// Name:
    2 \) M. S2 z! ?: j% K9 F// Desc: 2 o9 p7 V3 z0 Y. g  L0 A% M
    //-----------------------------------------------------------------------------
    6 i' ^+ l7 c' b- A) y. }, Uvoid CMazeServer::UnlockCell( DWORD x, DWORD y )
    ' p& e, @1 u" o$ s, a; V- K{  A, C  b' n, ?) [0 Y. ~* l5 H
        if( x == 0xffff )
    2 F0 c4 ^' P7 K        m_OffMapLock.Leave();+ V9 n& P+ r2 A& R
        else
    3 S* s) q9 u: o! l/ w  o5 X( f' E        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);) R7 N4 i' L. p
    }</P>
    3 C7 k. D5 ^0 Z9 o7 V
    ; ^1 z" Y  s( k( d<>
    / W# t4 O; M$ r& W3 X* Z2 z//-----------------------------------------------------------------------------
    . d5 z: x9 F+ v; l' H// Name:
    9 E. C2 d& z, x// Desc: 2 W& ?, U0 }- K( o( U
    //-----------------------------------------------------------------------------0 O" U0 C5 ~) O) E
    void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )3 z& X0 e0 S; o+ h  a# s
    {$ ~7 E5 ^' w" N- @. m6 t' W, N
        if( x1 == x2 &amp;&amp; y1 == y2 )8 E6 c4 u# d! k. a- a: B' W' D
        {5 y% A0 K3 x- j' S5 r) n, a
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    ; Q  J8 n4 b2 y1 r3 f4 D            LockCell( x1, y1 );* @& H) X! o0 B; S
            else
    4 o1 d% E; U# o  M            m_OffMapLock.Enter();</P>
    " A' q: j9 ~8 D' P<>        return;
    5 x0 [; O" C8 p    }</P>; I3 J5 V  _# l3 R6 u/ U# @
    <>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    / ?9 K- _) Y) f( I    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;* o& t5 `9 D6 l0 p+ }. d0 {5 J
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;4 [5 v$ T  K3 z
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    * R* A& m0 D" }% T. i7 {, u<>    if( x1 == 0xffff )' ?  ]! G7 L( H. c. z& \! A+ X
        {" O  Y3 K* f! Y2 p8 L
            m_OffMapLock.Enter();5 o- O8 f- f8 f- \
            m_LockGrid.LockCell(x2shift,y2shift);
    : T% ?6 j6 D% [    }: s$ M  \+ Q; d; }' ]
        else if( x2 == 0xffff )
    - z! j( _4 ?0 ^' P: B    {
      v* s$ t4 o0 T1 _        m_OffMapLock.Enter();
    2 X7 p0 I5 P) f: `        m_LockGrid.LockCell(x1shift,y1shift);
    0 w$ S% x4 h" x    }4 e- h' }- x, B0 h; X5 W/ |5 J' h
        else
    , w$ {5 G' \3 C, M0 v" g    {
    ; o6 P0 f$ y7 N4 v7 [6 a  a        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);, O" H8 f# m0 Q
        }
    ' X3 G. C/ H1 n* c}</P>
    5 x  I8 f' e& U6 v. K3 Y$ m
    ; x) J( B, W2 d5 b! l<>
    / b- W; @' N) I- i//-----------------------------------------------------------------------------+ r7 {* H' d/ C# p
    // Name: , n4 o7 @4 [* k! v  |* W4 ^! t0 ^
    // Desc:
    + u% D! j" ?3 L2 G: `  }% H; y//-----------------------------------------------------------------------------9 O/ [: T3 U9 a" O  w# x8 U
    void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    ) [; a3 R4 V$ C4 Y, I. s1 C, i  z{- O! o. }3 X' f( Q$ ]- C
        if( x1 == x2 &amp;&amp; y1 == y2 )
    ' \! \* K7 B2 }    {
    . [% f8 Q3 X( z7 M. s, P        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )6 m1 X2 I, V4 n0 }+ O0 B, U+ Q
                UnlockCell( x1, y1 );
    ( _5 I' }+ X% r6 |        else
    ( x0 A1 f* a! X3 `9 `9 N; @5 z  e            m_OffMapLock.Leave();</P>
      R) W) D5 }! N# o" U<>        return;
    ) L& W' r7 P8 q# y. u/ x    }</P>
    6 V! m: ^/ e8 d<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    3 Q9 b* P2 E: @8 D! c8 C* y  Z: f    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    / i" L% h; U8 G$ Q7 h    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    , b% V- N, W$ F7 V3 {0 z( Y0 N    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>' d2 E. o# R& Y: L
    <P>    if( x1 == 0xffff )/ i5 D. J- g4 {- P4 U
        {- b. ~/ h$ D; k, W8 O1 x
            m_LockGrid.UnlockCell(x2shift,y2shift);
    $ b$ A- O, ?& B4 u5 X! N' r        m_OffMapLock.Leave();" X  \4 Z* Y( B8 D
        }0 f& m7 a0 N9 h1 [1 |6 |
        else if( x2 == 0xffff )
    " t4 y  N3 X5 _' \& M8 e    {
    , Y0 b2 ^; n$ t0 H, Z* C        m_LockGrid.UnlockCell(x1shift,y1shift);
    9 V  |  [* u1 i  ~3 Z7 {& w        m_OffMapLock.Leave();
    ) c! b8 z- w: @2 @' Z5 u    }- G# U0 z/ ^0 x7 z3 f" r7 |
        else 6 e. }! ~% L8 c' N# H' i! ^5 O
        {: V% C1 L4 E6 E3 q
            m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
      p5 f+ w, d( o* q% C    }
    3 A$ D4 w: C3 v9 C" O. [. M  E& ]! m}</P>
    % {/ [  ^' N8 Y5 e9 Z$ R+ j8 F% _: @! \& V
    <P>
    # T7 a& Z. n1 p0 R2 y//-----------------------------------------------------------------------------) Z& U5 W4 S0 q' N7 v5 c
    // Name:
    % h& @) ~1 ]9 f4 `// Desc: $ V- P# g' T1 ?$ m9 f6 ?) [+ |* R
    //-----------------------------------------------------------------------------
    / G- I8 ]' {& R8 [void CMazeServer::OnAddConnection( DWORD id )  X4 F2 ?8 k- l# R5 q
    {% A" ~6 B4 R% i, v& C1 P
        m_AddRemoveLock.Enter();</P>
    , J/ l: f/ V' p. N: x<P>    // Increment our count of players. \5 }* Q+ V6 _& ^2 o# t
        m_dwPlayerCount++;
    % H5 n0 x0 j* X- k( R5 _# n0 H9 I    if( m_dwLogLevel &gt; 0 )
    & a; k$ |' x3 T' F  Z" ~, A, q    {
    1 C, [4 ~3 K; h0 Y        ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );, |1 Z) _% z0 @: y. `) V
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    6 ]& w% R5 m2 `, Q1 h" C! U/ b    }</P>& u: G0 x/ ?8 |+ g
    <P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
      `7 ~+ M5 u$ J6 Z3 _9 u        m_dwPeakPlayerCount = m_dwPlayerCount;</P>  B4 }# Z, U7 r  [$ G0 l
    <P>    // Create a player for this client3 R7 p# G* F/ m* {% m  g8 Y) `4 R
        PlayerData* pPlayerData = CreatePlayerData();" v2 G& P2 u$ C; J
        if( pPlayerData == NULL )
    $ \/ p1 {9 Y8 [1 H) T7 m5 [2 T    {
    6 t9 f9 c' t* t, ?        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
    . F$ M; I1 p/ n8 A        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );
    $ a% S* D" P* B5 f6 H5 a$ c        m_AddRemoveLock.Leave();/ Q  x6 u2 B& x# f8 d6 A# _
            return;
    $ F# ~; _5 v6 T- Q; o  @    }</P>7 I' ]* w' A& O* I$ w# i: Y. I
    <P>    // Store that pointer as local player data; P; P- V6 S+ c9 c/ D
        SetPlayerDataForID( id, pPlayerData );</P>
    9 ?' @! D1 ?' T) Z& v<P>    // Grab net config into to send to client
    4 u' Q+ b5 X$ O9 D    m_ClientNetConfigLock.Enter();
    $ |( o; O+ |, q2 u1 A) w3 g    ServerConfigPacket packet( m_ClientNetConfig );0 P/ X1 _) K) o( e0 I# n9 R5 p- j
        m_ClientNetConfigLock.Leave();</P>8 Y$ @( a7 V8 o" I9 `) b: U6 n: a
    <P>    // Send it
    6 @* L0 r7 j8 x! u9 o    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>
    2 T( V9 B( M5 v1 ~<P>    m_AddRemoveLock.Leave();
    ( T5 H! E( c: K}</P>* P- I+ U2 Y- @) C% @# V
    . V; ?  _9 ?; ]% c. w+ \4 U1 V
    <P>1 U+ W4 q4 z9 w1 p. U
    //-----------------------------------------------------------------------------6 [. |+ v6 D" T) i8 Z! P
    // Name:
    ; S3 [9 _* w/ w4 F// Desc:
    + f- Z  R9 d) I# D4 A* v) C) A//-----------------------------------------------------------------------------9 Q5 c, I) q! e9 Z8 n! U3 v) z
    void CMazeServer::OnRemoveConnection( DWORD id )4 l; v4 F, _& e# R  f2 P+ |- |
    {0 w' Q% V  C8 c8 w5 R! y( z2 I
        m_AddRemoveLock.Enter();</P>
    * X& }3 b. ^- _<P>    // Decrement count of players
    4 ]9 D% k% P2 j    m_dwPlayerCount--;</P>
    7 J3 ~# e" [4 e/ f- T5 ^<P>    if( m_dwLogLevel &gt; 0 )$ n5 ~' P% T& ~$ b( D
        {
    ' |" w( \6 ]2 }        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
    , ]- J7 y6 K+ _& O) c3 h        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );* o- K8 p/ T7 i8 o% i+ |
        }</P>
    - ?; ~, B: `, w) k' K<P>    // Find playerdata for this client
    2 d2 o* H/ f# T+ ?  C    PlayerData* pPlayerData = GetPlayerDataForID( id );
    , d! U6 {) e( c" B1 U- f4 a    if( pPlayerData != NULL )$ H( G4 |" Q/ g4 S( D( c
        {* V% t/ e$ Z8 g* C: @. p' m- w! X
            // Destroy it% b6 p+ H, l0 x9 k
            RemovePlayerDataID( pPlayerData );
      ]: Y$ T! N+ @, i* e% ^        DestroyPlayerData( pPlayerData );
      [* H9 z# D. B  N& T5 D" V% p    }</P>
    6 T6 v) ?/ V8 \: `<P>    m_AddRemoveLock.Leave();8 S2 r  }6 j2 ?1 J" P1 @
    }</P>
    % R- @8 C! B; U0 F- p
    , @; h! ]: J  R: l- n) O) x<P>
    7 }: i. l: }* `' o* ]( D: s//-----------------------------------------------------------------------------
    2 J# a2 A( U5 h// Name:
    5 m# U0 Y" M3 K4 T  K( F// Desc:
    % k2 [6 Q" {. ^/ U' U//-----------------------------------------------------------------------------6 g; y3 h/ @: q" B0 H
    HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )) H7 K; y* Q% G$ v
    {
    4 m- }& m4 N/ c/ N    BOOL fFoundSize = FALSE;</P>
    1 q$ O/ v! e; X/ e6 ]<P>    // Increment the number of thread we have in this process.# G/ Q$ b+ Q, |* i& @( K0 G" _
        m_csThreadCountLock.Enter();</P>
      x, ]& ~/ C0 S/ U( `, u1 m2 j<P>    //Get the start time of when we entered the message handler.
      D' ~! u0 h! G3 D    FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>  e" S4 C; D! G3 c; ]
    <P>    m_wActiveThreadCount++;" M; R. o2 D. w1 i/ M. Q
        if(m_wActiveThreadCount &gt; m_wMaxThreadCount)
    3 T" }. I- @2 a/ [$ K        m_wMaxThreadCount = m_wActiveThreadCount;) x% |  N4 q8 @3 H0 M- W# g5 E: U
       
    1 @( Q) {3 m6 K4 @* N    // Calculate and average.+ c' L# g4 V( o4 n! F! X6 J8 x9 X+ A
        FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;1 X' A2 P. h6 L& }% D4 N
        m_fAvgThreadCount += fdiff/32;
    ! ^7 ]$ {  j  n8 B1 L+ F    2 c+ P$ x! G2 {* S0 C# f5 F
        m_csThreadCountLock.Leave();</P>
    - A. O3 V( C# A+ W! u" p5 G  u- a<P>: I) t. B) u2 u: I1 M2 c, f( ^
        ClientPacket* pClientPack = (ClientPacket*)pData;
    2 t: S" O* b+ d+ p9 Y* X    switch( pClientPack-&gt;wType )/ f0 n' T2 U; r" G% O( S: P; g
        {; \0 x* f/ x0 p0 N
            case PACKETTYPE_CLIENT_POS:: V  p! R  W6 c" T) k, l
                7 L: I/ t4 [% O8 q5 G1 Y5 G1 M
                // Check to see if the packet has a valid size. Including , f2 b9 k$ m$ {) J0 ~
                // the custom pack size./ P1 Q8 l6 }& b2 T- A5 k( V
                if( size &lt; sizeof(ClientPosPacket))9 j, H1 E. m! }
                    fFoundSize = FALSE;
    " b1 a3 T" e8 E% {            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))/ m! A. m) o5 B/ p" ^7 w9 J
                    fFoundSize = FALSE;
    5 Y5 M! J9 n" `/ U            else( m% i1 L/ V- O- y3 ]
                    fFoundSize = TRUE;</P>+ Q1 H* F: Q; x9 W" c/ v7 E  R1 M
    <P>            // If valid sized packet, handle the position.
    9 t" f1 d1 K! ~' l% @* `            if(fFoundSize)
    6 U- |( z' ~& p. A: D3 ^                HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );
    ' z8 m% s9 w4 Y9 v            else" f+ N1 n  _% n4 {2 G
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>! t* r; V: @7 }5 l+ Q5 V& `( a
    <P>            break;</P>
    - E: `5 O9 F+ G* I<P>        case PACKETTYPE_CLIENT_VERSION:
    9 e4 t' H" {& ~% ^            if( size == sizeof(ClientVersionPacket) )+ o3 J$ O% |7 v* Y
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );( Q( }5 `, {! C; k# {) y
                else9 P% [+ C  X' f# V
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );( L* E8 m1 s) f
                break;</P>5 S* N' g( i  A
    <P>        case PACKETTYPE_SERVER_CONFIG:</P>
    , t) u! |# ]8 Y% L<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>: J7 h, {/ N; o/ O% y( Q
    <P>            break;- z% ?! r7 [( n$ E" N; V
            default:
    $ b- r# H, r$ ]            HandleUnknownPacket( dwFrom, pClientPack, size );
    + N" ~1 N& k9 T# {6 J- V            break;+ z8 ^+ P2 B- p1 _3 g( h4 I
        }</P>0 M- _3 _& L9 T: d
    <P>    //If the user wants to hold the thread, Sleep for given amount of time.6 U& _4 ~5 E6 D& l" ?( y
        if ( m_dwServerThreadWait &gt; 0 ). o7 @+ F7 c0 N0 W! u# N/ m
        {
    5 }* L" m) g9 N9 j        Sleep( m_dwServerThreadWait );) v6 ?: Y, b' U; [0 b3 p; C
        }
    $ K. n! {+ O6 t   
    . h3 `% `6 K6 m    // Retrieve thread data for this process.
    5 L( c6 ~0 ^/ S# _0 n    m_csThreadCountLock.Enter();</P>- t) P% G! O7 t# U% ~. y: |
    <P>    m_wActiveThreadCount--;</P>" w9 M+ Y$ e" \2 D7 w
    <P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;, e9 T* |7 A* H
        m_fAvgThreadTime += fDiffTime/32;</P>8 D" R6 G. U) J- V5 U1 n! E- Z
    <P>    //Get the Max time in the thread.7 `/ {/ T9 l% E$ t* C6 C& E
        if ( fDiffTime &gt; m_fMaxThreadTime )# G, g! t' s! X3 |
        {& u1 l3 D$ o9 y2 F" u
            m_fMaxThreadTime = fDiffTime;
    : L/ D0 s, G+ _7 W8 U' C    }</P>
    & k5 f/ R$ _( |% t5 `<P>    m_csThreadCountLock.Leave();</P>2 x( N$ M) w8 w# E$ ]6 Q0 [
    <P>    return S_OK;
    0 h! [8 u2 K5 U% a, B0 r}</P>
    1 K! a2 O, k2 a. j
    , y; p9 A5 L! u- ~<P>//-----------------------------------------------------------------------------. N4 G" ?6 s# U% b$ B/ c- C
    // Name:
      Q+ {7 q: F% a6 @' `( A// Desc:
      v, m3 L6 p2 c//-----------------------------------------------------------------------------* A4 x, X& d6 j5 r& K( h: A* [6 Q' i, E
    BOOL CMazeServer::IsValidPackSize( DWORD dwSize )
    " ^5 }$ f& s2 W/ F* D7 ?1 J{  h* e8 J$ L0 u7 M! W; X: I0 |2 [
        BOOL fFoundSize = FALSE;
    : j0 s# P2 \  }/ U6 C    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;
    2 \$ W! x- P" S( t" P    . \, A2 W5 {$ o4 w* E; }
        // Check through the array of valid pack sizes.
    * U' ~6 q" A3 A+ c- f    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    & P0 l9 W) V, y' K    {
    , l8 `2 e- z1 z0 S        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)5 A6 T& G* O3 ~/ ^: L
            {
    . e5 [+ ~- Z% d* x2 W1 K            if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])% n) b. \! c6 V8 W/ M$ t. b: N, i* t
                {
    , Q# e1 e$ Z3 |: ]5 l4 Y                // Found valid size in the array.
    ( e0 r( {) A8 W- \                fFoundSize = TRUE;
    ! t' m5 t! f" `: ?+ a3 q  R                break;0 |+ A6 h0 m! w. [6 R
                }2 t! F# A8 U4 Q
                if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
    , I- Z, G3 \$ S2 N        }" A$ {* U1 l3 ^- y
        }
    + N7 ~- L0 f" k1 x3 X    else& G% n# k6 U/ l0 E: ~- V# J- x
        {0 x/ S: v3 A' L/ G+ ~
            fFoundSize = TRUE;) ^7 _1 y9 F. D) T6 w' ^; l8 r7 D
        }</P>0 v3 c- z3 g! a8 h, ]! N
    <P>    return fFoundSize;0 W# R3 v7 d$ o. X: z
    }</P>
    : z; F& h1 Z6 W: `; y1 \% _<P>
    ' y) i; h8 s+ J% e1 y' T/ g//-----------------------------------------------------------------------------
    % \" A0 f! Q+ m# O2 J8 S& ?: R) a// Name:
    4 t9 v' ~4 K2 Q; ?  ~. N# ~' }$ T// Desc:
    2 U# p+ l9 K! U) `* }' N$ H( {//-----------------------------------------------------------------------------
    ( W& Y) Z6 g' X. Qvoid CMazeServer::OnSessionLost( DWORD dwReason )
    + @" b# S" e% Y. E- E: G# ?" `{) n4 Z& B5 \6 l% f6 R7 ^$ U
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
    5 i5 q7 s' a( X6 Y, {: q( r) w}</P>
      H0 g2 N( F6 F: `4 L+ n" o6 t+ ]' {" O% E0 ]2 X1 ?
    <P>) Z1 f7 c4 l2 O( a5 f+ O+ _2 E5 S& J
    //-----------------------------------------------------------------------------2 j  m0 b) Z' R. a6 f
    // Name: ' d8 w; _) _8 n, _& ~
    // Desc:
    , Q4 c- b7 v4 J; M, E1 s& V! ~//-----------------------------------------------------------------------------
    : B$ Z1 P- w' [PlayerData* CMazeServer::CreatePlayerData()4 _) h/ T- F" P
    {. V5 q# d+ G- G9 K, K' F1 ?* f
        m_PlayerDataListLock.Enter();</P>3 O6 h* ^, a9 j; w6 f6 g0 `
    <P>    // Grab first free player in the list- O, ?! M: P0 S8 y! U$ N2 S' ~" C. b
        PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>/ l6 Q8 A, j* o2 ]
    <P>    if( pPlayerData )8 k; b( y; ?0 ~' o2 Z/ E
        {- D1 `- d  Y% l, ^* g& {! i; ~
            LockPlayerData( pPlayerData );</P>
    ( _8 m% K: K$ F3 z9 j<P>        // Got one, so remove it from the free list* G% u( f) E% ]9 R8 M$ _/ l7 _7 U
            if( pPlayerData-&gt;pPrevious )# e6 c/ {9 F. S$ g: h9 M* d
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    ( K2 M) E' f1 n- M; s+ y( _. n/ `        if( pPlayerData-&gt;pNext )
    ' J5 U4 m+ b: W# G1 {; I: i            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;& `( X5 D* X  e4 `$ J2 n8 ^  Q
            m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>4 D# X; O1 M/ Y- q) O
    <P>        // Add it to the active list4 X5 V* n+ x! F* [: b/ X
            if( m_pFirstActivePlayerData )
    6 ~9 A0 [) A* g" R# U$ B            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
    $ |; v8 I7 R1 |' W1 _& [7 N: U2 O        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;7 {1 Z* p0 `! L% r4 o+ @$ P
            pPlayerData-&gt;pPrevious = NULL;2 j. S- c- T* P# _! |
            m_pFirstActivePlayerData = pPlayerData;</P>
    / _# J6 }: f/ B3 N: ]<P>        // Update count of players% w; P* e. B( l$ r. p* F
            m_dwActivePlayerDataCount++;</P>
    4 S# y7 T6 {( i, V; y- R4 o<P>        // Generate the ID for this player
    : [4 m4 r6 k8 i: @) `3 @1 m        m_dwPlayerDataUniqueValue++;
    / t" c( e4 f+ s$ f  L        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>$ N+ T; W; @" p0 Y9 T9 u$ `
    <P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
    4 ~, P( h. f$ m$ B, M; u        pPlayerData-&gt;NetID = 0;; o& H" E4 L3 ^! c# n  y
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>
    ; b& |& G' Z1 c% T7 u6 {6 ^<P>        // Insert into the "off-map" cell
    5 v2 J1 M2 v) x        pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;
    2 z0 O0 c5 H! q& G+ p8 v        pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;  h; O- q4 F: q$ n
            m_OffMapLock.Enter();
    9 g# L! k7 C- a! M) U- @        pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;) ?& B/ z3 t: }6 Y" ?
            m_OffMapCell.pFirstPlayerData = pPlayerData;9 Z0 }& Z3 Z. F6 W; E
            m_OffMapLock.Leave();</P>
    ( j; `7 _% F4 }) s<P>        // Mark as active- i0 \$ |. ^; b1 s2 z+ k
            pPlayerData-&gt;bActive = TRUE;</P>* t: h, `* d0 n( L
    <P>        UnlockPlayerData( pPlayerData );
    . H; l$ Q) W; X* d    }</P>& s& }" V& u$ E! d3 a* @
    <P>    m_PlayerDataListLock.Leave();</P>% |7 o$ k( l* `8 |, H# I- I. s6 j
    <P>    return pPlayerData;
    - `! \/ ?1 [% ?, e}</P>
    " J- O/ f7 `  n) S  Z) Y
    ) ?5 g+ B# q8 `$ `# E<P>$ [2 O; t% z* A& [
    //-----------------------------------------------------------------------------$ ^$ ?, u9 @1 t$ w7 F# W
    // Name:
    ) J0 ?' S3 [% C" ?// Desc:
    2 z& [- t. S% J* o, O  o' K2 Q//-----------------------------------------------------------------------------. e' g/ x8 X' ^) x9 E+ Z
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )3 Z3 [( T8 t& j, q; ~
    {
    / O; b( A) D% X& o7 I$ d5 A    m_PlayerDataListLock.Enter();
    7 D0 G2 J$ O4 J, F    LockPlayerData( pPlayerData );</P>
    5 W: A+ M0 q1 M- {" s' g<P>    // Remove the player from its cell
    7 q3 W$ O6 d8 D+ b    RemovePlayerDataFromCell( pPlayerData );</P>
    1 \" @4 G" f5 V3 l0 G9 u5 h! A3 u<P>    // Mark as inactive8 ^3 N# v% L+ y& ?0 R4 }' ?  W
        pPlayerData-&gt;bActive = FALSE;</P>5 F7 o1 W( G. j
    <P>    // Remove player from active list' b6 l% T9 v' Y& V, i2 l1 m
        if( pPlayerData-&gt;pPrevious )7 d' c/ H. a% R' w/ ^
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;5 z) ^& s; a9 x8 Y; Q& |
        if( pPlayerData-&gt;pNext ): R' P/ J& ]' U8 u! ?3 U
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>
    # Q6 `1 X) `8 {+ N<P>    if( m_pFirstActivePlayerData == pPlayerData )6 d7 k$ b5 T! G/ b2 S9 C5 H! M# l
            m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>
    4 P& r& C1 x% H! k& g- X2 k<P>    // Add it to the free list- u9 u% d8 L, {' Y! |5 X
        if( m_pFirstFreePlayerData )  Y$ {' N3 T1 w
            m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;) c& g- z' I* \$ n6 b
        pPlayerData-&gt;pNext = m_pFirstFreePlayerData;1 X# H2 t$ W' C% S/ m
        pPlayerData-&gt;pPrevious = NULL;
    " a8 ]: W1 r: q1 ]    m_pFirstFreePlayerData = pPlayerData;</P>
    8 H( H" e& \+ y$ b) q9 n<P>    // Update count of players
    $ \6 p5 D. v# w  Q: ]4 {8 e    m_dwActivePlayerDataCount--;</P>
    / t' q7 x" q5 t& y1 e2 ]$ e<P>    UnlockPlayerData( pPlayerData );5 `' m4 {: x5 K) ^8 B; A$ V1 M8 a
        m_PlayerDataListLock.Leave();
    & x5 \( ^3 ]. O) d) E8 B: ^0 p% y}</P>7 z, k9 H3 I! n9 M  g5 u
    ' h# M4 n( N0 _1 l0 f! i0 Y
    <P>
    # H; i# e! F! r6 W//-----------------------------------------------------------------------------! r2 @+ e. c0 h" y! y* k
    // Name: * M% S/ x" V. R3 ^" x3 ?: u
    // Desc:
    / M3 p( p9 W# N- J//-----------------------------------------------------------------------------* g# p* S8 K4 a) d
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )
    7 l1 q# ^% `  k3 ]/ Q3 E{
    4 q4 b& r3 \  @3 U# E% a    // Lock the player
    ) o# B0 z% b+ T4 R3 ?    LockPlayerData( pPlayerData );</P>
    $ G' V  h9 Y4 Y% n# f<P>    // Lock the cell the player is in( J$ y) ~+ D; p+ m
        ServerCell* pCell;
    , p( C  I9 Q/ n% d8 W2 L8 i    if( pPlayerData-&gt;wCellX == 0xffff ): U5 C' k. ~% k5 A
        {
    7 t) y- R. B2 u8 c% M% K. v        m_OffMapLock.Enter();; w" q( y$ u9 W. W! x
            pCell = &amp;m_OffMapCell;1 f. a/ R* X: \8 ]2 J5 R
        }
    2 a+ w2 x2 l, y: H0 Q) _3 ?    else8 q8 c" k1 p) T7 t
        {+ S5 y' D, F) ^% c" l( N
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );
    # j$ T* S/ j) \3 b) L0 w        pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];1 k/ o" v" I% S2 Z* _  h
        }</P>
    ; R! k2 A' \, s  k$ v# I& O<P>    // Remove it from the cell0 c" a2 T, e+ v+ F  m6 S
        PlayerData* pPt = pCell-&gt;pFirstPlayerData;( e3 \9 H( E3 A; Z2 I- K7 n- w
        PlayerData* pPrev = NULL;
    8 h' s* T( V; p) J  `/ Y. M    while ( pPt )
    " U" p0 ^: a$ W! K- O8 w) V    {$ k+ I" ~( {; Y
            if( pPt == pPlayerData )
    : f9 {4 c$ ^  ]  _" t  E) k1 j        {* p/ U* s# A& D2 q
                if( pPrev )6 e! \. ]$ b8 r8 n& n. M
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    1 Q# T; S2 G" G1 {5 f/ P" l  l" J            else3 K% w7 C2 i! x3 f4 J: i
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>/ @: v. Q' @# C* C* o* t! {$ n
    <P>            pPlayerData-&gt;pNextInCell = NULL;
      C$ a& _0 ~" _+ }            break;, J* o) D* _: U# f$ E+ ~4 Q+ ?
            }* l6 c. Q( N+ A" I; r) d
            pPrev = pPt;0 ~+ f; S) D) }+ O7 p8 p. X2 k" ~" [
            pPt = pPt-&gt;pNextInCell;7 j4 B. T& {  Z8 O
        }</P>" g# R6 W# B( c! ~# h5 O
    <P>    // Unlock the cell
    4 r& {; E8 N; T! D4 d5 m2 m. |: h    if( pPlayerData-&gt;wCellX == 0xffff )! D* R5 a7 p; c+ E, p4 m( h
            m_OffMapLock.Leave();8 S8 n: x  @3 z1 P0 N$ x6 E4 `+ m& a
        else
      O9 G* W: Y, v' |/ L7 G0 K' K7 r        UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>
    + |+ D3 `) f$ C7 O2 K, p5 o<P>    // Unlock the player
    . F5 K: C6 n# n* `; Z1 m, F. y    UnlockPlayerData( pPlayerData );- f& b; N: ^# E( L0 s
    }</P>1 u7 m8 V) [" C$ i
    1 x$ O' U1 W; D+ x( P: E# a
    <P>
    3 b4 j# z5 i# ]5 t//-----------------------------------------------------------------------------0 }. @: Y! l3 ]9 y# j
    // Name:
    ! S/ H) P/ M' }, b// Desc:
    / }& b# W$ Y4 i/ c$ ^1 b//-----------------------------------------------------------------------------1 X% O% l+ O9 v# `& b& `
    void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )- {7 ^, f- V/ b% k* [$ U
    {
    % |0 f. `4 `3 p* A    ServerCell* pCell = GetCell( pPlayerData );1 ?8 M, ^! `% h4 N
        PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
    ) D/ \( v" d! M- z( A2 _5 w1 y0 i    PlayerData* pPrev = NULL;; S; P: h" b* G; h1 \7 L+ |
        while ( pPt )
    % g" i' X& Y6 m0 i9 B* q; `    {
    2 M6 z2 a3 B8 j1 k- M6 [# @        if( pPt == pPlayerData )
    / U8 j/ M4 ]3 Q# S        {
    ! m4 E, f1 s9 P/ O            if( pPrev )
    & G( Q% z2 l+ H" g                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;4 S' H5 p; x6 r7 U, D( j
                else7 ^% Q8 d) ~* d7 V) N
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;) c; H! f! d" y6 ]. G- W8 R" }+ F0 C
                pPlayerData-&gt;pNextInCell = NULL;
    6 [3 @6 ^: {1 n+ b  s" q            break;2 x, [3 b4 k9 a- t9 q8 l" h: r
            }3 V  j  R6 E& r) Y. k
            pPrev = pPt;/ P5 X  U3 ?+ b5 j& k
            pPt = pPt-&gt;pNextInCell;9 ~% H. |7 [6 O2 {* _0 X9 @. f1 d
        }+ s4 W2 ?7 L9 _7 I) q
    }</P>  Z1 w! V+ y5 N2 b; f
    ( v9 }( |) z' g0 U1 n4 f4 y" p
    <P>5 v7 t# e! [& ^  u6 h
    //-----------------------------------------------------------------------------
    $ c) @2 A5 s4 c/ p// Name:
    ( S6 O% H4 {' S# ]' c// Desc:
    * O- W, m  S$ c* }& o//-----------------------------------------------------------------------------% X7 ~7 U. }5 A6 z3 h+ u* `
    void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )
    - X6 f- h/ z9 j3 j{, [+ m: ^2 N: ?2 r. I
        ServerCell* pCell   = GetCell( pPlayerData );
    ; h/ A* T, s/ v) E, ~  y2 k! y    pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;" Q' a+ v5 Q- Q: `6 ^# t: \) D" x
        pCell-&gt;pFirstPlayerData = pPlayerData;; r5 H1 w; c2 V4 c+ Z# I; x: J
    }</P>
    2 K' R2 Q' a1 k: ?$ A6 j
    7 q# b' V3 n- L  r6 U8 d* ~. s<P>$ y  u3 ]4 [4 Y9 ]/ p1 N
    //-----------------------------------------------------------------------------: L( J% C8 D5 t3 x0 [
    // Name: 8 J1 [/ M2 u" e6 h" a3 n4 l5 a
    // Desc:
    8 f" N0 s$ u# n6 m/ C  u' O//-----------------------------------------------------------------------------
    * p8 \% n: C* T: w+ `; \! vvoid CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )' h" A2 ~2 Z# I3 M, u+ j* v
    {
    ) f1 T- X" X+ ^. Z) N    // Grab player for this client and lock it
    $ }, S3 l8 f: S# I" y) s+ a    PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );7 H& p. r7 q; q+ |
        if( pFromPlayer == NULL )5 j( k5 J8 ~' j5 B& ?$ i* x
        {& z1 W; b$ J6 ^/ G3 o2 g: j
            if( m_dwLogLevel &gt; 1 )
    9 j. C; ]$ x. H2 r' J: A7 F4 }            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );! A% F- {9 _1 e; C" }4 L
            return;
    2 a+ C0 K  v$ N1 \    }</P>' n) X1 i& b  F) g% v+ u
    <P>    LockPlayerData( pFromPlayer );</P>
    " O6 A1 R8 U) I6 v, g2 z  g2 n<P>    if( FALSE == pFromPlayer-&gt;bAllow )
    2 c3 P% Y* X! P/ |( {    {, w" z+ p/ {" E" R* M" V0 U* L
            if( m_dwLogLevel &gt; 0 )
    $ \" m, X) |1 ?* v/ M% t            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>, N5 k3 I" X8 [8 y. S
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    ! R: s1 [+ W4 Q& A2 t$ L        UnlockPlayerData( pFromPlayer );
    ! ?1 q$ }) p# z: M        return;! ?, _5 {, x! G
        }</P>7 a; k! {. J  c0 z) Q' N
    <P>    // Compute the cell the player should be in now
    2 K! c1 h' A" c; [    DWORD newcellx = int(pClientPosPack-&gt;fX);; m4 [5 o* a0 F0 Z  G
        DWORD newcelly = int(pClientPosPack-&gt;fY);
    ) y4 k4 S+ S, [/ k6 ~    DWORD oldcellx = pFromPlayer-&gt;wCellX;7 H+ _0 F: A  ~8 q+ \) v* @; E
        DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>+ R& X: w" f$ R3 f2 Y
    <P>    // Have we moved cell?
    6 \( A6 t) d* e. p" D4 ]  O    if( newcellx != oldcellx || newcelly != oldcelly )
    ; J- Q. j$ F- u" K% M; t    {
    5 O' d- D! v4 ^: _* w% `/ w  d  J' j        // Yes, so lock the pair of cells in question! x8 A! l2 D4 x, C& A
            LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>5 X% B6 L1 e* z" o1 l6 e
    <P>        // Remove from old cell and add to new cell
    ' X, _  S1 V+ u2 Y* a; s4 n        UnsafeRemovePlayerDataFromCell( pFromPlayer );
    ( ]" k0 G# t6 J- }! L5 m        pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    # k5 A4 I2 D* U& }  p        UnsafeAddPlayerDataToCell( pFromPlayer );</P>
    & i8 n, v6 x4 Y1 A<P>        // Unlock cells
    - d9 |) X- f5 f# d1 N& R2 }' |        UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );; s: X8 K( ^' T! b
        }</P>
    3 {( E9 f$ ?% M" @, J7 Z) `, ]5 Z  j<P>    // Update player position
    ; B! l' s: l3 O    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;8 m. Y. G0 Z* ~% J
        pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    7 y0 L& g" h/ A4 N9 a    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>! \3 z. |' p# J8 i8 k
    <P>    // Allocate space to build the reply packet, and fill in header + F% {4 q/ G5 [5 Z; _0 x  y- ~
        DWORD dwAllocSize;
    ) S8 I3 I( N% s9 k8 T    ServerAckPacket* pSvrAckPack = NULL;</P>
    ! S9 q3 V  q4 B0 g+ u% h! s<P>    // Begin by allocating a buffer sized according to
    ( g$ _: h! U; Z8 r    // the current number of nearby players + 4.  This will give
    + y/ T2 T2 f# C    // a little room for more players to come 'near' without resize, p- L$ P9 X6 x3 ?
        // the buffer.
    + u  j8 Y& d# y) p% K4 }9 q0 W3 F    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>8 C( b, t! b5 I8 @; l5 m  o
    <P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    ; I& q" f; L+ V/ _5 k- i$ I    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    / G- x4 s6 d& t: u- E. B    if( NULL == pSvrAckPack )" a/ T) z9 a4 d- `0 T  [
        {. T, o  \) f4 H' v0 e: f
            // Out of mem.  Cleanup and return
    " D6 ?+ w8 ]8 z. V' x$ O        UnlockPlayerData( pFromPlayer );' [; U8 ~4 X/ C
            return;       7 c+ X2 x7 b3 K) M, j
        }
    6 D! e1 k9 ~: `8 V1 n2 w" s+ }    ZeroMemory( pSvrAckPack, dwAllocSize );</P>! y( n! i" ~, Q* L/ }  r. F
    <P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);3 [: |# t% L( ]; x: p
        pSvrAckPack-&gt;wPlayerStatePacketCount = 0;
    5 d2 g6 X1 [8 j' n) `' e. ]    PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>
    ) ^3 s: _8 T+ Y. s6 i* j" @3 `1 g6 s<P>    // Compute range of cells we're going to scan for players to send
    # ?$ D& s$ `: c% u& l1 E1 R, Z    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;4 `$ r, R6 w! |1 Y3 i* F9 A$ @
        DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
    # g: O5 f7 Y1 v9 h    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;% @, l' I! p# I0 ~( s! K0 j
        DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>
    - Y6 V- j9 m" \/ \  `<P>    // Lock that range of cells+ y9 O& M/ G; h" _& x. z. S
        LockRange( minx, miny, maxx, maxy );</P>
    ; |6 b, o: V% s; i2 }, L: W' v: s% m<P>    // Scan through the cells, tagging player data onto the end of# [  M2 e$ W, o8 D' `( [) Q
        // our pSvrAckPacket until we run out of room
    " o! T6 R7 h2 i    for( DWORD y = miny; y &lt;= maxy; y++ )+ R0 m! ~) W5 m- U1 x
        {
    + d: h+ Q( D6 B: h        for( DWORD x = minx; x &lt;= maxx; x++ )) W1 l  G, \; Q# ]9 y  g# E5 I
            {
    $ z5 v9 `* v# B9 b9 g" D            PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;/ Z' P( M; g' Z' w/ f
                while ( pCurPlayerData )
    8 k" X8 ?* j3 ~' Z+ h4 T1 g. U            {
    $ `. o  a5 @1 _. h                if( pCurPlayerData != pFromPlayer )
    3 d* `7 a/ I4 \4 \2 X$ e" x                {
    : ^+ c3 p# A- l                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )
    9 G! z1 q% W5 x$ e                    {2 i" q: }# ]# @0 X8 G
                            // Make sure pChunk is where we think it is
    ! |$ A& i7 X4 Q2 m, E                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>
    6 c" B$ B0 F* H<P>                        // There are more than just 4 new nearby players, so resize the
    & U! ?" @4 U+ a' I6 R3 m                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.' q7 N; y" P' l3 M
                            dwMaxPlayerStatePackets += 16;
    , ^/ H* E4 \' j; _2 V% T2 l                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);, S2 d  C( x7 W' d0 w3 z
                            ServerAckPacket* pNewSvrAckPack = NULL;, {* F6 q7 u' K$ h; b
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    4 _% r7 x+ f" @& o- U                        if( NULL == pNewSvrAckPack )
    * N0 |" D4 W- F* Y- s4 \( G                        {
    : A' N) ]" d" M/ `. N                            // Out of mem.  Cleanup and return/ b% t; y6 t4 A& t4 x
                                free( pSvrAckPack );% z7 m1 z% s& z- X. h$ F
                                UnlockRange( minx, miny, maxx, maxy );. g& R2 F& K9 j
                                UnlockPlayerData( pFromPlayer );
    % a7 f  A4 c6 h                            return;       ; Y6 Q/ I. L7 C
                            }</P>1 U0 F$ |% ]' t5 j) a0 j( [
    <P>                        pSvrAckPack = pNewSvrAckPack;% k5 _6 H7 Q5 A$ p- [! J
                            pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
    : S. q# t* d5 _8 r+ N2 b; k<P>                        // Make sure pChunk is still where its supposed to be
    2 a  E4 ^, [$ a% S% e9 a7 \                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );! d" r9 U0 `5 h) R" r; `4 V  ~! K- w
                        }</P># q6 Z, H; U& h& p- k, M
    <P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;+ n$ A0 Y/ f  P
                        pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;& G+ Z( `/ {8 g5 b0 V, {5 T
                        pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;
    ! @7 M4 U9 O0 S9 u                    pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;# w: g0 g$ E( D3 s; D
                        pChunk++;
    6 H4 [& E6 g. s. M5 P                    pSvrAckPack-&gt;wPlayerStatePacketCount++;
    ! M$ h3 p7 }0 q$ t7 v6 V                }
    " ?( u: f' P* q6 h) O                pCurPlayerData = pCurPlayerData-&gt;pNextInCell;$ Z+ |6 \3 A- Z8 ^) |4 P7 M
                }
    2 S/ f$ _" X2 [% V9 M7 V: Z" c% l        }
    ' G5 z1 A0 A6 f9 J' y* N    }</P>- E  j4 H/ s. H# D' y4 q" [/ {
    <P>    // Update the dwNumNearbyPlayers for this player+ _* g# x6 L# V. m" {( K+ D
        pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>
    - {; {. q9 c( H( b- q: r/ X<P>    // Unlock range of cells
    4 [* y2 N* D. v3 J5 U0 M, \" a4 g, X) y; c    UnlockRange( minx, miny, maxx, maxy );</P>- L9 f% a* O' D2 j
    <P>    if( m_dwLogLevel &gt; 2 )
    / C/ ?7 k/ G; p8 o' k' o/ U' A    {8 J% R% L8 a; b: s
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    4 n- I$ K3 ?1 P. P+ b1 p, r) w4 E    }8 p8 h; q9 R2 W
        else if( m_dwLogLevel == 2 ). {) u7 |2 i; e5 G/ a0 s- s, U
        {9 t- y3 R" _! m8 I0 W" f
            FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    : j+ C$ B0 z3 b! K: u        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )
    - z1 ~8 |& f  O1 ?7 f) z        {
    . u( @! }; {( `- u% [& O- Q4 R6 \6 H            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );. p4 j0 S' B4 g" \$ T
                pFromPlayer-&gt;fLastDisplayTime = fTime;6 b: e/ v. }: p5 R
            }
    + E  d- n' N! r9 D: {% a% l' y) |) T    }</P>4 l" B6 a% d% J) C. r& H1 S
    <P>    // Unlock the playerdata
    0 b) C/ x; }7 S- R- D; f    UnlockPlayerData( pFromPlayer );</P>
    + x  C1 q5 C5 R1 ?" L2 X<P>    // Send acknowledgement back to client, including list of nearby players
    ' b) c8 K) G4 m5 }4 t, L    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));
    $ N* C9 c6 A) |; {7 c; t
    * ^3 L' v9 P; H' L, s6 ^1 {    // Pack the buffer with dummy data.+ f! }% ?& y. E' V- J
        if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)
    8 w  u7 |, g: q6 H    {* ^, P2 q& |( j$ I' I' }
            DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];9 F; N( g8 g& J
            VOID*   pTempBuffer = 0;</P>) e7 Q4 t8 x/ u
    <P>        pTempBuffer = malloc(dwBufferSize);
    6 l; o4 _# h! s8 U        if( NULL == pTempBuffer )
    4 Z, h6 w  F; v5 e        {' a" g) V+ r9 K4 P# V
                //Out of memory* V4 b, C( K9 h3 _
                DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
      s. \6 |6 ^! B$ d# ~; Y            free( pSvrAckPack );4 A  G$ M: c2 T
                return;; V8 m/ l+ W$ W9 P. y
            }</P>$ s  G( r9 l- F( v# b
    <P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');# M; J! [& g9 }$ G1 w
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>
    ! g. K/ l/ X# N: q6 I6 e. d<P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );$ U& {  f7 C7 |' L6 A6 H+ o* m% k
       
      n  j1 r* T! S, y* D9 Z        free(pTempBuffer);
    " l% h8 X# T- Y1 R    }   
    # q, ]: d8 o* q5 T& C! I9 H# a    else
    ; }9 M$ z4 K( F! D    {
    ; n, i. j/ k. B* P5 j  j        SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );7 A% h- t  f5 ?$ ~7 k0 B& D! g8 e
        }</P>
    5 Y, y$ f  _5 D, C# |<P>    free( pSvrAckPack );</P>, w9 j8 r; s$ k# m! X  o# t
    <P>}</P>
    5 I1 f* M) F+ @( _: a; p4 Y; @2 k+ {
    ! E) o9 b4 ?6 O0 r% `<P>
    9 y" ^5 H' ^' }2 M8 d# T" ~; u0 q, r//-----------------------------------------------------------------------------0 Q  Z/ G, `% A+ V  ?
    // Name: 5 p, Y( m  C# Z) Q( d
    // Desc: ; _& |, g' R6 {& m" T& y& I" ~* p
    //-----------------------------------------------------------------------------0 b; v9 n4 T% T; W/ w1 X- _
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
    . B( |; J6 l1 o! a{6 C9 ^! P/ }+ u7 t) F; E
        // Grab playerdata for this client and lock it
    0 ^2 F: L/ Q/ b    PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
    5 l) r, g( G! v2 r    if( pPlayerData == NULL ), s# i8 p- v3 o: B
            return;
    ( n- z# q$ C# l8 j    LockPlayerData( pPlayerData );</P>9 T4 h% u/ O8 Y2 n, y& }' d8 o! k
    <P>    // Record the version number ) C: R. K  h  P) ~2 W  J
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P># D: Y% `5 r# H# c' [) X
    <P>    if( m_bLocalLoopback )
    - W8 C6 Y( k( a$ A  n" g# g+ n* V2 M        pPlayerData-&gt;bAllow = TRUE;% Y8 l2 G: d& J
        else
    - K' [) c# z1 q        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>2 j. `; _! z7 t1 ~% J7 ]- r
    <P>    if( m_dwLogLevel &gt; 0 ), A3 H: Y+ P! H% z* C
            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>
    ) G7 \1 T: D4 t6 ?! T2 |" N<P>    if( FALSE == pPlayerData-&gt;bAllow )
    * x- ^, |  W; O1 T# g    {
    0 _; ?9 I4 z4 M8 B        if( m_dwLogLevel &gt; 0 )
    ; a7 f0 @+ k% D  g5 r# [0 K- T1 {            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>
    ' m1 f6 d! c8 ?  p<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    & U- P+ r/ s- R, ~: u9 f        UnlockPlayerData( pPlayerData );6 c% G$ j1 C3 t
            return;
    0 c: F  X6 B2 ^' \! X    }</P>
    $ y  O0 P5 V8 [# S8 P" S' F0 R6 ]<P>    // Unlock the playerdata
    ( p* ~8 l+ b* [% q/ j0 z$ N    UnlockPlayerData( pPlayerData );</P>! G$ v( r2 C7 \$ y8 [
    <P>    // Send acknowledgement to client that the client was either accepted or rejected6 T6 y4 Q, ^0 \
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );9 h+ a: s- K0 r& i
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );/ X6 C( r3 _( W8 ^5 z
    }</P>* s# {! K3 S! J+ h

    9 q& E5 w8 g$ C<P>* q' j: u9 g  d# c
    //-----------------------------------------------------------------------------
    , l( p. S/ \) U4 `1 M% z! Q0 A& \// Name: 9 I2 [9 j% P1 j* k6 M6 j7 y$ S. d
    // Desc: 0 H1 {0 {8 C6 E/ [2 t5 s# C
    //-----------------------------------------------------------------------------' ]2 B+ u: v" D  t- l
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )9 V4 X5 Y  p7 A8 S; O% d+ ]. ]2 ~
    {
    ; M5 Z# J1 ]+ d6 G1 h# G! D$ s    switch( dwClientVersion )/ j3 y6 X( D- `! i5 T4 G
        {- Y8 Q* `3 Z3 w+ n
            case 107: // only v107 is supported
    7 w) `- Q& t% g. B            return TRUE;
    $ f; f2 ]+ h  ]" q( r: Q        default:
    " ]0 Y: W+ h4 h1 S2 s. z) S            return FALSE;/ z0 u( y3 l# H/ K/ A! q5 L& r
        }
    : ~% a* }! W' u, P) ~# D}</P>/ J8 A1 V: ~' `" P) @6 V

    : f7 w1 `2 r* Z<P>9 \1 W3 l7 o+ H, e' z! q
    //-----------------------------------------------------------------------------5 }4 T- i  |  P5 {5 i9 {
    // Name: 6 y+ m  B4 {0 }' t4 u1 x& y
    // Desc:
    , V8 z$ `. O% ]7 c3 l( N* S0 Z//-----------------------------------------------------------------------------. u4 I* b$ N( P+ n/ E$ [) Q9 v3 q7 b
    void CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )) q$ c/ q6 i4 @5 T: Y$ J' _
    {
    9 r; `+ J( m# P, X3 Z    if( m_dwLogLevel &gt; 1 )& G0 e+ z* j+ Q8 r! C
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>9 g7 k7 E  J: w7 g* ]- {
    <P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );9 ^, h. ?6 F9 }7 g
    }</P>
    7 \& x6 e7 ^$ j7 |1 k; ^5 B* Y3 ^1 `, w( n4 H/ i7 [
    <P>
    5 J  m! l1 W* h2 |3 Z//-----------------------------------------------------------------------------
    4 Q3 U: s' c: y& d* C( m// Name: : i& ^/ `. c/ e' O2 v
    // Desc: * Z! W) u/ ^* U) \$ |8 [
    //-----------------------------------------------------------------------------
    3 h3 D! f6 |1 fDWORD   CMazeServer::IDHash( DWORD id )8 V" m$ V" M4 {) N& F
    {* D9 m; r5 s, t% M- ^* o; P
        DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);6 R* j0 ]' T" e& g2 x7 k1 a# P+ W8 ~
        return hash;
    , D$ l1 T: X' V3 O' g}</P>! g: B; B8 b$ t7 k  k& q# g

    ( b6 J4 C+ O7 g$ K9 j7 k<P>
    * o3 ~/ q& g2 j4 g6 ~1 o//-----------------------------------------------------------------------------
    & W. ~4 F4 y" E// Name:
    2 P  W1 O+ S. H. ^1 z& @" N% _& c// Desc:
    , O) Z) B9 X5 V9 M8 b6 r7 k//-----------------------------------------------------------------------------+ R. v/ W, \8 \$ o5 Z- x; P
    void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
    & \7 |. l; U& }7 p* C5 z{
    7 L& W5 ^. n% Q: \& P, `+ {/ B    // Hash the ID to a bucket number4 g! x9 j# ^% Y1 }9 J
        DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>4 K3 a3 }) n8 G7 m  y
    <P>    // Lock that hash bucket' b  X" j8 b+ G0 A  h  \
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    % V0 R/ q% J6 l. C- b& j4 ~    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    & X  `% r, e& n+ e; N4 h* {2 K<P>    // Loop though players in bucket until we find the right one! A! w) l. A" r' i! G8 p1 w8 x
        PlayerData* pPt = m_pstIDHashBucket[bucket];
    ( Y& \% a) S, {+ n8 g    PlayerData* pPrev = NULL;
    ( n" d8 J7 J' c    while( pPt )/ B1 l. F" V+ s3 S1 }! a
        {
    ) y2 r8 x7 H; L# t  H+ p% {) y8 m. d        if( pPt == pPlayerData )
    & Q3 }2 M" C3 g* Y8 U; N            break;
    + \, f4 F  A* k        pPrev = pPt;
    " l- Q2 s2 }2 @4 Q. q0 ^/ y        pPt = pPt-&gt;pNextInIDHashBucket;* x  J! u: J6 H* |& F
        }</P>
    - y* R. m( ]( J  a<P>    if( pPt )6 U4 v' A) ]1 }1 i! e; a
        {
    " ]( S# t6 V$ F/ o0 g9 s* @8 l: N        if( pPrev )8 s. c% _  x" {) x
                pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;
    3 U* d: r* Y  X+ l  r        else' e2 u- M) \4 h. C) [
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;. U/ i! P, B& t4 _$ E7 ]/ W: z( t' ^
            pPt-&gt;pNextInIDHashBucket = NULL;. \/ t5 Y( T! `! {  N: J
        }</P>; m  I5 N- g. q. L' R8 H
    <P>    // Unlock the hash bucket
    % W! S5 J. f" d, [  C- N( K    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();' ?' S7 Z- W$ V( @% M" o8 C1 {
    }</P>' A- F: B6 B; o5 I' Z# E

    * B2 U( ^8 o7 t<P>% z6 ^$ a. ?9 F
    //-----------------------------------------------------------------------------
    0 c$ [+ N' Y* O// Name: + m0 `4 T, `5 B& a  O1 R
    // Desc:   Y3 p& x3 Y: I0 i# J
    //-----------------------------------------------------------------------------) ~4 `7 J7 k/ ]! w+ B
    void CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
    ! D& b2 T+ D* Y* V5 f. d7 G% E{( K  _) y  p; V+ @- O! p2 \
        // Make sure this player isn't added twice to the m_pstIDHashBucket[]" T8 T, w+ H" g& e* a# D
        // otherwise there will be a circular reference
    # U( b: d" P( d  ^4 O" j8 ]2 S( I7 H    PlayerData* pSearch = GetPlayerDataForID( id );
    5 J  m. ~( O% C5 O5 K# u    if( pSearch != NULL )8 Z3 @' m( K  s: i$ Y4 `) m
            return;</P>
    ' m0 A  @( b( E; H8 X<P>    // Hash the ID to a bucket number) Q; q( [" @* _- V+ q
        DWORD   bucket = IDHash( id );</P>
      Z( d  ?: i% N* K<P>    // Lock that hash bucket+ Y' t+ _& ]2 G# h: k
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    9 T. U8 I  N! ~    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    4 O* F) w% M8 O9 m+ k<P>    // Add player onto hash bucket chain
    - x, p) u$ _% h; s* P- x2 b! D! o! H    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];* E# c: G6 {5 W1 l: u! K/ {
        m_pstIDHashBucket[bucket] = pPlayerData;</P>
    6 p  t1 E/ I: r<P>    // Store net id in player
    # j1 R1 l! l9 _& N, t, J! M# T    pPlayerData-&gt;NetID = id;</P>
    3 H5 c5 E/ Q' V, J<P>    // Unlock the hash bucket' n0 L8 Z) c% {* v5 h; E( D( C
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();& ?8 H$ K' _; ]8 O% a
    }</P>, u6 x! h+ {$ J+ B: c, X+ M
    : i4 {1 z+ U6 {. l) M, @
    <P>  U. p; }8 w; B6 h
    //-----------------------------------------------------------------------------
    % k0 N9 `+ o  y  s2 H# B// Name:
    3 Z& w8 b4 k7 Z5 h5 a// Desc:
    , b. h) Z8 z+ g5 J+ \5 X/ V//-----------------------------------------------------------------------------9 F) Q+ Z/ c# E4 S* m, B3 ]4 N$ N
    PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )4 h0 }6 C* `, ^7 l
    {/ r4 s8 {8 `1 x" q- y; Y) k+ x
        // Hash the ID to a bucket number
    # Z; m" x8 q% s5 A    DWORD   bucket = IDHash( id );</P>/ ?3 l( U8 ^$ r/ E' W. g
    <P>    // Lock that hash bucket
    : ?) ]' R- ], Y5 r4 f* I    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    1 v5 C" Y& [) x: |* K    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>& W7 S, O& x) L4 n
    <P>    // Loop though players in bucket until we find the right one
    " h! `' u7 S8 ~: a& d    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    8 A' r5 S$ d8 X. b    while ( pPlayerData )
    7 w3 ^- v* |8 P! h9 a    {
    5 d: k. K6 g, s8 }$ M- N: Q        if( pPlayerData-&gt;NetID == id )
    3 y( }6 G. [) q* U+ q9 f9 y            break;0 u* |, n1 D" p6 ^( Q
            pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    ! }/ N2 x" P5 x    }</P>
    ' L% a  ~2 _" E0 B/ Q<P>    // Unlock the hash bucket
    7 ~2 B3 V' X1 k- g    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>1 L* v7 |6 j( t9 t: K0 D$ h4 {
    <P>    // Return the player we found (will be NULL if we couldn't find it)
    - i4 P/ L' U9 T, D( k; o; J6 K+ Y; h    return pPlayerData;6 R% f& d9 S  x# B
    }</P>, ~7 J, Z/ G  p0 s& z

    , `; N" y# C7 M* P8 ]- u<P>* @( H+ G1 V& X
    //-----------------------------------------------------------------------------2 V1 M. h- G& a/ \/ ?, a0 m$ N* {
    // Name:
    ) I  o3 F  `# H0 `/ e+ p// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner
    4 P/ Y) _( t* [) S* S& E: J& u//-----------------------------------------------------------------------------6 F$ r9 @# p. T
    void CMazeServer:isplayNextConnectionInfo(): `6 |9 @$ ]0 I2 D
    {7 k+ O5 Q3 u, _6 D6 v
        if( m_pNet )
    0 O3 ]9 a; A+ E# M9 d/ Z$ ]  y    {
    ; n3 R9 v) e' U$ r& s4 d3 x1 ]; j! v        // Find the player that was displayed the longest time ago, and display it.- E  y  I  q  M$ S7 N& N
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );  W4 ~" C$ ]; k4 Q) l$ i
            PlayerData* pOldestPlayerData = NULL;
      ~2 q! W2 K+ a4 d) ?) k2 ]        FLOAT fOldestTime = 0.0f;</P>! z( A' N: r' Q% a, ^6 R- C5 ~
    <P>        m_PlayerDataListLock.Enter();</P>
    . b1 r! G6 d$ `$ O; \+ o( ?<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;2 x4 j0 z% G! I6 K4 n
            while ( pPlayerData )3 r$ [, [* z5 {  V5 N: ^7 ~
            {
    * \. \. i# q% {+ M5 u( O            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )1 v6 {9 h5 ^! u( t% k: t* w
                {
    2 p7 I" ^7 N1 M5 j                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;
    7 D3 [$ r- R8 C# N  W- r" p                pOldestPlayerData = pPlayerData;& d; x4 D$ a, T* z3 `% f( g
                }</P>9 U1 }& R, t: i/ U% \
    <P>            pPlayerData = pPlayerData-&gt;pNext;
      z( m! w0 i& c        }</P>/ U7 n4 G0 e6 \% m, h3 [( m7 L
    <P>        // Display the player with the oldest CI field, and update its CI field.
    . D( @' |8 `- G1 M7 t& A        if( pOldestPlayerData )! f  ?8 `' @1 Z4 L) J
            {
    / H$ |& K- Y6 X5 Q            ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
    " V, i8 [5 C9 a1 I3 X% n            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
    ; S! r) @- H$ O% V            pOldestPlayerData-&gt;fLastCITime = fCurTime;
    " X7 [" C, K0 |" H  J% m9 J        }
    , i7 l( @1 _; W# n; N  C9 q        else* E- l/ d/ V9 Y1 Q
            {
    ' ~, {4 r2 h' [2 c" y9 Q            ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    9 {8 o0 ^( R: d: B& ~        }</P>' B. v7 p9 h  f5 }% M1 V" d7 l- Y
    <P>        m_PlayerDataListLock.Leave();
    " `. c3 a' O8 d0 f    }. d. b$ A" n$ |  Q- X7 H3 a; P
    }</P>$ R# ?6 Z. \# L7 o1 e) O/ K

    0 Z& n- K8 G& _0 |' V/ B5 R1 u<P>
    ) I" G, ~- S+ Q5 L//-----------------------------------------------------------------------------: `4 J) r9 W- n$ x: |8 u
    // Name: 0 \; m4 k! S; L& o3 j8 D7 ^+ s
    // Desc:
    % e& y/ [! j2 C0 b. s% _//-----------------------------------------------------------------------------, p+ ]( s! Y( R# w. m  G' y  `
    void CMazeServer:rintStats(). r4 i% ~  v, b2 ]6 ~
    {
      {) o  K  t* ]- e  M$ |' a    ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"), 2 R* ^2 }- K# J- F! }& g2 ?
                                        m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );
    & `( n) \0 H& Q7 q! m    ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
    9 ?1 [( i  N5 O7 l) x                                    m_fAvgThreadTime, m_fMaxThreadTime );- V% B" P! r! q- x* ^8 [
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );$ z+ q1 `, z8 N, H' a6 F( ^( x( y
        ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );9 K- ^2 V7 Q2 I
    }</P>2 \* Q) G1 E" t

    6 D4 R# `8 k4 g& ^; N<P>
    ' m: b- @/ ]4 v- j4 U7 G//-----------------------------------------------------------------------------
    " ]% l2 b) i1 a, R' Z// Name: - _' m1 T8 O9 V* D: a' W
    // Desc:
    . A: `5 T$ J! V7 i: u4 \, |8 g' I2 R//-----------------------------------------------------------------------------
    , K. y) |8 E6 Ivoid CMazeServer:isplayConnectionInfo( DWORD dwID ): J" y8 h/ Z* K- w9 N& Y- T& r! x2 H
    {" b' m/ t& U; y+ T3 \1 w
        TCHAR strInfo[5000];
    / U5 E9 g+ m) @" p2 f* T    TCHAR* strEndOfLine;2 t9 c9 t. A, R
        TCHAR* strStartOfLine;</P>* I9 X) l' N0 g
    <P>    // Query the IOutboudNet for info about the connection to this user
    4 Q% K4 \+ g: e4 z    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>; ], Z9 u) J1 N
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );
    7 X2 }+ o; g* r8 K# ?    ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    * g" m6 C% q# \<P>    // Display each line seperately
    2 ]- ~0 E- U( X( Z$ t9 T6 u    strStartOfLine = strInfo;
    7 }! S3 J7 ]) W3 ?( Q/ g: Q& q    while( TRUE )
    3 C1 _  ?/ C! _! Z9 w8 p    {
    . U" {* Y/ k& C6 C  [        strEndOfLine = _tcschr( strStartOfLine, '\n' );
    & _% a+ P2 y8 d% W, w6 X7 F        if( strEndOfLine == NULL )9 x$ u0 m7 g! f) p" H# b2 w
                break;</P># [# |7 k; F1 t! s+ @! g+ R, E# K1 h
    <P>        *strEndOfLine = 0;  D: l1 C( b9 u4 i: Y
            ConsolePrintf( SLINE_LOG, strStartOfLine );
    4 C+ p1 a& s- Y/ w% @1 Y        strStartOfLine = strEndOfLine + 1;
    4 m3 x5 s0 f1 @2 T' d    }
    ) ^4 ~8 C+ P0 ~* N: o) O}</P>* c) x- Z0 V; a- q0 L" L+ V

    & b% L& X! I5 b<P>
    8 t; k! n  }) Q' f# e//-----------------------------------------------------------------------------
    " s6 n) O2 r; O/ \- F1 H// Name:
    : ]3 _+ A2 U4 }. B# ]2 R/ R// Desc:
    ( J% E; F* v0 R3 J+ M5 Y* k+ h# v//-----------------------------------------------------------------------------. j5 F0 P' Q0 L1 o+ c
    HRESULT CMazeServer::SendPacket( DWORD to, void* pData, 4 K* l! L& y! o8 M$ j# ?9 Y" A
                                     DWORD size, BOOL reliable, DWORD dwTimeout )9 `2 ^  @; m  V" c+ |
    {
    , @- m6 _) ^* z3 E    // Chance of forcing any packet to be delivered reliably
    " \" x+ B! M0 ?* E    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate ), n- x  U: l( ^) w+ A. ~
            reliable = TRUE;</P>
    3 h$ i2 ~- S. B; `<P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    . t+ U. s9 P5 D# e}</P>
    , O: n1 {6 P5 @% h& i/ J- `" N1 m6 T. R9 H
    <P>
    - q8 c8 ^4 m1 K0 g! `$ M//-----------------------------------------------------------------------------3 b4 L* D! P) n2 u! T  A
    // Name:
      m# O' T( L% |) L: q& B// Desc: * ^/ z3 K9 p1 L! k# V- F
    //-----------------------------------------------------------------------------; E6 m0 Z5 I7 V! Q$ @
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )/ \6 l/ R9 a: e# Y  f" b9 `2 i
    {! Y5 j2 d3 }! a" ]+ i- `
        // If we're up and running, then send this new information to all clients& Q" o0 Z8 {& [* i1 m. J
        if( m_pNet )/ b* C) }+ M( m# v& A% l
        {6 W$ @( a$ L0 H- |
            //Use the AllPlayers ID" o8 E$ A, O0 i
            SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );
    7 |0 a$ r" @' f' [    }
    4 a, B8 w, o0 ~! @4 b7 \% U}</P>
    * Q/ x) o' E" l3 X; S; J3 h( Z# w  }: @: M7 ~
    <P>
    - ]' Y4 r% C5 p//-----------------------------------------------------------------------------& n# e4 M$ R, C( @8 B9 ]+ [7 ]) g
    // Name: ( T' L8 C5 T9 x. x+ E
    // Desc: - i$ k. E! ?3 U
    //-----------------------------------------------------------------------------: A" L5 G" E$ L& l- s7 b$ h
    void CMazeServer::SetClientReliableRate( DWORD percent )
      G; m4 j! l1 k2 ]{8 P$ R, O$ s2 E% L. _# g8 M
        // Update client config, and build packet containing that data
    , ]0 N9 x( w) K* _; |    m_ClientNetConfigLock.Enter();
    1 f+ R& _* O3 @; c/ g* q( V    m_ClientNetConfig.ubReliableRate = BYTE(percent);, o: @7 G" C4 w0 |$ U: P& Z
        ServerConfigPacket packet( m_ClientNetConfig );# l5 `' {% o6 |1 s4 Z- c. l2 m' B
        m_ClientNetConfigLock.Leave();</P>/ S% ?9 D7 l- B! }2 M4 U
    <P>    SendConfigPacketToAll( &amp;packet );
    " q6 P/ C: @4 W- K. W) N}</P>
    . _* \9 T' ~: i' q# H( P( f$ d8 U" e+ e$ W( c
    <P>
    : e1 j" u! L  L6 y7 ]5 e//-----------------------------------------------------------------------------
    , P% ^$ Q; F9 l// Name: / m+ X/ g6 W* N! ~4 i9 v
    // Desc:
    8 B+ o& F1 Z4 l//-----------------------------------------------------------------------------
    * k# k5 h7 S6 w5 o# hvoid CMazeServer::SetClientUpdateRate( DWORD rate )# ^/ ?+ _' G+ k' v* e
    {
    0 N) C" M  a2 i# ?    // Update client config, and build packet containing that data
    & ?% I# U7 M2 L; ]    m_ClientNetConfigLock.Enter();
    - Y6 y% ?; G" N! m- G    m_ClientNetConfig.wUpdateRate = WORD(rate);+ B+ X# Q3 J5 r
        ServerConfigPacket  packet( m_ClientNetConfig );' N4 n6 N$ S) Y2 l# h! N4 D
        m_ClientNetConfigLock.Leave();</P>6 Y9 |0 Y9 _5 {2 C1 k2 f
    <P>    SendConfigPacketToAll( &amp;packet );+ l/ b( B8 i+ N8 c
    }</P>4 U  Z& X" G1 t$ C
    ! }3 _" B/ X! U6 i$ t# H+ Y
    <P>
    0 h5 M# m0 {% s8 H/ w9 G% K9 {- d//-----------------------------------------------------------------------------
      L: A; r3 F6 _" X1 a// Name:
    2 i& R% B$ t% j9 z5 N% s; n/ @// Desc:
    + R9 P% \3 z: R; ]//-----------------------------------------------------------------------------
    5 p& t% R8 I( [: ?' X3 f, Xvoid CMazeServer::SetClientTimeout( DWORD timeout )
    7 l: N1 w/ I) i( Q0 B{3 X% k: V$ t. j' r7 w2 W% Y( R2 Y
        // Update client config, and build packet containing that data5 k7 @) m/ H, c$ u
        m_ClientNetConfigLock.Enter();
    % _7 K% U6 Y) R$ C% n& c/ T6 Z    m_ClientNetConfig.wTimeout = WORD(timeout);
    " T7 R$ E/ ~! x" Z* }    ServerConfigPacket  packet( m_ClientNetConfig );. n: k9 w. A1 U( \% s, d1 @! `; a8 y
        m_ClientNetConfigLock.Leave();</P>% i* D' o  q+ T( s0 q* {7 K4 Q
    <P>    SendConfigPacketToAll( &amp;packet );
    " R4 c% w4 A, o6 m: u$ d7 Z}</P>" r; F0 M( y" J! e

    * c! D& }4 b( P5 I) M) h/ l. P<P>
    * ~6 y: s( ~: U//-----------------------------------------------------------------------------
    : ?* f& E/ G, Q; P* j, i: K// Name: " z- K1 j% a2 D, b# P1 ]
    // Desc: # i  S2 C6 q- Q8 A: q& N, r9 i7 J
    //-----------------------------------------------------------------------------
    , |9 J$ \* m( l! Vvoid CMazeServer::SetClientPackSize( DWORD size )
    ) n, p* c' v" r, m{
      C  f% o! K/ l    // Update client config, and build packet containing that data
    2 ~: X2 Y7 V8 i( c/ F  |    m_ClientNetConfigLock.Enter();
    . F9 y5 S1 o% F  V1 K    & |6 r  k! y1 w) G# Q9 H8 q
        m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.) F1 v) V) ^! ?6 U& H. \
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   
    . x/ r3 i7 J! g/ s- G        m_ClientNetConfig.ubClientPackIndex = 0;</P>5 X) T& O& ?% @$ N7 Y/ N/ `) c' ^
    <P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);
    . K: b( x7 v$ V6 |+ s5 u    ServerConfigPacket packet( m_ClientNetConfig );
    ' f% }: G# C7 e) ~; L4 I* q( ]( Q) V    m_ClientNetConfigLock.Leave();</P>
    & U5 V, Y- {3 W; @0 ]<P>    SendConfigPacketToAll( &amp;packet );5 t- K0 M! ^4 ~  O% f: @7 k
    }</P>
    2 G8 [' R5 k$ |% L8 Q7 s
    0 L  j! w; }; J( b: _; Q3 F<P>" f0 O# M% B2 A9 J9 W
    //-----------------------------------------------------------------------------; J; n2 E7 q' s: o8 @
    // Name: , h+ i, j; G& U% f+ P
    // Desc: " I" |; _, b: ^
    //-----------------------------------------------------------------------------$ }5 Z' f8 I; I
    void CMazeServer::SetServerPackSize( DWORD size )
    9 o; `% o+ W7 t# u{
    # h- U1 j- K/ {& t2 X/ l    // Update client config, and build packet containing that data
    % D2 P' S- _9 p6 \5 x0 I    m_ClientNetConfigLock.Enter();
    % d" r6 @1 z2 x      i8 ]% w4 z- z8 m
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.
    6 _- M$ N( c$ K: s) V2 D& ]0 b) P5 b    if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   ' a1 G/ W' C, g  ~0 z1 \" O) p& v
            m_ClientNetConfig.ubServerPackIndex = 0;</P>: S* f. @! ?2 `9 l* @9 G
    <P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
    : |' F- b' S7 G    ServerConfigPacket packet( m_ClientNetConfig );
    , L* L% H- W8 ~3 }9 A6 X    m_ClientNetConfigLock.Leave();</P>
    % [4 v* ?- {3 P# ]<P>    SendConfigPacketToAll( &amp;packet );
    ; e5 X* R  z" Z# k' \4 v; w$ V' o}</P>
    $ z+ w5 o3 b) P<P>2 N+ k% o- q! D! G5 _; s$ Q3 ~  w8 t
    //-----------------------------------------------------------------------------
    * D) \" K  P6 l* O2 `7 w7 C+ j- `// Name:
    / G1 g3 y* h6 W: m$ F8 y// Desc: 3 S3 G! s) T: R$ k# }8 N
    //-----------------------------------------------------------------------------
    2 w, v  k5 m( Xvoid CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
    1 v9 _$ S9 p' f! L9 q{
    ( e! E$ k& O! N1 ~    // Update client config, and build packet containing that data6 z; E3 c' K. r- \7 z7 h
        m_ClientNetConfigLock.Enter();
    8 z/ p, `* }; A* s) n, l! z$ p5 ^- y. S    / _4 n* ^: f' z- Q
        m_ClientNetConfig.dwThreadWait = dwThreadWait;
    1 ~. d% h" J9 X- p; Q    ServerConfigPacket packet( m_ClientNetConfig );
    ! F5 U- z! x- ~5 A    m_ClientNetConfigLock.Leave();</P>, K# U! I, T2 G7 p, V
    <P>    SendConfigPacketToAll( &amp;packet );
    3 `8 @5 F. w, l0 q# |3 U8 M' R# P0 }/ j}</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 20:58 , Processed in 0.448122 second(s), 51 queries .

    回顶部