QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3845|回复: 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>8 n, r2 t( l8 Q) X+ y+ W
    <>// File: mazeserver.cpp* C" M! n" J5 n' n
    //
    5 h: B) c+ n% {" e4 x! x- \// Desc: see main.cpp6 M" L/ v# V' C, q
    //( Y$ S1 D- w" {/ p$ Y
    // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
    ! N  o) ^( B+ {, ]: X//-----------------------------------------------------------------------------
    1 S5 f& H9 V! o3 ~! J#define STRICT5 f3 K, Y" X9 O% Z! Q$ d2 b
    #define D3D_OVERLOADS+ H* M/ W/ M) i4 i; `, e) R' v
    #include &lt;windows.h&gt;
    - n4 u& s7 F0 ?5 |  ?/ X* m#include &lt;d3dx.h&gt;7 u$ v( n  i9 N+ [2 d2 q
    #include &lt;stdio.h&gt;9 v/ A* P: a" b/ n2 T  Q
    #include &lt;math.h&gt;' q+ U" \  Q$ o' V* U
    #include &lt;mmsystem.h&gt;
    - p' E( q+ B- J: @  E9 T3 \$ p$ w#include &lt;dplay8.h&gt;
    - x$ |# A$ j( L) k" P" M* J#include &lt;dpaddr.h&gt;# T/ Y3 ~6 T! I+ B* d* M" y
    #include &lt;dxerr8.h&gt;' I8 `4 [; d- Q4 j/ m
    #include "DXUtil.h"
    " a: F+ n4 }+ k1 D' A#include "MazeServer.h"
    5 I  y3 u6 {) d, _#include "ackets.h"/ H- H' |% a! H$ j9 M: Z* h+ N
    #include "Maze.h"; G# j7 S# R% k
    #include &lt;malloc.h&gt;
    - t/ y! _: T  [: f#include &lt;tchar.h&gt;</P>$ ]; }) W$ Q% D, g( h, ^; K. B- ~
    $ M0 ~. J* [4 f1 @1 Y# p
    <>//-----------------------------------------------------------------------------; w; d: [; R- V' {4 b, @
    // Name:
    6 e7 l9 w6 s, d* ~4 R- U8 y// Desc:
    , k% V" a5 m) _' C, `! T3 o1 `6 w6 S//-----------------------------------------------------------------------------
    " L3 \$ Z. s; L- ICMazeServer::CMazeServer()
    6 n& g& L& O/ @7 Z: Y{
    : G) J. K# Z8 D; _    m_dwPlayerCount         = 0;
    / s1 D) p  p4 x    % j/ \& j4 U9 c9 S: l' k
        m_wActiveThreadCount   = 0;
    ! Q! h) |& e; S# r    m_wMaxThreadCount      = 0;
    7 c" G, E* {3 r    m_fAvgThreadCount      = 0;5 A' B9 s: }) E5 a4 `
        m_fAvgThreadTime       = 0;$ R$ I: g; n$ q3 X$ g) ~
        m_fMaxThreadTime       = 0;</P>! [8 ~) R$ V  `$ h$ M% D# p6 }
    <>    m_dwServerReliableRate  = 15;" b% |: d. Z) y, i+ G
        m_dwServerTimeout       = 150;" h% {" _% T+ \: t8 H- c8 }, k( ^
        m_dwLogLevel            = 2;
    5 O8 A* p* g; e4 I. W, _# d6 c- w    m_pMaze                 = NULL;</P>% L# W4 p6 C, U5 w4 z2 V! k2 ^. H
    <>    m_ClientNetConfig.ubReliableRate = 15;
    , ~" Q# |5 j0 q9 j6 _- {* c    m_ClientNetConfig.wUpdateRate    = 150;
    ! s$ c0 B( P4 n$ m    m_ClientNetConfig.wTimeout       = 150;</P>% x5 }* a/ f. q' _: O' M
    <>    m_ClientNetConfig.dwThreadWait = 0;</P>8 V0 i! c; X( ]/ D+ t# D9 g3 n
    <>    m_ClientNetConfig.ubClientPackIndex = 0;# x" W8 c  [4 d2 ?% B
        m_ClientNetConfig.ubServerPackIndex = 0;4 F, e! M. k0 r
        for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)
    6 R5 p' w! \/ A8 d    {
    2 x9 i9 J* U  E7 B' E* S% L        m_ClientNetConfig.wClientPackSizeArray[x] = 0;. E+ c* j* {8 f( a# o% O* k# s
            m_ClientNetConfig.wServerPackSizeArray[x] = 0;
    : p7 e! X5 F/ M( U6 m' k' g) d3 u6 k    }% w1 V- `" W% c- T, @' j: j
    }</P>
    ' _( J# s# M+ {
    ' M5 w6 h: H! K# d. y/ [, j1 ]<>6 N$ o7 I4 r/ J  ~. Z
    //-----------------------------------------------------------------------------
    7 }( ]' G/ @! _& S// Name:
    * m  a/ w; t  `$ X" a8 [// Desc: * |9 r+ q: a5 @% _0 ^& I% j: d
    //-----------------------------------------------------------------------------
    " g, M/ \% y  X+ c! bHRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )
    1 S, O+ ]+ r8 J4 g! b: o{8 ]. c' n( A/ z5 \
        m_bLocalLoopback = bLocalLoopback;
    , n& S, ^0 J7 z% a    m_pMaze = pMaze;' J3 k4 z# l$ ^  W/ {! S
        if( m_pMaze == NULL )
    " J- i' {7 j5 t: \- m" T2 X# a        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>, t7 g) ?- Z( @2 o
    <>    // Grab height and width of maze
    9 E" N3 Z+ S" D    m_dwWidth = m_pMaze-&gt;GetWidth();
      F+ U+ q; n5 z0 P, a) h    m_dwHeight = m_pMaze-&gt;GetHeight();</P>
    ; H- @) w% V8 O2 ?* A<>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    / y9 q9 W  j, B6 e    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>) b: a/ p9 b: S
    <>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.
    0 _$ b: `4 F/ l    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )/ G# U  K, i6 ]# w
            return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    + F# u" K/ L  O0 L/ Z- z    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )
    3 b' Q" g9 P7 N+ g0 P! Z. w4 ~        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
    : y* Y* f4 b3 ?0 i3 z# r<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;, t; i5 @/ h& L1 U! O4 }, w9 y7 `
        m_dwMazeXShift = 0;' w+ a5 h3 P. x3 c0 ]: _- b
        while ( (scale &gt;&gt;= 1) )7 X' e7 f/ I- o  o. L
            m_dwMazeXShift++;</P>
    # o8 N+ T; i$ C* w! k<>    scale = m_dwHeight / LOCK_GRID_SIZE;- ~. @/ T6 r9 c& V1 D
        m_dwMazeYShift = 0;
    # T8 K$ I8 B6 X6 z& b$ f    while ( (scale &gt;&gt;= 1) )
    & d8 j6 g' `1 S5 p2 E- {1 ?        m_dwMazeYShift++;</P>$ v  q5 X) v. h: `" M* d1 X2 h
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    + b. ]  R9 N. \5 [5 I        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )) v$ C4 P6 F" @- N5 F$ l# o
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>! j$ Q+ v- J$ i- r$ p* D* t
    <>    // Initialise the player list$ k) @# F, Y- j( X( t8 y, D+ W
        ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );
    # o' o, J% p% |0 I; @6 Y    m_pFirstActivePlayerData = NULL;
    ( q8 m. }8 G& O4 x) n: k0 d$ R    m_pFirstFreePlayerData = m_PlayerDatas;0 g& S& n, h) O) {
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )
    % N/ I! ~3 ~% T2 K2 w' n/ M    {* _+ M; \/ O. x8 j. O% Z
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];+ ]# S3 O/ ]4 S# \$ s
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
    4 ^, N8 [( [$ @* Y3 J    }</P>9 ]0 X4 f6 M& @
    <>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];0 W4 B' {1 a0 H1 Y( Z( M
        m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];
    " j8 B) S3 J: t5 t1 G1 ?* A    m_dwActivePlayerDataCount = 0;% L7 H5 e; }6 ]8 N
        m_dwPlayerDataUniqueValue = 0;</P>* I7 L9 m4 o1 ~4 U/ ]
    <>    // Initialise the cells
    % z8 h: J7 o9 L+ h    ZeroMemory( m_Cells, sizeof(m_Cells) );) s  X$ e0 o5 H& L5 ?" m% g7 \
        ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>
    7 ?2 N; D: {1 f  @1 }<>    return S_OK;: S) _- x) m* s3 {2 b
    }</P>1 P# D4 n7 b1 M1 x

    6 }( W4 |6 g; q7 m- e% o8 K<>
    1 f+ L% F5 E" X+ \) |% Z* y//-----------------------------------------------------------------------------
      N7 d+ K3 j- x// Name:
    6 w2 J6 U0 E# I: j8 }$ E" C// Desc:
    $ w  g# @, r9 B) Z# q* c//-----------------------------------------------------------------------------% ~% j, Z# I+ A& v2 W( j* L6 K
    void CMazeServer::Shutdown()
    & n/ T/ o8 ^; p{+ W7 N' u1 d4 U
    }</P>& n, ^* M0 b  m2 I* D

    ' I4 ]- i& `6 k* L+ {<>
    2 U1 v( w7 _) z/ ~/ F* m//-----------------------------------------------------------------------------0 I, x* a# ]: r. R& D- S
    // Name: . H( f7 x8 `% ^, {% e, |
    // Desc:
    ! I6 X6 E# P( Z" v3 q3 f7 a//-----------------------------------------------------------------------------
    7 C+ T6 D2 e/ X( W  ?+ e* bvoid CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )6 f, G4 b4 {8 S
    {$ a- x2 p' L4 I8 ]4 s7 |  }
        m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    $ j0 R3 D, }4 f                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );3 A& ~, C4 \0 B+ n( U
    }</P>
    9 Z. y: t8 R6 |3 Y8 s4 O3 h
    $ h. I7 M- Z( V3 z<>0 Z, m0 Q0 V" I1 \8 b" L8 ~
    //-----------------------------------------------------------------------------: \0 Z3 h) G+ r
    // Name: 7 N9 a) {1 p; e7 v
    // Desc: 5 l  _, E5 Y: _3 I1 t+ K' M6 w
    //-----------------------------------------------------------------------------
    2 Y. {, j( ?+ a/ q6 U* z/ Jvoid CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    / {, j& h+ v; N* @$ M{
    , N. ]' J1 s& @    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    & U) ]: V5 ^& \. Y& @3 L" t: J' T) |                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    . M+ P3 b, d" m$ r4 S% g}</P>; S- ]/ I. j# p3 I- Z+ f
    ' E$ R) K2 ^. i. l2 Q0 w6 V  k
    <>4 y0 w" R5 r7 h
    //-----------------------------------------------------------------------------" n& b  ?' T8 V7 \
    // Name: 6 `1 }3 c- X4 ~. A* p
    // Desc:
    , e  Z/ d& E; e2 ~( j( B. i//-----------------------------------------------------------------------------* x+ m; D8 @  A# Y
    void CMazeServer:ockCell( DWORD x, DWORD y )+ i; H! H4 t. f3 I. a
    {
    6 F* L0 A2 X  _1 E- S7 }    if( x == 0xffff )
    ! N' [( D) _+ i4 T        m_OffMapLock.Enter();
    ; z' o+ N7 O# l$ n" U    else
    - p8 b$ `3 w$ ?+ `7 r7 _        m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);+ c0 m% a; t  O! u' u: n
    }</P>; P) c: f& X: p3 L
    ! `* B4 J1 M3 d9 O2 M+ N  t2 P
    <>% _' Q( F/ g- V: B8 m! g: [
    //-----------------------------------------------------------------------------. L( K% E3 O5 w' M1 t
    // Name:
    0 B: T! B. R8 L2 W4 U9 A// Desc:
    & K& X8 i; {. ^% X//-----------------------------------------------------------------------------
    ' m) b# @( w5 s$ {6 fvoid CMazeServer::UnlockCell( DWORD x, DWORD y )
    : s% c$ v2 a6 q- `  e9 r& h{) x- J% M6 b2 I6 H) ?
        if( x == 0xffff )/ i. A) w3 o! C
            m_OffMapLock.Leave();' C/ j5 i- \2 R* ~  A' m, e. V
        else+ K/ d9 T7 o- W! @* g" U& O) f+ m
            m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    6 U- B1 t. b, t}</P>5 Q1 A, ^8 Y: D3 l

    $ r( a8 r1 k) ^- r6 k<>, {+ I6 X; x. o4 U' D: d# X1 Q
    //-----------------------------------------------------------------------------
    ( g3 ]* s4 G8 b/ w" K3 A! Q# @0 K, o, ]// Name:
    / J  [, n4 w4 ]5 }6 F! v// Desc:
    * q4 Q2 Q7 M/ Z- \4 ]: ]//-----------------------------------------------------------------------------
    4 S1 C6 g8 Q& qvoid CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    $ W0 s* ], W. U) s' n) }{/ v3 K' |' Q9 N8 G3 s2 |
        if( x1 == x2 &amp;&amp; y1 == y2 )7 z# e6 b2 w  \+ T6 b
        {
    ' I+ k, \  u6 C1 L        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    / ~, A3 k3 F7 z* e            LockCell( x1, y1 );
    ) e' q- ?6 P8 A. y/ E        else% \) ]: M/ q0 n6 p  E+ K  F2 \4 T
                m_OffMapLock.Enter();</P>
    3 ?' ]8 ^4 [, a: p6 q' x2 }0 F  O5 v<>        return;
    + B) b1 ^! i* o. p" f    }</P>
    6 b  U" G1 i& j3 [! C5 b* K<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    0 R+ E: e3 K) ^5 k    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;  |2 g) Z/ i0 E
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    # D8 f- W* v0 z' E; ~    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    4 j* j. U6 ?4 s9 g9 A) ?<>    if( x1 == 0xffff )
    + I+ ^3 _9 K  W; \3 A9 q  y0 u    {. ~  i  Y: p8 k+ u
            m_OffMapLock.Enter();; J+ ^) f1 M) h
            m_LockGrid.LockCell(x2shift,y2shift);! C# l5 ^5 e! E: `0 e7 g
        }
    0 l' \+ ^( c  T; x- c, |    else if( x2 == 0xffff )8 b: v( a5 P9 }4 d/ D& {# c
        {
    1 D  c' Q5 C: U/ V1 }9 C9 D$ M4 }        m_OffMapLock.Enter();
    7 @6 u& }  ~) b. q        m_LockGrid.LockCell(x1shift,y1shift);, F$ B; z# L: g! I# {& ?
        }; ]5 C7 b8 a; P% o0 A/ B1 Z, e
        else 7 T, A; S( E* S" Y
        {
    - C" ~7 X( W6 L) {        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);
    # L$ p" u$ b9 N6 O' e    }1 u, n, e! g) n0 r+ V! J- L5 d
    }</P># |: I  j" g/ ?  X1 c% }

    ( H& F3 V9 S; x! d<>
    8 f+ C3 w  F% W; v+ M/ ^& {# S//-----------------------------------------------------------------------------" o9 {8 t; |( d; i! Q
    // Name: % @  g- F% e: H, q, F6 d
    // Desc:
    ' o; R% Q; Q5 Z' H! i* Y* ^' P//-----------------------------------------------------------------------------
    8 F- \0 ~( [( X+ C$ `void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )& Q5 }; s' b( T5 d5 j0 M
    {
    # ^1 w5 R' \; ^    if( x1 == x2 &amp;&amp; y1 == y2 )
    7 Q% \8 ]7 H& Y, q, C    {( I. Z8 x, e! Q, o1 Q2 k
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    " {& I2 g% ~7 |& R            UnlockCell( x1, y1 );, D, M1 _5 ~+ q
            else
    : E3 z) T9 K0 ]. \7 X9 u; {2 h            m_OffMapLock.Leave();</P>0 G  z- v+ C* s
    <>        return;5 S' m9 k9 D  T$ \7 x" j9 X5 l, @9 j3 A
        }</P>
    6 O" }: V( r3 }8 n! D. Z<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    ( t( G. A1 Z; C    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    ) H- e( U) y. b5 L1 `    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;7 N4 s2 Q% D4 H' n- m
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>1 ^, T5 X) K4 u2 b2 d9 C
    <P>    if( x1 == 0xffff )7 ~& J( e2 H) G
        {" v% n0 ?" i9 }8 L$ {8 v5 C4 R+ s$ j
            m_LockGrid.UnlockCell(x2shift,y2shift);2 F1 U# k( z; c9 a
            m_OffMapLock.Leave();8 q. Z3 [. R0 @! K8 I& F- z. d  {
        }
    : A- N! }  o" a4 c) V, j    else if( x2 == 0xffff )
    3 ~% z0 V! q) q/ R! _. ?    {
    # v2 i- M: z' M        m_LockGrid.UnlockCell(x1shift,y1shift);% z6 S5 E" ?8 ]
            m_OffMapLock.Leave();
    ' J$ D) s9 P" c& c8 U9 g    }
    0 _. J2 d# ^. F- i$ o& y    else
    , P$ o) S( c  j    {
    9 N2 e% \* ^! S  @( C! n        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
    ( i0 w* n- p8 ^2 y9 j* K) }    }& I7 S, r7 O  X: y
    }</P>
    5 [- o/ _  }* M- G, X( w1 x2 z( f0 C: b2 o2 J
    <P>
    $ j) C0 L1 f! T! z( Q) n4 O) I6 C! i: A//-----------------------------------------------------------------------------
    & A9 R2 H9 w" f2 k( }; M1 Q/ k// Name:
    3 k, P! ]0 A9 {4 M// Desc:
    : X, ?  T8 q8 g7 [' |8 ]//-----------------------------------------------------------------------------" v% `$ O/ G+ x2 {
    void CMazeServer::OnAddConnection( DWORD id ); B  T5 _4 e* u, `% L+ }
    {2 }. l5 G; ~) w! ~/ p
        m_AddRemoveLock.Enter();</P>  U& `( Q$ Q- b: ^* c
    <P>    // Increment our count of players
      z9 e/ @( Z) G7 ?$ @' [5 N# g2 C. {    m_dwPlayerCount++;7 v( Y/ E" n8 F( H, k/ q4 o" [
        if( m_dwLogLevel &gt; 0 )
    # P6 D: @; J+ u( I    {. i" z) e3 P9 m8 d, c2 v- P
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );- \: R; Q4 V. I6 f$ m
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );, e  ?: h" B! X+ D& I
        }</P>* g: p; c! j, o  n( z+ [
    <P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    ) L# G5 j- L, @- p+ o! o        m_dwPeakPlayerCount = m_dwPlayerCount;</P>
    ( c5 V& x* P( d2 ^0 [<P>    // Create a player for this client* v- l4 b( [- y6 N
        PlayerData* pPlayerData = CreatePlayerData();
    ! n0 u) n& J2 Y3 w2 b. ]    if( pPlayerData == NULL )( n; K& R9 x( {  y8 v2 \) P
        {  J! \% @0 ]* a' b& N% m5 r! C: l
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
    9 V+ S; S  s! P$ X+ k/ P2 N        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );
    4 M  n) R. {1 M  l* p/ I        m_AddRemoveLock.Leave();+ q$ O! e. d4 A  X: _
            return;
    0 O( @; H8 |% N. I5 D8 a    }</P>9 h) [  y4 M4 Q( ?$ G# X; h
    <P>    // Store that pointer as local player data
    " e* a1 w2 v4 m$ h6 \* G7 i8 p    SetPlayerDataForID( id, pPlayerData );</P>
    , Z; H! V  r( ^+ R, R<P>    // Grab net config into to send to client
    ) y' h* [& e# L5 B! J    m_ClientNetConfigLock.Enter();
    ; i7 B, M1 a8 ]! N& I, H" H. k. _    ServerConfigPacket packet( m_ClientNetConfig );
    ) ^0 E; G" b0 l" a    m_ClientNetConfigLock.Leave();</P>
    " Y4 ~$ s% k: g* B; D0 r<P>    // Send it
    ! G, c) y0 y7 q# L3 L# K    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>! S+ x0 U' k" e
    <P>    m_AddRemoveLock.Leave();' ]6 m5 k! x$ e, [+ ]4 G
    }</P>' n: x- D0 N8 C- O- t, h3 }5 Z3 @9 v

    ' O, k& M; Q, j* p& [7 o<P>
    2 C( [2 h; m4 [9 w! w- e//-----------------------------------------------------------------------------
    ) H3 `! y% c5 d9 U' o// Name: - k8 p2 U/ S4 T+ U* Z
    // Desc:
    + q, |) R8 W' z0 b//-----------------------------------------------------------------------------2 }5 ^2 v; M; u  f5 v% f
    void CMazeServer::OnRemoveConnection( DWORD id )
      r& N: T, e0 ?8 [2 K  j& u{- Q$ @$ {& J  f, t
        m_AddRemoveLock.Enter();</P>
    * O" A0 M& j) C% a+ p5 W<P>    // Decrement count of players+ W) r/ W2 {' p6 g% j. E! Q) b- f
        m_dwPlayerCount--;</P>; T8 s8 _* B/ E. b+ }9 K
    <P>    if( m_dwLogLevel &gt; 0 )
    : a; L% H% U  V8 R: F. h    {
    2 x. A; I6 M% n$ @& W: f        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );( w# ~6 P+ D3 Z/ j( E% g
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    0 E8 j, w* C! r; F8 a    }</P>
    . H* w" ~+ Y3 h9 H<P>    // Find playerdata for this client0 C$ v4 W2 v% ?
        PlayerData* pPlayerData = GetPlayerDataForID( id );( j1 p: a3 I, a* V
        if( pPlayerData != NULL )
    + M  {8 e+ q. q0 l    {) F9 j8 T1 R" j# q2 Y
            // Destroy it' i# C4 p8 s/ k9 s4 I) a% _) G
            RemovePlayerDataID( pPlayerData );
    0 G$ i3 W8 O# t$ B9 c: ^        DestroyPlayerData( pPlayerData );- b: w# T$ f5 \: U5 h* Y
        }</P>  `, w0 |+ \8 L
    <P>    m_AddRemoveLock.Leave();
    , o8 i% i+ M4 s$ t}</P>
    8 A0 o) v5 w. @$ z% n1 ]! b/ l
    4 @, {1 B% N9 L<P>4 F( n+ Y2 c+ n5 s  m" d
    //-----------------------------------------------------------------------------* _' y9 [" ]0 Z: d7 t2 t+ l
    // Name:
    # Y# e3 x' [! F// Desc: + s( s* r: m% Q4 N6 z* i3 u& C
    //-----------------------------------------------------------------------------* `4 Q" `  s$ }; v4 c  U; V
    HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )
    2 Y$ x; A; \# g1 G; Z  {{/ C/ C3 u4 L8 p. k& K
        BOOL fFoundSize = FALSE;</P>
    ) n6 v4 j+ m8 U<P>    // Increment the number of thread we have in this process.
    $ @! ^3 \, ?8 f0 F: O    m_csThreadCountLock.Enter();</P>2 }5 D% T- H: x- r! \1 f
    <P>    //Get the start time of when we entered the message handler.5 ~9 L  @* P2 \
        FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
    + Y4 q/ J- a  _5 y4 a<P>    m_wActiveThreadCount++;6 E- R. y: i& x
        if(m_wActiveThreadCount &gt; m_wMaxThreadCount)
    ; z7 W5 l* {+ s/ z! z4 S        m_wMaxThreadCount = m_wActiveThreadCount;
    % }  t/ H' G5 K* x$ L0 _    0 h: C1 ]0 y% e1 C* Z
        // Calculate and average.
    6 a$ y* j% }- }! C    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;5 J; K' R: Q, W  r
        m_fAvgThreadCount += fdiff/32;+ M. t! Z% U" C- d8 S* T  @: J
       
    ! v4 z) D0 D$ h* @0 j$ ]( P% F    m_csThreadCountLock.Leave();</P>5 t& ]6 s2 @  Q% \$ K9 }* J" }
    <P>( s+ Z' {: u2 @! Y: U& D2 {7 W) \+ O
        ClientPacket* pClientPack = (ClientPacket*)pData;8 F  G& D# R) y% L& y
        switch( pClientPack-&gt;wType )
    4 m- x3 U+ j, ^/ B: i    {
    6 U" \: _6 E6 \: F5 Y$ i        case PACKETTYPE_CLIENT_POS:" J7 P3 n3 d6 R
                ' R$ S6 Z; S6 D3 x) q
                // Check to see if the packet has a valid size. Including $ d1 t& H0 q. O5 W
                // the custom pack size.. M& S  w# s( W
                if( size &lt; sizeof(ClientPosPacket))
    # M9 \4 w/ ]; w8 ^  |* g+ {5 [                fFoundSize = FALSE;
    * d8 u  j3 g" i, B0 x1 D$ L            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket))). T+ E/ }4 ~, Z: s) k- a& q
                    fFoundSize = FALSE;
    . S6 s$ O+ Z+ r3 d4 \            else
    4 l5 ?) P  c' E                fFoundSize = TRUE;</P>
    ( Z, V- n; c# W' ~3 b9 E+ o* V<P>            // If valid sized packet, handle the position.
    7 T* X8 h2 a% [5 M# s            if(fFoundSize)
    . D6 d' u( f  V# Z                HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );7 p$ q+ v( K' d! ?
                else
    " P3 a9 d9 u7 R* H% D( D                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>/ [  g. X0 v4 t
    <P>            break;</P>6 f) n6 T7 z% I- W+ h( o
    <P>        case PACKETTYPE_CLIENT_VERSION:* x* m# F3 T; ^
                if( size == sizeof(ClientVersionPacket) )
    $ \, {6 e9 {+ z* ?2 `, |# W5 \                HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );( T+ T; `0 Z, R# j; b% H
                else7 C! S+ S6 h! k$ v1 w, e9 G8 `$ }
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    & n) s0 @7 W( c2 J& M            break;</P>6 }+ T- _7 Q6 n) W, y' p7 ^) |
    <P>        case PACKETTYPE_SERVER_CONFIG:</P>
    ; Y! |, N0 [. m4 ^' U7 B+ `8 n<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>% w# J5 l* ~! j
    <P>            break;
    + h: O# |8 `+ i! x6 a( a3 `! g        default:
    , x# O# `3 }; m3 \            HandleUnknownPacket( dwFrom, pClientPack, size );
    5 J# H! }, k2 g* E% V            break;8 J2 o! T1 D3 n
        }</P>
    ( J3 \1 U- m6 S+ t+ B% W* @" W<P>    //If the user wants to hold the thread, Sleep for given amount of time.
    2 j7 ]; `3 c# H6 U    if ( m_dwServerThreadWait &gt; 0 )0 ^2 b0 C- v* N5 o
        {
    ! P. }; e. @. }2 n* R: |        Sleep( m_dwServerThreadWait );
    2 a7 P3 p, }2 j, i; d( @    }  r" k6 ?# P" r9 J& x
       
    * h1 D  T1 Z8 C3 q    // Retrieve thread data for this process.8 T" W7 f) |& b  K& w
        m_csThreadCountLock.Enter();</P>2 t0 Q/ }) K. M6 O9 G3 R8 A3 t$ X$ ]
    <P>    m_wActiveThreadCount--;</P>
    ' u# o- t* c2 v<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
    ; Q6 o0 S' Y4 l/ g* Z    m_fAvgThreadTime += fDiffTime/32;</P>' C9 M/ B  v; U/ m5 {8 ?
    <P>    //Get the Max time in the thread./ ~2 J0 r6 x5 Y6 h3 ^3 m
        if ( fDiffTime &gt; m_fMaxThreadTime )
    5 N/ j3 t8 |) ]) c% ]    {4 V7 ^/ b, s% X! j3 r8 D* s% Y+ T
            m_fMaxThreadTime = fDiffTime;* ~1 K" b: K' Y* j5 }) V
        }</P>
    3 o5 @4 u1 N" @- q<P>    m_csThreadCountLock.Leave();</P>9 \" c* Y4 D3 b
    <P>    return S_OK;( q6 l: C3 z7 h" x5 S
    }</P>
    ) x  _2 x' l5 N+ I3 [  p+ [" A; y& P& B! r/ a* O8 F3 u5 C+ C8 v
    <P>//-----------------------------------------------------------------------------% n1 o$ `% E1 R# @! n. C+ t! w( Q9 T
    // Name: 9 }2 a9 q& A" o) N
    // Desc: 3 R7 g/ G+ t1 [0 Z
    //-----------------------------------------------------------------------------9 `& U! E7 |1 |: Y
    BOOL CMazeServer::IsValidPackSize( DWORD dwSize )
    # u( g5 @7 L5 [) ^0 y1 z{# Q( G* }& i0 B) [  w
        BOOL fFoundSize = FALSE;
    3 x8 V- u" h/ j! Y4 B: _/ l    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;3 `1 P2 Z, j& p+ k2 X2 J& K# ^, E
       
    ! s# S; O- w0 k0 W    // Check through the array of valid pack sizes.8 ^; G& J: p# C! ]
        if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    8 x9 ?( v9 U! R    {; v+ ?, U- I. ]* F
            for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)# I+ n/ ]8 G& T; L" n
            {
    : t) o4 G" f9 M: E" o            if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])* \- F* ?3 Q7 Y) k& C8 y! w
                {  W, q2 a+ Y0 R: [6 ]5 ]& P3 @) o
                    // Found valid size in the array.
    7 c! N+ g( K" k' S                fFoundSize = TRUE;6 l: i& w  t+ b' S0 e
                    break;& X* i' V4 c( s6 d* m3 _0 K
                }
    8 N! Q. b( _+ A# |5 z            if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array." X9 Y8 {4 L" n2 ?+ Z" T
            }
    & T' Q2 C4 A4 H    }" f" ^" o. i& H7 A- V5 B. D: i
        else& |9 G! ]: K- B$ i! B* x
        {
    . V, E) [- g5 s; I  A, x# i3 y: t5 ^        fFoundSize = TRUE;
    + m4 H0 I$ b/ i, b, e    }</P>
      ~- x9 M" \; ~$ k2 K  c' i$ V<P>    return fFoundSize;. }; G9 C1 E! _1 b/ f, E
    }</P>3 }! C& B' M4 {) e- ?& [
    <P>6 F; V3 d: q' o9 ]
    //-----------------------------------------------------------------------------
    9 I) t8 X7 t' m9 a; Y// Name: $ {- Z2 E9 j' Q  b' _7 a5 Y. f
    // Desc:
    , q4 k7 E- |4 y" r( A//-----------------------------------------------------------------------------% q& n! Z  f" F6 h! W
    void CMazeServer::OnSessionLost( DWORD dwReason )2 |' t8 r3 w/ D( a( H
    {
    1 t- }! f2 h0 }$ W3 C6 S    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );. @  W$ B* j" o4 j3 I, R/ q
    }</P>4 W: W4 y& v* ?! I1 u" i
    7 i9 F; b* V5 V4 B" m% B+ V
    <P>
    0 C  d* @* B0 I! m" D/ ?' u7 H1 }//-----------------------------------------------------------------------------) h2 @( Z1 c2 n! D( v0 O
    // Name: 0 l# ^, Z! }3 ~8 ^) p: `+ z+ W
    // Desc: 7 N1 e3 h' k! h, C. j. O  j0 D
    //-----------------------------------------------------------------------------
    ' t) z& ~) H/ [! Y) Q7 {: uPlayerData* CMazeServer::CreatePlayerData()/ d) o* c, N5 K
    {
      q) G6 |' C$ |8 e4 D    m_PlayerDataListLock.Enter();</P>
    7 C3 A- _2 Q$ ?9 j<P>    // Grab first free player in the list; L% a4 C* H4 m0 w% b9 i: x( p7 Q
        PlayerData* pPlayerData = m_pFirstFreePlayerData;</P># {5 {. t* X8 V4 |. c
    <P>    if( pPlayerData )
    & p" R( X3 H' u) x  n1 \3 P    {7 C2 i6 T# x' a& @
            LockPlayerData( pPlayerData );</P>
    7 Y* S8 C; x( e( j4 g<P>        // Got one, so remove it from the free list1 L. b* A# G: q* P) U
            if( pPlayerData-&gt;pPrevious )4 t  X& A9 O  p! j/ D' c
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;$ i, d5 a5 v- B/ z( {
            if( pPlayerData-&gt;pNext ): h6 {. E* Z$ [5 R6 ~: z
                pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
    2 x1 I2 r: `2 Z9 `/ K1 o        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>
    5 `( }1 u, n0 a3 n* F1 ~; p<P>        // Add it to the active list1 a+ ^7 O& \  Q) ]9 d# V! @
            if( m_pFirstActivePlayerData )
    * \( l; _- U0 S1 L) J5 @            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
    # Y8 {' D" y' j* b5 x+ ]! R        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;! U: h7 @" p3 i9 w
            pPlayerData-&gt;pPrevious = NULL;
    5 d: S8 r8 j9 e& a! V" J        m_pFirstActivePlayerData = pPlayerData;</P>1 T% r  h; `7 M0 i
    <P>        // Update count of players
    4 }' i/ d% d4 E6 V6 M        m_dwActivePlayerDataCount++;</P>
    / c5 e( i5 o2 R, Z<P>        // Generate the ID for this player
    + h4 k8 a. T/ _: M% X* G, `% L7 H        m_dwPlayerDataUniqueValue++;
    % l* I$ n; l% \( d/ }" y        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
    0 N4 h! E( c# q7 q<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
    # @- t. Q/ ~8 f        pPlayerData-&gt;NetID = 0;1 o, U$ m- J+ [. y
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>
    5 M% ]" h0 e) O) g) n; F<P>        // Insert into the "off-map" cell
    ; U+ @; _1 }' ~        pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;4 |+ y/ r7 w: L( a5 S6 B6 B
            pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;
    * s* T" U7 \8 i. A8 i        m_OffMapLock.Enter();
    ; S" o8 P7 d7 d1 _        pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;4 @6 m& u% Q- v
            m_OffMapCell.pFirstPlayerData = pPlayerData;
    , L: |8 o# H2 J* \4 {        m_OffMapLock.Leave();</P>
    , K6 O0 |* T/ t6 M& d<P>        // Mark as active. G9 I; _: M! D0 m
            pPlayerData-&gt;bActive = TRUE;</P>$ V) W7 d' n1 A+ u
    <P>        UnlockPlayerData( pPlayerData );
    % Z$ g6 u; k9 E( J  ?6 z    }</P>
    1 C' [6 d. n, y2 U4 q8 \2 g( ~<P>    m_PlayerDataListLock.Leave();</P>
    , L  |% O# `5 M<P>    return pPlayerData;' X, i  F0 [" b
    }</P>
    7 @% G! I0 m; p4 H# m% Q1 \2 e" n+ Z) K( z; `7 q
    <P>
    & w  d: t' O5 O9 g//-----------------------------------------------------------------------------
    . H  M1 q% [' Z6 ^1 v) h* T0 z// Name:
    0 Y+ Q7 x& C& b* @& \! p// Desc: , A; l4 h$ s. X8 t; X. h  J
    //-----------------------------------------------------------------------------" d+ x! S/ k0 P' }2 O% ?0 ?
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )' A8 o$ E, w8 X5 Z1 G# E
    {: C1 w! g& j8 \; `4 ~
        m_PlayerDataListLock.Enter();
    2 z- q$ m, H: j. l    LockPlayerData( pPlayerData );</P>
    5 E7 C" t" }3 k9 U. v% H# \1 N& n<P>    // Remove the player from its cell
    ) z, M6 Z+ f: }3 I9 A    RemovePlayerDataFromCell( pPlayerData );</P>4 X/ y: K, d; o; n2 U+ i
    <P>    // Mark as inactive
    - f7 {2 C) G/ g  B  ?; d    pPlayerData-&gt;bActive = FALSE;</P>2 i8 u! h) L* F% [% s
    <P>    // Remove player from active list6 ~# I1 e' m1 X+ |# ~9 Z
        if( pPlayerData-&gt;pPrevious )
    : M+ F' ?: r2 S1 e1 Z        pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;" L. ]0 ?+ r% R- ~0 U
        if( pPlayerData-&gt;pNext )
    8 C; I$ y- K0 z6 K        pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>
    . ^5 B6 ~$ ~7 l. T<P>    if( m_pFirstActivePlayerData == pPlayerData )
    7 Z$ o. e, b# [/ [( v  T; S5 b; t        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>
    & [+ p2 x* N3 ?' P! z$ c* I7 b<P>    // Add it to the free list
    # D: m5 B9 W# Y: T  i+ Y; X    if( m_pFirstFreePlayerData )4 q9 m: t5 M' Q/ p& v
            m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
    9 l& n1 M  s7 q- I5 a- K/ u    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;
    & Q9 {9 S8 m% v5 x) R1 b    pPlayerData-&gt;pPrevious = NULL;
    - v2 ]7 M5 H" g$ m  u    m_pFirstFreePlayerData = pPlayerData;</P>
    : r' Z9 f" y$ {<P>    // Update count of players) x: q! n" U4 j2 e
        m_dwActivePlayerDataCount--;</P>
    9 R. x3 J% P3 N5 c! Z<P>    UnlockPlayerData( pPlayerData );
    ) H, m8 ~: Z; s2 D3 S$ W3 n    m_PlayerDataListLock.Leave();3 m* C% y& e% E( H1 D
    }</P>
    $ N2 b5 ?1 a/ S7 D) t3 ]3 f5 d6 `( C% P1 E5 W6 S
    <P># b. ?0 l- K) a4 Z! w
    //-----------------------------------------------------------------------------
    0 L& |! m% H- n' P  o// Name: / U2 R3 g0 ~0 N7 @  P6 @
    // Desc:
    - _8 m' ~- A5 Q. _( E% u8 {1 M% C//-----------------------------------------------------------------------------. E% p$ j, h0 X
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )' H& _7 X1 r+ v/ r6 f) a
    {
    / {: }" r) n4 n) T; I% M    // Lock the player
    + |% E% Z6 ^( [, v% C    LockPlayerData( pPlayerData );</P>
    + P' Z' m. c0 ^  p<P>    // Lock the cell the player is in( k5 _. J! b$ l( s# x* L
        ServerCell* pCell;7 [3 I- R7 b, I
        if( pPlayerData-&gt;wCellX == 0xffff )
    3 T+ L9 s; I: o" i3 ^$ D    {
    & m. `5 p: r* L* Q8 [2 p6 M        m_OffMapLock.Enter();
    9 \; u( t$ K. L5 V  J4 l% g        pCell = &amp;m_OffMapCell;
    # p3 b8 O, w5 k4 M. M, \    }
    ) w+ S! `# O1 a6 n; i6 J5 e: r    else
    + g9 u4 n- M/ N. K! j2 i& [# E. I' Q3 ?    {  B) l, w, ?2 W6 d9 U. M
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );: q! _, |7 H/ I2 i  ]8 w: k- T$ T
            pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
    * U5 v! Q, r- \0 ~* m    }</P>6 ~8 ?9 |( F" V# o  u
    <P>    // Remove it from the cell
    $ }2 w' M9 h4 \* s, ^! Y  N    PlayerData* pPt = pCell-&gt;pFirstPlayerData;, {# L" @" c9 Z# \) v4 t1 E, U) F) ?/ q
        PlayerData* pPrev = NULL;
    4 h+ N( L9 `6 u2 V1 s( D1 T2 }' l    while ( pPt )
    ' F# c. w0 O! B1 B& E5 {' V    {9 M" Z( v- ?2 ?
            if( pPt == pPlayerData )
    2 E- r& W2 b6 v/ ?. z        {5 g$ j; l. }, y3 p
                if( pPrev ). L4 A3 T$ I7 E; t# k! f7 W  j9 a
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;" U/ Z* Z) C1 m9 q2 q' _* W
                else' _  a0 j8 G& t% V- l+ M1 a
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>+ d, ~" l6 Z- u* R
    <P>            pPlayerData-&gt;pNextInCell = NULL;7 O4 p2 m  K4 }
                break;( s# U7 ]2 u. N6 E; R! g
            }
    ! h( b4 |# o+ J2 ~        pPrev = pPt;
    # C1 O8 C, W4 n7 N        pPt = pPt-&gt;pNextInCell;% s, v' d6 Y1 \; |
        }</P>* Z  g' Q9 v. E+ E& _# P( s. ?
    <P>    // Unlock the cell+ U* J. J. x# M9 v5 N
        if( pPlayerData-&gt;wCellX == 0xffff )3 \) H6 x* D. h* w
            m_OffMapLock.Leave();* ]( v( R$ ~0 u( S* ]
        else# i8 G' N( U' M1 h3 H6 O5 z
            UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>8 l5 I# j- A4 A( T8 X
    <P>    // Unlock the player
    . O4 ?& Q7 f* E' ?2 |9 |$ V    UnlockPlayerData( pPlayerData );
    ! G! _0 K7 e+ `}</P>3 k" n3 X3 U: |. k
    * S% d  J" U% Z, Z$ w
    <P>. ^* ?& e8 r# b
    //-----------------------------------------------------------------------------/ k# A  U) b9 G* O
    // Name:   t0 u, i4 p  G0 f% A6 R+ |# l0 _
    // Desc: # W* w0 ~0 W3 V# h0 v- U
    //-----------------------------------------------------------------------------% U- R- A5 W7 D# B0 U. ?
    void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
    , B+ s) m, z& I; a9 ~- ^; f{
    % p* j2 J" S/ o+ ], L( q    ServerCell* pCell = GetCell( pPlayerData );) k) E! ]* V8 R4 F1 O% r$ D8 Q" E+ a
        PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
    3 V3 B, w9 Y/ }% O    PlayerData* pPrev = NULL;
    / T2 P$ U* E% F    while ( pPt )
    1 Q; g2 _! ~: e$ |0 n6 O, h9 E# M    {( Q% e, s* s; r" h
            if( pPt == pPlayerData )
    8 o" ]  d& U' ^        {
    $ V( B" \- {$ T% @$ Q            if( pPrev )$ [0 M1 C4 f! {1 P
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    2 g, G( I( M# Z# s! v3 y! T; d            else8 f9 F, \. Y- \/ @$ J" ^
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;
    3 F* G  u4 t2 r            pPlayerData-&gt;pNextInCell = NULL;, z8 ]0 p! S0 W, X& C; b3 b! M9 V
                break;
    6 C+ u% p1 F( j. U9 v, `" g' ~        }/ K3 p3 \$ b. l5 Q& [0 q- s
            pPrev = pPt;
    * N% c5 _. m6 J: N* P* P5 ?        pPt = pPt-&gt;pNextInCell;
    7 s$ w  R' i" F6 O8 q$ J7 F    }) @5 k& E3 Q% T$ a5 z
    }</P>( m, J  y2 |) l# n7 S0 {/ B

    0 e  @! R# @" o/ E. Y# y8 z<P>1 T3 S" i8 X9 D2 U, V/ e
    //-----------------------------------------------------------------------------  [% t2 A" T9 E! H* ^2 g
    // Name: 3 f# [1 R2 y( ?4 n" U  E6 v
    // Desc: 0 ?6 l6 i, Z/ \, A' a$ J. G
    //-----------------------------------------------------------------------------& d( o! u5 `" p" V
    void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )
    1 C$ J4 s' Y/ v, N6 u5 T5 R& ?$ {{
    * \: ?$ L. ?4 Y    ServerCell* pCell   = GetCell( pPlayerData );. Q3 h) }  P2 g# g5 X% B9 o# g# T
        pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;6 Q- C3 M( _5 z* @/ D6 Q
        pCell-&gt;pFirstPlayerData = pPlayerData;2 r$ V( O0 M, ^/ R& `# `! X
    }</P>
    . j$ c$ d7 [; B, S+ ~
    $ K. V* @0 F& |2 x3 T3 \4 X  j8 l<P>0 [2 d, z1 |, A% z% `
    //-----------------------------------------------------------------------------
    " L$ F! n5 @  v3 p( _// Name:
    1 l- e* A; y9 P+ I4 q  \1 g$ ?0 N// Desc: / t1 ^9 g1 U' M
    //-----------------------------------------------------------------------------6 C' ~$ V$ j: D5 ?3 l6 c3 H
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )5 r$ I% c7 @* B1 q/ c, Y" d, ~
    {! G# b4 ~% [/ M) H: b8 O. M" a. u, ?
        // Grab player for this client and lock it
    8 K8 k2 p, t" B& m    PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );. v( S$ A  W. O" b- U" x& V
        if( pFromPlayer == NULL )! ^6 E0 b; k% C* F& a( ?
        {1 G. G+ R+ Y. M: l0 I
            if( m_dwLogLevel &gt; 1 ); \2 e' T1 N- J# y. B- Q$ E% R3 ]3 A
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );
    # L5 B& M0 g! P+ g) d0 e# m        return;3 i0 I7 l, O6 O  _( l( g9 ]1 I7 f
        }</P>
    / n" q! C0 F2 B<P>    LockPlayerData( pFromPlayer );</P>3 @1 _& f: r1 \7 C. `+ t- g* b
    <P>    if( FALSE == pFromPlayer-&gt;bAllow )
    ' n+ f; }  p- f! R# a1 a6 d$ ?* R    {& _0 h  u- I' |& y& `' p* t6 s
            if( m_dwLogLevel &gt; 0 )
    9 m1 W: q& w1 V' h            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>* v$ v' k% f7 L! x3 q% C) _
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    + U0 H$ w" g& M/ c. z7 Q' x2 D        UnlockPlayerData( pFromPlayer );
    / V( E3 _  O4 Q/ v7 @3 L: _; m" V        return;" k' ~- b7 D$ e
        }</P>
    $ I. `, ^! M$ p1 i$ [9 ]" F. @<P>    // Compute the cell the player should be in now% q. d" R; O, O. p) V3 L
        DWORD newcellx = int(pClientPosPack-&gt;fX);
    - k4 |0 a2 G  i2 m: f7 V    DWORD newcelly = int(pClientPosPack-&gt;fY);: g- m( ]7 Z8 ?/ z8 I/ i
        DWORD oldcellx = pFromPlayer-&gt;wCellX;
    ) C' u% u0 h4 B5 _3 g" s3 ^    DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>5 h, F" |- d' C. G# l/ T1 S
    <P>    // Have we moved cell?
    & R0 d9 H4 S8 p, E7 d8 f" x; V    if( newcellx != oldcellx || newcelly != oldcelly )
      }% q7 {! L; e5 S* E    {
    1 n2 U" ]0 |: Z        // Yes, so lock the pair of cells in question( y: D4 v" v. r' B+ Z: L
            LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
    ) S8 @; |: H& }- u; P. m' D8 R<P>        // Remove from old cell and add to new cell/ o7 b7 R+ m) P0 e7 B& t2 q4 y
            UnsafeRemovePlayerDataFromCell( pFromPlayer );" r% Y" H( O: f( ^+ t
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);" K4 l& g; i$ j2 g
            UnsafeAddPlayerDataToCell( pFromPlayer );</P>9 Z6 E. k5 U1 a
    <P>        // Unlock cells
    , A" t% W$ K6 r% {( F4 s        UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );
    ; g: ?' g' G! ]0 _2 J8 }6 }! g; M    }</P>! k. s6 C+ D2 c3 c2 f: Y  e3 }
    <P>    // Update player position8 Z% M: m: x0 Z. g# f
        pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
    # z$ c1 O: b- `/ U2 I, N4 ]    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    / m* k- v6 _' b9 A3 m    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
    . m) L% K1 R2 P3 b$ w2 j$ R8 X<P>    // Allocate space to build the reply packet, and fill in header % J, y" D( U- L# @2 m) m
        DWORD dwAllocSize;9 d9 M" B) N1 t9 R6 L; X+ j
        ServerAckPacket* pSvrAckPack = NULL;</P>
      r) _- E, Y1 t1 n9 i8 D2 A, K<P>    // Begin by allocating a buffer sized according to$ ?. y; N) d0 I3 V' {7 a
        // the current number of nearby players + 4.  This will give
    * N7 X  O" _+ b- O' ?    // a little room for more players to come 'near' without resize
    4 w  v" n0 p1 t! h  _! _  [+ ?    // the buffer.
    ( z9 Q/ P; Q, K4 F( w    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>1 W7 @6 e/ {) j0 W) ^. V3 S
    <P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    + l0 Y$ a' ~' \9 a, d# e, Y    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );5 e/ m8 H; n; }* C' z
        if( NULL == pSvrAckPack )
    : B8 V2 {+ X* t, K- k* M    {
    / [" q8 Z( T* K% {8 K" z        // Out of mem.  Cleanup and return0 o, W4 R' ]( W! V- g0 ?2 E' T% }
            UnlockPlayerData( pFromPlayer );
    9 l+ U' A% s1 T5 m        return;      
    - a& |5 ]: n6 i2 {7 o    }
    ' Q" e( c1 n5 u$ w8 V% N* c! Q    ZeroMemory( pSvrAckPack, dwAllocSize );</P>2 \' I6 [" O$ j- E% z. @8 a
    <P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);; c  b1 B$ s6 J! a( |' [
        pSvrAckPack-&gt;wPlayerStatePacketCount = 0;
    3 \. z' W- B) r& }. A    PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>
    6 q5 w. K5 D# S( W* j<P>    // Compute range of cells we're going to scan for players to send
    ! \/ j1 E6 {0 f1 K  D* f/ N- X    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;
    9 T! |2 ?+ m+ ?) `2 e) F    DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
    9 k$ G3 Y3 c+ B& l& f: n% @    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;
    : I7 X# a6 F3 e( b    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>+ i/ Y' Y; F+ z2 n; _! M
    <P>    // Lock that range of cells
    8 B( z- K! t4 s: H2 Y    LockRange( minx, miny, maxx, maxy );</P>/ w% i6 |  ?/ e, r1 P) w
    <P>    // Scan through the cells, tagging player data onto the end of, v; `" \- l" p
        // our pSvrAckPacket until we run out of room
    4 z  D7 X$ ^1 h" u& J% x  A3 z2 m* `    for( DWORD y = miny; y &lt;= maxy; y++ )
    8 ?0 W& Z& B* Q# r" V    {
    0 v$ J% s  k' u; C        for( DWORD x = minx; x &lt;= maxx; x++ )& v; d' x/ ]0 i* J! k; q% G
            {0 u; q$ ~$ I1 H/ Q; v  n4 F* Y' a
                PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;  F+ e  o' s$ h( n+ x) S, R+ G
                while ( pCurPlayerData )
      B! Q. Q8 l. L8 ~* n& v            {0 F5 F- w( i+ x+ G1 W- \
                    if( pCurPlayerData != pFromPlayer )
    9 ^3 ?9 M$ O* r/ X! v8 O0 n                {5 J: S0 S' l! E$ |$ k8 ]+ X
                        if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )( k4 G0 X9 L; J- S/ ^
                        {; A" m9 u# l# O. U+ r+ e
                            // Make sure pChunk is where we think it is% v+ y/ N( [9 C% V& r9 e2 H
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>% G& g3 d6 |9 J# S& L1 Z( q
    <P>                        // There are more than just 4 new nearby players, so resize the
    4 v5 B( P& F; w$ G6 F- Q                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
    ( \  O% `, g) ]$ P                        dwMaxPlayerStatePackets += 16;
    - q& U2 P- [  w" t5 P8 q) G                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);; @4 M) U3 Q" Q8 T- z. p% V
                            ServerAckPacket* pNewSvrAckPack = NULL;
    ' }3 ?4 b( }, m+ w7 r                        pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );" C) U. c: L$ M
                            if( NULL == pNewSvrAckPack )3 z3 k6 ?* [7 ?
                            {1 e" o$ P% o6 y% I/ B' M. @9 g
                                // Out of mem.  Cleanup and return
    & q/ T- U1 _" P. [  P! b                            free( pSvrAckPack );
    / G- a. V4 V1 ?8 d0 h( f                            UnlockRange( minx, miny, maxx, maxy );
    ) f1 I8 [2 b: c2 z) ]( w6 o, [2 V# g$ m                            UnlockPlayerData( pFromPlayer );
    ( r+ l3 m5 S9 ^4 d% E                            return;       " V8 N# _* |- {' G* O9 g3 W. B
                            }</P>
    3 n" A* K( f% l# m+ F<P>                        pSvrAckPack = pNewSvrAckPack;* z- n! m9 q1 Y# G2 K
                            pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>% t" [- U0 a+ T; u2 j! b
    <P>                        // Make sure pChunk is still where its supposed to be
    $ L4 O( u8 Y' l& q  D" z4 |                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );' J8 p/ w# t. E+ Q% h
                        }</P>
    - @8 W% e( X% p4 {<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;8 S, E, \3 A6 Y, g. B. ]: `
                        pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;, [, j1 K2 p0 }3 N2 _
                        pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;$ q. c, U+ G3 y$ k5 H6 f
                        pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;8 I( ?/ k5 |# `0 g! u
                        pChunk++;
    $ {8 A- ]/ C* D  j$ D/ y$ J                    pSvrAckPack-&gt;wPlayerStatePacketCount++;
    8 A( Q" A* f/ I. z  o                }
    + r' N; S6 u' [8 M4 \4 d; x# [                pCurPlayerData = pCurPlayerData-&gt;pNextInCell;- b, o  A8 _8 T9 {0 z' \
                }
    ; ?' L8 S" F4 }, D+ Y' M5 y        }
    ( [" I: b, y/ e0 E8 W. _    }</P>' u% C7 p5 Q! [6 |; S( o7 g
    <P>    // Update the dwNumNearbyPlayers for this player$ `* x# p! `0 i6 [& @
        pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>) z9 a/ A( Y; P6 M2 x" c
    <P>    // Unlock range of cells
    ! y  O8 l3 y; ^4 p    UnlockRange( minx, miny, maxx, maxy );</P>5 @  R8 y8 t5 T3 ]
    <P>    if( m_dwLogLevel &gt; 2 )( F& J6 q3 V$ M2 g
        {( u2 F0 K- q1 q/ {: I# ]+ P8 }
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    $ A# s: c6 _) k9 m+ j, `  A6 h    }
    & w" |8 U1 P- A3 ^    else if( m_dwLogLevel == 2 )
    " u' }7 K. k2 ?) q    {
    8 M# x5 q5 D% Y+ n( C' G: }        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    : |: s8 f% ?. f; f, h, z! ?        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )
    6 b- R: ^4 p. C, H( b        {
    / T; @8 {% J, M+ L* T  l) O5 Q            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    5 m3 {0 q6 L, C            pFromPlayer-&gt;fLastDisplayTime = fTime;
    ; Q7 w+ d, k: f2 ^% M" v; ~        }
    ) c1 o9 M9 o( m' j" v    }</P>
    9 `/ X5 u  s/ F<P>    // Unlock the playerdata
    - o& K% V: C0 P5 U1 h1 L/ r, C    UnlockPlayerData( pFromPlayer );</P>
    ! Y3 H3 p# B! q" c<P>    // Send acknowledgement back to client, including list of nearby players
    , f' B; a3 N0 D) S0 y    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));
    % M) x9 |7 L6 {8 a* B  G$ A# O# o
    % i. h, e/ P. S: p+ g    // Pack the buffer with dummy data.# d9 e2 T; R( G' S
        if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)' s/ ]7 Q; G2 W+ }' B
        {
    $ y: q: E+ Z8 R5 z6 z' g        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];) B9 F6 m6 d: D' O2 \
            VOID*   pTempBuffer = 0;</P>( R7 L' m: J9 A! M3 \5 b
    <P>        pTempBuffer = malloc(dwBufferSize);, W7 H" \8 {2 {, h. f# _* S
            if( NULL == pTempBuffer )2 L% |5 ^2 \# C: @7 @8 S# l) g
            {
    / y/ p! n7 ]) m4 J1 r* h            //Out of memory0 f2 Q$ Q1 B- p4 Y0 h& k
                DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
    ; I- ^7 b- o- v            free( pSvrAckPack );
    / n1 P: h9 ?. `5 d* d+ j/ w' W            return;: q  b* C2 E$ {- i1 g
            }</P>
    : z& U/ |6 @7 ^- f6 |: b- k<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');
    % K9 {% e+ P0 m  e# _4 ?- A        memcpy(pTempBuffer, pSvrAckPack, acksize);</P>) v! [0 c$ j% k
    <P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );. K7 y3 g( c0 x; C+ |8 @
       
      D0 `0 c5 g" R5 C( i7 k7 r$ S        free(pTempBuffer);
    $ ], X$ a3 S0 }( s' _    }   
    + V  R4 Z% J% K3 Z- R    else
    0 g  T4 U8 u$ Z. R. \3 u+ \0 t) `    {
    / j9 {+ R  E9 H3 m        SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );
    - A& K/ O5 q8 ]# Z1 I. A    }</P>
    5 K/ T" [: k- f/ Z$ B9 B1 [<P>    free( pSvrAckPack );</P>; i$ u7 W* Q% T
    <P>}</P>0 J& v4 y2 J& Y3 I, Y) \
    : e5 C( r2 S! w
    <P>
    ! D" G  T/ L( ~//-----------------------------------------------------------------------------
    9 Z7 z  w/ f& t$ o: g5 H5 c3 M/ l. S// Name: 4 l" S/ x& a* i+ i9 y- }4 ~4 t  L
    // Desc: 2 d! u: x: n: f' E# a
    //-----------------------------------------------------------------------------) Y" B9 x- e! Z' [. {; z
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
    3 Q0 A- R5 X' e4 h$ F0 B/ P. T# d{3 n$ \7 c5 N: \% m
        // Grab playerdata for this client and lock it
    7 ]. s* \) Z% f% @    PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );) d4 D! l, |4 w( Y
        if( pPlayerData == NULL )
    , F" ]7 n  o$ \, u, T' U        return;, z2 D5 R3 m; Y# n$ H9 M0 A9 [
        LockPlayerData( pPlayerData );</P>
    2 t+ X; m4 g* F<P>    // Record the version number & l. V# Z1 b7 e% d( Q) p, S
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>& W  c! g3 X  u
    <P>    if( m_bLocalLoopback )9 U/ f7 E" D/ Y5 a
            pPlayerData-&gt;bAllow = TRUE;
    # _3 d4 Z( P0 q2 S0 y1 w2 n2 N    else( T) G1 t! E* q+ B$ V9 F9 z
            pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>$ C4 a9 k, o5 Y( m7 J6 p
    <P>    if( m_dwLogLevel &gt; 0 )
    & D1 f" B6 w* I* C9 y        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>
    5 |! @* Q5 d( g& m<P>    if( FALSE == pPlayerData-&gt;bAllow )
    4 m1 C' r# W1 ]  r: C4 I" p7 @    {+ L6 a8 b3 J. q" k; e- R
            if( m_dwLogLevel &gt; 0 )5 D6 f  n+ j) j9 g
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>( O* c4 e, e; @% j, z
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    ) U2 G5 B9 `6 U7 s& o% W: G# r        UnlockPlayerData( pPlayerData );1 i, j% \6 {( |6 m0 p
            return;4 x9 l: A7 ], k/ ^3 ^
        }</P>
    # J" O  x9 `6 p: l<P>    // Unlock the playerdata
    $ Y$ s: U" P& Q- I0 r    UnlockPlayerData( pPlayerData );</P>
    : K; |/ R3 h3 R1 A- u<P>    // Send acknowledgement to client that the client was either accepted or rejected4 ~' V, F% A1 m  l
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );
    5 N# O. s% v* g  o9 g    SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );) z6 C1 O' E5 K6 r& a( i5 A
    }</P>1 R: E( Z, O7 ~5 X5 }
    ; v0 L0 S% Z0 Y4 G+ M  ^) U0 X6 y
    <P>
      N0 Q/ {/ t7 o( I! p//-----------------------------------------------------------------------------
    & ^, B1 e! o, e, `* l& k( k, F// Name: 4 S* m! }, D( O) m. Q
    // Desc: - l% \& `* M) I6 }( V
    //-----------------------------------------------------------------------------
    0 C: [/ u. P0 \. q: Y' }3 x- d  QBOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
    * m+ j) t) Z/ K0 J5 C+ M{
    " i- n% ~7 @7 x  Y  V    switch( dwClientVersion )7 G+ g/ U9 k- d7 J$ K2 U
        {
    1 w6 W# S! i$ {5 F        case 107: // only v107 is supported
    , h% |, F) _$ N2 P8 X4 N            return TRUE;
    8 ]! ~/ h0 A" ~* f3 M$ C0 m+ n        default:
      n; S+ l3 |- H! \/ M9 _            return FALSE;( t4 y4 ^; t3 T+ M* E2 k8 ~4 `
        }
    3 v: |( t/ ?/ D7 m' ?& p}</P>
    6 \, x8 u6 `( S7 _- R- \2 `% ?* x: u) O# k( ?- E# h$ o4 Y
    <P>8 ~. p( A; M, a, E# ^% h  A/ g
    //-----------------------------------------------------------------------------+ @; [" Q( X. f) f! A  t
    // Name:
    ( N: V' V' }# w# C* G// Desc: ; `+ {* W4 W& X2 }8 [4 ^
    //-----------------------------------------------------------------------------
    ( w& O- h1 I& k. rvoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
    / ^, _3 J8 k/ E- o1 d{3 h6 w+ x0 k$ q
        if( m_dwLogLevel &gt; 1 ). S; [7 R! Y0 p, l  h' e5 r. O5 `
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>. G# ]4 g/ o# |- U* i. ^- @
    <P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    # G2 ]4 H& m3 c7 R}</P>
    " l7 k* Z# U# l. n: h. ]. P2 i
    - [2 z8 |8 w7 I+ B5 w<P>
    3 J2 A' u  W9 C' \9 [//-----------------------------------------------------------------------------; C4 K4 n% ]- `8 n
    // Name: ) A. ^5 v! V/ b7 T( U
    // Desc: 5 B8 r0 R1 ~" x2 J8 m; s! w# z
    //-----------------------------------------------------------------------------
    - B3 `0 m' s3 e0 E1 q9 a0 qDWORD   CMazeServer::IDHash( DWORD id )
    3 Y+ O& f6 l* `; |+ U4 S{& m+ W: L  }/ Z% A. @
        DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);6 b* S2 n) j+ p4 \. ?" g
        return hash;. A6 u/ P3 O) v! F/ d7 a2 |1 A
    }</P>! |! I+ n& D9 t7 V8 a9 _) Q
    % x/ x  w2 J8 H* O
    <P>, A* F- i) p+ B3 Y$ D
    //-----------------------------------------------------------------------------* p+ S( q* n: z3 ?
    // Name: 7 M2 H' E# e2 V
    // Desc: $ E/ }" t" K8 H! E  S0 j+ H
    //-----------------------------------------------------------------------------2 ^+ P# f9 T' q( @+ [* Y0 O1 [
    void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
    # w" a1 R: W" n{6 i" ?0 j& j, t5 ^8 X
        // Hash the ID to a bucket number
    ' h/ b8 v9 f8 T# W" z3 y. M/ h' T: ^' Z    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
    ; b7 S% W" b! _<P>    // Lock that hash bucket
    " b/ U5 z5 o2 ?0 N, ]) T    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    6 U, }- ]" i+ q+ K    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>/ p# J0 _7 j$ T% \2 z
    <P>    // Loop though players in bucket until we find the right one0 @0 _. O( A& Z3 m; Z8 ^3 N, Y
        PlayerData* pPt = m_pstIDHashBucket[bucket];
    0 J9 [, b, J1 }% N" t3 f' ~% S    PlayerData* pPrev = NULL;
    0 @. o6 G" v/ L* \    while( pPt )  A; x- i) r4 y  ]5 ^
        {/ c- r2 @3 W* R
            if( pPt == pPlayerData )
    1 y* u" w8 |2 W: E            break;
    2 U2 l- d0 Z4 ~. q; S+ n+ h( A; l        pPrev = pPt;
    , N  r$ r, s8 M' j        pPt = pPt-&gt;pNextInIDHashBucket;% [3 Z2 I, _3 G/ O1 k
        }</P>+ E/ G% E$ A( Z: X8 R+ O- v8 e
    <P>    if( pPt )
    1 h5 ~7 e2 J* N- A1 c# L9 c* ?0 Q    {' ]( A8 r$ ]/ j
            if( pPrev )
    1 v6 \! C' W3 b* e5 Z: f1 r2 G            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;
    9 |' C6 L7 [/ f: z$ h3 W        else% ]# J6 E! X2 ?" s7 H
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
    $ [( A9 V# h& M4 h! |% d. q" H        pPt-&gt;pNextInIDHashBucket = NULL;
    * ]* X1 K/ l" B    }</P>
    & w- Y$ h1 W0 L6 B<P>    // Unlock the hash bucket1 o+ Q2 \+ |' s3 \" c3 z6 \2 a
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    ; ~3 g& Y+ V2 i' L# T}</P>4 q: t. `' D5 O/ {

    & x, X2 L8 L9 v<P>
    6 D3 A3 x+ B5 W/ r4 N//-----------------------------------------------------------------------------
    5 b/ x+ o, |  w. U1 j' i7 ~; n// Name:
    1 e! i- g! j! K3 e// Desc: 1 C4 z' ^  @: X6 ?# C  l6 b* L
    //-----------------------------------------------------------------------------
    ' `0 W, d! u- H  Yvoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
    . {% ?6 v0 _0 Z/ W{
    / b- `6 v+ @3 q1 K" A    // Make sure this player isn't added twice to the m_pstIDHashBucket[]
      x6 ?3 {( e3 }/ ]& Z( }' z0 @, M    // otherwise there will be a circular reference
    5 x4 ~+ L1 H) R" m    PlayerData* pSearch = GetPlayerDataForID( id );
    ' F' w+ ~1 j! A: [% ], `    if( pSearch != NULL )
    ) H, d6 R1 C; y* ~        return;</P>
    - \6 C  I. m- K7 s, @* w2 s5 J<P>    // Hash the ID to a bucket number
    0 N+ z$ B8 A% v) D0 R, O, G    DWORD   bucket = IDHash( id );</P>
    / I/ F0 n* y( p8 K<P>    // Lock that hash bucket* T" o; G) \, e6 O, l+ B$ Y
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    4 d: t& v' h& r    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    / y% G: |" T7 S0 F* v6 G<P>    // Add player onto hash bucket chain
    / S' Z$ ^& I. d) q    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];
    9 k% O  g  b$ D! ]1 \; i) a    m_pstIDHashBucket[bucket] = pPlayerData;</P>
    : @) m5 |* ~) J7 ^; n<P>    // Store net id in player
    9 r3 h, `, [7 A2 h# V6 X    pPlayerData-&gt;NetID = id;</P>
    . J9 N' L4 ?6 u) B, R  c<P>    // Unlock the hash bucket
      K( x. ?( ~" Y5 k4 _: G0 K    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    6 h+ \& D& y- R* F: u}</P>1 m  K7 t) }3 I+ l. Y6 k
    1 h: z1 i* c9 d% R, z+ ]! b; i
    <P>
    % I: \5 A, J& f4 {' n4 S3 x//------------------------------------------------------------------------------ K5 \* j; o7 \% S! S' n* Q
    // Name:
    ( T" e: m2 Z: |' x% r$ m// Desc: . `' W, _9 {0 H4 S' I8 u
    //-----------------------------------------------------------------------------
      v' u0 m. T+ L( I, r% KPlayerData* CMazeServer::GetPlayerDataForID( DWORD id )( w* y6 T" \  f, Q4 Y
    {
    , c" K7 x( r8 F+ }% g4 I1 \: v% z    // Hash the ID to a bucket number' X3 c" M7 Z& y; [' [3 O* K
        DWORD   bucket = IDHash( id );</P>+ g' }) j" H; d% V5 s, ]- @! K
    <P>    // Lock that hash bucket  C' U6 o# H1 D6 \. [
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    1 D# ?/ \% L  w6 s1 ~$ G1 y    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    5 U# Y; ~8 B1 L* U! s<P>    // Loop though players in bucket until we find the right one
    ' B8 ?  C/ `' N( i% q1 A3 o0 w    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    , m, U# V3 U3 F+ A7 B+ q    while ( pPlayerData )
    6 }; X- G" l/ o! v, l    {
    - a2 M& I  H4 [  _5 u; `1 v1 e        if( pPlayerData-&gt;NetID == id )) o' m) q& ^, D$ D
                break;
    ; H1 X% A* J4 g2 d1 w        pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;2 D1 L0 h( n4 ^) k9 E8 S: X
        }</P>$ s" f  M: H2 f# f
    <P>    // Unlock the hash bucket
    . E* B# i+ A, y3 Z- F5 z    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>/ \/ n% E+ r) W6 {1 P# Q$ s9 m
    <P>    // Return the player we found (will be NULL if we couldn't find it): g- ]4 Q' w- y! F/ i) @2 `* Y1 x
        return pPlayerData;% [! E3 @+ ~& v6 p
    }</P>
    ! y( Y- }. H9 c% _, t1 h% X  `$ V
    <P>' ]8 ^' U) C: v- P) ^
    //-----------------------------------------------------------------------------* ?$ @% T' ]# J8 b
    // Name: 4 h' O6 [1 B$ ]' C1 E. K
    // Desc: calls DisplayConnectionInfo for each connection in a round-robin manner; o+ ?6 m- C  O6 F
    //-----------------------------------------------------------------------------! o* _1 @7 z3 @, {% Q
    void CMazeServer:isplayNextConnectionInfo(): J5 u. K; U+ {+ X, y! g
    {- g5 l7 y; m" e* |
        if( m_pNet )8 {) G6 b- N( W3 H, A( ]; j" @/ o
        {6 z- x% c6 N1 }7 _9 f
            // Find the player that was displayed the longest time ago, and display it.9 ], u* r( F# X0 |( ^; G, ^
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );$ k6 }7 `( I4 t& o5 }% p
            PlayerData* pOldestPlayerData = NULL;, w' |' x4 s6 n$ b
            FLOAT fOldestTime = 0.0f;</P>
    1 s: ]0 ~3 U7 r+ L0 s% F6 l<P>        m_PlayerDataListLock.Enter();</P>; o, A" P1 y. ~/ O5 s2 A4 s
    <P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
    ! I6 V/ v& L1 I/ f9 j        while ( pPlayerData )
    ) O0 c: G& V% A& w  ~        {3 B& K3 v& S7 R3 V3 h- j1 z1 U' b
                if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )1 X' f, N* a6 u; h
                {
    5 h5 x' R+ d1 }0 W1 }8 G# _2 a                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;9 l2 y+ p, R/ G! C$ C3 Q+ W$ E7 `
                    pOldestPlayerData = pPlayerData;
    6 o$ v0 P" J) c% Y  |7 V            }</P>
    ! w0 `' E0 A8 h( Y" @& a<P>            pPlayerData = pPlayerData-&gt;pNext;6 o( _0 G+ s* r
            }</P>5 O0 s  ]5 X1 q% O& f+ {% d
    <P>        // Display the player with the oldest CI field, and update its CI field.
    7 y8 a" {, P9 T0 I        if( pOldestPlayerData )8 e: ?. ]  t% m/ E) h
            {- o- P4 e& J* B0 O/ Y
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
    " k4 `3 |9 l6 u( J            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );! D& Y; p0 g; b
                pOldestPlayerData-&gt;fLastCITime = fCurTime;( G9 _$ s, W7 N1 @7 X
            }
    ) x+ K* v0 e0 c# e, T3 R7 S        else" C: q( z' Q' `" i9 }: p: Y
            {
    " n: ^8 e/ c" [1 O            ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    7 k/ \$ h& c( ]        }</P>, {" y& v' ~5 @* w/ Z
    <P>        m_PlayerDataListLock.Leave();
    " p& D* p2 G0 H. `, H* h) Y    }6 s3 E8 x+ P& ^) o$ c
    }</P>% p! n- P% T" v. x
    : f. W4 u0 O' a2 M4 U
    <P>
    : }/ M7 x5 }* z; i//-----------------------------------------------------------------------------5 h+ d3 |) {3 m6 N, Z! ?
    // Name:
    : I, T6 a6 {. V+ N8 C// Desc: - z% [& j: {$ _4 G+ V0 `
    //------------------------------------------------------------------------------ q/ S4 T4 V" o8 [6 Y( L
    void CMazeServer:rintStats()
    # J4 ]: t& b, u( x; r3 E' z; O+ r7 v{
    6 b4 f6 R: v$ x! Z5 S- R    ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"), / C6 C( g" {6 `, _, E3 z
                                        m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );
    ) |" B! \2 z+ R8 @8 s0 |* ~# c4 b    ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),9 z& L% V/ b2 Z- x" E
                                        m_fAvgThreadTime, m_fMaxThreadTime );3 F; e/ x9 ^( N& M
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
    5 c, X0 D; r7 c3 @8 O( q' q    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );1 K7 I- R0 e6 C2 d( s+ {
    }</P>9 U6 F2 b/ i* K0 K% V& h; v
    & n" p+ _' `% D- `' U
    <P>2 f1 ^  V# ]4 v
    //-----------------------------------------------------------------------------# Z7 c- I. ?+ g9 S5 R: T6 k( c
    // Name:
    ) n7 p. ]* ~' i" b9 D; Y$ h% _8 j// Desc: ( y5 ^5 ]; L2 u0 @& s
    //-----------------------------------------------------------------------------; x" [1 |7 L4 \4 H  _
    void CMazeServer:isplayConnectionInfo( DWORD dwID )
    : h8 g" o0 u( _: a{% X" t) C. r$ L  r0 t' F
        TCHAR strInfo[5000];
    ' T" g3 T) d# M$ s8 I2 a    TCHAR* strEndOfLine;
    0 Q) j* x) I5 Y7 ?$ p0 v4 A    TCHAR* strStartOfLine;</P>9 V! R; T, ]' s" h
    <P>    // Query the IOutboudNet for info about the connection to this user$ y. d& N+ O" u
        m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>; `' \* q" j, m
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );& q  m. X4 \6 [/ h
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>! x5 s* D* u- ~( {8 Z0 w
    <P>    // Display each line seperately
    0 R9 A* {9 J# S  N  P    strStartOfLine = strInfo;
    1 K- F3 T" b  Z2 t% ^6 b# y6 o    while( TRUE )
    ! g1 l7 q6 r  A0 h! B8 N    {
    8 ?$ e* ?/ \; @* k/ o  [        strEndOfLine = _tcschr( strStartOfLine, '\n' );
    1 n$ X! @3 x0 d) j6 U        if( strEndOfLine == NULL )5 P/ m% B3 @6 ]1 ^9 N
                break;</P>
    8 R" S$ z1 b# k; m" Y$ `, y<P>        *strEndOfLine = 0;! [7 Q2 g0 E# d7 U: ^: Q- v
            ConsolePrintf( SLINE_LOG, strStartOfLine );7 Y, c1 ^( l/ s8 P$ _
            strStartOfLine = strEndOfLine + 1;+ G7 l0 P8 S! g8 V0 e
        }
    5 B# c/ A. `" a+ s, S}</P>
    , p3 J" f' i# m) N* D: m7 B0 Q! _" m% u3 j
    <P>
    3 O) C: W+ W* E6 G) W. ~9 s  \4 g//-----------------------------------------------------------------------------, w& ]% B% ]# w* l- F
    // Name:
    0 q, S/ [1 o" B- P8 n7 d/ x$ ~// Desc: ( l, y* E: l' J4 S( P
    //-----------------------------------------------------------------------------
    " a5 Z/ e" A2 N( l' R- f( ?: LHRESULT CMazeServer::SendPacket( DWORD to, void* pData,
    ; l: m6 a9 Z9 q0 g) a: e2 B# f                                 DWORD size, BOOL reliable, DWORD dwTimeout )8 u3 [$ i+ k7 g: ~( y! J: ]
    {, f& e2 J7 A! e* F) p4 N
        // Chance of forcing any packet to be delivered reliably
    ' w' w8 D3 |9 F/ B) w% g  m# j    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )4 n6 e+ F( C) C3 I
            reliable = TRUE;</P>: E* Q1 o9 E! P* K5 V' l
    <P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );! |: u6 l$ y! @# }3 t3 ~' }9 G- c
    }</P>, P$ F( W& _  S# X5 s

    5 L" B. k  P& R2 I<P>& s* @! f  k8 N
    //-----------------------------------------------------------------------------% v6 s4 P  ?3 L8 p. b/ k
    // Name: 3 t  t- `4 Y" a# H& Y+ h6 x% y9 a4 F
    // Desc:
    + M3 m; |0 O/ N! E# k0 D+ i/ H! y- x4 A//-----------------------------------------------------------------------------
    8 B' P+ |$ i: c% i1 `void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )" G5 ]/ k# K. M' k" }
    {
    7 H* O8 m+ F# |    // If we're up and running, then send this new information to all clients
    6 M2 p& j' i' @' Y& \* ^  ^. J3 t    if( m_pNet )7 A9 Z$ Z. H! w. V1 u! J
        {
    + a+ w: v) Y" U8 K+ {: _0 o) [, O        //Use the AllPlayers ID
    + n! r. T, ~4 o        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );
    : |2 G; |/ }  w: l    }2 F0 V2 c8 A8 q% J; S8 h
    }</P>
    & W7 k! C' y, t% a2 R. }0 ]/ f7 j1 }3 Y" q5 D3 A5 E
    <P>3 G& F" ^& v6 T
    //-----------------------------------------------------------------------------
    ; ?# I1 z9 e/ D9 X$ H: T// Name: ( `  ]5 ~! ^" D- ~
    // Desc:
    9 G& s+ J1 R9 h* Q0 o( A7 y, a//-----------------------------------------------------------------------------
    ; P/ w' d1 h! [9 D2 P5 v* Cvoid CMazeServer::SetClientReliableRate( DWORD percent )% k, m# t; Z; p( q4 P# A# j
    {
    : |" }8 X  [  ]5 e- }2 D; u    // Update client config, and build packet containing that data6 q* ~1 c: ?# d7 d( N
        m_ClientNetConfigLock.Enter();0 r+ K! L( D9 x$ V/ L
        m_ClientNetConfig.ubReliableRate = BYTE(percent);
    & k5 f6 p+ J! W# d    ServerConfigPacket packet( m_ClientNetConfig );
    7 |& F1 P" p9 a  ^! ]    m_ClientNetConfigLock.Leave();</P>6 \' K) {( N. F3 c% x3 f
    <P>    SendConfigPacketToAll( &amp;packet );$ R. y) I8 z; p' c1 U
    }</P>0 g6 C5 r1 M4 \& l9 E2 L8 X* u' q

    # F9 A6 S' V6 u4 Q+ j: v( m<P>
    + Z, s5 c! o% z  l% e//-----------------------------------------------------------------------------: E6 w+ b8 S7 G" \+ t; R
    // Name: . m8 T  v7 B1 u* Z0 [
    // Desc:
    + S2 }; q. o: E//-----------------------------------------------------------------------------' V) b" G  s3 p' r
    void CMazeServer::SetClientUpdateRate( DWORD rate )! s8 S2 q- m, I, \: u4 a
    {& S+ E* {  x- b1 ~6 }
        // Update client config, and build packet containing that data  _- j3 `! l9 e- j  O% b
        m_ClientNetConfigLock.Enter();$ `) m9 v! V7 h+ C
        m_ClientNetConfig.wUpdateRate = WORD(rate);# }& d$ n; T3 @# m, B  n; V: P
        ServerConfigPacket  packet( m_ClientNetConfig );
    . ^( Z# b) e. j% G9 I. X    m_ClientNetConfigLock.Leave();</P>. I2 m1 g1 T- f& B5 K5 `
    <P>    SendConfigPacketToAll( &amp;packet );3 @4 V( s9 i( b' W: O# ]6 k
    }</P>+ h5 a3 p- A) ]+ o

    2 o  U4 L1 q" Y4 g/ U3 p<P>
    7 m: ~' o5 `1 L! [//-----------------------------------------------------------------------------6 B) ]5 }2 V7 f4 o
    // Name:
    - `4 f8 }9 {' _// Desc: ' E+ R9 |1 U0 O' C* t( w
    //-----------------------------------------------------------------------------
    . Y( l8 K  h- I. Vvoid CMazeServer::SetClientTimeout( DWORD timeout )0 Z1 I3 r9 M4 d# c2 f
    {
    ! v- x# g6 @4 O4 e5 K' v# Q4 ?6 k  K" z    // Update client config, and build packet containing that data
    2 h# @1 Q6 z4 R    m_ClientNetConfigLock.Enter();  c7 c1 P! J* \1 ?
        m_ClientNetConfig.wTimeout = WORD(timeout);
    % n) f) h" e' h& n$ ^    ServerConfigPacket  packet( m_ClientNetConfig );
    / d- K" u6 G& M$ W+ g# J$ b    m_ClientNetConfigLock.Leave();</P>8 q, N+ {+ J% ^. D) ?5 O
    <P>    SendConfigPacketToAll( &amp;packet );: |- g" d* }0 C  [1 l# r
    }</P>, }/ k0 d  l9 o, ^# W

    % A0 H$ }5 T8 ]' B9 r# `9 b2 \<P>) R0 \- ~2 M# S0 j
    //-----------------------------------------------------------------------------, x) _5 R  m9 e
    // Name: . t( [% ]9 \0 V7 w- }' k
    // Desc:
    3 {, \0 }' S/ J//-----------------------------------------------------------------------------
    9 H6 U, `& Z8 i* H" X2 O4 Yvoid CMazeServer::SetClientPackSize( DWORD size )
    " m+ |3 }# N+ D3 ?$ ?8 e{
    ' j# |6 a* D+ z% z    // Update client config, and build packet containing that data7 R( e6 T2 Z" A$ H7 ^
        m_ClientNetConfigLock.Enter();
    5 u0 X) F  [- Q4 {2 E: D! b" ?% y4 H    7 j# i2 L4 f, S8 v* P) q8 A
        m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.
    0 T( {5 e4 j: T' ~6 N0 G    if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   
    0 r) {, g: k/ s& |8 K8 U/ {        m_ClientNetConfig.ubClientPackIndex = 0;</P>
    ! M. p+ W$ Q5 O* R. o' o. s/ N<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);
    9 T5 U; s# d* i3 A- l    ServerConfigPacket packet( m_ClientNetConfig );6 Y& o' }* R8 J( \
        m_ClientNetConfigLock.Leave();</P>
      S- [% U& n' `' ~. A, B<P>    SendConfigPacketToAll( &amp;packet );! S1 p/ B& f! a* g
    }</P>7 D6 T7 `# P# T1 Y5 Z5 P2 x5 V
    + j! V" P: W3 ^2 U2 d- Q; s" T  l
    <P>
    & M* }( k) A' |) J//-----------------------------------------------------------------------------  s- b% ?% j2 R7 N/ c
    // Name: * ]' R3 T5 P& ^) p2 f
    // Desc:
    1 H( e2 c+ R0 |" ]. c//-----------------------------------------------------------------------------
    4 t$ z$ b; \) J" O7 J. Ivoid CMazeServer::SetServerPackSize( DWORD size )& b  o  Y1 M6 c3 c3 O; n" m) U
    {
    2 z/ Z/ T4 C0 T4 Z$ |" p    // Update client config, and build packet containing that data' A6 c/ h* l( A! Z+ x. ^7 G7 o2 a
        m_ClientNetConfigLock.Enter();
    9 ?8 \4 r6 O% C* ~) @* z9 T  n      Z0 B* F* p$ K. @5 \1 T
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.* W# k2 u  r$ P0 R0 o& x+ ^+ J7 u/ |
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   - Y; B2 O$ h- ?+ W9 Z5 D* X; U
            m_ClientNetConfig.ubServerPackIndex = 0;</P>
    , N& o9 o" f' X<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
    4 [9 [( G# t! s4 u; t    ServerConfigPacket packet( m_ClientNetConfig );
    % w  l( v# ?- P& E& Y! E- G) J    m_ClientNetConfigLock.Leave();</P>6 T6 {& w( j' s0 h  L; a$ S
    <P>    SendConfigPacketToAll( &amp;packet );
    2 R) I: s5 q) @1 w}</P>' ]7 E( C3 n, ~
    <P>
    ( G' V' @; @/ ~; G9 V//-----------------------------------------------------------------------------* z* T) q$ y' E# i) ^. s' v7 h8 ?
    // Name:
    * o$ i5 D" o0 I// Desc:
    . ?  ^: N# |. M" c# ^//-----------------------------------------------------------------------------0 \& P: N) ^0 t& ^6 p( h) T4 a
    void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )3 U* ~" d% D  S9 T% C2 v2 Q$ J
    {: x% C' S4 U' B! [- `2 N
        // Update client config, and build packet containing that data5 k) {: ~' _4 `7 }; c3 H
        m_ClientNetConfigLock.Enter();
    % I. Z( h7 \6 P% y. a4 B    6 f  a+ ]( M/ v* `8 u2 S% O
        m_ClientNetConfig.dwThreadWait = dwThreadWait;
    & ]* y/ Z2 k8 H* t! l# ]    ServerConfigPacket packet( m_ClientNetConfig );
    3 y) {1 u: J6 E( [" a. k4 R    m_ClientNetConfigLock.Leave();</P>
    * @$ I3 \5 P. u<P>    SendConfigPacketToAll( &amp;packet );  k) i' d9 h; H: Z2 B# M
    }</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, 2025-8-16 01:13 , Processed in 0.393903 second(s), 51 queries .

    回顶部