QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3851|回复: 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>
    ! R( B2 N6 q( E2 K<>// File: mazeserver.cpp
    " m- O7 I" e* i# ^( i//
    4 R" |* z: k+ ]0 ]. `2 S; m// Desc: see main.cpp
    ) E& E4 z) K1 e) r; F//
    2 P& W1 f3 k  T7 ?  }: J5 t// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.: L  H2 a: N; B7 v$ v! j  ^
    //-----------------------------------------------------------------------------+ E, m4 }$ m, y! [) Z/ S8 Q: p
    #define STRICT5 _% h7 t+ i. ^0 u0 F3 [) H# i4 X  I
    #define D3D_OVERLOADS
      t9 g* X8 A9 D; J#include &lt;windows.h&gt;
    ! |" }; p# D5 o# O8 `6 x8 x7 Z#include &lt;d3dx.h&gt;$ N5 \2 M: E" O4 g9 D4 b
    #include &lt;stdio.h&gt;
    5 U) I0 D0 u! D3 h  Z/ X; H$ [2 t#include &lt;math.h&gt;
    , l6 `$ J3 i+ Q# ^# A: p# M4 p#include &lt;mmsystem.h&gt;. }: ~. O6 A/ U
    #include &lt;dplay8.h&gt;
    $ d2 W& l9 @7 X8 y7 [; K8 _#include &lt;dpaddr.h&gt;: {% j3 v$ R" \! \( L! v& |) N6 ?
    #include &lt;dxerr8.h&gt;2 Q# G- P' ]4 p
    #include "DXUtil.h"( R0 s0 i/ Q4 @" Z0 ]/ Z2 l- e
    #include "MazeServer.h"" m% @7 D0 G1 g: a
    #include "ackets.h"
    * L. h4 z5 Y4 L1 x" M! K5 T2 e#include "Maze.h"$ I; \1 R. I2 {! Y# U4 G' _- K
    #include &lt;malloc.h&gt;
    * ^$ C7 o) T* U: L, r. L7 h#include &lt;tchar.h&gt;</P>5 q3 r- Q3 @5 j  p- n1 Q3 U* T
    ! Y3 n* M; T0 w; A0 a
    <>//-----------------------------------------------------------------------------8 _0 a3 X) m0 ~$ K
    // Name:
    . m; N5 h3 j6 [$ A- t// Desc: 4 l% _, n' N1 F# \$ e! _5 K
    //-----------------------------------------------------------------------------1 R% m3 _  m- |- T: Z3 m
    CMazeServer::CMazeServer()
    ' r2 g$ L& h: W( I% p* ?' F. ^{" X1 B6 P7 E# m! {  j" R
        m_dwPlayerCount         = 0;
    4 Z- ?9 j* O4 o6 n" u    4 H9 X$ y' t# C4 K/ a
        m_wActiveThreadCount   = 0;5 \. c, ]$ l/ p& J
        m_wMaxThreadCount      = 0;
    3 U/ I9 l/ w5 K5 r' I    m_fAvgThreadCount      = 0;
    ' }3 a9 I: V. y* j. H8 C    m_fAvgThreadTime       = 0;* K; f1 `' S9 F# ^: }
        m_fMaxThreadTime       = 0;</P>" O+ F- i; E, V9 s3 H* a
    <>    m_dwServerReliableRate  = 15;
    . B) ?9 Z& C. h4 E. K    m_dwServerTimeout       = 150;
    9 D# v2 k: A+ o, Q; `/ h/ [. g/ y    m_dwLogLevel            = 2;3 J( G& H4 U+ h! s: K8 F) o
        m_pMaze                 = NULL;</P>
    0 V1 b/ J& M/ [5 v% ^<>    m_ClientNetConfig.ubReliableRate = 15;) H$ b) _) E) M. o: g$ {  T
        m_ClientNetConfig.wUpdateRate    = 150;# N3 q' K% T5 ^' m3 e
        m_ClientNetConfig.wTimeout       = 150;</P>
    - {1 `! B& w1 X; s. y+ U  v0 o8 {2 @<>    m_ClientNetConfig.dwThreadWait = 0;</P>1 s7 m, c0 Z2 E
    <>    m_ClientNetConfig.ubClientPackIndex = 0;
    2 [5 J% J; J9 h  R  C) c    m_ClientNetConfig.ubServerPackIndex = 0;
    # h& F4 {$ {+ \    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)! A& g, f  q, B; p6 f! W* G$ s9 v
        {
    , I( _; d& f  o3 J# r        m_ClientNetConfig.wClientPackSizeArray[x] = 0;
    4 {0 Y) |7 Q/ F! x% P) o0 C        m_ClientNetConfig.wServerPackSizeArray[x] = 0;! X4 S0 E6 O, T$ q* a
        }
    8 @" ~. T% a* k: O' O6 R}</P>
    9 i( ?2 D' Y% `3 T$ F) B+ P4 ^0 `
    <>
    6 Q5 c$ }. V8 j; i$ P7 P7 H' J//-----------------------------------------------------------------------------
    ' {% i) S% K& n$ X8 S// Name: # q: {, |. ]0 t/ H+ G
    // Desc: 8 ^) l9 e1 G6 r  q3 v& o0 E
    //-----------------------------------------------------------------------------
    7 j3 S( g+ }- lHRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )& r# i9 G, m+ x( [$ _1 r' k
    {6 }0 S0 u3 D* g7 Y3 y1 w& g3 g
        m_bLocalLoopback = bLocalLoopback;
    & X4 S6 p( f: b$ q    m_pMaze = pMaze;
    7 \" l; t5 ~2 u- X) V    if( m_pMaze == NULL )/ L7 R* I  A1 O- n: Y
            return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>' x8 I# @7 Z6 B+ r
    <>    // Grab height and width of maze  K' x0 ~+ x, E! ^6 \! K& X2 J5 {
        m_dwWidth = m_pMaze-&gt;GetWidth();- S- O0 x8 N7 w: Z7 K# N# \' |7 }
        m_dwHeight = m_pMaze-&gt;GetHeight();</P>- D7 O# F. M, I
    <>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    , e3 p7 l+ d/ Z0 c8 y0 c, Q4 W5 b5 H- U    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>0 k8 {' g9 m$ J' m! S; C9 Y. h/ o
    <>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.4 m! l5 _# ?, D9 e
        if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    0 }5 q, L/ d9 ~        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    9 u4 y" V5 Q+ E% R    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )
    * ?$ r! ?0 d! c: B4 y1 v) Y0 k! Q        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>- }, W9 C+ p/ e. j5 f
    <>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;
    5 }* r! X6 p8 \% a# ~    m_dwMazeXShift = 0;) y9 ~$ U  P' C. r
        while ( (scale &gt;&gt;= 1) )
      P3 N# ~8 I0 T" H  v- H        m_dwMazeXShift++;</P>; O8 Q9 R0 F9 y7 ^  Y9 P
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;  }0 \, ~5 i- ]
        m_dwMazeYShift = 0;
    ! F# j: I- H- q) o    while ( (scale &gt;&gt;= 1) ). R+ D- l: G" A
            m_dwMazeYShift++;</P>
    $ i$ n( k8 H& p8 D0 k* [- M<>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    $ F& Z& W* b7 O# y, J; y        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )' X, W# W( U* H' C3 n2 |- R5 e
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>! R& ]# z7 c, G7 I& N
    <>    // Initialise the player list* L1 a- E! _: @. B+ J* t$ P
        ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );
    8 p( e2 a  C, F    m_pFirstActivePlayerData = NULL;' ?! d3 \( |7 Y
        m_pFirstFreePlayerData = m_PlayerDatas;; p" M& {* f2 Y. ]; o
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )5 |9 ~: X& z( i9 O/ @+ N2 q
        {
    $ w0 D! B- D4 x* t: F3 H        m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];0 R! `; G$ v9 q5 j  R1 N
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];$ z* Q' Z) \* F- G- k; i
        }</P>* F" \# e- A4 @% F
    <>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
    3 m  p2 C0 N& H& n    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];) E# O8 \  r7 Y# q8 `% z) l
        m_dwActivePlayerDataCount = 0;
    ; W$ N4 E$ F" S  a9 @4 b# C    m_dwPlayerDataUniqueValue = 0;</P>
    . {: u' i3 r" T: Z% J3 u1 V<>    // Initialise the cells/ x- D* l* C6 P, s
        ZeroMemory( m_Cells, sizeof(m_Cells) );
    ; s: _# C5 {: C1 W" Q. m; {+ u. _    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>
    . z% m" D: G& o! v+ [<>    return S_OK;
    ) [5 y5 L( ^% J* g}</P>
    1 {* @. U- j* d: T3 U* e( e: V1 O: Q, n6 b) B9 Z) K4 W% ^
    <>1 C5 {% {1 _3 V( Y8 j- T4 P7 a* `
    //-----------------------------------------------------------------------------
    ! G2 g1 U+ J6 y# m, V0 M, L6 ?* L( y// Name: ' B  @5 b9 F4 [, `3 N" k: _
    // Desc: ! s* q- ]" F) x' L
    //-----------------------------------------------------------------------------. Q5 ^$ c! G) l0 a# A$ O2 |
    void CMazeServer::Shutdown()
    ! N4 ^( L; ]( E  M{
    9 H/ b  u6 c& H}</P>
    # a- D  G$ W0 u' d2 ^4 ^7 Y
    9 Q6 {- T" Y$ A' M: b<>- V/ f' o( z& M5 x2 `% X6 B
    //-----------------------------------------------------------------------------8 ^# c9 M3 V7 F, T8 p, I0 t
    // Name:
    + u  i: W. j9 b2 K// Desc:
    3 a* |. T5 i1 t8 p' X" ?8 c//-----------------------------------------------------------------------------
    ; Q3 e7 s6 O5 k0 ]void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 ). s2 L6 g; O( G- K1 T" H
    {
    0 `' h+ H9 h' Q% ?    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    ' v- \. x8 k( V- @$ b                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    4 [0 |: C! s/ S- f! F4 U& h: j, K}</P>
    , u1 E$ u# _' V, Q3 v3 v  f1 O
    $ m9 X  j1 |" r/ n( [0 h! i<># n  n! n  ]% y( a. ~* N
    //-----------------------------------------------------------------------------
    $ n8 q# _; @( N: f% K// Name:
    % _; f9 f- w! x* A# `9 G// Desc:
    9 ~$ h9 x& L$ d//-----------------------------------------------------------------------------1 @1 ]8 r0 J0 d7 f' I
    void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    ) l0 r# |7 b+ N( g9 B9 s1 K- w, T{1 A0 T# K; h4 C' T
        m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    & m) ~8 T8 ], @0 Z                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );/ x" w, O) d6 \1 V: A
    }</P>
    6 s6 q* ?* ^1 H. g2 p6 U0 S4 ?! U2 ^+ ?( O  }
    <>
    4 f) i6 a5 ~  d# @//-----------------------------------------------------------------------------4 A- U% d! d6 L2 T4 h& {5 R
    // Name:
    " n3 q9 s2 _4 a' d// Desc:
    - x* L' s9 Y: ^6 C: f9 c//-----------------------------------------------------------------------------+ ?0 ]. [' T7 q
    void CMazeServer:ockCell( DWORD x, DWORD y )
    ' u' z1 ^6 e+ ^4 `; ?  j+ U{  V- B% N' L  P! @0 N1 I# m  U
        if( x == 0xffff )
    6 H& U0 {6 v3 s( f' j) D        m_OffMapLock.Enter();
    8 T- _: `' ]0 a1 b( G8 Z. R    else% A! U# ?& s8 _4 a- `
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    7 `$ J; j9 f; q% S6 N' b}</P>0 R. v4 \( A' y. P, [% k3 n
    3 V7 T% K, D; x5 }
    <>2 b9 q5 [3 M: v3 b
    //-----------------------------------------------------------------------------
    4 m& ]. n3 h& c& {0 i( d// Name: 5 A4 b0 m8 Q+ [3 M5 [/ Q3 W+ d
    // Desc:
    + v+ F( v/ X# ~* b" s; O8 ?" C3 H& h//------------------------------------------------------------------------------ [% I$ U- Q. v/ f: A, b
    void CMazeServer::UnlockCell( DWORD x, DWORD y )- G1 t# j$ U8 ~" a( M& [
    {
    . y9 v. u. N" c! }7 o: P; K5 ~- \    if( x == 0xffff )
    ' |# w& \" X( S8 D0 v2 K% T" x2 C        m_OffMapLock.Leave();
    6 c( t4 p  d) c9 A/ [  N5 J    else
    : y- {' ]7 |) G% N9 L$ |; z  G        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);( |' G" x  J. _# @, d7 a
    }</P>4 b7 }& a& z& T) Z

    0 h* b* V( U! q: m  V6 k7 s! n<>. F3 @- R2 H7 F8 y& f4 ~0 S
    //-----------------------------------------------------------------------------
    8 V  a/ o( _1 x" C; s. S1 E// Name:
    - {  O+ H- G* N// Desc:
    $ W, B( w% A6 \( [& m2 _* N//-----------------------------------------------------------------------------9 r+ \$ K7 Y# W% Z* J  C
    void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )3 Z! V4 K, o  }, ^" J) q# Y
    {. m- K( S+ d; d5 y
        if( x1 == x2 &amp;&amp; y1 == y2 )$ D0 B! ?7 K! K4 k' K
        {6 A! {: ^$ x( w) e1 H' x
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )) P) P& K) X  `; A, C
                LockCell( x1, y1 );
    4 T1 N# Y0 p, x( Q2 @3 R' L        else0 q' B) n$ u8 ?0 C7 C' h
                m_OffMapLock.Enter();</P>
    0 y0 d4 U9 F2 b& s; n. X7 T<>        return;
    / V4 W# O3 t& q! M7 x) j    }</P>
    , U2 Y" k( J4 O# n9 c4 S. V<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;1 H" _! k- ]2 m
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    + f9 O: W& X# Q3 W6 \* Z0 o  B) r    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;, a- [! w) `! }7 j; \, \. E' U2 G
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    & u0 w  l( c- k! L! E<>    if( x1 == 0xffff )
    & W0 B0 o5 F, [' J    {! ~) E$ y: a/ Z/ Q2 s
            m_OffMapLock.Enter();9 i! O- G1 K; O1 b! @' h6 i8 v) K
            m_LockGrid.LockCell(x2shift,y2shift);2 _4 m8 U8 T% e, O+ ~/ d
        }% `& I& T; N7 T& o* A: K4 \
        else if( x2 == 0xffff )7 |- n) i) `4 Q: H& C
        {' j" r2 f* ~$ _5 u
            m_OffMapLock.Enter();
      N$ G) S$ t. y% V8 A        m_LockGrid.LockCell(x1shift,y1shift);/ _" m. m1 k, S5 r
        }
    / L/ x1 P) Q, l    else
      L( H4 s8 Y1 z; }3 C" ~" O    {! s5 D: ?5 `0 c+ i
            m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);' U# Y0 a0 r- g& _( }# H
        }
    : Y& {% ^" M/ m}</P>
    8 W+ O1 w" s$ ~" E4 O9 X- C! n4 y% Y+ ?5 v
    <>- G0 M& {( t8 v) t: j
    //-----------------------------------------------------------------------------
    ; V+ M  E) D% ], H/ X// Name: - v6 d5 A4 ~" o# O! G* a/ S. r
    // Desc:
    ' X% I* \- p% }2 J3 X0 B! ~: S//-----------------------------------------------------------------------------: \: C* C$ s; u- q. P( w
    void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )( W( Z5 J+ I: p( h6 a2 u- C6 @% ~+ u
    {
    8 G  ~3 i9 X( \( ]. H# H( S" ~    if( x1 == x2 &amp;&amp; y1 == y2 )- Y6 z7 ]# K7 E  x( Z$ a& _
        {
    . o0 d& x2 k! v* D: N. @        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    7 M) Z  @' Z- }            UnlockCell( x1, y1 );4 z+ j, d2 o( A) g7 c" y' d% i
            else
    8 G# E$ ~: \- i/ Q; x% j9 f            m_OffMapLock.Leave();</P>. U, M+ ?' Y' z1 P) O0 X0 T: o
    <>        return;
    # Q" U% ?4 U" P5 X3 n* q- S7 q    }</P>
    ) F5 E" S0 X8 r/ p<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    : N& ]! z8 o6 C6 ^' d    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;5 |) A) S* ]' f
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;8 Q4 Q* k/ u: }. V3 x# o
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    - c2 ]8 h6 N/ b$ q1 z# J3 H$ C4 m<P>    if( x1 == 0xffff )
    9 Y7 l% A3 R2 V* k    {
    8 s5 y, @8 T! S4 Y$ X! P        m_LockGrid.UnlockCell(x2shift,y2shift);
    ; ^9 f" `& E" U# y        m_OffMapLock.Leave();6 o; r( ?1 |% K# C
        }
    / Y  Y. M. @4 |6 ^; A2 o" e3 R% L7 I    else if( x2 == 0xffff )
    / M3 V2 F% v% L    {
      F8 a3 r; W, ~3 b! \        m_LockGrid.UnlockCell(x1shift,y1shift);
    ( ^0 `* z7 L' l* k0 e6 J        m_OffMapLock.Leave();8 v4 R; t( t2 u* A  u7 c
        }3 {3 y( r8 Y" l' M5 ?) y4 ~0 T2 S
        else 7 t3 V0 d# A4 ~
        {1 I$ m6 I( \& |8 e! d1 y
            m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);* [1 p7 n+ O! ~# X* d! w/ t. u
        }7 M' h# c9 R5 S
    }</P>) g. _* q/ }9 t
    7 T- U, |# ?- X' F* l: @( ]
    <P>
    ( }# r$ {3 E  T2 x$ b' R//-----------------------------------------------------------------------------" x' R2 a. R+ G6 L7 u/ i
    // Name:
    & k7 K6 B7 ]; ?0 ~1 k6 }+ t% X// Desc:
    ; m* `. g& N# U//-----------------------------------------------------------------------------
    + I2 i) j! ]. F- Y: t' M% @$ vvoid CMazeServer::OnAddConnection( DWORD id )
    , \5 M+ M. l+ B$ \, g{
    8 o; l4 A6 K9 Z    m_AddRemoveLock.Enter();</P>
    # D5 T- ]5 N! c<P>    // Increment our count of players5 l' ]) H% O' ]3 ~. K& s" ~  }
        m_dwPlayerCount++;
    , O, r. @, B! G; i    if( m_dwLogLevel &gt; 0 ); g8 Z7 ?3 N/ ^' v6 [
        {
      \( H$ a# G8 M' d9 J        ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
    7 I  i1 ], }. Y- b1 L& a        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    9 a9 F6 J0 [/ U- Z6 n. T    }</P>
    5 n0 k* S/ r. @( c<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )' O/ y' C$ p! [( G, m3 R
            m_dwPeakPlayerCount = m_dwPlayerCount;</P>) l3 e( c6 i& `1 q$ o
    <P>    // Create a player for this client
      X) G! C) M" n8 w    PlayerData* pPlayerData = CreatePlayerData();
    1 r7 ?6 B7 Y& n5 T; Y, o    if( pPlayerData == NULL )+ B& _8 N! \. e* P& A/ t* M! _: E
        {
    * k% }1 |; K% v* y! N% K        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
    ) U# x% C) U$ d# I, Y" ?        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );9 y6 n; g7 V( y! h
            m_AddRemoveLock.Leave();# ]# k0 U% |) A6 n9 Y
            return;
    - m; M$ k) ~$ @* J. p    }</P>
    1 y; w7 H. {, ^* U<P>    // Store that pointer as local player data
    1 H1 H3 b, y) S) }0 J7 [; o5 B  p( |    SetPlayerDataForID( id, pPlayerData );</P>
    2 L, P" H: R5 }<P>    // Grab net config into to send to client
    0 A7 a. a* I3 M; H, @    m_ClientNetConfigLock.Enter();/ i# ?0 }0 F" }% {
        ServerConfigPacket packet( m_ClientNetConfig );
    / r, a) U% V  L9 R- e+ y+ x    m_ClientNetConfigLock.Leave();</P>/ C, q# J6 s+ J3 V8 {
    <P>    // Send it3 @. a, B* a( w- Y9 C
        SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>
    - \$ D+ w2 d) E) U+ d* d<P>    m_AddRemoveLock.Leave();5 ^" M4 O! ^& P" Z4 h
    }</P>
    % ?7 K4 F$ V% b/ ~1 R+ w, \4 V' \4 r3 |8 p0 g
    <P>
    . M0 e: Y2 _# v: J4 S: \) a" g//-----------------------------------------------------------------------------6 P( p2 [9 q8 [) \: [
    // Name: " @  P) v6 e/ E. ?+ S7 R8 w0 X8 j
    // Desc:
    % o7 o  a! ~9 U/ I% j- K; k//-----------------------------------------------------------------------------1 ^+ d0 G9 R) v6 A' j; u/ \
    void CMazeServer::OnRemoveConnection( DWORD id )
    $ b9 n' G% r  x{
    % K+ g) f5 e4 Z" ]    m_AddRemoveLock.Enter();</P>
    , d- y+ }% X0 \" S% }8 f<P>    // Decrement count of players
    3 D& \5 J$ W1 p$ o1 P  o% r1 U9 M    m_dwPlayerCount--;</P>
    : Q! p( S. M4 Q4 b. e, t<P>    if( m_dwLogLevel &gt; 0 )
    - S' i7 Q3 R1 b( E9 T5 N. `    {* i; o; W) p* B* z
            ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );4 T1 v' ^+ i7 Z" T. v9 j2 L
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );9 ]8 t. {$ T! G6 J* M
        }</P>
    % r3 ~! f7 G' p" w& _<P>    // Find playerdata for this client
    $ y2 P4 {. D3 k% O, X% U    PlayerData* pPlayerData = GetPlayerDataForID( id );
    5 q2 v: n  P6 v+ I    if( pPlayerData != NULL )
    5 z: @# K1 r5 n$ ~4 \) b  g* V, T    {
    + o+ g) X, k7 f9 o1 v5 G3 u$ X        // Destroy it" W3 D9 [, Q2 F$ p6 a0 z1 u( f8 g9 O1 H
            RemovePlayerDataID( pPlayerData );
      n4 W* j7 I' J7 ~        DestroyPlayerData( pPlayerData );
    ) a+ D% S8 g0 a8 \    }</P>
    , h& K: v3 [8 h<P>    m_AddRemoveLock.Leave();
    1 o3 X% e, K: V. I4 M3 j$ g}</P>. ?$ ~, g- v$ X( o! d3 B  N$ w5 |7 z

    / X8 Z. R2 ?- A$ g8 X<P>) m2 o8 u: i9 Q8 i
    //-----------------------------------------------------------------------------* z) q" g5 ?' b6 z+ G2 b) _% v
    // Name:
    8 {( p4 y% n$ U3 o* l, H// Desc:
    - {! g+ [% h, d//-----------------------------------------------------------------------------. J& O- H7 R# t( z8 f
    HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )' a# `% X( ^0 F) u, x) X! |
    {: L+ s" }9 ?' c8 w. M# e9 H0 [
        BOOL fFoundSize = FALSE;</P>1 ~8 J$ t, s1 i. m6 G5 p0 R
    <P>    // Increment the number of thread we have in this process.0 G  ]9 b& K& M' I8 N5 x8 k
        m_csThreadCountLock.Enter();</P>
    ; M# R# c6 f6 J. V/ L& M$ w- t<P>    //Get the start time of when we entered the message handler., H3 _) s" X  m: M
        FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
    ( P/ S7 B, H" S, R<P>    m_wActiveThreadCount++;
    - d+ H! L' {3 }" _: u    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)* x6 K  B1 L$ T$ s" A
            m_wMaxThreadCount = m_wActiveThreadCount;
    " G3 t8 y! u2 s   
    2 z0 B2 }" n1 e$ w0 j    // Calculate and average.) _' J) V  R- u/ I& g
        FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;0 Z, c5 i( ~9 h2 S3 Z) d7 [" t( B: u
        m_fAvgThreadCount += fdiff/32;4 z( m! U8 ?$ R9 B9 a2 j
        7 S6 w0 l1 _* O2 I+ {
        m_csThreadCountLock.Leave();</P>+ B2 T2 S+ v/ c8 h* z
    <P>
    1 v/ M4 e8 J0 d3 {0 c: g* A    ClientPacket* pClientPack = (ClientPacket*)pData;  u7 R: a, T8 {% I
        switch( pClientPack-&gt;wType )" }1 W  M. @  s2 b5 h/ c5 G# D- |
        {
    % d# U/ F: P! i) ^        case PACKETTYPE_CLIENT_POS:
    $ y1 r% r. x* W- Y            ! t( [. b6 ?) E7 p8 Y' b% g! ^
                // Check to see if the packet has a valid size. Including 4 D+ |1 l3 y& X$ K) J. d% p
                // the custom pack size.
    7 S# {3 Q8 l; ~/ X+ D            if( size &lt; sizeof(ClientPosPacket))+ i9 d6 b/ {- M8 O1 D2 K2 M: _5 L& l* ^
                    fFoundSize = FALSE;
    7 R1 G  p. |6 ?; Q& _            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))  t; \) F3 K8 D+ B" M" J
                    fFoundSize = FALSE;
    ( t* y1 E' ~# a9 E" A* M& B            else1 N* H/ o: u- y8 u! s
                    fFoundSize = TRUE;</P>
      \; Z6 m) I% ?- W<P>            // If valid sized packet, handle the position.: m7 f: {) b8 B* n4 }0 N. i
                if(fFoundSize)- `, v2 e4 V6 f% [0 u+ u. n
                    HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );
    $ Q6 O3 L& ~3 p) @; o7 `            else
    6 m2 k- r0 [, |/ f1 |                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
    : D, v9 H! `: \/ G6 e. `6 k$ c<P>            break;</P>
    3 K1 {5 p% V1 }& w* w<P>        case PACKETTYPE_CLIENT_VERSION:+ |8 p; C2 C& H" c
                if( size == sizeof(ClientVersionPacket) ): N9 W/ f* s+ ^) [0 M
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );
    / R+ [+ \8 H) B            else
    1 P' ^6 N+ w- r  H- ]# \  {! c5 w                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    % E' m/ a  Y9 [" z5 R            break;</P>
    0 C+ `' h. Q* p<P>        case PACKETTYPE_SERVER_CONFIG:</P>- J* [$ Z! B/ j3 s. j
    <P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>
    ( h+ r2 h, B* k' V0 n- M( X% F<P>            break;
    , N4 ]+ Q# u$ T        default:
    & |( D" E) S8 x            HandleUnknownPacket( dwFrom, pClientPack, size );
    ' m/ t; J/ A3 T* y$ K2 e            break;4 @$ P  \; R; Z: k
        }</P>
    ( M: m+ n2 a7 F# I1 l2 R6 C<P>    //If the user wants to hold the thread, Sleep for given amount of time.5 O. F1 N! t) X# m
        if ( m_dwServerThreadWait &gt; 0 )
    ! z' h( u) B* {4 {2 ~3 G2 S. h6 ?& a* q    {+ c8 h: G* v6 G
            Sleep( m_dwServerThreadWait );
    6 W5 _1 m1 p4 E" ~    }0 l! ^3 ]9 _5 |4 ~. J7 M
       
    . K( q( A' p% [* m$ D# B8 |: q; C    // Retrieve thread data for this process.
    8 ^& p7 N+ L( f+ t    m_csThreadCountLock.Enter();</P>* w+ O) U/ B% W
    <P>    m_wActiveThreadCount--;</P>
    3 C% ~, W- P2 `5 K/ B! `- G( X6 [<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
    $ Y+ I) ?( H# ^1 _9 [( X    m_fAvgThreadTime += fDiffTime/32;</P>
    9 I8 \  ~5 p7 }: Z( g  d# f<P>    //Get the Max time in the thread.$ `6 A- \) G+ k- j  N
        if ( fDiffTime &gt; m_fMaxThreadTime )
    3 m) S% Y, q+ M* x4 K    {5 r4 `# V4 N0 x7 P: e
            m_fMaxThreadTime = fDiffTime;
    0 j5 ]) b# j" t: m3 s    }</P>
    2 K9 k. \" e+ M+ C; t: m<P>    m_csThreadCountLock.Leave();</P>- O1 k9 X6 D4 h1 g# ?1 e' H: X' {* _# w
    <P>    return S_OK;, E& J, o# U( }. |1 D6 N
    }</P>
    8 q& z- y3 m" T: R6 a1 H- ]" |, K: g7 R  F/ J4 l
    <P>//-----------------------------------------------------------------------------1 X. S$ {  f" F' E
    // Name:
    % M# N( p! [% y$ t" h/ K% }// Desc: . }8 A/ M2 V6 N
    //-----------------------------------------------------------------------------
    ; N3 f$ E6 Z6 e# O; f8 S9 a9 M( wBOOL CMazeServer::IsValidPackSize( DWORD dwSize ), Y9 ^; [3 S! ?1 E3 A$ X9 e
    {. D6 o4 t& p( g3 N8 G
        BOOL fFoundSize = FALSE;
    , l/ z8 S* U: N0 z  ?    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;/ u/ {1 L6 A2 q9 A3 p' Z
        3 k7 V2 K* k6 d9 V
        // Check through the array of valid pack sizes.
    0 T1 U) y2 ~; X& H2 n* o    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])$ ~  u+ ~. v8 h2 y% d+ k
        {
    5 t' w/ x2 {; |& g, J0 o* l- |        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)
    , S1 K9 q, y2 O2 z        {% d' b, ?) X7 ?1 ?+ a: [3 b6 `$ @
                if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation]); s9 o) U5 F+ f) b- B
                {0 n( b+ d( ]' k8 c  b  p+ G
                    // Found valid size in the array.# L" C* L: X7 b% X, f* I( C; `
                    fFoundSize = TRUE;1 N, x( ^8 x  K' ~" _. `% I& C
                    break;
    ) |& [! |6 Y0 s( @8 i' ~4 y" v            }
    + l: M7 i$ [) l! b) R            if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
      b1 w2 C  D. ~        }' }7 k. m: Q" @. J; O1 Z
        }
    , B. z8 d+ X8 z" B    else* B8 |' j/ }4 b& b1 N
        {9 L; c5 t3 I$ \1 r# }, k' W
            fFoundSize = TRUE;' f; I+ B6 h7 U
        }</P>/ I# l2 Y8 S) S# v$ z
    <P>    return fFoundSize;
    ! O- s6 o7 U: l/ u" U}</P>
    0 \+ e% e. R+ I8 c7 X# O* ]" ~7 T3 T4 y<P>: ?% ]4 K9 r5 q8 p7 Z
    //-----------------------------------------------------------------------------
    * c. _0 X# t8 z// Name:
    # ?* F3 O( \0 ]/ @1 e* [// Desc: + ~: m" `# P, h
    //-----------------------------------------------------------------------------/ P+ Q! J' `) Y) `
    void CMazeServer::OnSessionLost( DWORD dwReason )9 ~" A9 w+ ]  B) t
    {& ^4 f+ S6 F) C( w+ w/ h
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );  Z1 W% @4 D& p& y7 H: B! i( U
    }</P># {& J% g( R6 H1 i7 i6 P, Z

    . \% R5 [  D2 n. i4 m<P>: x* j  P: s( l4 A$ n
    //-----------------------------------------------------------------------------6 s$ T1 m  P3 D1 U9 U* k( e
    // Name:
    : m# |" A9 L% F# J9 ~// Desc:
    ! C% j  G9 u' D: f//-----------------------------------------------------------------------------
    4 |  x! p& W1 {, V6 WPlayerData* CMazeServer::CreatePlayerData()
    8 H, \, ~( J/ `+ _- }{. b% T; v7 B9 Y$ a0 V& e5 T, @
        m_PlayerDataListLock.Enter();</P>1 C6 [, `  r$ K8 ^4 b! D. F
    <P>    // Grab first free player in the list9 r/ K2 @9 v) r0 F- ^
        PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>; W3 B  Q8 O# o9 H7 [
    <P>    if( pPlayerData )1 \% x; ^7 u" A9 N
        {/ i6 Z" o% V& F  H$ E/ @, e
            LockPlayerData( pPlayerData );</P>
    % K6 i. N! P" l* L# z+ r4 Q8 g0 T<P>        // Got one, so remove it from the free list( m/ D' @0 n) L3 |4 W
            if( pPlayerData-&gt;pPrevious ), b  l4 N: o1 O/ [, _# v
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;9 _% g2 I0 y4 n" r7 @  ]4 b0 {
            if( pPlayerData-&gt;pNext )
      J( s9 X3 k. w  \5 q, Q7 t            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
    ( Q8 A/ d& z! Q7 H" {3 b' L        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>
    ! f. ]/ }9 U3 e- F7 y' [<P>        // Add it to the active list7 s- K# Q- j" N8 Q# \: l
            if( m_pFirstActivePlayerData )- h8 J8 k, Q4 Q% L( p( {
                m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
    " @5 T  q: Z# i+ F% d: v+ z5 Q        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;; u% S0 P" d' M7 a  N3 p
            pPlayerData-&gt;pPrevious = NULL;, L: X5 x+ V" }% j4 A" [* v; h! z4 A$ {5 N
            m_pFirstActivePlayerData = pPlayerData;</P># t( h$ W9 e0 Q3 e7 ~2 Z; b, [0 k
    <P>        // Update count of players
    " I* N: S7 b5 n" d0 G  q        m_dwActivePlayerDataCount++;</P>
    6 S6 Q3 Q% \. {+ k4 i$ ?+ }<P>        // Generate the ID for this player
    ! J& A  o. l. y! s) A/ U        m_dwPlayerDataUniqueValue++;1 S8 g2 N- I$ r3 K! w" U; }6 Q1 d
            pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
    % r. e/ M& z) ]( J<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;9 K' [; i2 a6 `- `
            pPlayerData-&gt;NetID = 0;
    9 |  I6 I6 s5 q8 Q! u+ a        pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>" P- [9 f5 [5 k# ?' v. w
    <P>        // Insert into the "off-map" cell
    . T- u7 R  B4 m+ V. e  D' I" {        pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;2 q3 K5 M9 z6 j+ v
            pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;
      N0 n* w) @' w2 M. p; l        m_OffMapLock.Enter();( K/ X6 }; T2 M" o8 X4 q& q
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;! p8 [' b' t3 t3 Y8 B) l
            m_OffMapCell.pFirstPlayerData = pPlayerData;
    * ^/ n  a  L7 H8 V        m_OffMapLock.Leave();</P>2 P5 O4 E* }3 Q* h
    <P>        // Mark as active
    + j  s9 m% o" W% X9 M  ~' Q        pPlayerData-&gt;bActive = TRUE;</P>
    , n7 w5 g6 m0 E- C  B& U<P>        UnlockPlayerData( pPlayerData );, }8 [$ f3 x/ c% U; n/ p
        }</P>
    1 a/ a" |/ d! H9 ]1 f6 E0 X<P>    m_PlayerDataListLock.Leave();</P>; t8 a1 n- q! t7 C: i
    <P>    return pPlayerData;
    + ], I  v' O+ i9 {}</P>
    4 w+ o3 l% ^: |$ x, M+ o" N! H6 I
    6 s6 \+ U3 u. `- s<P>! p, `' I& z* m) p
    //-----------------------------------------------------------------------------% A4 I- {+ `2 I0 v# a) ]( n
    // Name:
    # i' \+ Q& q( a2 I$ c// Desc:
    7 Q" W  r* e6 I9 Z- r  K$ |  s' Q//-----------------------------------------------------------------------------7 t; B" z* k1 j) ^! n
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )9 @  U9 G9 {- y. K
    {: B5 A6 F% v8 H# T4 s' U
        m_PlayerDataListLock.Enter();
    ( d; w; e5 d- J5 O0 k3 X7 W. s    LockPlayerData( pPlayerData );</P>
    8 ?) C9 N; K4 v9 ?<P>    // Remove the player from its cell* b% T+ f- l4 y8 P" H. J, }7 b" O: Z
        RemovePlayerDataFromCell( pPlayerData );</P>
    0 T1 D" w% Z7 A+ L* X7 Q<P>    // Mark as inactive: S5 w, o, ~6 x
        pPlayerData-&gt;bActive = FALSE;</P>$ P- C0 r. b2 z% l: T
    <P>    // Remove player from active list" Y$ R' |0 O& I) W3 U+ _+ J
        if( pPlayerData-&gt;pPrevious )2 d! t9 O# S- Z9 [+ |/ L
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;! H0 M/ @, P- {# F2 v
        if( pPlayerData-&gt;pNext )4 c3 z- S8 B- {, L" T+ F& a
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>
    ) }) ]. y5 u) u% l$ d8 }! H<P>    if( m_pFirstActivePlayerData == pPlayerData )
    ; \& E" p* j3 x4 @, s        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>
    9 Q; z* u7 k  X) c/ |<P>    // Add it to the free list
    - P6 e6 j" P# g+ v( H0 n7 a+ h    if( m_pFirstFreePlayerData )
    1 V- o0 M( |# B        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;  A+ `+ J; S/ f/ n( I. }
        pPlayerData-&gt;pNext = m_pFirstFreePlayerData;
    8 U1 [5 t1 k) Y5 P# ]    pPlayerData-&gt;pPrevious = NULL;8 t1 Z$ ]2 }% b5 P! q3 `
        m_pFirstFreePlayerData = pPlayerData;</P>% O$ U/ C/ |0 N( v0 \1 @; e1 f
    <P>    // Update count of players
    % `  p2 l6 R( Q: F9 \    m_dwActivePlayerDataCount--;</P>. v  T/ K. N# W, M3 H: X+ V* D
    <P>    UnlockPlayerData( pPlayerData );
    0 Y% O  ]  E) b2 g7 i    m_PlayerDataListLock.Leave();
    / j1 R; }- N8 C; e}</P>  y6 Z2 x/ }1 c) G1 Q
    5 M1 b! P4 J1 l- K5 ], c
    <P>
    ; A- k7 m" I* U* {5 R//-----------------------------------------------------------------------------
    4 Y8 |1 q1 T# q: J3 W( b// Name:
    7 a1 B2 u' k1 V// Desc:
    " W$ }9 |* [! b+ P, S; {: H//-----------------------------------------------------------------------------$ Y6 |8 I" _8 c: u9 l! [
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )0 P) E* Y$ R, v) d" Q) A
    {1 w# C# `4 k+ W* }& `
        // Lock the player
    % E2 a+ ]; q# w/ u1 V5 ]+ G5 w    LockPlayerData( pPlayerData );</P>
    ; g% Y8 Q8 ~: j' c# @: L<P>    // Lock the cell the player is in
    3 \- O5 K/ m. E  |% j# m    ServerCell* pCell;
    6 Y: A& D9 o* h. ?    if( pPlayerData-&gt;wCellX == 0xffff )% T+ Y3 M+ E4 R1 X3 t
        {* s% u+ ?( F$ h: @5 v( a
            m_OffMapLock.Enter();
    4 B9 W  Q+ w& T0 ~7 ^& _$ r" z' h        pCell = &amp;m_OffMapCell;
    / N, t( C& F  R! s2 L    }5 }2 F9 t9 ^. Z& h
        else4 q( A2 O( A. y
        {0 Y' v3 W$ V+ Y/ g
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );
    3 m# F" z2 P1 y8 s7 ?. I        pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
    $ a- ^3 i% C% {! G    }</P>
    9 s+ I2 S/ W5 s4 H. J# x' K<P>    // Remove it from the cell
    ; ]5 q# C8 {" h    PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    + `! T! p) k/ G) g# [$ s    PlayerData* pPrev = NULL;$ L+ G/ [& `: z. D" R# X+ i- u
        while ( pPt )4 F2 T6 R, f, Q, W3 M
        {
    ) t: i2 k: n/ m0 o' P% T        if( pPt == pPlayerData )7 W3 c, P+ ~* I% r3 |" J% {, I
            {
    8 u! L; S, `% W( G/ Q            if( pPrev )
    8 J6 `: s7 q8 `5 v                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    & d' T4 U: D+ j4 V( P' S" U  ?6 ]% G            else
    0 @. O% a6 r8 h                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>% Y) M! V& {  T" r( K
    <P>            pPlayerData-&gt;pNextInCell = NULL;
      k& T% {- a9 X! R            break;
    ) o0 k* u  X# L2 L, i0 V2 `: M" d        }
    6 N; t, U! ~. R        pPrev = pPt;
    - o3 H0 b; f+ e* `" @; R        pPt = pPt-&gt;pNextInCell;8 t- i0 j% ], }8 c) D  `+ \
        }</P>
    2 D4 }+ l+ t1 R6 \5 z<P>    // Unlock the cell2 Y7 @& s+ _5 p
        if( pPlayerData-&gt;wCellX == 0xffff )
    . U: H4 p* a1 B; z1 a4 q        m_OffMapLock.Leave();1 y" P# W  t' Y# }
        else" m; J# ]2 y. w0 J% s/ B/ _- O7 N, R
            UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>
    8 d+ q, z5 G; _* F& B! o<P>    // Unlock the player
    + `- {" J' t. q2 o' K    UnlockPlayerData( pPlayerData );
    * \/ B1 q4 ]# G) p  z: ?}</P>1 K$ d2 i! F- d) o% p# V6 X: q
    7 y& p3 J% b1 g  _. @( d  w
    <P>' E6 O( v+ N) k' O. u- h
    //-----------------------------------------------------------------------------
      x" W8 |- _3 o9 `5 L! o, B// Name: ; ~8 h6 Q; F- X2 x
    // Desc: - Y5 K4 B8 ?) L- t
    //-----------------------------------------------------------------------------7 {4 z1 K% {1 z8 E9 E
    void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
    ; h5 O4 k0 `/ S% ?; h  _{* v1 ^+ y+ V7 L/ f# I4 C
        ServerCell* pCell = GetCell( pPlayerData );
    ( X9 x0 W' Y+ ?  O    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
    2 ], o; |7 B+ q& q* Z    PlayerData* pPrev = NULL;
    ' {& |" S7 l& H0 D2 P    while ( pPt )+ G6 K; I& P( J8 q, }+ F. J
        {
    + C. M) Q& A, p& o$ x        if( pPt == pPlayerData )4 P- q) V$ |1 i4 C7 }
            {2 d/ |) C4 V# s1 @" }$ g7 J& V
                if( pPrev )
    1 c$ ~, f' g! j7 u! V                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;, b7 z5 a3 E3 o9 X: [8 S; ]0 y6 m
                else
    9 H, f. B, l+ \$ C  p6 N' x                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;5 x, m/ k  t# f" M2 P6 o9 |
                pPlayerData-&gt;pNextInCell = NULL;
    8 y* F4 m$ y% V: f9 e& @            break;
    * e% b% p" N% l        }
    0 V. R% w; f% |2 g' v3 m8 ?        pPrev = pPt;' I& m8 t4 V/ ?- k
            pPt = pPt-&gt;pNextInCell;1 q0 r/ w8 Z+ V
        }
    * Q) Q, D/ G4 ?* t; c5 f}</P>
    % U+ A& g! o' M6 W$ j
    ) z) n% @: t: s. u+ C% U# v& }: q<P>) E6 _* _, Z. d' V
    //-----------------------------------------------------------------------------" A  ^4 J7 S% C+ W2 _: ?2 G5 }% J
    // Name:
    8 H' l8 q" J) {// Desc:
    9 }, c0 _8 q5 \1 l$ A/ E//-----------------------------------------------------------------------------
    3 J$ j, w- ^2 [7 Zvoid CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )6 i: ]5 j2 @- Q
    {
    4 W. q/ B3 S/ I, V3 J& @# e9 K6 n- |    ServerCell* pCell   = GetCell( pPlayerData );5 X* f4 K' V- Y# a$ y
        pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;
    3 o! D6 G# X' J# N9 f6 U    pCell-&gt;pFirstPlayerData = pPlayerData;
    ! |5 o$ a- G8 {/ ~( w  h. [! y* ^}</P>0 [) L0 r: ^1 k
    ) r8 x; D3 G( c8 a+ F
    <P>
    , G, j+ ^7 m; ~' {0 `5 {; e- e//-----------------------------------------------------------------------------! I& a7 t4 a2 r5 p9 I
    // Name: 3 Y$ r4 b1 n! p6 g
    // Desc: , _+ \' }* B8 N
    //-----------------------------------------------------------------------------! P7 E' n# }2 S/ J
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )2 I% t! X' F' [. V" s" t
    {' b. p* }, k, \/ F
        // Grab player for this client and lock it! e/ s& w& e1 D% F3 J
        PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );! w: h) {5 E% Z% l3 l+ i/ {
        if( pFromPlayer == NULL )) ]4 Q) r+ ]9 k
        {
    % y, _8 k7 L1 I! V2 Y& ?        if( m_dwLogLevel &gt; 1 )
    7 V4 F1 V5 a* a' s. b" [3 t' X            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );9 \- g. B; `5 d' E' d9 I* U" n& i+ @
            return;
    8 n! g1 I- I4 F6 G2 \/ q    }</P>
    # Y" s& x& M! X( s" C<P>    LockPlayerData( pFromPlayer );</P>! i9 }- s7 H( P% _6 @0 r
    <P>    if( FALSE == pFromPlayer-&gt;bAllow )
    : i" l" h7 `4 o2 Z* l    {
    3 X- ?1 S1 z- O) R  J; e2 `7 R        if( m_dwLogLevel &gt; 0 )
    ) k9 g6 z- U. D' W4 }            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>: t# a* r; u& V2 V* j$ Q
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );+ `( t5 i0 ?) r) I9 S3 v" _. [& c
            UnlockPlayerData( pFromPlayer );
    ( E7 ~7 Z$ z, ~$ _        return;
    3 J: K3 T  |% _, ]: m; [. l    }</P>4 l& B! R8 O/ B2 E) o
    <P>    // Compute the cell the player should be in now
    2 O7 M$ j& R* Q- O% i" z    DWORD newcellx = int(pClientPosPack-&gt;fX);! g0 h, ~, M1 L1 h( N: L
        DWORD newcelly = int(pClientPosPack-&gt;fY);
    ; t' A: Y: r  u8 l    DWORD oldcellx = pFromPlayer-&gt;wCellX;
    3 F/ J+ D& B. I8 z$ z" e# D    DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>5 k$ E4 a0 `2 }! w0 V. S/ C. I
    <P>    // Have we moved cell?
    0 R: N- ~. @" X2 c8 O6 `8 D% _    if( newcellx != oldcellx || newcelly != oldcelly )
    # G3 O% L6 J2 j2 h/ |8 B    {7 o4 L$ h' P  |* Q7 a  c6 \) u
            // Yes, so lock the pair of cells in question9 u# h/ D* o' q- Q- w0 T% n4 D
            LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
    ( V0 u, |2 B' p2 n/ p. K<P>        // Remove from old cell and add to new cell: H- N$ B$ t9 N5 t) b
            UnsafeRemovePlayerDataFromCell( pFromPlayer );
    ; {& M/ Q: X8 B        pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    2 c. ^0 S9 L+ J5 k1 I8 ]0 `" t        UnsafeAddPlayerDataToCell( pFromPlayer );</P>
    ( c6 i2 j  O1 `7 w<P>        // Unlock cells9 e3 L% R: Q8 G" w. N: v
            UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );1 E8 H. u- X8 ~( n
        }</P>6 @' X6 c+ F# c
    <P>    // Update player position8 g6 X/ [1 E4 R8 J* f8 O% G6 G
        pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;  Q1 o' U' ?. x5 o
        pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;8 r7 `$ v: k& v3 l8 V
        pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>- v9 D! A& G/ O, n  x
    <P>    // Allocate space to build the reply packet, and fill in header
    3 Z3 l$ C# L. D3 X- H# J  ?    DWORD dwAllocSize;
    7 Z% @( \0 k6 p7 S4 N% l+ X! T    ServerAckPacket* pSvrAckPack = NULL;</P>
    . U; U4 }1 b' v+ M  }; x<P>    // Begin by allocating a buffer sized according to* X1 ~9 @! k* |, u
        // the current number of nearby players + 4.  This will give 7 p) E3 ?, S) y  s( l  j
        // a little room for more players to come 'near' without resize) J# w8 ~1 x& W* O$ B) ]+ G
        // the buffer.
    9 k8 x6 d5 c' o) t6 ^# v9 y0 x    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>+ `3 `* t0 l; G, y  P
    <P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);2 L. z) u3 D( f- l" @
        pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    5 J- y! X. W* {; f    if( NULL == pSvrAckPack )0 q- x$ z" z4 }2 S- |- a
        {$ v" Q9 _% z' j0 }7 D. N0 i0 o
            // Out of mem.  Cleanup and return0 e! V7 ^; q' s! m
            UnlockPlayerData( pFromPlayer );
    ; M' x6 F1 z+ D7 N1 ^        return;       3 _, `- a; H6 k/ O
        }; T! K/ _! V2 @
        ZeroMemory( pSvrAckPack, dwAllocSize );</P>3 Q- J# @/ Y5 }% b1 T0 D, C
    <P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);0 \  ^1 Z, p  K
        pSvrAckPack-&gt;wPlayerStatePacketCount = 0;1 `. c% p; h% O/ q6 D
        PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>  a. A& z& i, k8 [2 U: l( W
    <P>    // Compute range of cells we're going to scan for players to send
    % [/ f, p: R. d# J2 v# N    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;% \+ p/ L5 ~7 e0 C, x
        DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
    % L# V$ _6 H! @    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;; `; d5 u4 \0 g0 h1 _9 W
        DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>
    . B, x! j6 ?; u9 Y1 l2 \<P>    // Lock that range of cells  Q; H2 r4 t! v" n  c! ?
        LockRange( minx, miny, maxx, maxy );</P>
    % ~0 [9 m& P$ h8 F9 b$ ^6 U<P>    // Scan through the cells, tagging player data onto the end of  w. ]3 v( |- i+ l' g# x( j
        // our pSvrAckPacket until we run out of room' @1 a. r  c1 J1 }- w
        for( DWORD y = miny; y &lt;= maxy; y++ )3 d2 o0 c7 o5 d/ X$ ]" h/ X
        {' O7 f, |* O2 L6 W9 U  [
            for( DWORD x = minx; x &lt;= maxx; x++ ), w# t( }/ N! {5 s# _) Q" B5 p! K
            {2 G1 r% z. j* o' t) r
                PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;1 c$ P2 j- r6 w. q5 F7 s# n5 C
                while ( pCurPlayerData )
    ( M, |' a6 T& I2 x1 y. t9 j7 R            {" J) E+ {* i0 H5 Y" I
                    if( pCurPlayerData != pFromPlayer ), z* G3 E  W* k3 D) w
                    {
    + l7 M7 }( y# W# G: U                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )" N- C& }- y  y9 p1 E1 I# ^
                        {
    ) G, j8 B/ _4 z1 Y4 D+ j                        // Make sure pChunk is where we think it is
    0 h! V  t$ K* `. r. t" m( M                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>
    2 a0 w/ T. @! z4 L# h1 }<P>                        // There are more than just 4 new nearby players, so resize the ! n/ N3 y4 l  H+ t$ b. Z5 ^7 {
                            // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.6 P. ]6 ^* N6 Z0 y6 ]
                            dwMaxPlayerStatePackets += 16;
    8 e1 F  q- J- p3 c5 E; Y! [! K                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    9 N6 ^3 t2 t# h4 f                        ServerAckPacket* pNewSvrAckPack = NULL;8 U" Y+ K0 N6 B# H3 v
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    + W  P. f% }9 c1 @- W1 U6 T                        if( NULL == pNewSvrAckPack )
    4 @1 {4 Q5 K! S                        {6 P# @3 h' j# s
                                // Out of mem.  Cleanup and return
    $ E$ |; [( c) i) `                            free( pSvrAckPack );5 |9 A$ w0 \" ~8 u) e
                                UnlockRange( minx, miny, maxx, maxy );4 P7 Z. i  J; Z' J8 A8 Q; n7 ?% O. O
                                UnlockPlayerData( pFromPlayer );
    & B8 H+ g8 Y6 l, u+ o# G                            return;       8 L- j9 A$ i3 E5 b; w& R' ?
                            }</P>% h: {- m$ P0 x; K4 F) q
    <P>                        pSvrAckPack = pNewSvrAckPack;
    5 ?  ]% m% z6 o$ t9 U: O                        pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
    6 d1 @  t& G- N4 P2 e<P>                        // Make sure pChunk is still where its supposed to be
    & c6 u) W; u- W$ b/ Q, n2 x                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );
    , H0 O0 \6 T( T! E                    }</P>
    4 S% |/ k1 Z  k; S, w6 U( y" R) d, n: q<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;
    # K- [' V7 ^& u% M! q5 W                    pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
    5 \$ J5 n: ^' h% M0 |, ~: O                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;
    5 w+ \5 D$ E8 x( J1 M$ a                    pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;2 F2 b- f* i" r; k
                        pChunk++;
    7 h+ Q7 p; _: U                    pSvrAckPack-&gt;wPlayerStatePacketCount++;
    9 l+ L3 O' b. d% o                }
    / y  G& Q3 n/ u  K                pCurPlayerData = pCurPlayerData-&gt;pNextInCell;( ~7 F6 F! H2 S$ K1 G
                }
    * Y) k, h/ h/ D# G% Q# t3 ]1 R7 c        }$ F/ p" N( X$ i9 P+ z' X
        }</P>
      x! ?0 m1 X3 k. A<P>    // Update the dwNumNearbyPlayers for this player
    ! ~: C  o( _' p7 g    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>
    4 j" H9 O. V4 W1 [5 w! l<P>    // Unlock range of cells( l1 J6 D  n  O- _5 x9 I
        UnlockRange( minx, miny, maxx, maxy );</P>/ e0 A& N; R6 C2 y
    <P>    if( m_dwLogLevel &gt; 2 )' E" i$ M8 _( |( G# c5 e
        {( @# ~( z, {1 T+ T
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    - H1 q% t9 P2 z2 R0 c& S$ V& E    }0 ^! k4 u5 Z8 {% l. u1 L- k
        else if( m_dwLogLevel == 2 )" L5 c1 H0 i  x0 J
        {! l! C2 ]" {/ n! {* o! x
            FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    3 J) ^  @. _# B( {# h% ?9 z        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )9 N4 i" e2 O+ S6 W. L
            {8 K" \5 m, I" E; u, E5 n
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    $ A$ J0 n! x2 _* |9 x            pFromPlayer-&gt;fLastDisplayTime = fTime;. i: ]! [8 d# `
            }
      q' s. N# [5 i# V    }</P>
    1 B! Q  @8 q6 |$ f7 N4 g<P>    // Unlock the playerdata  K. s; V1 k& o% F7 t
        UnlockPlayerData( pFromPlayer );</P>, h, \1 P1 V4 m8 T
    <P>    // Send acknowledgement back to client, including list of nearby players - ?& ?) p) O$ g! S3 z( ^8 R: V
        DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));
    ( q) t3 J7 N$ |4 @ * X8 l3 \2 `3 [4 f) N# d9 p
        // Pack the buffer with dummy data.
    1 J. K3 E: Z2 p) d    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)' ]% W# Q% h! s
        {- S! t$ o$ T8 n" j
            DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];* L; s- e1 P7 L( F) y! i
            VOID*   pTempBuffer = 0;</P>- N7 D9 B" D" k5 j
    <P>        pTempBuffer = malloc(dwBufferSize);+ E8 u  H7 O) o# Q( C/ D
            if( NULL == pTempBuffer ); Z# v5 e) H+ s: p# I: X' U
            {
    " C9 g3 t+ Z  O" i! F            //Out of memory
    $ G$ k" s$ r7 V" ^* T( m            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
      v& u; o+ F- N3 E! u! G- Q1 i) q: o            free( pSvrAckPack );5 U" i  v$ g+ u/ S% d0 ]
                return;
    , g& Q. u2 C- x' @6 a        }</P>8 M/ ~+ u# [3 t& I9 ]9 A" K* P+ @; g
    <P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');
    1 ]" e# J" O; @9 b! F) c        memcpy(pTempBuffer, pSvrAckPack, acksize);</P>
    4 s' W3 q5 b3 i' f! a<P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );
    $ R: P5 b% p( W$ z; W% y6 c   
    3 }; p! ?% m! q5 ^% s0 d        free(pTempBuffer);
    , }$ v, Q; D8 V6 t! u' U" a    }   ; T/ R) T  I% X& Z* t
        else
    0 Y* C) Z6 _$ N9 f" ~3 Y  j2 C: A    {
    - L7 L# T# O( X& w( H        SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );
    % e1 B2 p8 T  y5 v8 L, `/ L    }</P>
    5 V' c/ g. X8 r/ m1 E# o" d<P>    free( pSvrAckPack );</P>
    - g- G# u2 Z+ c, N# U+ u* a1 b  @7 S<P>}</P>( P4 y1 J, \& \# E4 R2 B

    + ]$ q3 a$ e: w" b3 P' [<P>! V: E3 |" Y' k  Q9 ?3 z
    //-----------------------------------------------------------------------------
    . `& t  M9 D+ v! o  M3 Z// Name:
    ; p8 E2 \& S$ p& v) r// Desc:
    7 w; ?4 M( H  A) c, ?//-----------------------------------------------------------------------------/ A& P. E/ I, o3 u: N
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack ): h% U$ }9 v, i! d. r
    {
    , L6 ?" A8 L, w2 {; T    // Grab playerdata for this client and lock it8 A$ M$ e- S2 ?: H" j1 L# A
        PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );9 ?, J; L3 o+ T. M6 D3 i
        if( pPlayerData == NULL )' L6 A/ R4 X0 P, p) z  T: R6 ^3 X
            return;' r$ i: H1 m" t/ _# s" A6 T
        LockPlayerData( pPlayerData );</P>4 S& c8 ?# U/ U. {
    <P>    // Record the version number , `7 i, k4 r! ~7 r$ x7 l, _
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
    . `! u6 G, I6 `+ O1 L<P>    if( m_bLocalLoopback )
    $ h( n, o( j9 n# _" g" n9 N2 _        pPlayerData-&gt;bAllow = TRUE;
    $ a9 N5 n5 D) e" o2 t1 \    else
    . h9 \$ K# a: O( s5 L        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>
    ! D4 j, Q- h& e# O4 [2 V  H% |6 |<P>    if( m_dwLogLevel &gt; 0 )/ T4 \3 x- ]. ?* G& H8 Z
            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>
    " M2 E! A( V- V4 i" p9 @<P>    if( FALSE == pPlayerData-&gt;bAllow )0 N0 [  ~+ v2 n  e
        {) y* L; d+ h- Q! R
            if( m_dwLogLevel &gt; 0 )
    + y9 Z: f( P- G5 o' E& j. b            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>! |. K! S* f! I( I5 \8 R3 p5 s1 i
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );3 Y4 w) q; U3 O% }  B
            UnlockPlayerData( pPlayerData );
    - `5 f5 T: V4 K        return;. n. z% m! w9 Z
        }</P>
    4 r8 h2 Y! I4 C<P>    // Unlock the playerdata
    8 [2 I# f8 J9 x$ {: \    UnlockPlayerData( pPlayerData );</P>
    8 m, }3 t7 i  m. o/ E1 V<P>    // Send acknowledgement to client that the client was either accepted or rejected
    3 V; ?- H) o0 a; ~& P( q    ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );' x$ e, @3 d+ ~/ Y+ a
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );2 t- }. Y# `: K( t# O  d7 B
    }</P>
    : k4 l) v* B$ x, b( ?* i7 X. e' g# U
    <P>
    9 O' {* h$ X' I" ]7 o! w$ c//-----------------------------------------------------------------------------
    5 r3 q$ }5 _/ }; r$ j9 _% O// Name:
    : j! h/ X) u4 F7 V// Desc: ; N: Q: D+ L' d
    //-----------------------------------------------------------------------------
    " E8 }+ S" w7 h* M0 [: J1 e+ KBOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )' g; U! U2 n; v' ]/ q
    {; \+ ]/ s7 v! n+ q1 x, K
        switch( dwClientVersion )
    4 J. y: K  ~6 q1 ]8 p, r    {
    ) d$ y% K. X( w2 ^        case 107: // only v107 is supported; j! r7 K& U) P1 F; D6 w2 N
                return TRUE;4 t& T. ~$ S- J; ]
            default:  G$ g: x, U6 ]7 @4 B
                return FALSE;/ v5 A* G+ ?  w5 a. ~: k
        }
    1 V* a6 G3 R( s  D: J% t}</P>
    ! _% P3 k3 h( Y9 C  h2 C% k- Q
      U/ h/ k7 D2 O! {( ?& B9 c! K<P>& l( `" Q6 L' L
    //-----------------------------------------------------------------------------
    7 o! @% W2 a; B3 o7 \1 ^4 V// Name: " S" W& i  P/ H
    // Desc: $ C. M* Q+ M1 H1 c: ]  u
    //-----------------------------------------------------------------------------
    * R. Z. G$ |( Cvoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
    ( v  E' |( H" {' s{- K' n% B: b2 \# g6 w
        if( m_dwLogLevel &gt; 1 )3 Z# Z  |! A# j5 W; G. G0 M& k" \
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>: S+ d9 L. G1 E5 v0 H3 Z# k
    <P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );6 @( o6 b$ o* B" Y" }7 U+ |
    }</P>
    . L, p$ I: j% c6 w6 T% q9 c1 w; Y) x0 u1 U
    <P>
    6 E6 W7 k) T3 t. x( J# Q9 S//-----------------------------------------------------------------------------6 g: c- U. J1 L) I# ^# [# U
    // Name: " J4 @6 T4 F- |
    // Desc:
    9 c& J- X6 V/ o; z) n//-----------------------------------------------------------------------------
    $ X, M8 K2 Z6 \/ KDWORD   CMazeServer::IDHash( DWORD id )+ U1 b: ~$ i8 f  ]4 B5 x
    {! q$ C! ]) O6 R# M
        DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);: F, c+ M% I* D: b* _3 b
        return hash;
    5 m! a. {9 {# z7 `* f}</P>
    ! h( J+ u% Z; o4 T4 z
    9 a: w* ]/ q& M+ S) F4 T<P>
    ) Z& K0 X+ {3 f//-----------------------------------------------------------------------------
    ; S0 G) h& v6 |. H. i// Name: 8 N: H0 k# F. {0 C/ x
    // Desc:
    6 X: l& s7 x" x) b//-----------------------------------------------------------------------------
    7 k- M  ~+ a7 F3 P, U" rvoid CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )9 J  Z5 ?% @- ^/ N$ Z
    {
    , o" `/ j4 h' x, c3 I1 E9 _    // Hash the ID to a bucket number% l4 w  {, V# y8 g9 z8 n8 E
        DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
    3 V3 O4 P9 w2 B! r, {<P>    // Lock that hash bucket
    / u9 r3 u0 g+ m3 k1 n+ ?( x: B# D7 @    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    9 f" F& K8 b/ j( x/ q    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>1 n- g6 g0 i( @9 E% ?6 A3 X
    <P>    // Loop though players in bucket until we find the right one5 m9 L0 Y1 `+ {4 m! Z8 }7 V5 x) |1 Z
        PlayerData* pPt = m_pstIDHashBucket[bucket];" k# k7 y0 O2 n9 E6 c5 ?$ f1 p
        PlayerData* pPrev = NULL;$ d  w+ I6 f) c. r. p; ~( H
        while( pPt )& [  u2 A6 R5 e2 z5 S& ?
        {
    8 q7 v' c+ [* \% w5 U3 P- D& b        if( pPt == pPlayerData )) I8 i6 y) O( C9 n/ G- |; M  e
                break;
    0 O. p/ w3 n* h9 `9 `8 ?% \+ x        pPrev = pPt;
    + g8 m  b6 \) V% l( m        pPt = pPt-&gt;pNextInIDHashBucket;
    - D! @0 t% F$ f8 E( m9 s) D* F5 ^    }</P>
    1 A) G4 ~4 |6 N! ]<P>    if( pPt )9 B' Z. t  I9 ~6 H& {% d- z2 N
        {8 e' G5 k' v# M8 o1 L2 `, u2 |
            if( pPrev )
    $ \( o% m* x6 x0 U7 o$ j! K+ y            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;
    5 x1 A! C0 }/ C* W) Y" N        else
    & r( }% I9 w' W8 D, C% X            m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;1 K0 g7 _$ \- ?' d1 l
            pPt-&gt;pNextInIDHashBucket = NULL;1 x5 ^3 ]5 U4 A4 v( n$ E9 [
        }</P>0 x. w, J+ W* ^6 w
    <P>    // Unlock the hash bucket% X0 L2 b' f. m9 ^4 O& f  e  i. d
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();1 V+ f+ M  [! z9 D, Z
    }</P>
    / u( m: K) W) I. Q% K- b
    * e/ r9 Z/ }. g3 C<P>
    0 T9 E. z7 k" u) C( p//-----------------------------------------------------------------------------
    $ m' z2 w% m, u7 m// Name:
    * d% O: f- g% Y5 G// Desc:
    ( }) {, U& ~% B+ t. R" x//-----------------------------------------------------------------------------
    $ `( b7 i$ I+ j( b1 \  Q/ Kvoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
    3 L3 A% W0 O1 x{
    / o0 s9 l( u2 j+ q- L7 ]    // Make sure this player isn't added twice to the m_pstIDHashBucket[]
    8 b3 t1 _# y/ ^5 J! F- s    // otherwise there will be a circular reference- o. \7 G. `: Y& N% [
        PlayerData* pSearch = GetPlayerDataForID( id );
    7 E- j' ^4 l( |. y) M    if( pSearch != NULL )
    5 v% B4 A; k; f        return;</P>- T0 n+ X. M8 x7 n
    <P>    // Hash the ID to a bucket number
    , p) Q3 ^3 \  c& d. i    DWORD   bucket = IDHash( id );</P>8 U8 O+ a5 [; S# A4 r4 D
    <P>    // Lock that hash bucket- Q1 T, Q- P- E; ~& r* W' w& p# r
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    6 f2 l+ v0 M5 P, k% G) H" w    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>4 w) t! l% [& U8 Q2 s) T3 r
    <P>    // Add player onto hash bucket chain0 V0 }) d4 z6 s" T) C
        pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];
    " }4 g% p; U# A, B  M, H    m_pstIDHashBucket[bucket] = pPlayerData;</P>
    ; \9 }, H! W: R9 {<P>    // Store net id in player! O% Y. C8 ?! c% F# G
        pPlayerData-&gt;NetID = id;</P>
    # ]+ [3 a! E/ A9 D<P>    // Unlock the hash bucket
    4 @2 {+ E6 ?3 {4 I) m) P    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    - l2 A, T  I7 B" [; b1 t. A}</P>
    # i  m. V4 u8 s- C8 V$ z$ ^4 V5 |* {% `/ z: G! p, R
    <P>/ c: S( g: l* B$ N. ]* n# W
    //-----------------------------------------------------------------------------3 w1 O8 \; s* w0 ?6 i6 H
    // Name:   |% A1 }: a5 M) U- ^
    // Desc:
    * j9 t7 G9 }2 d//-----------------------------------------------------------------------------
    3 B0 U9 u# [- z1 J' q, ZPlayerData* CMazeServer::GetPlayerDataForID( DWORD id )& }+ B! h5 Y1 T- ?! c
    {
    + \' b* B% c  }2 B* R* b+ y    // Hash the ID to a bucket number: n+ k/ ?9 a; O$ P- z
        DWORD   bucket = IDHash( id );</P>8 H- \# H6 J$ @. n7 q
    <P>    // Lock that hash bucket
    ! i# `. Z4 E* J3 e; i, P4 o    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;3 _. F7 s7 P% D; `; c; X
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>/ p4 i0 |8 n! P& n8 G
    <P>    // Loop though players in bucket until we find the right one
    - {2 g4 C% u/ I( u: {4 L/ o    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    ; ~. E% l/ M7 `& [$ ~    while ( pPlayerData )0 L8 u" u. c4 [- R
        {
    % f5 ?# [& I. K2 M4 \+ }+ d" B* k        if( pPlayerData-&gt;NetID == id )
    : K: b* W9 k! g2 m- w8 B! y  D5 g; ^3 p            break;
    + [& U/ U% H& G6 [        pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    . A& o, N5 g3 W3 T  {$ K4 C: A/ i    }</P>; U( u" ^# O$ f
    <P>    // Unlock the hash bucket  j) V. ]; ?" p- v) _0 {% f
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>
      c8 L6 f  C0 o* c$ E- ^, c/ ?! ~<P>    // Return the player we found (will be NULL if we couldn't find it)7 |/ D! z- u$ E& T) w: {+ Y/ b% c
        return pPlayerData;
    1 y  Q" u, R3 }( l" Y6 m$ X9 T9 s% t}</P>
    , g* ?- R! Q2 U! D( L2 X) T2 t- k$ O% [
    <P>
    $ q& W  i* }; B//-----------------------------------------------------------------------------& ^/ A% y4 ]2 d+ q
    // Name: ) n* H* V, ]) X+ s0 d7 q; G
    // Desc: calls DisplayConnectionInfo for each connection in a round-robin manner1 }3 d( r8 {* C- A% D" `
    //-----------------------------------------------------------------------------
    : y" m! ~& P) Q$ Ovoid CMazeServer:isplayNextConnectionInfo()8 D% H8 f" O8 k
    {
    8 j2 x3 w9 I4 v1 w$ K    if( m_pNet )
    . M# o7 V3 }- \0 Z$ c8 Q4 E/ x    {
    & H6 m2 @# ^* `' ~* ?; r: J        // Find the player that was displayed the longest time ago, and display it.% f2 ]8 F0 i4 `7 p& l" |
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );1 ^- f: J' q2 _' O" H: @) A( X- |4 P
            PlayerData* pOldestPlayerData = NULL;
    % w2 E( i3 i# t( x        FLOAT fOldestTime = 0.0f;</P>8 M6 ~# Q# _$ \% x, K5 s
    <P>        m_PlayerDataListLock.Enter();</P>0 l7 p  s; a+ f  E. ^3 U' z
    <P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
    : K+ k" w) |" @# m! X& r        while ( pPlayerData )6 s8 @" s" s- u$ ?+ L
            {  A+ p" P9 d0 O; g1 z4 \
                if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
    . R7 z: p* R. r            {
    % V+ g8 S0 ]3 t; B9 k: x6 f                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;
    2 G/ r& f1 `/ F/ M4 }4 w/ T                pOldestPlayerData = pPlayerData;: c6 O+ M2 T0 ~. t7 u5 I
                }</P>
    , I7 l9 }- M' K% Z7 T<P>            pPlayerData = pPlayerData-&gt;pNext;
    2 p8 u4 l, k" ]' R: a9 {+ T( I7 B        }</P>
    ) s9 N) x' u/ ?8 j" P<P>        // Display the player with the oldest CI field, and update its CI field.1 \; A5 A0 O; x8 i
            if( pOldestPlayerData )
    * v4 O7 v0 [! T        {8 }! k" }8 P0 m, J7 z/ S3 F, S
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
    * ]) a2 l% A2 d            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
    , |- g8 S" {8 Y( [/ ]            pOldestPlayerData-&gt;fLastCITime = fCurTime;
    % P% {1 h9 ]8 B" M5 D. |% N, Z- L2 W/ V        }& C1 s( u( `9 u7 V/ T+ O) y* ^
            else
    . F. ?" `" L  C3 q        {
    7 N- n& [7 t3 @            ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    . p! f- }0 P& U* B' ^        }</P>
    9 d8 M  [" O( v2 A; R. s% L- u% o<P>        m_PlayerDataListLock.Leave();
    5 ?! c' |) d4 H, r  {    }& P( R4 m; \( n+ H: G
    }</P>
    ; V2 a2 x$ E" _- s2 C
    # U! d, H3 B: T' d& w/ A' u) C! K<P>
    # E9 o+ y! l1 U0 G& R: X  T8 [  h//-----------------------------------------------------------------------------1 c+ |+ o- A, Q
    // Name: ) L/ {1 ^- V0 G$ k
    // Desc:
    3 J6 K( J2 a! L2 y4 c" M//-----------------------------------------------------------------------------
    7 I. F/ T6 M8 Rvoid CMazeServer:rintStats()
    # R1 J5 Z( E; s2 F8 c$ x{7 R) y2 y- [: H0 c( p( J2 c
        ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
    3 y5 w# D8 b6 z, Q9 ?3 V! T                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );
    # Y2 Z8 l9 E  e    ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
    4 C: I+ J4 \, P                                    m_fAvgThreadTime, m_fMaxThreadTime );( v: G: ]' s# y; u
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );$ s9 w$ A- h1 A! U) ]
        ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );# B4 Y( z& U  J6 Z" G
    }</P>
    5 r; c+ A% d5 Z6 P
    ; |+ W* v$ R6 Q: @0 ^* \<P>/ L' e' A$ |+ W# l' M
    //-----------------------------------------------------------------------------: u" W! p7 f( t' E% L) k- c9 t
    // Name: 2 j/ {8 k5 a3 n; Y9 K$ Y' {1 x) d
    // Desc:
    $ ?. j: D' t& e* V//-----------------------------------------------------------------------------
    # O  t& e  ]% m8 L9 W' i$ V: j3 Ivoid CMazeServer:isplayConnectionInfo( DWORD dwID ), [. E$ [; c' C* K: r1 @& n/ o! h
    {
    ! Z8 ?5 ^9 K6 J5 ?9 @  F6 K8 |# N    TCHAR strInfo[5000];8 F! _( X- B( n9 P4 r" z5 S
        TCHAR* strEndOfLine;
    , _% A# k8 D& L6 s    TCHAR* strStartOfLine;</P>
    . b8 a) Q) b* _<P>    // Query the IOutboudNet for info about the connection to this user
    1 _! y4 C; y8 J    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>  {2 O: I+ g( n/ R9 X2 U) o. U' F
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );0 J. |* z7 N7 y6 F. t( D5 X
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>; Q1 f% x) u8 K+ C9 ]* P
    <P>    // Display each line seperately
    - E6 l9 z( z$ s$ n1 j8 ?6 W    strStartOfLine = strInfo;$ @; l$ ~/ ^8 M' }* F
        while( TRUE )7 A" j& V! m$ ?- p  O2 `; f
        {% a& \* J0 ?5 n, |$ P" T
            strEndOfLine = _tcschr( strStartOfLine, '\n' );
    ' N) F: a& h* h% n* Q2 A3 {1 Y0 R        if( strEndOfLine == NULL )
    + Q! Z0 Z7 [: g- l0 m            break;</P>( B6 Z  s7 w7 w  ?
    <P>        *strEndOfLine = 0;
    # T- s- I3 G( r- t$ Y        ConsolePrintf( SLINE_LOG, strStartOfLine );  `  r3 E+ B* L5 U+ O
            strStartOfLine = strEndOfLine + 1;# M* h. |/ l4 I2 a8 q8 _/ }* e9 D( S* ^
        }
    5 v% ~" p' ^6 @7 @1 L4 q}</P>4 ?, M  |: W" ~, D; Y; _& x- F. E3 U5 y
    5 T. q! ]1 ~. L" T
    <P>/ A1 _6 F( s- _/ {6 n: {
    //-----------------------------------------------------------------------------  b2 y8 g7 s" [  F
    // Name:
      l- n' v% U0 f8 O6 g// Desc:
    / D; b( V/ ]. f. q1 t//-----------------------------------------------------------------------------& h' `' u6 a4 B% l* D6 o" o1 v
    HRESULT CMazeServer::SendPacket( DWORD to, void* pData, $ l! g  A* y7 R$ Z6 A
                                     DWORD size, BOOL reliable, DWORD dwTimeout )
    $ q; j! \0 |) W2 ?# {* K{& F4 ~) N  Y# \4 y3 T2 D& S
        // Chance of forcing any packet to be delivered reliably4 ~8 F& P# t" u4 r, E6 r% X
        if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )
    : Z, ?; Z! ^& Z+ z8 {        reliable = TRUE;</P>
    ( S5 }. \* c2 ~- }' P<P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    - p. V  P4 _8 w, a0 a# m}</P>
    0 y% [  n9 o7 A/ A
    ( P( t" {% O7 f" a1 G7 T( ?' g<P>
    ' [6 F2 X0 f) Z" U6 g+ C9 n//-----------------------------------------------------------------------------% X4 i: O' l! S- x. R
    // Name: ! [3 V2 [; [9 _" ]  ]$ m
    // Desc: ; L0 i2 Y; I0 K- V
    //-----------------------------------------------------------------------------2 L- G6 |: E- x4 e+ D
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )
      C  j& K) r! G2 @0 l{7 J- B0 c: V% o! Q
        // If we're up and running, then send this new information to all clients
    7 j, |5 X/ o, F    if( m_pNet ): L: g/ Y' O% }$ ^
        {
    " M0 J1 z: C  N" `, W% M, L. x3 a        //Use the AllPlayers ID
    + l: K" H$ d2 @) p, K        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );) H6 D. y; ]1 ~6 F, X$ _
        }# n  r7 c7 p5 |6 x+ M3 |$ h
    }</P>
    + g  k2 }7 E% ^
    ; p& }$ i' R, c8 X8 X5 v8 [) M<P>& G( @+ O7 `# n& N& |5 k1 y* b
    //-----------------------------------------------------------------------------+ R$ u, ~7 K5 Z% A& `0 v7 Y
    // Name:
    ) V) m0 X  Z9 r; \// Desc: ) O0 S' X2 r' Z  @1 Y
    //-----------------------------------------------------------------------------
      M9 f0 u# L' N& w' `; h* Uvoid CMazeServer::SetClientReliableRate( DWORD percent )6 d9 A7 u' g6 S  v
    {
    . X2 A  K( S$ R1 V    // Update client config, and build packet containing that data
    ! y  U2 w( Q& G( W; T  N    m_ClientNetConfigLock.Enter();
    5 j# _, U( L0 z    m_ClientNetConfig.ubReliableRate = BYTE(percent);' L7 v0 x  v% N' G
        ServerConfigPacket packet( m_ClientNetConfig );
    3 L& `) B. i- O- Y4 r) A& V8 l    m_ClientNetConfigLock.Leave();</P>( c+ [2 j% s8 c) R) X
    <P>    SendConfigPacketToAll( &amp;packet );$ c6 W8 _6 {2 a0 _
    }</P>
    * \' ]( q" L# m7 d! O: G& b6 t* ~& M4 t. P' o% y* j. f
    <P>( T1 l" V  R' v  O* k/ j
    //-----------------------------------------------------------------------------
    4 U9 Z  L5 r  ?" P( M) M6 y$ ]// Name: " e6 W" ^: r. p) `$ ?7 b
    // Desc:
    " p' |2 [+ \( X* }3 r0 D& H6 \//-----------------------------------------------------------------------------
    7 h5 g5 {6 Z; k5 avoid CMazeServer::SetClientUpdateRate( DWORD rate )
    9 z' e, v& T4 y! I{+ b* ^6 {5 B' H% Z3 b
        // Update client config, and build packet containing that data4 u. d1 d- ?8 Z4 Y6 u
        m_ClientNetConfigLock.Enter();+ K0 S' V, {5 j  h! ~" ^! q
        m_ClientNetConfig.wUpdateRate = WORD(rate);" U9 }, B- f% H( W+ @6 M
        ServerConfigPacket  packet( m_ClientNetConfig );5 E( Z5 f" D! V. @4 ^
        m_ClientNetConfigLock.Leave();</P>% ^- C& T1 ]5 B' x! K8 z
    <P>    SendConfigPacketToAll( &amp;packet );
    ( T# U& E  ~9 [3 W3 O}</P>
    ) @2 R( Z" O, ]; V' e* I9 f3 g* v7 ~- ~1 P
    <P>
    : Z, k3 s* ^7 X2 B//-----------------------------------------------------------------------------
    2 `  z3 c8 b  H// Name: 7 X- J% u# e* q+ C) n: Z/ \
    // Desc: 3 y/ V" Y# s5 M; T
    //-----------------------------------------------------------------------------
    ' j4 M" @! ?7 J' i: J3 i9 Avoid CMazeServer::SetClientTimeout( DWORD timeout )" F( W" T6 A: y
    {7 B: k" M9 A) Z+ q6 f5 m
        // Update client config, and build packet containing that data
    3 m" G# L8 Y6 j/ E- P- w    m_ClientNetConfigLock.Enter();
    2 d0 }- F1 F. U# m# ?    m_ClientNetConfig.wTimeout = WORD(timeout);
    1 g. r2 f# ~8 X+ m5 @2 l, C    ServerConfigPacket  packet( m_ClientNetConfig );# p/ k, V: P( m8 L
        m_ClientNetConfigLock.Leave();</P>
      D: L  ~! Y2 I' f" @9 n<P>    SendConfigPacketToAll( &amp;packet );
    % d7 j) W% W" [4 i, Z8 ~5 V}</P>
      I! _4 M1 y2 V9 e3 o$ `+ M0 K% I1 E- \1 ]4 s, W. _, K* ~2 @
    <P>
    ! R9 Q5 w1 _* F: |8 f+ a5 {0 F//-----------------------------------------------------------------------------# |# F2 V2 X* z! s- e4 x. K
    // Name:
    . U7 m0 ^7 K0 }, q/ j! X& @// Desc:
    4 K% ?& s- _2 D% G//-----------------------------------------------------------------------------, w. z: N, W+ A. P: [* ^
    void CMazeServer::SetClientPackSize( DWORD size ); U* z" Q- d" A" G4 {0 P9 Q7 y4 i
    {
    & f  `7 p% n; M    // Update client config, and build packet containing that data
    / }; I# I# U9 z- w& i    m_ClientNetConfigLock.Enter();  l) G% a9 m* P" A
       
    / L: b. @  l: H% N# y' V    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.! x7 A$ I% ?. n! g3 a- m% t
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   
    . A5 G8 X$ f4 c' |, l6 ^' A        m_ClientNetConfig.ubClientPackIndex = 0;</P>( T/ n' U. Q5 Y8 b
    <P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);; `; W1 O: D7 K; ?2 W! A9 s
        ServerConfigPacket packet( m_ClientNetConfig );! {' `; ^4 g9 d# t0 z/ o6 y* H6 _
        m_ClientNetConfigLock.Leave();</P>
    - i) k. [" G' S; K. y9 l5 [, |+ K<P>    SendConfigPacketToAll( &amp;packet );
    ( v9 v; Y8 }4 A}</P>+ i: Z& K3 {0 J5 B' Y0 I/ U& `5 }

    7 G0 U& A- [- y0 l<P>
    8 s5 P2 X0 m  g+ w6 A$ Q//-----------------------------------------------------------------------------
    8 k: b0 o& g" d4 y; B// Name: ! i/ X+ Y. B4 w  C. I1 d, c  x4 N) r
    // Desc:
    - O/ R1 S7 M! P% X) j/ H//-----------------------------------------------------------------------------( _, p7 X8 N- e2 j
    void CMazeServer::SetServerPackSize( DWORD size )9 l# ?, }( d) j5 ]
    {
    ' g  L$ @9 g% c8 O/ g    // Update client config, and build packet containing that data2 z: @4 L7 T3 j5 b* {
        m_ClientNetConfigLock.Enter();* r/ x# g& V$ @4 r" j! ?
       
    & `1 s% i3 A) r- m! n! q    m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.; I; {3 Z1 ^; k7 ?
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   # U; x/ @3 |- m
            m_ClientNetConfig.ubServerPackIndex = 0;</P>
    " K7 U: i- P* x+ {: K2 t<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);& d: M% y5 V8 n6 b
        ServerConfigPacket packet( m_ClientNetConfig );
    : ?9 _/ Q# Z9 g% L3 v; v    m_ClientNetConfigLock.Leave();</P>
    5 L  @2 A3 [: s9 q<P>    SendConfigPacketToAll( &amp;packet );6 K+ L' W" H: q! b# a. p
    }</P>
    9 ^  G$ Z/ A" N% Q<P>
    8 m8 f+ v* i- I! N! m- h& }//-----------------------------------------------------------------------------8 V3 ]# ]  U* ^" b" E, ?% F
    // Name: - o4 U- t- J6 B2 T; I9 u
    // Desc:
    4 \! t/ u* J) T4 Y: @+ ^//-----------------------------------------------------------------------------! H/ k+ p- I0 O2 f0 b  t: q  l
    void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )9 J$ H0 v# T) o+ P' \1 w
    {2 {0 X) d2 [# F5 S9 H; A$ M
        // Update client config, and build packet containing that data" j  p' \) a% ~/ y! C3 g
        m_ClientNetConfigLock.Enter();
    2 `7 R& S. I) l+ O   
    7 S3 y) i& D. @; ]9 [    m_ClientNetConfig.dwThreadWait = dwThreadWait;6 K3 U- T+ a. I) J2 D
        ServerConfigPacket packet( m_ClientNetConfig );
    9 y# T3 V: ~- [9 g( @& _! Z4 ^    m_ClientNetConfigLock.Leave();</P>2 |& q# E  {, o( r" m
    <P>    SendConfigPacketToAll( &amp;packet );1 i3 D! R2 X3 G
    }</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-18 06:50 , Processed in 0.386972 second(s), 50 queries .

    回顶部