QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4244|回复: 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>/ P5 u" C0 u3 M: D- C* q
    <>// File: mazeserver.cpp
    . m4 a& C( n' f* u8 Q5 w- h& U//
    . Q0 T* V8 m5 J3 b# ?// Desc: see main.cpp5 r/ ?2 `2 W3 b; H2 p8 E
    //
    ( F9 d$ W. ^! P1 f1 ~5 {// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.. K6 s9 t$ x6 v
    //-----------------------------------------------------------------------------: Y7 H7 \* \  ]1 K2 Q& Q* Q
    #define STRICT. x# _  Q6 v! j, o
    #define D3D_OVERLOADS
    . H7 e. v, T* _: |5 Y4 ]#include &lt;windows.h&gt;* j; Z& Z! w6 |9 m2 S/ E
    #include &lt;d3dx.h&gt;/ y; A4 }1 c; P# K; a! C
    #include &lt;stdio.h&gt;2 |/ G2 P2 A( e$ f
    #include &lt;math.h&gt;9 M7 T: y; l8 ]$ B  r6 F
    #include &lt;mmsystem.h&gt;
    : C/ m) n/ L5 |3 I8 a- ^  ^#include &lt;dplay8.h&gt;
    3 H/ @, C) i1 ~; m. O#include &lt;dpaddr.h&gt;8 Y3 A) J- W, x+ X' Z( r8 d
    #include &lt;dxerr8.h&gt;" D+ s. i, P" J$ E! v( G) R
    #include "DXUtil.h"/ j4 A  \. E% u( J6 G! V8 N
    #include "MazeServer.h"
    4 }5 d8 I0 J& P- B#include "ackets.h"0 Q/ f& `. o& a
    #include "Maze.h"
    6 f, w' S. @% O1 }8 _#include &lt;malloc.h&gt;! E3 N' J' n( c# Q6 \/ T
    #include &lt;tchar.h&gt;</P>, }6 U/ q! B( \' I# G
    ( y; e" Z( ^5 c# o0 Z1 m
    <>//-----------------------------------------------------------------------------
    ( G  _4 U2 ^& _, e/ G$ F// Name:
    # G5 O4 i, M( N$ D- X// Desc:
    : t: O, J  l# D) H7 Q//-----------------------------------------------------------------------------
    - a4 Q5 K8 ]! g% C+ F$ e- t- z0 MCMazeServer::CMazeServer()
    + o2 d9 t7 S3 S9 w{! [7 O% T, Z* d8 q5 g
        m_dwPlayerCount         = 0;+ u; P5 ~" d& v! F1 {
        ( N8 d! b: V9 d* I
        m_wActiveThreadCount   = 0;$ ~8 {# F/ p! j! G$ S0 i8 Q
        m_wMaxThreadCount      = 0;( S3 N1 |5 w, T% \5 R
        m_fAvgThreadCount      = 0;5 q( v5 D/ {4 j
        m_fAvgThreadTime       = 0;
    - C% a4 s% \4 O3 {) g    m_fMaxThreadTime       = 0;</P>
    $ n- Z& W. a. D  \<>    m_dwServerReliableRate  = 15;8 h' E* ^( x0 ^, ]3 w
        m_dwServerTimeout       = 150;3 w1 }! n; \: D( O4 I6 d- o* ~
        m_dwLogLevel            = 2;
    5 B3 a8 `  J+ t+ i    m_pMaze                 = NULL;</P>
    5 ^% `7 ]6 r+ q# v<>    m_ClientNetConfig.ubReliableRate = 15;% i, f! Q2 T) w7 O- r2 c
        m_ClientNetConfig.wUpdateRate    = 150;
    " |" J$ m# o7 C  v* T) ~3 z    m_ClientNetConfig.wTimeout       = 150;</P>) d# e) N' J6 K7 o$ [
    <>    m_ClientNetConfig.dwThreadWait = 0;</P>
    ) q: u5 B! ]0 V2 d<>    m_ClientNetConfig.ubClientPackIndex = 0;
    / Q1 x" q  b2 {    m_ClientNetConfig.ubServerPackIndex = 0;4 S0 s8 U9 m/ T: ~
        for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)
    ) S, i; l, O3 j( |    {* @5 k( K' ?1 x% _6 x8 p  |  ?& {2 F8 m
            m_ClientNetConfig.wClientPackSizeArray[x] = 0;
    ( ^! m" e2 n# I  q- j# Q        m_ClientNetConfig.wServerPackSizeArray[x] = 0;
    : V. l* L- h' y$ S; e    }
    7 |1 ?, S9 P" Q6 r6 p}</P>
    ( Y# y/ l$ t" J% o! h3 ~2 Q) S9 P
    <>) K- C7 l. \$ ?, ~6 F5 q7 k
    //-----------------------------------------------------------------------------( m1 i$ u4 r. u5 C+ P6 H
    // Name:
    & ^+ b. ?! Z; n: ]// Desc: 7 e/ A$ p; ]! Y3 e5 z* u8 P
    //-----------------------------------------------------------------------------
    # Z' P5 c. y8 `: }4 Z6 p# x5 ~% ~HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )
    , |: L' t+ P# j) ^" k{2 C  [; i' A2 I9 Q, `2 z
        m_bLocalLoopback = bLocalLoopback;- A' M' S2 z: Q. O
        m_pMaze = pMaze;" G* e8 j) N, p6 S5 v8 {
        if( m_pMaze == NULL )
    * \- v/ `4 e* r8 T        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
    8 ^) D5 N) _% ^<>    // Grab height and width of maze
    0 ^+ Q$ p5 Y1 k! H; z    m_dwWidth = m_pMaze-&gt;GetWidth();3 F/ m& o6 m7 b; o' f
        m_dwHeight = m_pMaze-&gt;GetHeight();</P>
      z  ^: ~2 o( O" i" @, f4 W5 q<>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    ( k  c% r6 i% d6 D5 [( U# \    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
    - k6 A' ]9 @( E3 A  E9 E& v7 T$ A<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.
    8 H8 Q. g. q4 t7 r0 u, _& }$ H7 k. y& f    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )( x9 @# C8 S3 r2 n" x1 S+ i2 O
            return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );! h0 z4 o5 r  t% a0 m
        if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )
    2 D- P! c! l3 @* }        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>1 D- k. e2 j- ^( M
    <>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;* ~* x. I" Q( M' B3 U
        m_dwMazeXShift = 0;
    $ d8 R8 B4 H+ r# R  e* ~9 k# Y: d0 G    while ( (scale &gt;&gt;= 1) )9 q! d' D9 N4 ?3 p
            m_dwMazeXShift++;</P>9 C0 }6 z1 R- o3 M
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;
    ! H& a/ K* ?" h    m_dwMazeYShift = 0;
    5 G9 ^1 y" t% `, J! k3 b7 N8 P    while ( (scale &gt;&gt;= 1) )+ k! }3 R$ Q0 k8 V- `
            m_dwMazeYShift++;</P>
    # k5 U/ Q2 J0 _! Q& J<>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||# T3 @# ]% o1 r$ ^" d, ~
            ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) ), K" @5 n+ f4 W0 q
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>
    ( F9 j+ B$ t2 u: e9 N3 w1 [<>    // Initialise the player list
    3 Y; ~( \- e" k# {. O    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );
    2 n& n; [( N) c, c) ~  Y7 {    m_pFirstActivePlayerData = NULL;8 t4 u- {; q9 C( {# Z
        m_pFirstFreePlayerData = m_PlayerDatas;5 G3 Y1 g0 t& F$ Q( i" `
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )1 I. B8 u5 t; r4 B7 p- F
        {
    ! `: O7 [. |, E  b; r, r# P        m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];
    1 u" T- e& D/ z4 w' d% w        m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];8 u; o" c% T$ q: p
        }</P>! ]( U! {; L; c  R
    <>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
    % C! _: a, q4 O# ]6 F+ e1 c    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];
    + |* C4 w$ z$ Q( _    m_dwActivePlayerDataCount = 0;2 B) b- i6 `2 g# r9 E4 B# x4 j! v
        m_dwPlayerDataUniqueValue = 0;</P>
    + D7 p% w; |" n! t0 q0 j/ q<>    // Initialise the cells4 o! I+ p+ t5 A/ O( o. [) K
        ZeroMemory( m_Cells, sizeof(m_Cells) );
    7 @# c2 }6 A% i) m; w    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>, A& ~* ]( D, v1 u! y% F2 E$ @
    <>    return S_OK;
    - J7 z/ Y; _$ S" e}</P>% y* \$ l5 B) y# R2 g4 P/ b! \& }3 W
      g4 P; }5 t& {3 G! {$ Q+ X8 X
    <>2 A9 \! w. E& c7 |, I
    //-----------------------------------------------------------------------------
    : q" V% r# f$ S/ i. K% ?// Name: / v) q/ G- H, A
    // Desc:
    * k, X, K* Y  D//-----------------------------------------------------------------------------
      o$ n3 u! `  M! vvoid CMazeServer::Shutdown()9 p1 {3 @) d) c' |  d; w. s
    {
    # G; x( g. k: t4 k}</P>8 e$ Z. C* h; n: Z6 R

    4 Y; E7 b4 Z) T<>
    & k9 g. t* t+ C  ^//-----------------------------------------------------------------------------
    : C% `' U0 }3 B4 u# K3 h// Name:
    , R6 x5 s- L5 m3 F' u/ \& L9 W// Desc:
    5 D: [% X; K1 P( g& X* L//-----------------------------------------------------------------------------
    % g: B+ `' f% d, G: Z! u7 avoid CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    % o$ U& k: S# x# {7 B$ f6 n! [{) x; F2 S5 R  ~& O
        m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    . P& F, M0 q6 z8 w  ~6 ?9 a                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );9 I' G1 ?$ H( }% i& F& B# g% c6 ]
    }</P>6 d* M% s6 w/ M; z
    4 A# A! g% `; a7 C
    <>- L; p5 |3 t% ?3 Z4 |% s
    //-----------------------------------------------------------------------------
    8 r/ z5 o5 ^9 ]( V; o/ G5 A2 y// Name: 5 E3 O& w% Q" D; V- n
    // Desc: 3 l7 O7 z8 i# Y; K, M, x8 ^1 H; D+ A
    //-----------------------------------------------------------------------------
    * [  U' p' J& {) Fvoid CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    0 ^- R: S* `! c) y8 P5 ?7 X7 e{/ u* a, k; u# e# K+ F
        m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    9 V) E: d, E" i. J4 Y% Z2 Q                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    - N6 t& f) l  S$ M}</P>0 |! Z( M& o+ d# O
    : D; K7 ?0 v/ q; F% u
    <>$ d; g. @* m5 D6 e9 y3 @' ^
    //-----------------------------------------------------------------------------% U8 A9 u# s8 k4 }$ ]7 n
    // Name:
    2 Q; \. O, f+ J2 I: {  F; Q// Desc: & N0 r8 f( |+ |2 n) D& H! W
    //-----------------------------------------------------------------------------, `+ Z4 Y; y, X" P
    void CMazeServer:ockCell( DWORD x, DWORD y )
    $ t! ^& l8 {  Q+ R{
    7 S5 g5 y3 P* e. E" A+ t, o4 |# v. h    if( x == 0xffff )
    ) s9 T4 a! z, A9 p        m_OffMapLock.Enter();: X3 i& O4 s4 ^  N$ R( f
        else
    ; D2 O% ]( I. F8 o" o6 n. z. h        m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);* c: c- K2 n, S
    }</P>
    ( S% ~% T( M; N* e3 p" L
    " Z; u  _. I) E% `<>1 I- C% Q/ E3 S
    //-----------------------------------------------------------------------------: J4 z8 y6 J) u6 O9 a$ c. y& V
    // Name: * g8 M1 @7 {7 L- a! g; y9 d4 ?
    // Desc: : I' p$ t9 Z, r  u. v' z
    //-----------------------------------------------------------------------------
    2 u6 Y) m3 n" i' o4 d. h  M3 mvoid CMazeServer::UnlockCell( DWORD x, DWORD y )
      S, b' q- _7 h. Z{' s! _; \( D7 Y( W7 K
        if( x == 0xffff )- G6 S7 j2 o6 M. `/ y: C( B& ]( k
            m_OffMapLock.Leave();& l1 a& p3 [' w7 _0 W$ x9 ~
        else7 X  \3 A# ]' [7 _* P+ c
            m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);+ D4 a5 Q3 W/ v  z$ @) r2 q' h
    }</P>
    - }+ v: A/ R/ o/ V! s/ g" `4 _
    * w4 f4 _  S( a& @( E$ T<>
    9 r4 Y* B+ o' Q# A//-----------------------------------------------------------------------------
    : I1 r8 K! S" f/ x# j- |// Name: ) B) r, u3 B/ q
    // Desc:
      Y; g" K0 a9 ?//-----------------------------------------------------------------------------
    - ~* f( C4 w7 W5 E# l) @void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    ! o/ Z: b! \, f! G! ]7 G{! A% H2 b! j: e, F+ A3 N
        if( x1 == x2 &amp;&amp; y1 == y2 )
    / q( t6 Y1 u) m( |: ^! n/ ~# I    {$ t0 i1 g& N, T8 [
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )4 S( x* d1 j3 b8 P5 D+ Z
                LockCell( x1, y1 );! d5 ?6 u$ H8 s$ H) j. O
            else" r) b* G6 L# K
                m_OffMapLock.Enter();</P>
    / E+ E5 u5 C) p4 O+ ]6 B<>        return;' Q; l; Z% j( ~; q
        }</P>
    + @; [! l& f5 J$ p: v<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;' Y8 j& _5 o. l2 {3 {0 {
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    . q- L8 F  r5 G) ?  z    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    : K, O4 z5 e4 |9 u, S0 }7 D- ?1 ~    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>( M+ X$ A- E7 x
    <>    if( x1 == 0xffff )1 T/ B5 ]2 m/ s1 x$ j6 x1 Q
        {
    0 U; c, t! C7 u$ |9 o8 Z& ~        m_OffMapLock.Enter();' K" v& ?9 q# y* [- W
            m_LockGrid.LockCell(x2shift,y2shift);
      E2 g( V- h) n6 Y. Y5 T4 F    }
    ; Z* G4 s: r- P" C$ ?: D    else if( x2 == 0xffff )
    ; A3 x8 W' ?% y/ [) T( M    {* H4 l/ X) \8 C! m- y. {0 j
            m_OffMapLock.Enter();+ {+ [! d" I; U- t
            m_LockGrid.LockCell(x1shift,y1shift);
    $ E- G- W, o! F' {8 v% z    }
    % V/ h. L2 J( F, Z7 d$ f" L. d    else ; m, {& k9 k( ~5 K/ V& t9 x
        {
    , ]( ?# W# @% K* r, W/ ^, R        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);
    $ D# O3 f- j/ b' W" \" K: `* H    }8 w* m' E: R! ]6 |/ ^7 r  o
    }</P>
    / y$ U$ e/ S7 G5 x# ~9 z, U: ~
    * m# R$ F0 `: f' k, o<>0 l+ q* w0 h% S: ]/ G
    //-----------------------------------------------------------------------------
    ' }3 ]$ v  I, B// Name: 9 Q" z& R7 A2 |
    // Desc: 8 @3 F0 x7 l7 Z2 ^) S) ?0 k: x5 ^) g% V8 }
    //-----------------------------------------------------------------------------
    " R6 \3 Y2 o% ?4 c: Q" lvoid CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    / `+ e$ Z9 G# x& a5 U{" D" q+ G$ u- N9 R# E! [
        if( x1 == x2 &amp;&amp; y1 == y2 )
    7 g9 ^0 s, Q9 c  k! D. C    {
    1 |/ M; K8 V; e        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    % ~! i: N+ o8 }7 ?: n+ X8 s, S            UnlockCell( x1, y1 );
    ) j9 U2 k1 I6 A! [        else  U6 _8 ^! k) {% Q7 H
                m_OffMapLock.Leave();</P>
    ' k8 I6 a* s5 i' B& x* T$ F8 _<>        return;
    # A; r2 W! h' p    }</P>
    , g8 |" z( W# K7 r<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
      Z% R; M# _3 F4 M1 e4 `) t    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;' @# ]# H; ~, n& Y- }7 W. K8 T
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    ' G! i* i! ~, k  T% c: g- R    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    6 r$ S; g  G% Z<P>    if( x1 == 0xffff )2 \$ ^' m- s* s" v8 ]% t! b+ x
        {; m( K9 k0 V0 z9 s/ u
            m_LockGrid.UnlockCell(x2shift,y2shift);* K& E- x* y3 I3 k
            m_OffMapLock.Leave();
    + {3 X# ~1 F; z    }
    " N7 k5 F5 G- O  x/ `9 R8 D    else if( x2 == 0xffff )
    3 {. R0 U$ {: E0 J) l' [- G9 }* |    {% L. b/ @+ E) Q
            m_LockGrid.UnlockCell(x1shift,y1shift);
    0 j% q: x* L9 H2 g7 M( r6 G        m_OffMapLock.Leave();* e! D/ T  {3 Z+ V& b
        }
    4 A/ e  I6 s$ z2 E3 C3 V! R& `7 Z    else
    ! T* o1 H( t/ u; ?  @, O    {$ M" B' f4 `- y
            m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);9 B! i8 M) A/ v+ E% W! y
        }
    & ]; C' X* W% L+ F' I0 \6 B& g% p}</P>
    3 E/ D. U  c2 V
    $ d7 Y: I- |. o8 z<P>$ l4 A( g6 J9 s9 D; E4 W$ s2 Y
    //-----------------------------------------------------------------------------+ X: @0 v* }  r0 N/ g
    // Name:
    8 F3 s- ?2 z3 j0 [* W// Desc: . _: ~, p; `# ?1 Z" s
    //-----------------------------------------------------------------------------
    7 W, @2 C4 G' p9 P( Gvoid CMazeServer::OnAddConnection( DWORD id )
    ) C4 u8 Y6 [4 E' P{: \9 @- I. W5 h2 Z3 _/ x
        m_AddRemoveLock.Enter();</P>" m" B7 @; F' |$ V9 ~  g- Q
    <P>    // Increment our count of players
    " c0 L7 j' O6 w; j( f8 X* ]# a    m_dwPlayerCount++;2 X8 c2 `: m" Y5 T) [
        if( m_dwLogLevel &gt; 0 )
    0 |8 E* ~+ R% w- C8 p/ O3 T    {9 D8 h! s( y" Q! v+ R
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
    ' W/ m4 F: o  E% ?/ `  k% z! C. l2 T+ T$ v        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );" [0 |1 g, z: o0 Y# ^
        }</P>7 Y# U; ^7 C8 D) l+ w# R
    <P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    9 O( I; _  U6 w$ F# w/ j        m_dwPeakPlayerCount = m_dwPlayerCount;</P>
    8 ?- u; [- S, O% g<P>    // Create a player for this client* b- z* U$ k" C3 A1 B6 R" \
        PlayerData* pPlayerData = CreatePlayerData();
    6 F! @! I  g8 }5 C    if( pPlayerData == NULL ): a: B- R/ d1 Q4 K/ E( _7 K
        {- @2 i9 e9 e; G& }2 a6 Q
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );/ G7 i1 i& P7 W+ M5 L( J
            DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );
    7 K3 \; S$ P  ]& E1 o/ K) @8 c        m_AddRemoveLock.Leave();
    ) W; \( V1 n4 Q! ?0 C* z4 T        return;
    0 k  m9 V2 ?9 D4 ~0 w3 g8 o    }</P>
    : e4 [# d) E1 s* B+ T( P<P>    // Store that pointer as local player data  h8 J3 B- h# x; o' o8 o) R
        SetPlayerDataForID( id, pPlayerData );</P>
    3 v! s$ W! ~$ u2 G, W6 x4 o<P>    // Grab net config into to send to client, C# Q8 S3 S: [6 m  w, A
        m_ClientNetConfigLock.Enter();3 e# R- @! H" {( x9 t
        ServerConfigPacket packet( m_ClientNetConfig );
    9 w6 r3 {9 X. y7 b5 o" h" d    m_ClientNetConfigLock.Leave();</P>
    7 s8 Y  d4 A1 ^<P>    // Send it
    : l3 r' j8 S: p3 w$ L8 H    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>/ O6 U8 [' K( J
    <P>    m_AddRemoveLock.Leave();
    # i% b8 [  A7 x8 r+ Z}</P>" B) k! R8 B' Q" K
    0 c6 E" P* c+ n2 a3 @9 z8 R3 l1 K- w
    <P>6 {6 f$ p9 K) u/ ^, R
    //-----------------------------------------------------------------------------' C- I# B. {) X/ S# }( z5 t
    // Name: . `8 o$ ?" [& ~3 i! @6 {4 ?
    // Desc:
    9 `: |/ w) \$ g- X5 o//-----------------------------------------------------------------------------6 O& u2 z% f/ @3 D8 S8 s( W; d* g1 e# F
    void CMazeServer::OnRemoveConnection( DWORD id )
    ! B  w) D' e( C4 M( p- @2 R, S{
    ) Z5 @" q' C# ?9 V( `! a! l* D7 j    m_AddRemoveLock.Enter();</P>& e" G1 L/ M1 `) @' e3 _' q
    <P>    // Decrement count of players# y* g2 |! e2 D6 e  L( L3 a) ^
        m_dwPlayerCount--;</P>0 {( c" y' k5 J4 M
    <P>    if( m_dwLogLevel &gt; 0 )+ Q% N* F; f) P3 M  G
        {
    % O! O5 w. G, H  Q+ G$ W9 g( }3 \        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
    8 F: s9 U& a5 q. e        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    " o; A0 N* S* ?% y9 M. Z- {    }</P>
    $ _  X! S# l' `3 l7 e$ Y* u. A<P>    // Find playerdata for this client
    + g. x/ ?9 h4 z# `$ w8 K    PlayerData* pPlayerData = GetPlayerDataForID( id );
    . ^& B" D) K1 C+ B2 [    if( pPlayerData != NULL )) Y2 M/ d0 `/ u: `6 }
        {1 t) Z$ J: Y5 b! z7 l% P
            // Destroy it8 l' u+ A( z4 l! X- g
            RemovePlayerDataID( pPlayerData );" D. U2 f# L# V
            DestroyPlayerData( pPlayerData );
    3 x, Z, l6 R8 x- x4 e' ?; ?    }</P>
    ) @  \: w6 T( B0 c<P>    m_AddRemoveLock.Leave();
      Y, o0 u; M' o) V4 R+ Y9 z1 L}</P>' S3 P5 E' F4 O: o* b
    / k+ Z5 q$ |: x. c- x, ?6 Z' w
    <P>
    ' L/ J. g+ N) R  p! Q//-----------------------------------------------------------------------------
    6 N* Y" C0 ]5 ?7 D* E2 `& @$ r: o- C// Name:
      Z) X/ H7 Z; W% m( \// Desc: 0 ^- P. L+ X  t5 E5 h
    //-----------------------------------------------------------------------------9 C: S( `& y* w: F: z
    HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )
    , `  R2 |( l% C  t* F0 Y; |{
    # H7 r2 M8 g2 @. F0 k4 `    BOOL fFoundSize = FALSE;</P>
    ) z! v3 I' Y/ R4 z<P>    // Increment the number of thread we have in this process.
      D- f: z$ T/ c* {  h% G" N+ W. L    m_csThreadCountLock.Enter();</P>
    4 ^6 M0 P" N+ m+ }1 o2 j<P>    //Get the start time of when we entered the message handler.
    $ A, V0 |$ \  ~    FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>2 z' f# x% g- `9 ^
    <P>    m_wActiveThreadCount++;
    " x3 s; h1 o8 i    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)+ H1 O( F% ~- w$ ?3 b; ^! j
            m_wMaxThreadCount = m_wActiveThreadCount;& a7 |1 T3 y5 }5 U, R: L- p) H; J
       
    9 l) G$ c9 O; f+ C5 p- I    // Calculate and average.' ]; _1 m* o4 Z- i6 |
        FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;. O# z$ U3 I; O" l) ]+ D
        m_fAvgThreadCount += fdiff/32;8 V  `1 ^( E! _5 W- Y7 B
       
    0 R, u7 t% L0 W. R. Y9 R    m_csThreadCountLock.Leave();</P>, D, }, a+ U2 k
    <P>! a% F2 t2 X" p8 |
        ClientPacket* pClientPack = (ClientPacket*)pData;
    + r6 }8 B  z: A$ D6 _    switch( pClientPack-&gt;wType )
    2 ^. D7 ?* o! D0 a% l' {. `    {
    , g) _% L8 N( B! A4 L' u0 {/ }        case PACKETTYPE_CLIENT_POS:6 h4 }6 E: i$ ^: U/ r% y- A
                $ P" q7 E+ y: l. ?  r' C9 ]. P# ?
                // Check to see if the packet has a valid size. Including ( w0 K8 B, g* }/ J3 ~( Z
                // the custom pack size.
    ( Y, W  Y- G! }3 S            if( size &lt; sizeof(ClientPosPacket))4 }% o+ N5 p$ f" s# p
                    fFoundSize = FALSE;/ f% v9 A2 t* ^+ t. L# g
                else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))1 ]6 A' N$ z- m6 A& W. Z# j
                    fFoundSize = FALSE;
    + F9 `; V1 I# j3 n            else; `- j% T7 R2 ~4 @, D% y  Z
                    fFoundSize = TRUE;</P>- H8 G$ {  M: ~# j  V% P
    <P>            // If valid sized packet, handle the position." N7 S4 S& y) Y% T$ E$ Q  R& {9 i4 b) e
                if(fFoundSize): H, i# e+ K8 G. m' ]6 ~% ]$ w- u9 |
                    HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );
    . c9 {) Y+ B5 r: h% P8 k2 F5 j2 R            else
    6 S6 ]' P) k  e3 z. `# h                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
    4 m& W. }$ B' @; C<P>            break;</P>3 E( r# ~0 l# E& c2 G+ H' ^
    <P>        case PACKETTYPE_CLIENT_VERSION:; K, t: R! w. {. j& k4 i) [
                if( size == sizeof(ClientVersionPacket) )
    + u5 z/ @3 h- y0 T0 h4 k                HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );6 Y$ k' B" `" l6 F
                else; H! V7 r# c' c  t$ X% R9 ?
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    8 E" D( E$ Y, C9 f/ Q* ~' m& @" J            break;</P>
    / U5 M: x5 Y) D<P>        case PACKETTYPE_SERVER_CONFIG:</P>3 q1 p1 N; L% N3 Q
    <P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>- x$ y0 x% E$ d  S
    <P>            break;
    5 q( D4 ]( Y- L' L        default:. N7 w" N: S/ O  X7 p( ^5 V
                HandleUnknownPacket( dwFrom, pClientPack, size );
    ( Q6 c; J7 M3 O& i4 s            break;
    $ f6 u4 z, S- f8 l    }</P>0 }% O7 V$ {) C/ o% k
    <P>    //If the user wants to hold the thread, Sleep for given amount of time.4 y6 W, F- d1 P+ r8 @
        if ( m_dwServerThreadWait &gt; 0 )& n5 Y' y. _$ W) Y5 h6 ]
        {, c- y/ x! \3 t& W
            Sleep( m_dwServerThreadWait );& W. G4 K1 e4 T( g+ ~
        }, \- W, ?9 b; R- v; o
        + H: k9 j0 }, x2 L- ?7 A
        // Retrieve thread data for this process.
    - b, Z) F3 W& l2 Y9 k    m_csThreadCountLock.Enter();</P>( M4 D3 M& r, {6 w6 O& S
    <P>    m_wActiveThreadCount--;</P>
    8 D; P" P% w: C! x2 H1 C<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
    2 B- p7 r0 P! q- t* C+ l0 f( a, e    m_fAvgThreadTime += fDiffTime/32;</P>$ a& T) f* V8 T  i5 [3 Y) r
    <P>    //Get the Max time in the thread.
    ) P% o0 Q) H3 h' W, @) H    if ( fDiffTime &gt; m_fMaxThreadTime )
    1 D7 y) E. m! h' ]: G2 C" T1 ~3 n    {/ a) b# P9 z/ k9 f9 B
            m_fMaxThreadTime = fDiffTime;( y* ~4 [+ @5 A, l5 H* Z: `0 A
        }</P>% o  I3 [5 s0 V. w
    <P>    m_csThreadCountLock.Leave();</P>. }3 \+ f: f  ^
    <P>    return S_OK;
    - |6 Y" ^3 D* ~5 C0 |& p}</P>3 \$ Y2 A! Z" m4 g# W
    9 q/ H: D! n3 p8 L
    <P>//-----------------------------------------------------------------------------
    5 A# k8 a6 j, _& Q// Name: 7 v; I; u/ q" E* x
    // Desc:
    ; W, }+ M0 t* h5 j: a5 D//-----------------------------------------------------------------------------
    ) l! h+ i$ ?% T* eBOOL CMazeServer::IsValidPackSize( DWORD dwSize )& ~% D8 e( [* g  J0 Q0 J2 G3 q
    {
    & ?9 I" D4 j$ N* ?    BOOL fFoundSize = FALSE;) d1 K  d# X, F
        BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;
    4 |- ~& v+ Y2 a  ]( l* {$ I( `: E: p    , b/ e7 U( J7 Q% M
        // Check through the array of valid pack sizes.( V! O" x: O9 T2 V! w2 _
        if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    * z5 [& ?3 |9 u    {. w- ^: A4 |6 J% ?7 _- G  v1 |
            for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)
    ! G; O  V# g9 W# y* v8 X; J        {' B. q7 R  f' c8 K
                if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])3 r  s" Z: V1 o5 {3 a7 P3 w
                {7 \" n. F* d" {1 l
                    // Found valid size in the array.
    ) P4 p( Q% Q  y. [! o- T% q                fFoundSize = TRUE;: u' M7 `$ |3 C) G. S% I) ]; q
                    break;
    5 M* |7 t+ d9 j/ i/ l3 W5 W4 l* m            }" t5 _" F3 x$ a+ l, a4 l2 `
                if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
    ; k3 p# t% M) }7 [4 d8 {        }3 n# l1 c1 D5 o; ~# W7 R: Y
        }* P; ~$ w( w0 @. B
        else% |% x% i9 B4 W
        {
    5 F2 s, U# g/ G8 u! E( }        fFoundSize = TRUE;
    + F7 L8 l3 a8 W( [( K    }</P>1 b: T- _8 Z; O
    <P>    return fFoundSize;0 Z& R6 Z  f8 @8 M; M# Y, d  t! ^& H
    }</P>
    3 e2 n' l/ I# L* A" B3 c/ {8 Q7 Y<P>
    6 I/ y/ y, A$ l+ d$ o! P//-----------------------------------------------------------------------------: c3 \  u! d& Z8 y
    // Name: ; R4 y3 j5 p6 \4 G( v( O) ]4 ~
    // Desc:
    8 s. S7 q+ ]+ ?6 X4 F. n. F- g//-----------------------------------------------------------------------------1 l( F3 x' O6 j4 S
    void CMazeServer::OnSessionLost( DWORD dwReason )# K1 k. b. ?, Y& ~7 `* N
    {" i3 `7 g. W0 `* m0 K- A
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );4 K) u, m2 C% g( a% ?
    }</P>1 G: Z# ~% Q6 I
    5 L1 R% b  S; V% L
    <P>9 m' E) b5 }9 O% S- t0 N! D4 l& e0 }
    //-----------------------------------------------------------------------------3 ~5 @" o0 I$ O" ~1 ]
    // Name: ; x. L1 A7 ]& I. `; k9 h5 A
    // Desc:
    / ^2 K/ c' I3 J: B& g- J//-----------------------------------------------------------------------------
    : G0 T4 A7 {; s, J2 H2 P+ |PlayerData* CMazeServer::CreatePlayerData(). T, U; N4 g, s! e! z2 b- e
    {
    % b$ ?3 R2 O, y. S3 D& y  B% d0 K    m_PlayerDataListLock.Enter();</P>0 D) f+ A- s/ d: b9 t6 A
    <P>    // Grab first free player in the list
    7 O, @7 F4 D* W& b+ v    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>
    " k+ N/ x0 d6 t<P>    if( pPlayerData ), [! r% q$ f; U: b: s
        {
    & p4 T; Y  I) z. V        LockPlayerData( pPlayerData );</P>  u4 @% t2 D. b. R* ~5 g$ h0 D; w
    <P>        // Got one, so remove it from the free list  d4 c; O4 g2 w- n
            if( pPlayerData-&gt;pPrevious )) _; B1 I0 M. n/ J7 ?; e
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;0 e5 O; E% d* o$ x3 C" q
            if( pPlayerData-&gt;pNext )
    ! J& `% u; C% z1 a- m            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;+ [* G  n6 m2 d: W
            m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>
    % M4 I$ o9 d# ?8 L  W$ {0 A<P>        // Add it to the active list* G2 E, _$ Q9 @
            if( m_pFirstActivePlayerData )
    8 L0 U, S9 y; \8 f) V            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
    ! ]1 [: R- r: _: J7 {1 E: ?6 q        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;% q0 J2 d$ T7 x2 B) z# s1 y
            pPlayerData-&gt;pPrevious = NULL;. I! P0 X: Q. A( p
            m_pFirstActivePlayerData = pPlayerData;</P>( q4 \$ K- r5 [
    <P>        // Update count of players3 I/ P4 F; x/ H1 ^  q9 d, n
            m_dwActivePlayerDataCount++;</P>$ m" D. z  t3 c
    <P>        // Generate the ID for this player& N: q% [7 n3 o! H
            m_dwPlayerDataUniqueValue++;5 i0 u: J  D& T3 u: s8 C9 J5 y' d
            pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>, F) u) Q3 z6 [' W
    <P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
    4 p+ |; H& X" n  ?- j6 r9 m        pPlayerData-&gt;NetID = 0;
    - C  ~3 a; T; _  m        pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>
    * S+ k# A0 y7 ~% B6 f/ H<P>        // Insert into the "off-map" cell7 O. J# L$ p- v
            pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;
    + D. S8 L6 Y: ^' V( ]        pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;
    / K; @4 ^8 d+ W/ ^' U/ R+ F        m_OffMapLock.Enter();
    ! X7 b3 ]8 K) Z        pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;; q& i! t8 w0 x' S
            m_OffMapCell.pFirstPlayerData = pPlayerData;
    ! G  ~7 {, @- c4 ^$ x, q; k3 @( w        m_OffMapLock.Leave();</P>
    - M3 r3 }; P$ U7 _5 ?  u( ~<P>        // Mark as active$ M8 e- }, |2 v) e& ]0 D6 v& N
            pPlayerData-&gt;bActive = TRUE;</P>
    . x+ g) J* I- C+ z<P>        UnlockPlayerData( pPlayerData );
    3 w+ A0 b) p  H/ h: R    }</P>" F; P4 B* d. Z3 \5 b3 }* Q7 o
    <P>    m_PlayerDataListLock.Leave();</P>6 D0 c$ C7 Z1 l9 h
    <P>    return pPlayerData;
    ! i1 G( k3 q! b+ b" E}</P>
    . g* K6 |( Y. g7 F" T9 A( g. l# E) x" ?& L0 V% c* f
    <P>
    / Y. m" `. o  K) f1 Y% n$ g, D6 J# W, J//-----------------------------------------------------------------------------8 `. V* {, {) S  u& `3 ]  c/ U, C
    // Name:
    # {! y) W' [8 b6 L// Desc: - L# ~. l! B3 Z7 [1 K
    //-----------------------------------------------------------------------------
    , `, q1 f  C! C/ r7 }0 H+ E( Wvoid CMazeServer:estroyPlayerData( PlayerData* pPlayerData )$ n3 J8 _/ x+ b8 q( |0 v% Q$ M# ]) k
    {* ]) n3 ^0 c2 h, [4 H% B& ]
        m_PlayerDataListLock.Enter();; V4 R$ R: d  p7 z! i" q: {& M9 D
        LockPlayerData( pPlayerData );</P>
    * g0 Q9 C9 o" I) M8 r4 |2 q& ^. g<P>    // Remove the player from its cell
    ! b5 {* m# p3 |9 ?0 I    RemovePlayerDataFromCell( pPlayerData );</P>
    " _6 L) ^9 _/ e+ B+ I! O<P>    // Mark as inactive" i7 e) D. C6 \
        pPlayerData-&gt;bActive = FALSE;</P>/ q: t" j; _5 g2 q7 d
    <P>    // Remove player from active list
    % Y( c0 `$ h( H. y$ D2 _$ G    if( pPlayerData-&gt;pPrevious ): T. A  ~% Y4 y4 Z+ C. l6 E
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    * d3 q& A6 N  j% T. y% ^9 y7 @& H& a    if( pPlayerData-&gt;pNext )) e' x4 V/ E3 p* R$ \
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>
    8 n# N( s& I/ D<P>    if( m_pFirstActivePlayerData == pPlayerData )
    3 J( f7 S+ K' C  V+ U        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>9 p, _$ V) T0 W0 p
    <P>    // Add it to the free list' B& Y( p1 H. L4 W' T
        if( m_pFirstFreePlayerData )
    9 l: \4 E$ U2 T* @9 h( {        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;: l0 _$ Q7 q+ B8 B- K7 U
        pPlayerData-&gt;pNext = m_pFirstFreePlayerData;
    % A0 l3 R+ i8 [0 W    pPlayerData-&gt;pPrevious = NULL;
    * j: L5 Y2 b* @/ X( _6 q7 @    m_pFirstFreePlayerData = pPlayerData;</P>
    0 E/ r7 D, [6 I6 c<P>    // Update count of players
    . @$ W& Z( B7 N% C- k    m_dwActivePlayerDataCount--;</P>) D- f" l2 V" S' P$ V% ?' Q$ s
    <P>    UnlockPlayerData( pPlayerData );  s* i3 H. L: y$ O/ r- k
        m_PlayerDataListLock.Leave();0 u' b8 C/ H! p% `
    }</P>
    0 f/ z; n& `% F0 t* W" j" Z. Z. s- y  |2 P# `4 A
    <P>
    & y# D. _' K9 i  O9 j2 j4 h//-----------------------------------------------------------------------------; G- M- Z; s; N) b. p, Q  S
    // Name: ; N( o) h( z" y) q
    // Desc:
    7 z- t) h" |# [) H4 v/ I8 `8 ?/ q//-----------------------------------------------------------------------------
    # m. a8 S/ o/ N4 A% qvoid CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )
    : y2 O. g5 J* m6 ^' r2 K- Z9 c9 s{
    . w6 U3 i* S3 h* `    // Lock the player
    ; x, F3 U9 _7 @# a9 ^* H5 M    LockPlayerData( pPlayerData );</P>7 `' n9 [- j8 S' r/ ?7 J; }9 g
    <P>    // Lock the cell the player is in& I# O* G1 n$ X( z0 X1 M) R  D
        ServerCell* pCell;
    6 z' r) g7 V3 s) L: N$ O    if( pPlayerData-&gt;wCellX == 0xffff )0 c. A$ Q8 `, t& s9 ?; X
        {
    / b/ W* a; A" X! }" z$ S7 {+ d7 N0 e        m_OffMapLock.Enter();+ c- X0 v0 X: Q% Q: @5 ?
            pCell = &amp;m_OffMapCell;1 u0 q' ]9 n/ T0 N6 m
        }* P, a5 g2 E( K: ~1 T: I0 j
        else+ y( e4 e# M. f1 m
        {4 m' s# w( D! N. p) h
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );
    ( P- Q( |2 q! _0 u( S) v- P! W        pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];# O. {6 L) ?, j, q
        }</P>
    ! s8 T) Y1 x# a: g7 a<P>    // Remove it from the cell
    9 D3 h) V; O4 `* u    PlayerData* pPt = pCell-&gt;pFirstPlayerData;$ |  T4 D) }- D( _
        PlayerData* pPrev = NULL;
    ( G# X8 F2 X) x. R    while ( pPt )
    - _* O8 k0 l7 E3 H% U! u9 k    {& @6 |8 x% A( x7 ?' w0 q+ F
            if( pPt == pPlayerData )
    4 a) o' Z6 \; v3 Y9 M4 O        {7 A  r4 r! }  v* T
                if( pPrev )
    ) S1 O6 E7 c6 @8 A! S7 f! D                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    & V' b5 o6 r- [9 @            else& `* U2 m; r( `1 n
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>& [* u8 m7 a% f( c$ q
    <P>            pPlayerData-&gt;pNextInCell = NULL;
    " a" A) ]/ T, t3 v  V- f0 T            break;' `5 ]: g2 X2 [0 t$ I
            }
    ; U3 E1 U4 k+ h( a" A) O# a9 m& l. p        pPrev = pPt;
    ) c. ^) z/ [- \/ h        pPt = pPt-&gt;pNextInCell;0 h  x% M7 t) j3 p% ?+ z
        }</P>
    ) K9 [) r4 Z! G6 `<P>    // Unlock the cell- C; \- g" v, N8 k" H, B4 h
        if( pPlayerData-&gt;wCellX == 0xffff )
    0 o' k5 A1 ?5 }) {- f6 {  y        m_OffMapLock.Leave();
    ! `# n2 G! z; A: O    else
    * \1 j0 k! O; R        UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>. U8 u0 ]( M- g+ z  [' n/ w: w
    <P>    // Unlock the player4 q+ j1 S9 @5 [6 [% t
        UnlockPlayerData( pPlayerData );
    5 G" z& k; g, B1 A4 g( q& r+ |}</P>/ o, Z/ C; A: v9 _* Q% r0 E3 e* n2 R
    4 F) B" k  M. v. O( f
    <P>
    " f: B4 b6 P% f0 h; C; H* l. {* q//-----------------------------------------------------------------------------$ `3 |/ k* \4 H
    // Name: 0 \; h3 w1 V: ?3 U
    // Desc:
    " ?0 Z8 i6 E  s# t//-----------------------------------------------------------------------------0 k/ m+ M3 |* p$ p; `. o- s
    void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )- O4 ^0 e1 ~1 a1 {3 M& P
    {, B  T' m; g" b* ~
        ServerCell* pCell = GetCell( pPlayerData );, ?( C/ u# L. L# c! b
        PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
    2 u5 O6 ]4 R& p8 o& _3 X+ f    PlayerData* pPrev = NULL;
    6 E8 a/ A/ k" ?* W$ L" d+ ~! ~% s    while ( pPt ); v- H/ [2 y4 l+ T8 R! J3 G
        {
    # l; p3 V! j+ \3 b5 l        if( pPt == pPlayerData )
    / ^( ]# W2 R* d! G4 U% m# z        {7 p8 E% E; B7 m) U: n, ]( L
                if( pPrev )
    ) u! y0 O' L2 |& t+ \$ ]                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    8 Z! O- }. g# x) Y# R            else
    2 j: [, A/ |  `, }1 b                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;( d" o0 y% @( c/ M
                pPlayerData-&gt;pNextInCell = NULL;4 M4 x3 p7 l" [$ \
                break;7 I0 @  t* L' V9 F
            }
    # y/ G/ m& J- t, Z. F. j. z7 _        pPrev = pPt;
    ) m' {5 Y  q! ^6 `9 k        pPt = pPt-&gt;pNextInCell;8 O1 _5 V, K6 u. P6 [( p/ g* h7 }3 G
        }" E: l$ m' D0 Z
    }</P>
    7 ?* K4 o& ?' y8 m' p' W7 e- y1 T; g" Q
    <P>
      u/ ]' s; p! V//-----------------------------------------------------------------------------
    0 T! H3 b2 P, h3 v/ h* }9 b! J+ C- R// Name:
    : C0 k8 e. |: ^2 p$ i// Desc:
    7 l1 C9 X6 V6 G2 l0 w//-----------------------------------------------------------------------------3 ?& @- ]1 j. M# P
    void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )5 Q, [4 \' {- ?1 |
    {
    2 s' d( \! V1 ]2 p1 n    ServerCell* pCell   = GetCell( pPlayerData );9 _0 L. m( n& _+ F. L6 S6 S
        pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;
    ' t& t" K2 g$ i  k2 k    pCell-&gt;pFirstPlayerData = pPlayerData;
    8 ]$ Y) j+ A7 \8 w3 [8 P}</P>4 {! Z# X! Z4 C6 i0 T2 g) [6 z

    1 X6 w1 v* P' e, H. x8 O" M<P>
    # W; S, o. f2 i# R& e0 `//-----------------------------------------------------------------------------, Q" N, r% W  `! s* |! X0 n, _
    // Name: $ I, ~( E* Q! S: `5 f
    // Desc:
    9 B. D8 |$ M( K2 t6 Z//-----------------------------------------------------------------------------
    * y$ U/ v3 G7 \9 B. Uvoid CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )+ S% [& x8 O5 m7 M( j: i
    {
    2 p* y) p, u3 P3 S    // Grab player for this client and lock it; R3 B, r8 W1 `
        PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );4 B0 \" D0 T# f
        if( pFromPlayer == NULL ); b3 s; m" o6 M3 h: k
        {+ m: J& R3 f" E0 U
            if( m_dwLogLevel &gt; 1 )
    & J; T8 w& b  b5 O3 \0 i8 C+ J            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );# X# J3 }8 J& e' g; g$ y
            return;% E1 L8 X; W% f0 P4 c
        }</P>% s; |' i* G: n2 P- G* y
    <P>    LockPlayerData( pFromPlayer );</P>
    " }& @5 ?) i( D' P6 i, G<P>    if( FALSE == pFromPlayer-&gt;bAllow )
    5 a- Z# J5 W: q    {* x) R9 v  T7 v8 x$ r
            if( m_dwLogLevel &gt; 0 )$ O% M, t* `2 k2 A
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
    9 v& O3 {- k$ B<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );2 s% U) C. s5 e: D
            UnlockPlayerData( pFromPlayer );- e5 q- |+ \4 a5 D
            return;9 [6 u8 F$ b/ b' r
        }</P>
    9 u1 p* ^+ V6 G7 r& z<P>    // Compute the cell the player should be in now
    # v$ o$ f/ u8 T4 I/ [9 U    DWORD newcellx = int(pClientPosPack-&gt;fX);: R9 N- T% {6 G: q" j& y4 Y! M9 |
        DWORD newcelly = int(pClientPosPack-&gt;fY);
    9 @3 T0 v' _/ G; p5 ?    DWORD oldcellx = pFromPlayer-&gt;wCellX;( _4 D5 k* W6 f2 _5 r- t% z
        DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>1 \7 q8 B! \1 k* f/ o
    <P>    // Have we moved cell?/ O4 z" R$ W( U) ^
        if( newcellx != oldcellx || newcelly != oldcelly )# F' W) l# }4 R0 L- |' T
        {4 u1 h8 U+ ?1 Y' I+ {8 Z
            // Yes, so lock the pair of cells in question
    ; N4 {4 ]+ U" @: Z9 G        LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>) M2 V# G) I8 Z5 h. i$ g' U4 f
    <P>        // Remove from old cell and add to new cell+ N2 E* s' B0 ~7 R! ?$ b) n
            UnsafeRemovePlayerDataFromCell( pFromPlayer );' J6 K( s  [6 ^* T2 `  K
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    - F& c: t' j0 B0 h        UnsafeAddPlayerDataToCell( pFromPlayer );</P>
    5 H* V# L. [8 h0 c% y& \" G4 J<P>        // Unlock cells% C* k0 J( {  v! N% N+ e# n- I3 \
            UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );: {  p; Z% k  e# \0 w5 m
        }</P>  L9 J" e; ]$ L$ E! P6 U0 \
    <P>    // Update player position! q3 X0 [6 u4 d. _0 J6 t
        pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
    ) `" n3 l2 k7 a/ ^; ^5 o    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    : x: N0 G5 m; p# |4 W; L3 j    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
    " m' q% M: j7 @/ T6 y5 ?<P>    // Allocate space to build the reply packet, and fill in header
    & n! q2 O' M' N3 {7 V  S8 W) [    DWORD dwAllocSize;( s9 m# b+ e9 H/ v: c
        ServerAckPacket* pSvrAckPack = NULL;</P>
    # {1 N4 ~: H* W" K. a/ Z<P>    // Begin by allocating a buffer sized according to
    2 ]- P) e4 L  L" z. h; T    // the current number of nearby players + 4.  This will give
    # t& U8 v6 l- ?2 e. R1 S    // a little room for more players to come 'near' without resize6 ~" j: ~$ r! L; h7 C
        // the buffer.# i- n* o/ g- `! i# P) d& n0 r
        DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>3 ]2 z& W/ R1 I7 ^6 Z0 n
    <P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);+ L% ?2 f7 @, L- e2 ^
        pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );" b7 l" ?/ t  ?
        if( NULL == pSvrAckPack )
    ( n; x3 L2 M8 ~0 S: Y    {1 q4 `" S/ R; Q! B( `
            // Out of mem.  Cleanup and return
    6 V% `4 [2 g5 N* ?% C        UnlockPlayerData( pFromPlayer );9 G2 W$ U5 m1 h
            return;       8 E0 a" H' U. }7 e
        }; }4 Z) h, _8 U0 q" j6 e
        ZeroMemory( pSvrAckPack, dwAllocSize );</P>3 o. ~7 l5 I& l; [1 b. A1 C% c; E6 o- i
    <P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);
    0 ]% U' R7 T4 `1 E    pSvrAckPack-&gt;wPlayerStatePacketCount = 0;
    % ~, R" U5 V* Q4 x2 p% M: J  o    PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>
    . X0 V, P. p! U<P>    // Compute range of cells we're going to scan for players to send3 I/ ~6 t5 o$ c$ j
        DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;; U2 }# p4 H+ F+ @/ i; S
        DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
    ! o% Z" J& N0 V2 f/ B    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;. A! b  t/ U9 s( m% i0 y9 `" r( K
        DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>  J9 i5 O$ a. i! d; u
    <P>    // Lock that range of cells
    + |( ?( W4 k0 @) w- e& R    LockRange( minx, miny, maxx, maxy );</P>$ C' s- u9 K6 V! {
    <P>    // Scan through the cells, tagging player data onto the end of
    ) q+ U/ S: J+ Q, U    // our pSvrAckPacket until we run out of room
    ' z' C4 }1 j! Y- j- _    for( DWORD y = miny; y &lt;= maxy; y++ )
    2 q: y& d" t2 h* D3 p- P    {
    ( k6 s" z) v2 [0 C  {+ n' P! O9 g        for( DWORD x = minx; x &lt;= maxx; x++ )/ v( k3 L* J0 N/ f7 I. Q; y) L  r
            {
    / G. J2 I+ f7 A- R" l( _! c. ?6 I            PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;
    & D% r" f2 J" F( n; K6 ?            while ( pCurPlayerData )
    ! S+ L# Y* T. S- H, D! }            {5 A" w) G3 G  q& \& c9 ]% p0 }
                    if( pCurPlayerData != pFromPlayer )
    6 n7 h9 E/ F+ [; [& \" ]                {
    & ^3 j% Z2 \# E7 w6 o                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets ). z9 c6 x, Q0 J
                        {( ^* v) c# ~" R& G6 t% C
                            // Make sure pChunk is where we think it is5 W9 V' t/ ]/ H; _3 E" C
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>& i% c; {5 e2 c) d+ {
    <P>                        // There are more than just 4 new nearby players, so resize the
    : N$ p! T2 G) E                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
    7 J9 Y! G# F2 g' \" k) K                        dwMaxPlayerStatePackets += 16;
    ' W2 ]- j% |) t! L2 G' t                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    2 y' \7 u  P; L2 _7 [% d                        ServerAckPacket* pNewSvrAckPack = NULL;  x* s8 Q. L, U$ [; ^
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    ! @" Q4 H5 n* e8 i/ T                        if( NULL == pNewSvrAckPack )
      k1 ?/ r- X2 j: H% c4 Q  G- F                        {
    7 r. c6 `# j9 D                            // Out of mem.  Cleanup and return- z4 U, x6 A- j: z0 m! a; d# N+ ~
                                free( pSvrAckPack );
    ! v. y, k$ w" A: q# N+ f                            UnlockRange( minx, miny, maxx, maxy );8 w& z; y1 G$ {4 @2 l2 x' @8 q
                                UnlockPlayerData( pFromPlayer );- ~/ P* z1 I, {1 Q7 v8 j5 z* H
                                return;       + P+ ]/ r2 q6 d" Y" x1 A$ Q9 [
                            }</P>
    6 r" T& h* p: s# w& Q1 `<P>                        pSvrAckPack = pNewSvrAckPack;# @4 D- o$ H1 D8 ?$ Z! c1 c
                            pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
    " @! _0 Z4 L+ g" \( m. C<P>                        // Make sure pChunk is still where its supposed to be
    $ z8 |, H/ [9 H0 v2 Y9 i" n                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );/ v5 o3 E* E) ]  j9 v4 n# U
                        }</P>9 b  u2 C7 V" ~! Z
    <P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;: A6 U1 W) p) H9 a  [
                        pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;7 |" x. {- `" {* [$ [+ K0 X& \
                        pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;7 a( K7 d4 D$ _
                        pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;
    4 I/ S+ t" I! s                    pChunk++;
    % `0 [2 M4 ^2 }$ a' o                    pSvrAckPack-&gt;wPlayerStatePacketCount++;# Z+ i* K$ s; D9 X7 o) G. p
                    }! U$ y; a9 N( b+ j/ C- A
                    pCurPlayerData = pCurPlayerData-&gt;pNextInCell;. @( d( {) ~+ h. c. T. Q6 x) e  M
                }$ T1 I$ s4 q! T3 p4 N& o
            }$ a/ O3 U; R6 U, H; c
        }</P>
    ) e/ E; {" k. B<P>    // Update the dwNumNearbyPlayers for this player( e+ J  H. H( l, F& ~" L* H
        pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>
    1 b" Y7 \1 n8 z/ y5 Z* h! X<P>    // Unlock range of cells7 D5 L/ |, P+ c. q0 U
        UnlockRange( minx, miny, maxx, maxy );</P>7 S7 e4 Y* v2 ~1 ^0 b  V9 _* h' W
    <P>    if( m_dwLogLevel &gt; 2 )
    * w9 p" p, x5 G3 A* E6 `  A' c    {% H' y0 V! t, X5 {$ b( r
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );& j2 D9 z& R. i, F3 w5 H3 g: R
        }& Y3 Q: M4 q* W. d/ C
        else if( m_dwLogLevel == 2 )( U/ X  ?: j" l! w0 [
        {- {1 ]/ m+ P/ T7 }
            FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    $ u" S) T6 I! S2 `        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )
    4 n3 z6 j; F# L8 R! p* y        {
    6 B0 Y; w" j! N0 z: g3 A0 Y$ F" a1 Q            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );4 s- P* o2 M( ~, G, M
                pFromPlayer-&gt;fLastDisplayTime = fTime;( N. j8 m. M8 b! k  R6 ]
            }! v. k' n* C4 P( q
        }</P>
    % H' j/ Y' i, R- r2 Y4 A# i<P>    // Unlock the playerdata  [7 O5 c. N3 _/ a$ |3 X
        UnlockPlayerData( pFromPlayer );</P>% R1 Y# H8 s2 ?
    <P>    // Send acknowledgement back to client, including list of nearby players
    ) b) ]2 u% V! d    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));) t& v9 a7 @" L6 N5 D# ]% z+ N
    ) {8 `- P/ z! y& O1 P$ b
        // Pack the buffer with dummy data.3 J/ s1 Q+ j/ i( Q
        if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)
    : f( f* n4 J+ k" {+ s    {0 L2 Q) }; H8 I. B
            DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];2 h9 w4 S- k- x( y
            VOID*   pTempBuffer = 0;</P>
    & i9 k2 D" H& K4 S<P>        pTempBuffer = malloc(dwBufferSize);; ?: D. }+ Q9 `
            if( NULL == pTempBuffer )
    9 }1 ?7 o) o8 K- e( O        {
    9 y* u* l3 U5 M" ^            //Out of memory8 }3 j7 B: C( v( w5 z0 z/ [
                DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
    + g5 i, M% o$ R4 `  t            free( pSvrAckPack );! e5 }, e, S! x
                return;9 {, R2 Y  @: f) c4 b: Q
            }</P>
    1 {6 Q* ^7 D1 N6 F3 Y- I<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');2 ?" _3 j& F; n  Z* {3 l6 o
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>8 w/ T0 A1 I& I5 L( [; R
    <P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );8 E0 M# @1 G9 d7 W7 A; s
        5 p8 g3 x7 T" J% D/ m6 e% O; P+ i
            free(pTempBuffer);
    4 _9 W# m: c7 H- s    }   + ?' I! ?# E, L( G% D7 I
        else% W' E$ b  T, R1 ]# ~$ N$ X+ s" n3 m* l
        {" ]: y/ B4 w$ R4 Y3 d
            SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );& U# b- ]4 k- I' `2 ?
        }</P>
    . @4 w: l5 z0 f& u<P>    free( pSvrAckPack );</P># u. y5 a' c, H" r3 }5 k* N
    <P>}</P>2 R5 O9 p$ A& q5 v& w/ l

    * v1 Q1 v  M' {4 C1 _<P>1 N( o5 o) C# G  A5 p6 G) x
    //-----------------------------------------------------------------------------" h% i9 K) f# Z: h' q4 J! T7 B( j
    // Name:
    ! B$ K% G# C# c% |1 u" W: [; ~8 s// Desc: 2 k3 C4 L& O* p( T
    //-----------------------------------------------------------------------------
    7 R- t& l" E8 O1 ~1 m1 O4 Svoid CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )5 B& ^: ]5 ?9 g" }; N& L% a
    {
    " ?7 P  P5 v8 z& C    // Grab playerdata for this client and lock it: U( M, t  M) x. |6 }0 Q
        PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
    / i" \  y1 y9 @0 z3 X& o' E/ O7 L0 E    if( pPlayerData == NULL )
    + c6 B( F$ [2 t6 X1 [        return;: T" y: P, x( R  M: O1 r
        LockPlayerData( pPlayerData );</P>
    $ y: ]  l. K2 S) Q4 a8 `<P>    // Record the version number 3 s3 Y# A. m3 j& Z7 s
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
    8 P+ U$ P" F0 N/ v" j* S  b5 N<P>    if( m_bLocalLoopback )
    4 {; V1 |' y& p5 u. Q        pPlayerData-&gt;bAllow = TRUE;
    " y$ S4 H" ]1 @' ^3 k    else- N6 W7 E# J! T" L0 j1 G
            pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>; R/ x( F+ M9 L; X3 c' d  h
    <P>    if( m_dwLogLevel &gt; 0 )- Q+ ~9 k2 x  W3 x
            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>! u  T! e( f" |+ g
    <P>    if( FALSE == pPlayerData-&gt;bAllow )6 K7 ^# }; w: Q
        {9 P' _. h9 O" ]7 {. o. o
            if( m_dwLogLevel &gt; 0 )
    9 C0 N$ ?! ~/ F; _7 h3 S8 o            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>
    1 _" r+ K2 z" t/ Q6 A; \7 `<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );  p. b9 ^" K5 f5 x' U
            UnlockPlayerData( pPlayerData );
    ' s% v, n8 d( I9 c# D2 u* M        return;
    * S' X7 T' Q8 H* c2 M    }</P>4 o% m# b  o( }/ S+ @" T1 U. l1 C
    <P>    // Unlock the playerdata
    ! l  u% j$ i- j; s: G5 {9 u    UnlockPlayerData( pPlayerData );</P>. Y7 g. Z: u' E+ j+ g
    <P>    // Send acknowledgement to client that the client was either accepted or rejected
    0 C  }9 ^8 X$ i# F5 H9 `    ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );- i. z! p8 N3 G2 y" }# f& b9 U/ I
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );, x) z4 I% Y3 U0 {* r( c3 z
    }</P>1 p1 k7 N& E; Q6 _, l/ O

    : B; k; S! l$ p5 l<P>
    ! L  T5 C. m' k$ ?1 h& W//-----------------------------------------------------------------------------
    2 X# X/ n% P) |- _0 M# ^4 Q+ i3 p& _5 f// Name:
    1 e1 y$ g( n  M// Desc:
    5 C7 w0 @7 y8 v0 g$ U//-----------------------------------------------------------------------------
    2 S* v, U  j/ B0 X0 Q, P( O$ bBOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
    / d6 W! a6 T' S{/ W" a0 a( {2 ?$ {2 F
        switch( dwClientVersion )
    7 P3 I9 W1 W1 u# q. C- I7 g: h( s    {
    9 s& w4 X. l; F2 }0 R& @8 @3 S  h        case 107: // only v107 is supported7 {0 e; t4 G8 Q9 K/ F
                return TRUE;
    ; e" Z9 a; W# R        default:
    6 I* T* c# l2 ?8 d( B! ^5 C            return FALSE;
    " ?: Q5 a+ n/ U+ @1 S    }9 X3 m. b/ T! F! v# N
    }</P>
      ]/ X2 `8 P, K6 I" ^8 x4 M1 x9 V) u: _0 t. t
    <P>+ |* P$ S- p  Y+ ]3 d0 D
    //-----------------------------------------------------------------------------: Q. v4 n$ {" {  }* t% X
    // Name: & a1 D$ V! g" W; B: a0 ^
    // Desc: 5 a  R, ~1 E1 k$ S
    //-----------------------------------------------------------------------------5 u" d. ?: a0 b' g$ e" J
    void CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )9 G0 v6 {/ u% }5 _0 l6 w& V0 F
    {
    9 [) }0 |$ v6 c- l    if( m_dwLogLevel &gt; 1 )
    " ?! M, i* q) F1 Y% V3 l9 F        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>
    3 ~& i- f3 H% A# z& W<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    ! R3 j& ?" O3 V' |$ A. Z" }0 R3 X}</P>4 B) [' \. y9 r- d

    7 L: u% j2 c$ K  ?9 e<P>
    " b4 R% B5 Q4 W8 T//-----------------------------------------------------------------------------+ v6 w# [) G5 \* E; Y$ ]3 Q
    // Name:
    : E; I# H: f7 Z8 B// Desc:
    2 v& B0 i/ V* }+ H& P//-----------------------------------------------------------------------------
    + B  X2 k$ S/ QDWORD   CMazeServer::IDHash( DWORD id )
    - G8 i1 X* ~( L" J  V{7 ?- A, f6 Q; F+ j7 y3 Q6 D
        DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);/ o1 i! l. A1 S) f( ]
        return hash;0 [$ e( X& k- r/ a- P. L
    }</P>$ _( r/ u2 f) I, x7 b

    " D5 d6 h3 a. D$ T<P>
    , P0 L+ K# h: I" [. J, Y2 T+ \//-----------------------------------------------------------------------------
    ' x$ b, {: U% M  ?; x' h1 Z// Name: ( |5 ^3 J% ~  z
    // Desc: - Y8 g1 d" l8 w9 H& k7 [  G* Z
    //-----------------------------------------------------------------------------
    $ L1 n) A- I' H* _' k" I1 {void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )$ C! D0 @9 [& c# m
    {7 H  g: u7 Q, z7 T
        // Hash the ID to a bucket number( ]& Y2 R+ m' [, J+ `" I
        DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>! x+ F$ M) @0 c. Y/ r
    <P>    // Lock that hash bucket) e  @  X9 S. m+ e
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    / t( h$ o% l% l9 M( q4 k! w( {    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    0 z6 g1 W& |$ N+ u( I<P>    // Loop though players in bucket until we find the right one( l) V' ~7 h5 E8 t* P
        PlayerData* pPt = m_pstIDHashBucket[bucket];
    0 }: \6 Z+ j5 a: X. c" w    PlayerData* pPrev = NULL;
    - K) z4 W0 b  m3 D  g3 o! B( f    while( pPt )4 n4 F( @& M2 {, y5 Z
        {
    6 U! c! N( l7 D* Q0 ~3 w& q' f+ i  i        if( pPt == pPlayerData )! ?6 p+ g0 s  S$ w7 H5 H2 i) L- b; o  |
                break;
    ; b* b6 ?# S, |6 ^        pPrev = pPt;
    5 g  E  @+ K1 u9 O        pPt = pPt-&gt;pNextInIDHashBucket;
    7 R9 P/ Z" n* `( a3 B! d    }</P>6 z( _* N. h7 n6 K% X# C) W
    <P>    if( pPt ); q+ N! V" v* N' U1 \
        {0 r1 n3 j( l; S! \9 }% y
            if( pPrev )
    ! \# n0 K. E$ }! l* V            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;
      ]2 ~) w0 Z. j  O5 S        else! C5 Q, x5 P8 N% k: w. k+ E" ]
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
    5 Z! _( j3 v: w( i0 `        pPt-&gt;pNextInIDHashBucket = NULL;5 h/ c; ~* q3 m7 V5 a
        }</P>3 }2 z# t- `' X  n+ F4 I& f/ B
    <P>    // Unlock the hash bucket
    ' u2 f/ \  v  p3 K% A) P    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
      u( c% ^$ E( p8 c7 S. o: r3 v* m}</P>1 ?" ]  M* u4 h# w8 {+ u/ B
    % ~1 g/ t* w' ~0 y) R6 f% z
    <P>6 b$ g/ N, Y5 T
    //-----------------------------------------------------------------------------
    ( J# [/ V+ x6 Q( |6 `8 c4 u// Name:
    ) W/ X2 ~0 P  ^$ [1 R// Desc: ! ]4 l: ~1 S  j: y2 y
    //-----------------------------------------------------------------------------4 ~) ^7 _( F# _" v+ S; }
    void CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )1 H- o" K" {8 q  T7 n
    {& N9 b4 F, M) E" g9 n
        // Make sure this player isn't added twice to the m_pstIDHashBucket[]
    % ]+ _! C& r0 p8 S4 N    // otherwise there will be a circular reference
    $ X7 s) f' @2 E    PlayerData* pSearch = GetPlayerDataForID( id );$ I  S9 R5 Z( O  ~: E/ \- ~
        if( pSearch != NULL )1 Y( {& i- I8 j; X- n( X) \% Y
            return;</P>  @6 ~. h1 p! s" I! u: O4 {* r- X
    <P>    // Hash the ID to a bucket number! t/ {6 {+ K. x
        DWORD   bucket = IDHash( id );</P>
    ( g; a4 |( n# t8 w. L- A5 d  f<P>    // Lock that hash bucket
    6 n2 [7 N9 R8 i8 H- J: U    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;4 V/ n5 R. O7 v
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>* T  b1 @% i# s
    <P>    // Add player onto hash bucket chain
    8 O  Q3 L" S. H0 K2 l8 e    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];
    0 f" c/ M/ X! [5 S' R8 u$ P    m_pstIDHashBucket[bucket] = pPlayerData;</P>
    8 A4 _# N  s* K1 ~! w8 ]<P>    // Store net id in player
    & u/ ^+ J3 y; u, j2 O% C    pPlayerData-&gt;NetID = id;</P>2 B7 J& j! x+ V: a1 x! f+ o
    <P>    // Unlock the hash bucket
    6 l" Y' n6 B5 h5 }  I. |- u2 @    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();- t7 r7 @, M2 B
    }</P>
    3 c+ }& I$ m" m; k% L5 z  l8 T
    $ ^* p& B8 ], e8 O<P>, c* D1 p9 H8 R1 u. Y: a5 H
    //-----------------------------------------------------------------------------
    : @% `: ?& I! t// Name:
    . B! F. F# M8 n+ ?// Desc: 5 v) {# ?2 ^+ D; O
    //-----------------------------------------------------------------------------
    " R+ Q6 m0 x# c  B  [9 H) qPlayerData* CMazeServer::GetPlayerDataForID( DWORD id )  j( j+ H- q" w" W
    {0 m4 b. Z" v4 \9 ~# C* U5 G
        // Hash the ID to a bucket number, F, O' m# Z9 m! _; \
        DWORD   bucket = IDHash( id );</P>9 r, @3 B+ q6 [4 e! G" W- U: h
    <P>    // Lock that hash bucket
    6 O1 r1 D9 i! H9 i! p" h    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    , J+ X. L% f  O" G' o- ^7 F5 j+ q    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>. R! _- k% N/ C- q: O
    <P>    // Loop though players in bucket until we find the right one
      q! Z$ v5 M6 v+ J' ~    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    0 n$ \. {$ g6 Y5 x    while ( pPlayerData )3 j# a( M5 F; w: s! L7 L0 O
        {
    2 i, B4 H2 i5 ]6 [        if( pPlayerData-&gt;NetID == id )
    3 o" B1 g; Z) h. ]            break;
    6 K0 d% w8 T: b2 p: B: E2 x" O2 T& I        pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    ) C% s) p5 X- C7 g    }</P>' V: k% T: X* e$ h& H
    <P>    // Unlock the hash bucket4 J$ F. {! c$ n0 i
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>
    % J& F  S; I! U! U<P>    // Return the player we found (will be NULL if we couldn't find it)6 \. q9 ?+ j8 I- g+ `8 O
        return pPlayerData;
    . P7 L% j& f4 ?* W; k% m& Y}</P>
    : D9 m1 c1 C, I# D4 k' m  p5 c# }& E1 R+ x4 k1 a) O' v: B1 u
    <P>
    , K# U: u, L3 R  e//-----------------------------------------------------------------------------" p* [& T6 K" }4 A) j( e
    // Name:
    7 r( O" ?9 P, C( i// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner6 D; m, f6 H# H+ |# p; s! E1 m
    //-----------------------------------------------------------------------------
    ( M# X$ v, {; ?! F" @) Xvoid CMazeServer:isplayNextConnectionInfo()4 K5 Q4 }5 o0 M* S6 v
    {3 p7 k1 U$ w0 y3 P
        if( m_pNet )
    , p+ E* Q2 h9 c    {7 r$ F3 A0 n  y  L% [
            // Find the player that was displayed the longest time ago, and display it.
    0 E2 D' N9 e, z4 O9 k2 q# V0 S2 y        FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );. d& E$ B' D) g% ^, a5 {
            PlayerData* pOldestPlayerData = NULL;
    1 |. h( \; h: f! m: {  n$ y! v        FLOAT fOldestTime = 0.0f;</P>2 v+ k* I6 B; T, v7 r$ N# E
    <P>        m_PlayerDataListLock.Enter();</P>% B/ F3 [8 M1 `1 ~9 a
    <P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
    5 m! j: T4 _# s+ W        while ( pPlayerData ), T. {% I9 ?6 R% F/ I
            {1 y# U' g3 A' G! z& ]
                if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )- j* K6 M4 h" s9 n( M$ c
                {
    - K9 c1 [: V8 g                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;
    0 z, \- {3 G# U# {7 r9 B6 f                pOldestPlayerData = pPlayerData;1 U# f7 n* _$ [. `) V" m2 O
                }</P>
    ! G8 ?- j+ ^7 O9 |+ _<P>            pPlayerData = pPlayerData-&gt;pNext;
    9 A; ~$ g! X" ^2 c2 q7 G$ R3 i- Q2 s        }</P>( A6 y! [$ T9 z6 K8 J+ Y0 j( C8 q
    <P>        // Display the player with the oldest CI field, and update its CI field.
    & k& e# x9 o1 t0 ~' n        if( pOldestPlayerData ); p4 F! d# @2 h/ u" u
            {
    . C; M/ _- @7 R4 C1 x! f            ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
    ( ~. e8 A6 f" Y! d            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );  b) Y  d7 n& p/ c( ?; r
                pOldestPlayerData-&gt;fLastCITime = fCurTime;, K0 A, i8 e  o
            }
    / J  q- g6 h4 T! w/ v# S/ j$ w- |        else
    ' l$ K& L: p# q' T- U        {
    : d/ U( s" k1 V0 V7 N            ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    + A. \8 c! z" w2 Z        }</P>) K* Y( y) j! \% W  S% j) X4 }
    <P>        m_PlayerDataListLock.Leave();+ Y7 B3 k6 c& s" M' G# m" O
        }* U4 z* k4 {  z+ w, G& o
    }</P>: I2 B% I8 Z2 E) V

    2 d) S  T' X; ^. n, z<P>
    , n( `% T3 P; U: m- L//-----------------------------------------------------------------------------' J' V: U% w$ X( @% e$ I
    // Name:
    ' M8 }7 w6 t% e" a! F& G2 z// Desc: * S; f/ N; J% d* F& N8 l
    //-----------------------------------------------------------------------------4 A3 ?% K7 }# ~5 |5 i
    void CMazeServer:rintStats()  H8 W" b, M0 h  g
    {; v/ W; l/ ~' }0 O
        ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"), " j: x) ?7 Y1 z
                                        m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );
    . ?; b0 ^! Y+ z$ l6 |3 V: B4 C8 D    ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),8 B7 G! ^7 U% y+ Z+ c) I2 _
                                        m_fAvgThreadTime, m_fMaxThreadTime );& U# ~1 l8 E6 q* M
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
    0 m2 [0 W+ {7 I& T, e    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );% @/ v3 E( r! c
    }</P>3 K5 [8 f/ S& {& Z5 p

    . d: v% R: \+ ?' O$ m! K<P>% x' K! F- q$ |7 Q) }+ c
    //-----------------------------------------------------------------------------
    % L0 E% q$ I. }4 C" b/ J// Name:
    , I) l4 o' M* x# k, o// Desc: 2 `6 u, [4 V7 [6 M. d
    //-----------------------------------------------------------------------------: h, S9 ]& ^0 W% r6 D
    void CMazeServer:isplayConnectionInfo( DWORD dwID )8 y. T6 y" W; S! e4 w  X
    {
    . M6 J8 U; n. Q    TCHAR strInfo[5000];
    4 i! W0 n3 z: f/ u    TCHAR* strEndOfLine;
    ) ]+ ~1 f0 w# `; y    TCHAR* strStartOfLine;</P>& v+ q+ s3 s  Y7 [5 r) R9 C' w# [
    <P>    // Query the IOutboudNet for info about the connection to this user. R" w0 [, g4 L8 R9 m  Q
        m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>1 C5 o& H" e8 s& W
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );" \# `, A1 B9 H( Q) b* Y
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    / {4 X. m3 v/ Y( w' @7 R9 @0 |<P>    // Display each line seperately
    . T4 h1 V/ K2 }' A    strStartOfLine = strInfo;& B6 N/ g. l/ z: ]  ^' l* H
        while( TRUE )+ f' b* D1 w& E" X1 S5 Q) m  s
        {  \6 {- n( y4 @1 {) v
            strEndOfLine = _tcschr( strStartOfLine, '\n' );" j* {2 |& }# ]) V5 V
            if( strEndOfLine == NULL )9 w) s4 g; ^% k% H
                break;</P>
    4 A! P* c4 c' l1 x; ]<P>        *strEndOfLine = 0;
    6 t2 `- s9 ]1 g9 F7 w+ z# x        ConsolePrintf( SLINE_LOG, strStartOfLine );1 P9 t) v7 [+ @
            strStartOfLine = strEndOfLine + 1;! K8 W9 b/ R$ Q  j: _
        }0 U* f- t+ J6 ~& G& {& J- o4 o
    }</P>
    0 e4 |6 S, U( d+ F. b' [; X( G
    . |; _) k( J4 ~<P>" t; v8 t  M' a# B4 P! M
    //-----------------------------------------------------------------------------
    " j& |5 l. f* }7 P/ p+ R& i* y// Name: : V5 A9 D) m. h+ l5 S( S
    // Desc:
    5 e$ R) R( V4 x1 P3 I- J//-----------------------------------------------------------------------------, s7 h$ B0 c. K3 ~$ p
    HRESULT CMazeServer::SendPacket( DWORD to, void* pData, & I; R% A/ f5 Q8 Y; z# N8 q" w  Q  ^
                                     DWORD size, BOOL reliable, DWORD dwTimeout )- Q' b" \$ S( R$ D9 W0 J
    {
    $ B5 L1 K( v% }3 Y5 ?" S% c7 m) \8 r( }    // Chance of forcing any packet to be delivered reliably
    + k4 [. w3 i& S    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )
    4 ?) G+ r) \! \- D; N        reliable = TRUE;</P>
    1 w% N8 H& I: c4 T  t<P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    $ `: F8 t) ]. q0 A& u* Q}</P>
    9 w. s7 v  p* ~9 ^5 w; q$ h: f+ ]+ S2 }. k: m4 i& \4 P
    <P>
    - t+ M$ k" d+ d( B. W4 A  h/ t//-----------------------------------------------------------------------------
    : a. r; ?7 R. z1 P// Name: - c- @* S$ \# j# O8 {
    // Desc: 2 `4 u. n1 E9 j  C5 z, ~
    //-----------------------------------------------------------------------------; Y  V( L6 G/ {8 Z
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )9 @" w. v* F% }% o
    {
    / t+ }7 r# k2 c    // If we're up and running, then send this new information to all clients% U4 ?8 f$ k( O- r9 H9 n
        if( m_pNet )
    ; N  B3 R8 P; j    {
    * Q- |2 M/ m( F5 [8 ]6 L        //Use the AllPlayers ID' _- ^8 G: S3 Q2 r/ M
            SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );2 H4 z& Z0 W- v" w& W
        }* a% a: }% m! J- O: \: j" y
    }</P>, O$ ^2 _' x. _6 X

    0 P5 V" T  {4 |0 m2 o<P>6 X/ G, g8 x3 T( l. T
    //-----------------------------------------------------------------------------0 Z2 X0 p% f! ~/ X& w9 u* @- [
    // Name: 9 O" Y3 y/ a* N! w5 I; l0 k
    // Desc:
    % y4 q% w9 ?: I: G- U2 i//-----------------------------------------------------------------------------, U# G6 O) j5 X! `" o# f- Y- y0 j
    void CMazeServer::SetClientReliableRate( DWORD percent )
    5 d& v* h8 N$ f% b/ C4 v{
    0 l5 }/ U0 k& k, H1 i' `    // Update client config, and build packet containing that data
    8 }- [0 w( E' g    m_ClientNetConfigLock.Enter();
    0 J$ @) M6 q7 H1 c& D( a/ M    m_ClientNetConfig.ubReliableRate = BYTE(percent);
    $ f9 O2 D& ^9 M& c. o; A    ServerConfigPacket packet( m_ClientNetConfig );. u& W9 \# ^1 Q- d
        m_ClientNetConfigLock.Leave();</P>6 K; b" S7 Z6 m$ `: Z& d, j
    <P>    SendConfigPacketToAll( &amp;packet );
    # x5 K# I  J2 D; o# G8 c}</P>2 K( o( {8 N; K. _
    * x( ~* j$ f! X
    <P>" o; Z' o) y  b& I" n
    //-----------------------------------------------------------------------------2 a, G9 }" n9 v- \7 F7 Y* ~- m
    // Name:
    ' I, H6 {6 E+ M// Desc:
    9 b& d& Y4 {+ v; m) h8 J& I% v//-----------------------------------------------------------------------------5 y: l3 G+ T7 d
    void CMazeServer::SetClientUpdateRate( DWORD rate )
    * E) {* Y$ e! ^; t2 |9 T{( r; y+ H% }) I6 t0 {* W/ W
        // Update client config, and build packet containing that data
    ( J: ~( D4 U" W1 U& Q, N, e& u8 [    m_ClientNetConfigLock.Enter();0 T! H, a0 m; w2 Y0 ?7 T
        m_ClientNetConfig.wUpdateRate = WORD(rate);
    5 W( M: Q+ ~& w- y    ServerConfigPacket  packet( m_ClientNetConfig );
    ) E2 j% B9 b- O/ H% C& C; Z2 [  ~    m_ClientNetConfigLock.Leave();</P>
    0 b1 R3 o* ^$ K; s<P>    SendConfigPacketToAll( &amp;packet );' A2 U* O9 M9 l9 G4 [. s, c
    }</P>( t$ x7 q# m0 P2 v

    ; y1 W+ D2 x6 `* D% D9 K/ V<P>8 ~* ^, P, u- U9 S- b2 N
    //-----------------------------------------------------------------------------
      o9 j/ S8 G" K4 D: }$ d1 b// Name: 6 S( R7 s+ O) Y4 Z
    // Desc:
    " G) x9 d) f+ R+ l+ |0 j& k, w) S//-----------------------------------------------------------------------------
    6 ~' T: D" H7 M0 n* d$ fvoid CMazeServer::SetClientTimeout( DWORD timeout )
    2 q3 I7 n( L; }% N1 M& j{
    ' W! M$ ^* c# K7 u- u- _( F( V) x* t    // Update client config, and build packet containing that data8 a! C5 h4 x. o
        m_ClientNetConfigLock.Enter();
    2 W6 x# C9 |0 R    m_ClientNetConfig.wTimeout = WORD(timeout);& {% h4 t) c" M- t# c3 `
        ServerConfigPacket  packet( m_ClientNetConfig );0 m9 t6 V. V5 o
        m_ClientNetConfigLock.Leave();</P>
    / i3 h2 u8 A. j8 ]<P>    SendConfigPacketToAll( &amp;packet );; c; v* n0 R7 ]& r
    }</P>5 j1 I$ M% E8 w" b
    : u' w9 a- |" O" S* s
    <P># }" d( r& Q! n3 x
    //-----------------------------------------------------------------------------
    8 m2 k2 |4 |5 t// Name:
    ' X# c- M4 b  @- B+ F/ x0 O// Desc:
    7 i0 m) Y; S: V! n# c  w. W//-----------------------------------------------------------------------------
    & M; P* J9 k3 f+ m5 D" ]( y5 Jvoid CMazeServer::SetClientPackSize( DWORD size )9 `; J2 V+ _- t3 u0 @* s) G8 }
    {' l" m4 Y% z& r0 h# N# i7 `
        // Update client config, and build packet containing that data
    , f) i- j' `! i; x- ]) p0 E    m_ClientNetConfigLock.Enter();
    + M2 ^% w% N/ s5 s2 p! v0 i" n9 K   
    . l6 G, h9 `5 X    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.4 j3 X& M7 b8 w4 [" R8 G$ d# ?1 F2 ~
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   3 ?! u1 a( h- t0 l" l" Q) W  G
            m_ClientNetConfig.ubClientPackIndex = 0;</P>
    ( P( ?& `  P  _<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);4 N/ z6 S1 S  O* k& C2 p
        ServerConfigPacket packet( m_ClientNetConfig );: [9 k- {9 E/ w
        m_ClientNetConfigLock.Leave();</P>- G( C) W7 t4 F/ O2 q! U, q
    <P>    SendConfigPacketToAll( &amp;packet );( {6 E. S1 p! b. D" }5 s2 Q
    }</P>' L. M( k6 o2 G

      g' J. s! w6 G6 A<P>
    " y9 i7 W% y/ [- [. T$ Z3 S4 w) ^//-----------------------------------------------------------------------------' M0 f/ I& r- ~
    // Name: ) I' D/ p! f% Q, }& q0 D
    // Desc:
      o, M, t0 C/ Z* V# M//-----------------------------------------------------------------------------
    $ \. \3 c: A9 q$ d4 r3 I4 [. j6 ]- V% Fvoid CMazeServer::SetServerPackSize( DWORD size )
    - _. K! }2 E( N{
    ( _6 @' {$ d! u' j0 W    // Update client config, and build packet containing that data
    ! s+ L# ^8 q3 }, b' R2 E8 K- s    m_ClientNetConfigLock.Enter();+ F) i' E; D% o5 r4 B1 U
       
    7 R( G6 q1 q! o* a" ^6 h$ T    m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.0 j8 d* X% ^6 M0 Q/ G& m' s
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   9 {; W! X( a3 v& ~3 [8 i* C. j: H/ Z$ [
            m_ClientNetConfig.ubServerPackIndex = 0;</P>' i1 E$ A# _. o/ d+ F0 S
    <P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
    , {9 p6 I" o% a$ ^6 D7 T    ServerConfigPacket packet( m_ClientNetConfig );
    ; G' l" {5 G2 E' T, r$ b    m_ClientNetConfigLock.Leave();</P>
    / m8 W7 W; R, T, p! |6 |9 Z; t<P>    SendConfigPacketToAll( &amp;packet );
    7 ]- {6 ?9 ]# J}</P>) R5 s9 q  Q2 {. D/ q4 ]
    <P>; ?6 L, }& _, D3 [; I# ^' q
    //-----------------------------------------------------------------------------
    ; l+ K' x7 U2 v/ T/ l3 [% F$ J// Name: 7 [9 |5 G5 c& ]
    // Desc:
    7 f* G, Q, R, v+ n, j//-----------------------------------------------------------------------------
    # K1 ?% Y2 H+ X: Q6 Y# Y5 Ovoid CMazeServer::SetClientThreadWait( DWORD dwThreadWait )2 ?! N; x2 U# C( p* o6 R8 P/ \
    {) [( q) r  x4 L, [6 g% ]. V
        // Update client config, and build packet containing that data8 k4 H  i$ u6 P  z$ V
        m_ClientNetConfigLock.Enter();6 u- N9 l! F1 V1 D5 Y& g" y
       
    ( _# a# h  V# |6 I3 @/ L    m_ClientNetConfig.dwThreadWait = dwThreadWait;
    * ?. J8 s4 [& G" T# x9 g: Z    ServerConfigPacket packet( m_ClientNetConfig );  g* r7 n6 I7 E4 f. ^
        m_ClientNetConfigLock.Leave();</P>
    ) h2 C8 w7 w7 u- y8 {: B<P>    SendConfigPacketToAll( &amp;packet );$ H4 G8 E& c) h( d4 }" b
    }</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-10-8 07:27 , Processed in 1.128992 second(s), 56 queries .

    回顶部