QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4202|回复: 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>6 G4 L+ ]0 |+ n8 Q# @, T& l( N
    <>// File: mazeserver.cpp
    + L$ }& i8 w  H1 B  s9 z; Y6 \8 m//
    6 Q$ o2 ^' G% w4 `9 u, m// Desc: see main.cpp5 Z8 o, }& {2 e+ ^2 f8 B0 m
    //9 F* `$ a; H9 S, i& ~' Z7 @; A
    // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.( x1 x  z: l: c1 P3 P  C
    //-----------------------------------------------------------------------------5 g# h+ B5 y% Z9 ^
    #define STRICT
    2 |9 G% C: \- s! @# o! \$ R+ h- F2 O$ j#define D3D_OVERLOADS, @$ [* c1 |. I- Y+ s
    #include &lt;windows.h&gt;
    " u; P" \0 ?1 a1 ^: W/ Z#include &lt;d3dx.h&gt;
    ) Q, E2 E  A5 t4 D# b#include &lt;stdio.h&gt;
    , a. q: v  q2 [+ T( b#include &lt;math.h&gt;
    9 \: @/ [* r; z7 l$ O$ t( q6 g#include &lt;mmsystem.h&gt;
    ; a. _; R8 ^# F+ f7 I$ U8 u/ t4 u7 F#include &lt;dplay8.h&gt;+ F- |# G( e1 |2 _( f7 x3 _
    #include &lt;dpaddr.h&gt;
    " M! x8 s4 T  I0 [5 c5 K2 ]" e  v; ^#include &lt;dxerr8.h&gt;  S9 Y1 U3 ?7 T1 m$ j1 O3 H
    #include "DXUtil.h"( V( D0 V7 f/ y
    #include "MazeServer.h"
    0 N3 E& `- i; r3 }; q: P" V#include "ackets.h"
    8 w$ S! l! c* T+ T#include "Maze.h"
    2 D2 b0 J  Z  `$ [5 q$ s#include &lt;malloc.h&gt;
    + ^3 k! \7 c$ O7 t4 e3 p#include &lt;tchar.h&gt;</P>
    ' v0 k; J3 ^8 E0 B
    $ X/ U- X4 t* s<>//-----------------------------------------------------------------------------
      b7 ^. A2 m! T7 G; ?// Name: * d0 O1 d# a' x: T
    // Desc: * U0 W/ E$ A9 Y
    //-----------------------------------------------------------------------------
    $ K% m+ E. T; k6 g/ {CMazeServer::CMazeServer()
      U! {' K2 r8 c/ @{
    . z% {9 @5 l( O' }( p! Y    m_dwPlayerCount         = 0;
    . r- G' _2 p3 @  R5 W7 z    - m' z0 O, Q) j+ K: N9 X
        m_wActiveThreadCount   = 0;
    ' O) Q0 k# g- t) W    m_wMaxThreadCount      = 0;% }4 K: m. Z  y, I  t
        m_fAvgThreadCount      = 0;
    1 j8 e" o) U1 z    m_fAvgThreadTime       = 0;9 B+ c% I) O1 A6 O/ }+ u
        m_fMaxThreadTime       = 0;</P>
    5 _! q% i" `  w( |2 \; f. H<>    m_dwServerReliableRate  = 15;
    0 s. K" J- p" l/ S$ A    m_dwServerTimeout       = 150;
    3 m0 }8 G& {5 c3 F2 ?5 i3 t6 a2 R    m_dwLogLevel            = 2;/ h' w- H) N1 Q: _
        m_pMaze                 = NULL;</P>2 |/ `3 m8 ^! T; k' ?
    <>    m_ClientNetConfig.ubReliableRate = 15;
    ; q6 F, f1 V( n    m_ClientNetConfig.wUpdateRate    = 150;
    2 p5 t- V# D8 D1 B    m_ClientNetConfig.wTimeout       = 150;</P>
    ( @5 w7 i. S3 E! `" A- }( A' O<>    m_ClientNetConfig.dwThreadWait = 0;</P>
    ( Z" u5 D# {: |. @3 B<>    m_ClientNetConfig.ubClientPackIndex = 0;; ~2 h: m2 e) U' b) Y
        m_ClientNetConfig.ubServerPackIndex = 0;( V# _: {& m' m% n
        for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)1 @! a: k% ?' K+ v% K
        {0 d( E2 ~+ S' t
            m_ClientNetConfig.wClientPackSizeArray[x] = 0;
    * F8 ^9 W4 \2 ]6 X. T1 G        m_ClientNetConfig.wServerPackSizeArray[x] = 0;  a. W$ s1 U" s' Z- ]
        }
    + a' p6 ^, u+ M' w/ m5 r}</P>8 X! X5 |& [/ C2 A* x
    ) o& q% _# O$ ?6 R' ?; i& h7 F" j
    <>3 p) q$ I+ i- |8 y- m. D( j
    //-----------------------------------------------------------------------------
    ( }" b$ J4 O1 f8 ?8 t// Name: ! \5 l' l; R9 l1 f- f
    // Desc:
    # N  [4 x" ?: @! e8 `0 {. m, @: B//-----------------------------------------------------------------------------
    3 V0 B8 K$ P9 ]( Y* P2 y9 ^HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )! C# [3 \+ [6 l7 r8 [' ]; T/ v; R
    {
    , D) [5 J( c# N3 D; x4 H    m_bLocalLoopback = bLocalLoopback;
    & i( J( S- p; |% W+ v) s4 c    m_pMaze = pMaze;
    ' H% s6 n, F" Q) S4 ]    if( m_pMaze == NULL )2 H+ X% k6 G4 q. c3 q+ X  [
            return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>. `& J: u' g9 N2 |# D/ v0 s
    <>    // Grab height and width of maze6 ]! |' P* C6 q1 ?* d
        m_dwWidth = m_pMaze-&gt;GetWidth();
    2 v- `3 b1 D& e    m_dwHeight = m_pMaze-&gt;GetHeight();</P>
    5 J3 n( d7 Y2 C' \6 J1 o" V<>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;) b' {; h$ r7 B6 B  `
        m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>( ~- g# }& Q7 a1 j& ]: x, C
    <>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.0 v) E- e, m* ~( W" z% G, ^
        if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    / V3 ]5 U4 c/ E& t7 v+ {! c        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );9 r# \0 |/ f8 U7 c! z, N
        if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )
    6 h2 K: a# x4 e9 N        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
    0 G  c  U  J8 c2 u# b* @: j2 A<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;6 o4 a3 E$ C. H/ @. H3 V1 ^$ Q
        m_dwMazeXShift = 0;
    ' y4 d; J* a  y4 |( V% C+ T% S" x  v    while ( (scale &gt;&gt;= 1) )# f: J8 ~8 V9 L7 X
            m_dwMazeXShift++;</P>+ q1 ~+ U; p! l( e, O. ^9 r4 l
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;. H2 v% x; Z  S4 }( j* e" x
        m_dwMazeYShift = 0;' R  i1 r$ Z2 B, l6 [
        while ( (scale &gt;&gt;= 1) ): U9 P5 z! [- }* A: O
            m_dwMazeYShift++;</P>
    ' x' x8 M4 V/ ~9 I0 I<>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||' w% r0 z4 m6 N$ D. I
            ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )0 p, p! d- h2 w2 x: g7 x
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>
    $ p) @+ `8 S4 O<>    // Initialise the player list
    * Z. l7 A0 k* h# R) O    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );) m' f( @  n. h; ~& i
        m_pFirstActivePlayerData = NULL;
    3 }% T4 M* P, p* J# o/ R( X    m_pFirstFreePlayerData = m_PlayerDatas;
    2 ]) X: x( H/ h* C9 w5 f    for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )
    1 m3 l, {; r3 ]' \% m+ z- K    {, o( K' P2 |. E5 |8 K$ v
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];3 d* v( b& `2 V% z3 z
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
    6 \+ j. ~+ E4 [( G6 d    }</P>( m* u0 }0 d7 \! k" P8 R6 Q. l
    <>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
    5 m9 i# j2 E: }; [9 A    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];+ y+ g$ Z  n4 h# s) U
        m_dwActivePlayerDataCount = 0;) B4 S7 F' _! Z6 _5 [) L. G
        m_dwPlayerDataUniqueValue = 0;</P>
    # D" W% J- b1 _<>    // Initialise the cells
    * X% T7 p- |4 u7 m& g  n7 s    ZeroMemory( m_Cells, sizeof(m_Cells) );4 B! r, `0 N& T8 G
        ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>6 V, Z" T+ V% g
    <>    return S_OK;
    6 q7 i& v4 A1 A) w: _}</P>
    7 G( M; z+ K! Y9 v# \% \* l5 j, K% o: E
    <>
    7 F# }/ j9 F0 j//-----------------------------------------------------------------------------
    ' g$ C2 ~& H' C1 `  d// Name: ! |9 r9 P9 Z5 f- _
    // Desc:
    4 A( `2 O! A3 g+ a( _) E5 i: `//-----------------------------------------------------------------------------3 S9 e; h) F* f" u+ B
    void CMazeServer::Shutdown()
    ' Y, |3 i6 Y: e4 P{
    - _; a3 ?; @5 r1 t8 C}</P>
    : A: R0 Q% b+ H5 e6 V# S, Q# `2 Y& K/ u3 o
    <>9 V  {, O/ g9 `$ ~4 ^1 m& I
    //-----------------------------------------------------------------------------# w% {5 B* }& Z4 k
    // Name: 2 K' ?  f. p" K$ u" R, c2 {
    // Desc: " E& r: U1 O5 v( L1 P# \. e
    //-----------------------------------------------------------------------------! J5 c- G0 V1 Q* p/ M) p
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    / J# i. j, m1 A: H8 V% w1 T{, X! O' h6 D9 r4 U8 ?5 e: y9 o
        m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,) b( O! S* B2 H
                              x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    5 k' Z7 ^( a1 `6 K1 D% w}</P>+ `7 H$ o/ C4 @1 v) c

    9 t, Z- Q  b4 p+ c) X' K1 W<>3 U0 b0 w4 m8 m$ \8 m% O
    //-----------------------------------------------------------------------------
    3 t$ s  T3 i$ Z0 a; G. Q, ^3 R// Name: / C" i& H+ t( k; m: R5 Q4 O
    // Desc: & |9 o( b8 `& p( y7 D
    //-----------------------------------------------------------------------------+ ?2 k+ `$ g' r3 z) d& m
    void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
      {. Q# [* T* H{  e2 [+ L( `1 |% x: _
        m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,* J8 y6 N8 |# A! O4 ?7 @4 Z
                                x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    8 T$ S$ ~8 C) w3 a. X0 t" f0 K* o}</P>
    ' i* g; \# Q8 Y. I6 g  F( w
    " A7 i0 N! m6 ]! _2 Y3 X<>
    4 Z, {: }. K1 ~: C//-----------------------------------------------------------------------------# j: j1 T* h6 }6 {
    // Name: & y2 }( e) }6 O7 J( |/ v7 Q  u, D% w
    // Desc: ( U( S+ Q; k) Z1 G; P: d  H" B
    //-----------------------------------------------------------------------------2 T/ @0 L/ ?8 m! n& ?5 X
    void CMazeServer:ockCell( DWORD x, DWORD y )6 u( T" K9 B6 \6 l/ Z2 |) Q
    {  C& G& i1 D1 R& Q
        if( x == 0xffff )
    9 M5 O3 H# u: i% e        m_OffMapLock.Enter();
    6 _* w8 F$ Q2 t    else6 P3 L* I; ^, m# z3 `0 V6 H% G( u6 ?
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);9 m  z  v' Q: ^9 n/ w
    }</P>1 h) k; _/ d# X

    7 L1 [+ `& A2 p' A/ i0 a, c) j<>& E7 ~! G- S# o% _/ g+ ?7 o
    //-----------------------------------------------------------------------------* |3 ]+ {. V5 Q3 |  C  L
    // Name: + O- c2 D8 g; S' Q+ W. u5 ~5 P) D
    // Desc:
      R( M/ [( @/ E$ H- D. `//-----------------------------------------------------------------------------, B6 X2 Q& N+ D# A3 f. O7 b% G
    void CMazeServer::UnlockCell( DWORD x, DWORD y )3 X: p& M# k6 E2 v
    {
    9 G# y2 ~3 _  o) ~( n( {    if( x == 0xffff )
      e4 N; H- b% l7 U( `0 ^. m4 C        m_OffMapLock.Leave();1 v' N: u) o4 U: t) f
        else. h/ M8 l7 {7 e6 q: s$ ^
            m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);- h8 M& A6 W4 A5 y, S* }. R
    }</P>
    # m/ F2 m( |# E# o( e5 z- }3 D$ l% @4 B* t' t
    <>
    " `: `# M/ T. K  z//-----------------------------------------------------------------------------
    3 c9 m1 O2 P0 u1 `// Name:
    6 e" B& d. A. f// Desc: ; q9 F% D4 y/ f+ r! S
    //-----------------------------------------------------------------------------
    - A6 B" h+ E( Y8 Dvoid CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )$ c6 O3 `4 m( y3 u$ f
    {
    . }' d% F4 Q; a7 W' n( v    if( x1 == x2 &amp;&amp; y1 == y2 ), y3 P0 O! T# [/ C- g6 Q( i. l8 y
        {5 A; n9 z  p0 A8 q) g2 }" i8 t- h
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )/ U' D  a$ I3 s+ Z; u  q' s
                LockCell( x1, y1 );
    1 n% j- t$ ~! {& |' r6 @) x: A        else
    $ H, Y. V" t0 Z4 M* U$ j& V# `2 i- g            m_OffMapLock.Enter();</P>9 q+ x' ]  i$ I% V; ~2 s
    <>        return;
    % c0 w* d" r- l- ]) a  m/ H0 g    }</P>
    4 @5 Y; @- M% G( F. C% F<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;; w. j: r$ c; Y0 s/ U# s" K% {
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;# X3 B. \* Q4 R7 U+ M1 H9 v
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;& }5 h+ Z8 @& J' c# }
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    ! `+ W3 z/ k) C0 M' Q<>    if( x1 == 0xffff ): ~+ X. G. O. L! k. l) Y8 ?
        {6 R- X! M8 [+ E+ n7 N% Z7 N
            m_OffMapLock.Enter();
    # I# u+ G; R3 c" d+ ~( [        m_LockGrid.LockCell(x2shift,y2shift);
    3 d5 {& u: X8 J, X/ i    }
    / o/ b4 V( n. F' v( u3 |    else if( x2 == 0xffff )
    . N6 k4 K& B7 f4 n1 C2 D    {* p5 A( x( X1 y1 s0 A3 Q
            m_OffMapLock.Enter();" I3 J% x. Q3 M% U1 u8 R
            m_LockGrid.LockCell(x1shift,y1shift);
    % u2 ]6 L+ ]2 y. }0 g2 s1 }% s2 z' Z    }! H: _8 @  H5 Y& o
        else
    ' G7 W' [9 Z1 v7 y    {
    0 \; t5 P7 Y' A3 P5 [7 S6 i5 K, u# W        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);' a1 G; d& B$ b& t0 [" [6 m6 |9 [
        }( O% q7 W7 t7 D9 H( C5 c! u; W5 E
    }</P>
    7 u0 s$ [% e) E( _5 @6 s. O3 y9 P; S4 y2 J! b; z
    <>
    ' c5 ^2 a% V% w* x1 C" T//-----------------------------------------------------------------------------
    1 v# T! Z) r$ \7 v// Name: & q; K8 L  V: I1 Q4 ]5 k% t9 e
    // Desc: 9 ^! G! W" t3 \
    //-----------------------------------------------------------------------------
    8 E/ b2 g7 G& Z. Q: o/ }void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )" g* H8 ~4 I: m* s- Z
    {. r% D/ ]% n: V( _% O$ M
        if( x1 == x2 &amp;&amp; y1 == y2 )9 E- {3 t+ o5 x( r$ ^! [
        {
    ' b8 K* J: ]8 @# ~: n9 S        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    . O% N: U4 x+ e. i/ O3 t  P* g            UnlockCell( x1, y1 );' ^) r" A& p7 R% {3 S' a' a9 d  X* o
            else
    ! H6 C' p1 w6 K0 ~* ?; {            m_OffMapLock.Leave();</P>5 {8 v; L" @0 m9 [& ^4 A: s
    <>        return;
    - g) \, z. J# g9 d    }</P>
    ! O' j0 w1 |" y2 k/ w( x- u- L6 K<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;" f( Q1 b: f, b: E8 b1 X
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;( J5 K3 k& X( ~1 h3 h8 G. Y& W) l
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;' c- w% i+ _8 i. {) ^) x  Z
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>; g% C! a( U& e
    <P>    if( x1 == 0xffff )5 F' e" q0 u- ~4 U5 w9 t" b1 `
        {4 B/ p3 x9 t! w: d0 ?  h
            m_LockGrid.UnlockCell(x2shift,y2shift);( D. F9 H; Y2 t; p6 r" m" Z- W+ p
            m_OffMapLock.Leave();2 E6 M+ E1 ^0 }
        }
    , [7 Z* x( t" a1 R% ^* L* K    else if( x2 == 0xffff )
    + \! A$ E+ P) u/ b  h3 g$ q9 |$ L1 T    {+ u2 u8 H2 L2 }7 R5 I
            m_LockGrid.UnlockCell(x1shift,y1shift);9 C+ I1 ]" p$ n4 z1 S
            m_OffMapLock.Leave();6 Y; c6 W4 M5 |7 X
        }" m2 ?' ]' ]+ {5 a& ]8 z
        else * u: C  }( ?: O6 d# X
        {
    " \" j$ C  _- [        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
    9 n9 H* R0 ^, Q/ Q    }
    : B% ^+ F, U! ^2 t}</P>
    9 J8 e  p9 R3 j9 u) L
    : @8 P, ~0 }1 a1 N<P>) {% ]# G  g% c8 P  Q: ?  w& V5 `
    //-----------------------------------------------------------------------------& _8 B8 z( A. t, \
    // Name:
    ! @, d3 k9 @! j  z// Desc: * _, ?/ X6 M* ]$ ~
    //-----------------------------------------------------------------------------
    1 R) ?2 q$ M1 Z8 |& P4 mvoid CMazeServer::OnAddConnection( DWORD id )
    2 S/ Q) a" f& m6 O{
    % Y! {7 G; b/ T4 }    m_AddRemoveLock.Enter();</P>* L/ [% s/ R2 S7 Z6 ]/ n
    <P>    // Increment our count of players
    / u2 u6 r, q. m9 }    m_dwPlayerCount++;, R" ?( O. ]5 N, p7 c; J$ }0 Z
        if( m_dwLogLevel &gt; 0 )
    ) E  O. j. x6 B( G! n    {  P) n3 U6 l8 R
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
    - a0 n. q- J! M. O        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
      Q4 Z8 d$ |) ]2 T) G$ M3 u& u0 I    }</P>
    * x# h# z/ b2 B9 M- W2 e: T, z$ W<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    / H) `- ~- s$ Q1 c        m_dwPeakPlayerCount = m_dwPlayerCount;</P># g4 s! m7 F* ^3 O7 C3 N
    <P>    // Create a player for this client6 \* M8 }$ v7 y  t
        PlayerData* pPlayerData = CreatePlayerData();
    & y9 ?# U: N: \$ H- L) y    if( pPlayerData == NULL )
    2 P0 O. _: @- d0 C1 W* _    {% {+ t9 `7 B! ]1 i2 v8 y
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );! \7 `+ u, ]* G' Q4 q/ n
            DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );
    5 |6 Q+ `  `1 W        m_AddRemoveLock.Leave();# T; f: k( r( k, f1 Y& z: l" F, r
            return;, R( \3 X. J8 M) _& n* f
        }</P>3 |( O6 M; g7 `, i' K0 I
    <P>    // Store that pointer as local player data9 z& J5 c) s$ q
        SetPlayerDataForID( id, pPlayerData );</P>2 u# J* A5 A# [; x; c
    <P>    // Grab net config into to send to client- B. L, n1 |4 `3 \3 ^( q' p
        m_ClientNetConfigLock.Enter();  H% @' X/ G- Z& j2 R
        ServerConfigPacket packet( m_ClientNetConfig );8 N1 E, w/ |2 r# f" [0 V5 }- u
        m_ClientNetConfigLock.Leave();</P>; }8 r# H( K: }& ]! p
    <P>    // Send it
    / P3 R" ^; y: r) L$ b0 k, c" L    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>! f4 D$ X3 z: N5 p. C  Z& m  u! I
    <P>    m_AddRemoveLock.Leave();
    ' y5 X+ z0 I: g4 f$ [}</P>, \' s! \* @. R5 k
    # j; d5 |# Z# u; F# J! O- @
    <P>  q, w4 F/ m& n
    //-----------------------------------------------------------------------------' c7 k$ K, Y. _: M
    // Name:
    % f' w9 L* ?% L% I$ \- e+ @// Desc:
    ( K; h9 t# T/ x. q//-----------------------------------------------------------------------------/ d0 Q4 V& K. v; F' v3 x" K
    void CMazeServer::OnRemoveConnection( DWORD id ), ^$ W, u/ |$ s2 r  D. Y
    {
    $ [/ V& ~. a( e$ O    m_AddRemoveLock.Enter();</P>4 a4 h4 Y; o# ]. L8 r/ A, o
    <P>    // Decrement count of players4 |+ P1 Y1 ]9 u' O& |; e6 Y9 E
        m_dwPlayerCount--;</P>
    2 ~' h; m: q5 P3 I% Z9 X# X1 L9 B<P>    if( m_dwLogLevel &gt; 0 )
    * _$ s( `3 J, ?5 w! J  C: |. K- v    {
    ! S) d" ~" y8 |: Z7 V  B        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
    % l$ S- C' z8 ~  U- h/ E/ X0 X! z        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    . a# @$ g8 @& M; G2 b% b. o    }</P># P8 O' `: }( h) {2 g' y) o
    <P>    // Find playerdata for this client
    3 `% T' H& U% D; E% E# }+ M    PlayerData* pPlayerData = GetPlayerDataForID( id );
    5 y) }' V0 l9 ?; i7 J4 b% t    if( pPlayerData != NULL ): m, O, g2 L4 g. F3 l) Y  J0 i8 F- R
        {
    ' K" r* n: C5 L0 M! f        // Destroy it
    9 L  t# S4 _" P( \% N        RemovePlayerDataID( pPlayerData );
    , F$ P3 C; l3 @' A        DestroyPlayerData( pPlayerData );9 j( {9 J9 }, x: F' o
        }</P>
    ( \* q; B( Q5 p  A<P>    m_AddRemoveLock.Leave();7 ^1 a( t# m8 v1 |  r7 v
    }</P>
    ) f& X+ e# V* W0 B
    3 `2 p5 B6 q2 p: P1 s/ _( d<P>
    ! K( D; H4 D3 {# \0 J  Z//-----------------------------------------------------------------------------+ \/ v6 r9 |& l8 P6 M2 D
    // Name: , R+ R8 z7 }8 Z* n
    // Desc:
    6 T1 K+ ~' K3 a4 d) \* f, ~//-----------------------------------------------------------------------------
    . Q) h# c+ D7 z" ?( H, gHRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )1 V# C% |# D7 T  t8 o
    {
    ' D7 W1 d% e& U# c, j    BOOL fFoundSize = FALSE;</P>
    & b+ G: C3 c; K  _, h8 G% j' q<P>    // Increment the number of thread we have in this process.
    : [. g/ x2 y4 O% ~5 Z    m_csThreadCountLock.Enter();</P>* f% F# C1 V2 ~" R/ R5 X
    <P>    //Get the start time of when we entered the message handler.! X! Z5 h. f' f
        FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
    & N8 r6 ~, Z0 L: @: ^/ x( r<P>    m_wActiveThreadCount++;
    . t3 a- q# E# N8 N* y% K0 s    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)
    ! K1 \+ o) t+ \        m_wMaxThreadCount = m_wActiveThreadCount;( o+ v5 L( E- v5 t7 w" @
        # d4 ], {6 D" c
        // Calculate and average.* |& l- b# K2 _7 U% o, d, q
        FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;" G& w1 f/ A! r9 w1 B$ ]
        m_fAvgThreadCount += fdiff/32;/ H$ t. O6 m, Z/ ~
       
    6 ]/ D; w1 R1 H2 q    m_csThreadCountLock.Leave();</P>9 `/ x9 D5 a* {
    <P>, f: C$ }% K' z/ X, s8 v2 e
        ClientPacket* pClientPack = (ClientPacket*)pData;
    : o& K" t% U, ^( z# H$ C  d9 I    switch( pClientPack-&gt;wType )
    0 m* B4 D" x# h4 i" c    {; d7 [0 ^: ~" q! ?7 Z9 p
            case PACKETTYPE_CLIENT_POS:) j) i6 K8 |8 X+ o( B' e0 j
                  f3 t* ^0 L, e2 e
                // Check to see if the packet has a valid size. Including
    : G& H% o% |' ~( i9 b            // the custom pack size./ ]( D8 X4 K2 E! Z+ B- J4 Z
                if( size &lt; sizeof(ClientPosPacket))  k  n' f' m+ e2 D( L3 P. X' n
                    fFoundSize = FALSE;
    ! U$ a( c& X/ W            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))
    ; @. I/ _! m1 _$ B6 c) S  `                fFoundSize = FALSE;' e* F) G- f- n' w8 y9 W
                else
    # S. S+ {* i; R; E% P- s  l                fFoundSize = TRUE;</P>  b$ a& s7 m7 R; Q
    <P>            // If valid sized packet, handle the position., B; N2 Z7 ?, S7 p# W8 Q
                if(fFoundSize)) B+ h  c/ z" \. t$ ^
                    HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );/ w2 _$ }# d8 x
                else6 h0 H* x& ~, t& H6 X- x- R3 B
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>. H  G, X& E6 J4 q
    <P>            break;</P>9 f( E1 I! z0 g: P& @. z+ k8 b
    <P>        case PACKETTYPE_CLIENT_VERSION:% i# _% D3 y' o% B8 Q
                if( size == sizeof(ClientVersionPacket) )- e% U7 X$ v3 u
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );
    * a- M! N) s+ D" m3 \  O  U/ T; {            else
    - v% B, k- q( k" X' Q. d" \                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    , U& K& h; A) K, i1 \* w            break;</P>' F  J# h  Q0 I; f4 k- i
    <P>        case PACKETTYPE_SERVER_CONFIG:</P>
    4 p5 m; p) G: r4 ]# q4 L<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>; l& B/ x6 x  o6 X) q3 g* b1 Z/ P
    <P>            break;
    2 f6 S" F6 q  {! `8 v        default:
    , `. x$ O; X3 Y8 T; G4 Q, c            HandleUnknownPacket( dwFrom, pClientPack, size );
    9 ?5 `2 W  G/ z$ `/ ?. t            break;6 r3 I) C: @) w5 ^" e2 ?
        }</P>
    8 m+ k- z; e) r  q<P>    //If the user wants to hold the thread, Sleep for given amount of time.
    ! o8 B  j1 _; y7 ^% d% y- p6 K& a% z    if ( m_dwServerThreadWait &gt; 0 )0 o3 A  f: [1 ]
        {
    - v8 Z2 M9 J5 N1 A$ J) C        Sleep( m_dwServerThreadWait );
    9 S" I" r* s' H2 `. [    }
    2 s) ^. r& J2 V, `, M! N    9 y& o, G, b, `8 D" A
        // Retrieve thread data for this process.
    , `, `9 `/ `) p% ~; r6 x+ @  x: M  q    m_csThreadCountLock.Enter();</P>1 X4 T6 ^0 S/ v  c$ ^) G+ M9 ?  c
    <P>    m_wActiveThreadCount--;</P>, R! a# D9 G. {
    <P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
    0 R2 a+ _  f: k$ L) \+ ?5 S    m_fAvgThreadTime += fDiffTime/32;</P>
    & ]* ]3 e, Y; }( V<P>    //Get the Max time in the thread.
    " Z0 e: ~5 g& f* }    if ( fDiffTime &gt; m_fMaxThreadTime )0 o! X- J" u( e
        {
    - ~! Q. K0 {, {        m_fMaxThreadTime = fDiffTime;
    2 h6 \2 m) ?; W3 {2 n* ~% n0 n    }</P>
    & G; t3 R8 a0 s, D4 C: W<P>    m_csThreadCountLock.Leave();</P>9 @% {- G* S) m
    <P>    return S_OK;
    ) T1 D' x/ v% Z  @- ]4 P$ ?! N/ |}</P>  v" l7 V( @$ v& |* x  `* a
    & c* M$ Y4 M) ^! B! Z/ j
    <P>//-----------------------------------------------------------------------------9 ~1 @3 L! n0 Q0 O+ w
    // Name:   r) P6 c1 W  W5 x
    // Desc:
    / B1 |- Q9 b+ }& d+ ~//-----------------------------------------------------------------------------8 t8 D  i& w' S* E* }
    BOOL CMazeServer::IsValidPackSize( DWORD dwSize )
    2 R/ u1 m% q, c& ~' t3 [( S7 m{
    4 m% x' [. @. b& Z- a    BOOL fFoundSize = FALSE;: N' i" q- L3 {
        BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;
    ; I- D% d! P9 \: A    ) d, X1 H4 [+ {6 A
        // Check through the array of valid pack sizes./ u6 @# S: B( ^# M
        if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])! p# b0 x) x. Y+ P; _# o
        {
    % f4 l5 f/ h0 C8 R' @- x7 _        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)
    - c0 ~5 U  Y; B, B3 F6 a% F2 T# A        {8 B( C* e& N& Y3 p6 g4 b6 Q
                if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    . G2 U* w6 V: Q6 V/ a2 t, p            {
    . f  l! w6 m. I! P/ \                // Found valid size in the array.
    5 C2 x# l) N$ g6 i. B/ T                fFoundSize = TRUE;
    ' ?1 d+ i8 i/ T3 e                break;9 W/ F. r3 \* o1 @( R2 N8 w& p& X
                }
    + G) f* _2 J& Y            if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.1 P5 V- ~" N# p2 M+ O
            }- c! [( ^# Z6 w
        }
    8 C; T% a6 S/ ?  S% C% c: |8 O    else
    , r4 J. T8 O( ?2 a9 c- N' s3 H    {8 m2 R$ y; p( o- j3 h% o
            fFoundSize = TRUE;: J8 I) p% d! `  t8 B" s
        }</P>( p0 K3 x+ H  k$ g+ d* T
    <P>    return fFoundSize;. s0 B+ m" p5 U" N
    }</P>
    ; ?7 I2 M( n) a. Z. n<P>9 D6 t0 c# u6 @
    //-----------------------------------------------------------------------------
    1 o+ q9 ?, ]: a/ v1 v) f  S' W// Name: 1 j6 z% U4 q" P  P' f
    // Desc:
    / N3 d+ j& d/ u: C* ]5 P& z6 g//-----------------------------------------------------------------------------9 ]+ }* a/ v- ~  A5 ^! x: d! F9 s. B7 g
    void CMazeServer::OnSessionLost( DWORD dwReason )
    . y1 _) x7 P; \3 _! f/ [* e{
    % l4 x2 \3 d4 a/ ~8 w    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );6 p8 u3 h) J6 h
    }</P>. o7 n8 o! G% P% g

      l. k3 f- N1 K2 S! b8 X9 Q8 ~<P>) y* S( Y$ b3 r4 X% J$ n8 E# G
    //-----------------------------------------------------------------------------5 I5 A- r  u) n# f/ G7 P" J
    // Name:
    3 U( V1 O2 B2 N/ d2 N/ G// Desc:
    & H+ O/ ]- A: C' C* d//-----------------------------------------------------------------------------
    7 m. ^4 W  I$ w5 `. CPlayerData* CMazeServer::CreatePlayerData()
    % |* [5 t0 s, J2 [8 b{7 q5 O" [  ~  R2 E4 V1 R* e3 o% Z
        m_PlayerDataListLock.Enter();</P>" C6 S! s! x$ x
    <P>    // Grab first free player in the list
    # k0 ~* Z  m8 F    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>4 U! L' f8 d6 h/ {+ a
    <P>    if( pPlayerData )
    " R. j# R* _9 t7 n8 g7 _9 ]. N5 w; e    {
    ; i# e0 S( c& n+ N' n        LockPlayerData( pPlayerData );</P>
    , g3 u! J" Q. i# q& M# u<P>        // Got one, so remove it from the free list
    " g1 Q/ h  P5 Y        if( pPlayerData-&gt;pPrevious )7 ?' i- }( v8 s# n
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;! x2 n) i. _* O5 S! S
            if( pPlayerData-&gt;pNext )
    2 t# V; D% g; w6 i+ `$ Z5 @5 v5 B' o            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;% H& j5 ]) L3 D$ \" B3 f
            m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>. k; v; f% L, r: u7 N7 C. A
    <P>        // Add it to the active list7 U; \0 A: ~! x, |% W
            if( m_pFirstActivePlayerData )$ B" {& `2 W5 X' u2 u/ L
                m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;' i2 c9 F( B% k" w; S( j9 b
            pPlayerData-&gt;pNext = m_pFirstActivePlayerData;
    ( @3 X  P& [; ]2 V/ o        pPlayerData-&gt;pPrevious = NULL;* Z  ~: k4 C; Y/ e" N
            m_pFirstActivePlayerData = pPlayerData;</P>
    . r6 h) s2 r; [, _- B  d9 [" z3 c<P>        // Update count of players' p. h' [9 D( w) n- Q
            m_dwActivePlayerDataCount++;</P>( v! s. d6 `9 O4 v3 u
    <P>        // Generate the ID for this player
    . @( O# M* x+ A! t2 O3 [        m_dwPlayerDataUniqueValue++;
    + X1 w) Y3 i7 x        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
    1 p+ T7 i+ y1 `0 S3 ?4 H<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
      a) c; g% H& e. \! X  D' @        pPlayerData-&gt;NetID = 0;0 {7 V. W& C4 Q# `- B
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>! T, F  h! I4 \7 Y+ O( B0 M5 Y! E5 e3 Y
    <P>        // Insert into the "off-map" cell. N; }  p+ J/ J0 G3 R4 d
            pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;- x9 V# N7 q/ J3 S# F
            pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;
    - O0 q" i# y) Y- Z4 w) _        m_OffMapLock.Enter();7 w4 L, n/ S; b) }
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;
    - |5 F0 a7 f# o, }        m_OffMapCell.pFirstPlayerData = pPlayerData;- k; J  T8 l# Y9 O9 r
            m_OffMapLock.Leave();</P>. w$ W* T% a- d" B" K
    <P>        // Mark as active- s; e% `* v: t. U, ?% t
            pPlayerData-&gt;bActive = TRUE;</P>
    $ b. ?" ]. N2 i4 O0 S0 d<P>        UnlockPlayerData( pPlayerData );1 a8 P. t! L0 J$ p; r( K. D, C
        }</P>
    ) b+ q" j1 Q5 S# z% o4 D9 T* p<P>    m_PlayerDataListLock.Leave();</P>
    : \3 G6 c+ Q; c" P$ h- ^! R! |<P>    return pPlayerData;( i* h  a  g% P4 ?3 i. A  y8 I/ K
    }</P>
    ' R) n' a( C5 r# [4 {
    ' t7 |; u, S! }3 t$ Z- Y/ {9 W- I( g<P>
    . \5 w: b1 l/ W( ^//-----------------------------------------------------------------------------. p3 _  B, k! ^
    // Name:
    8 y% u: C" m* ~: N, k// Desc:
    / `4 s; Z+ a8 C+ a) L7 g* m//-----------------------------------------------------------------------------
    2 G8 k# r% k+ M: T1 s$ V+ jvoid CMazeServer:estroyPlayerData( PlayerData* pPlayerData )
    1 s  V2 {- @- F! V5 |, Y8 D; ]{- O" f2 Y6 C2 |8 I& y4 u
        m_PlayerDataListLock.Enter();
    8 B7 h+ [$ h7 i+ ?5 }& ]5 v    LockPlayerData( pPlayerData );</P>
    0 ?& T6 G! e; ^4 h8 L<P>    // Remove the player from its cell$ F% K+ Z  s! {6 N9 e7 r
        RemovePlayerDataFromCell( pPlayerData );</P>
    - O: `9 |& K# t  Q9 `2 }<P>    // Mark as inactive1 t4 h; P+ M  r4 I
        pPlayerData-&gt;bActive = FALSE;</P>
    ( U' K' d) S: I<P>    // Remove player from active list& o) `0 M8 t* y( C
        if( pPlayerData-&gt;pPrevious )( @# z  ^# e  M5 i( c
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    , r1 N1 z# i# ]  f    if( pPlayerData-&gt;pNext )2 \1 _* K4 z- ~% S( q
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>
    + V/ O9 m; D9 i. N9 l. G<P>    if( m_pFirstActivePlayerData == pPlayerData )
    / I! M0 l, f! O6 w! A" r        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>5 O1 _3 Y) X/ B( \/ ^- `% o
    <P>    // Add it to the free list
    " u: q6 ?2 k& e' [0 m/ ?    if( m_pFirstFreePlayerData )5 V8 ]5 F$ |) `1 L
            m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
    * v; u+ g! p$ `* {0 b( m$ p) [" B    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;
    2 m, f% E. _3 r, Q0 W    pPlayerData-&gt;pPrevious = NULL;
    , L' b1 S, _- R% P7 Z    m_pFirstFreePlayerData = pPlayerData;</P>
    - V5 U/ u/ g* t<P>    // Update count of players; ?# k8 ]8 {. T" U8 ?
        m_dwActivePlayerDataCount--;</P># C; D5 x, r2 v2 B
    <P>    UnlockPlayerData( pPlayerData );& y+ \+ n* d9 h
        m_PlayerDataListLock.Leave();  T/ E. k; b* E  z' {. J4 ]5 g
    }</P>2 g4 q* k$ g. u7 j4 t

    % c  L: Y# j: A* P<P>
    8 a* g1 q1 x3 t7 X//-----------------------------------------------------------------------------
      _0 n5 X& |& l/ Q0 l. _  C9 r$ d// Name: 3 L$ @& X& U6 O" [" w# L  P/ i
    // Desc:
    6 H- o9 _2 s2 U! w! D//-----------------------------------------------------------------------------
    , h  [) p3 a9 P% Hvoid CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )
    5 H' O& t' V6 q" D6 p{
    2 T' W) J% D. E' r7 a. K) |    // Lock the player
    / L6 f7 i/ {# V6 h6 y" F    LockPlayerData( pPlayerData );</P>
    7 v) B4 d4 [) {( }$ U0 r6 }<P>    // Lock the cell the player is in: {% e; l" K" b& s0 n$ i
        ServerCell* pCell;
    1 @* A! `; L' D5 D% o$ e* \3 K    if( pPlayerData-&gt;wCellX == 0xffff )
    1 P( F7 X  A% P4 r. f9 S    {3 E( k' p) o0 t, m( x6 O% s4 [
            m_OffMapLock.Enter();
    ' S; Q* |9 m2 }1 a( c        pCell = &amp;m_OffMapCell;% s$ o. j" _2 q1 j" ^6 X
        }. ]" z& g, @) ~" m2 x" f
        else
    0 c$ c0 }) p2 p) ?, Z( g! c    {3 X0 Q" N! @! F4 e  l/ ]" q
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );
    , m, [1 a$ B$ D* m        pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];' v  {2 w' x% K- O% q4 B  _4 F$ ^
        }</P>
    , C# N9 q5 F1 `0 I& h: x<P>    // Remove it from the cell4 U4 W' g# i/ \4 G% `. D- `. H$ n
        PlayerData* pPt = pCell-&gt;pFirstPlayerData;8 q8 \6 `* c3 j8 N6 x, M+ `
        PlayerData* pPrev = NULL;
    : L1 j/ F$ |" ^4 m( V& `; d* a& i    while ( pPt )
    ) W7 P0 l3 }5 n* ]/ G+ a    {- _: w7 r9 S1 t; \; A
            if( pPt == pPlayerData )
    % F6 q5 [9 A% R! M  i        {
    2 S0 U5 t/ [* K! C! w+ N# c* z! c6 g            if( pPrev )! a' `- X+ J& P$ p) K; E1 z
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    * u( z6 U9 \, J/ j. `' w            else
    $ a3 m3 c) y: h: s) r                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>/ b" `1 x! E: a9 b& K
    <P>            pPlayerData-&gt;pNextInCell = NULL;
    2 n& ~0 J6 S. q# ]% U: e            break;
    $ Y' l$ V) m3 t4 f7 ^$ V2 X        }  t+ C( @9 {) W' O/ Q
            pPrev = pPt;* C$ V1 k  ^+ d0 \  e$ l
            pPt = pPt-&gt;pNextInCell;6 M* \4 [5 i, Y/ {6 T! |* R
        }</P>
      X1 q: P, t# \8 U" `8 o8 V<P>    // Unlock the cell
    ) k) {2 h! C9 V* Y4 }    if( pPlayerData-&gt;wCellX == 0xffff )
    ( `( r7 ~  a: R8 V6 ^) F: R# _        m_OffMapLock.Leave();/ ?- v. U! M- m
        else& y' ]$ m( v7 B, o
            UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>! V# S. {  b5 ]# Q/ N8 k: j; N
    <P>    // Unlock the player
    % E1 `4 C* g. ^! l* z+ ?; ]& \  k    UnlockPlayerData( pPlayerData );
    - h6 @1 v3 n3 e5 ^}</P>; b# Y6 i1 A" s/ s) O

    3 k5 A& k8 [$ ?! j& `6 s<P>
    $ l/ j9 `) d+ ^9 r//-----------------------------------------------------------------------------
    * y; f! A/ a& S: p. x' d// Name:
    ! ~, m1 L  ?" g$ q2 {: V9 |// Desc:
    3 a$ q( _$ t1 z2 Z. q. X6 y//-----------------------------------------------------------------------------1 @& v; [0 S% r5 W) {
    void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )  M1 Y0 [, G: U
    {
    . Y2 ^& Y8 {8 @' ]    ServerCell* pCell = GetCell( pPlayerData );
    ! k) n1 M  c6 l6 ?    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
    1 M  `8 }- G* E9 E2 j    PlayerData* pPrev = NULL;+ {: H, a0 R* z4 D( ?
        while ( pPt )
    - m9 w$ J5 k! O# v: z    {. X# U5 q1 z4 V% S' x* S# t
            if( pPt == pPlayerData )' @5 l* b6 m) n1 {. J+ _& m: h' P
            {
    ' H& _" K2 ?$ X* w7 u; r6 D7 T# y            if( pPrev )2 B  t! t) V! z' ~" k' L7 k
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;% g% A# s" f- E; E: l. s1 n% c
                else3 e- N( S( f  j: t# H  @# a9 k
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;3 N8 }6 p$ F, o) t
                pPlayerData-&gt;pNextInCell = NULL;0 w" N' K" }  c; [
                break;+ H0 `6 w$ o8 K" G3 S+ x4 y4 k( T: r
            }( f6 ?: U) b4 G) x9 |$ q
            pPrev = pPt;7 Z1 H" G" r! x/ g+ T, q+ p$ k
            pPt = pPt-&gt;pNextInCell;) |* T( o3 ?9 W' e$ |) H3 m# W) M$ I
        }
    / R& B6 g0 J, I9 y- }}</P>
    9 c! z& b& x( @9 ~1 x. A3 P1 j2 C: s: |* o: `$ F
    <P>
    % g6 l0 Z; T1 Z//-----------------------------------------------------------------------------
    + U9 A1 p& ?  R! v/ r9 r// Name:
    2 V. j9 i; h! r, ]) x// Desc: $ K3 C% p& `) L% D* Q9 l& g8 ~/ ~
    //-----------------------------------------------------------------------------9 E. C% |* p: E
    void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )" l4 C, C/ c& X0 X0 D
    {7 o$ G6 d) f7 s' G
        ServerCell* pCell   = GetCell( pPlayerData );+ e* w+ a* x' |
        pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;
    , B0 d8 w! ^) z2 Y    pCell-&gt;pFirstPlayerData = pPlayerData;
    9 k+ x9 {6 e% t. ~) O0 z}</P>
    ) v2 e5 j; b: H: `, v7 C3 x4 d! O4 k8 w" L* _9 D# A
    <P>
    8 ?+ v, u- w8 j* b6 s//-----------------------------------------------------------------------------
    " j' m' ?$ M; f6 V4 G7 |' R, g// Name:
    2 `# t/ z' c0 G# `% y// Desc: 5 W+ A! f% x0 X9 G. y
    //-----------------------------------------------------------------------------, o: K! K/ }/ o0 E5 s
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack ), m; o# c  C( N. }8 y! Z
    {3 Y( @7 [4 o" Y
        // Grab player for this client and lock it: b: H8 G; l" _* L6 `1 z' D" Y
        PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );, |% M3 X7 p" a" }) r( W1 L
        if( pFromPlayer == NULL )* K! O0 E* Y% J5 C  j0 b4 Y: Y! _
        {
    % C4 b9 b" ~( @! }$ u( W) x        if( m_dwLogLevel &gt; 1 )
    , [4 A1 Z& m+ M% o            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );
    2 q, O( J; x9 C        return;, u9 }. @, S6 t; f) ]  q
        }</P>1 Q+ F) ^  `0 A; ]
    <P>    LockPlayerData( pFromPlayer );</P>- x" K* R( k6 F8 w1 t+ J
    <P>    if( FALSE == pFromPlayer-&gt;bAllow )+ F! r, G" _5 Y% x/ R
        {) q0 f3 K+ ?; _$ j4 ~& a
            if( m_dwLogLevel &gt; 0 )) v+ t: g( c" J2 X0 t5 H8 }6 }
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
    ; j: }& C7 g$ m9 e2 u% M7 T<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    9 e8 O  H' K; i  X4 G5 P        UnlockPlayerData( pFromPlayer );
    ( z  Q! e' R+ x0 A        return;4 j+ c0 F' g' U/ ?8 R
        }</P>
    $ J( y; B( t; ~2 c* `4 X: f9 I" b& N<P>    // Compute the cell the player should be in now
    $ _& S% H1 p) K1 }# V1 g# h8 q    DWORD newcellx = int(pClientPosPack-&gt;fX);% W! L% ~, T3 |; H1 z
        DWORD newcelly = int(pClientPosPack-&gt;fY);
      z4 G- e+ L2 j5 B: C) z# z& E    DWORD oldcellx = pFromPlayer-&gt;wCellX;  c2 V+ I" j* G2 n* ~, a0 S( h
        DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>
    $ Z7 N9 L7 d2 ^4 \7 Y<P>    // Have we moved cell?
    6 H# J  a3 ^+ j5 P" n    if( newcellx != oldcellx || newcelly != oldcelly ): Z$ ]* N/ |# L) N" y( {9 L
        {
    & }; V& ^& y; [8 j1 s" i* d        // Yes, so lock the pair of cells in question6 T6 R/ L& m0 C7 p7 r7 o+ `$ l
            LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
    ; R( `- g( y' j* j7 ~<P>        // Remove from old cell and add to new cell
      _2 @/ x; B2 Y+ b! ]/ R: |- z        UnsafeRemovePlayerDataFromCell( pFromPlayer );  Q  |1 U8 g, c7 x
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);5 E' q* K  |4 c4 e  p, E
            UnsafeAddPlayerDataToCell( pFromPlayer );</P>, z- P& h* c4 ~
    <P>        // Unlock cells/ Y9 Q- Q$ a, s
            UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );
    7 j. r  P' {+ V* S    }</P>- F9 ?  ?$ ~# H+ \2 T- V
    <P>    // Update player position
    $ q- b! r. h8 h/ g0 c; ^) j* Q    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;4 @: d5 k' R( ~5 g# X
        pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    , b2 `& q; m4 n0 Z( ]1 Z! Q    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
    6 b, G/ U, N. ~" }' `5 W$ _<P>    // Allocate space to build the reply packet, and fill in header
    $ z8 M4 R3 [" x. A    DWORD dwAllocSize;
    # I$ Y, R) u& m- M    ServerAckPacket* pSvrAckPack = NULL;</P>/ [6 O7 p* X$ H. z* L
    <P>    // Begin by allocating a buffer sized according to
    - e0 f8 U* D* y9 h) K; T( U    // the current number of nearby players + 4.  This will give
    6 w( q' O; G  c" k+ L8 {    // a little room for more players to come 'near' without resize
    ! @* s* q5 x, N9 j$ w/ D/ E! t/ `    // the buffer.
    9 P: X1 [& T2 S5 a  A4 Z    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>% ~& h9 k9 }6 s! n% g
    <P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    & w2 U1 _1 ]0 T) a! Y' z    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );0 R6 V+ M1 T$ `* M1 K& M( d
        if( NULL == pSvrAckPack )
    2 d- d' V/ a% S" x, ]    {) `& a, [+ r: m, @: L$ }0 Z& l; b1 ?
            // Out of mem.  Cleanup and return
    " v+ F" }1 n% P  n) }% S2 e        UnlockPlayerData( pFromPlayer );2 q2 k- `, {0 F3 E! O+ A. \3 @
            return;      
    & G- n4 S/ d* T    }& I* i2 f# {1 ]  q6 d' O# h/ J
        ZeroMemory( pSvrAckPack, dwAllocSize );</P>
    ) Y6 \1 t! J& W6 |' e) C$ P<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);$ F1 d0 M9 r  @, g8 S
        pSvrAckPack-&gt;wPlayerStatePacketCount = 0;
    0 [) `: O. O5 r7 d4 [) ~! y0 O4 _    PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>
    * |2 R5 U( @, r8 L/ J$ R  d" u5 M<P>    // Compute range of cells we're going to scan for players to send4 t1 G/ e9 c3 S4 c, t
        DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;
    6 O7 i3 `1 K3 i. _9 v! b3 o2 ?  W    DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
    ( @' j  n# `4 b' U* B9 B5 s5 o    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;: }" @6 E. F& g/ h# l
        DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>
    * M5 @. \; m5 W8 }8 T: c<P>    // Lock that range of cells
    , b, c+ b# w  ]  v    LockRange( minx, miny, maxx, maxy );</P>
    7 C) I7 a( [. D<P>    // Scan through the cells, tagging player data onto the end of. H& L: S- ^1 ~' N4 j2 ]1 y
        // our pSvrAckPacket until we run out of room
    1 ]4 n" ?, Q6 ^$ U    for( DWORD y = miny; y &lt;= maxy; y++ )
    : i9 i( a4 x2 W* [' B5 @6 \) X    {4 E- `5 V+ N9 p# j, @; |2 R1 @
            for( DWORD x = minx; x &lt;= maxx; x++ )
    7 M0 J* S3 ]2 R1 @# e- a        {  [8 y" |* ~' O3 X& q
                PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;5 {/ }0 i2 r1 o) E$ O
                while ( pCurPlayerData ); v8 ?- \! _. p- S7 g$ H2 C; L
                {4 i5 o+ }) L: o2 U8 D
                    if( pCurPlayerData != pFromPlayer )" b' |" x& Q( [9 z
                    {1 E5 v; q- ^% `, h6 s
                        if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )0 O! g% A3 B$ C6 j+ S
                        {# O+ @# z6 S# A% z
                            // Make sure pChunk is where we think it is
    1 j! D% a& [3 r/ B5 o                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>
    6 {, K7 p7 w1 l9 ^, ^<P>                        // There are more than just 4 new nearby players, so resize the
    . K" g" I$ O8 z. t; A! k( W  `                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's./ K( |9 j; j* O
                            dwMaxPlayerStatePackets += 16;. ]- E0 e0 i6 i2 G
                            dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);  V# }/ E( n$ d9 I, q+ U6 z" X
                            ServerAckPacket* pNewSvrAckPack = NULL;4 ?2 k9 u! P7 r" `; D/ A' _/ b
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );* U4 r" d  u4 j7 h# S% b0 x8 E+ V" _
                            if( NULL == pNewSvrAckPack )0 _  f" J( g( i' a2 H9 R) A" M0 C2 F
                            {% _+ p+ i/ c/ V0 s! {( M" T* e; Z; c
                                // Out of mem.  Cleanup and return; ?( L( N* q: R* u# f% F5 p
                                free( pSvrAckPack );* f: n& x" m1 Q( ]
                                UnlockRange( minx, miny, maxx, maxy );
    " ]% @' G/ c+ f/ T; N3 T                            UnlockPlayerData( pFromPlayer );0 V) V3 y( i2 o" H2 K# c1 Y
                                return;       3 R( e- u7 D. {$ Y! P
                            }</P>
    ) w* W" F4 F. N- R9 k/ `<P>                        pSvrAckPack = pNewSvrAckPack;" Z6 F; ?5 V4 `  T, x" m
                            pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
    # F  r5 ^2 e! T5 h7 J/ _<P>                        // Make sure pChunk is still where its supposed to be
    ; t% x+ ^) Z* G8 R+ x6 U& \% m& Z                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );4 n" \% ]5 V: @8 n8 A
                        }</P>
    % l2 Q5 v1 \# T" {<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;
    * S7 c+ r  J( C8 J                    pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;; @2 z" ~9 Q" `1 }7 z
                        pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;
    9 @4 a4 E, R2 |* ?5 o% R                    pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;
    # R% b  Q1 g7 U7 M3 I' V6 G: L                    pChunk++;
    / l; ]9 I9 q+ `& j" B2 ^                    pSvrAckPack-&gt;wPlayerStatePacketCount++;9 c* A* Y$ G4 q4 J+ w1 I5 u
                    }9 L" `8 ^1 I0 G% r) x, G; G
                    pCurPlayerData = pCurPlayerData-&gt;pNextInCell;+ H! v8 \) i+ K% e  C7 x" l
                }
    3 p7 w7 T# H( l  k; f8 G2 N        }' H* y, q; q" e8 R
        }</P>! M- j5 t. c. v+ F( K
    <P>    // Update the dwNumNearbyPlayers for this player+ U2 x* E+ W, r; t# E  i' H+ H
        pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P># ]& [/ c) O3 A% d$ f9 x+ q; j% h
    <P>    // Unlock range of cells
    . r5 n( S, P5 z2 g4 I. h    UnlockRange( minx, miny, maxx, maxy );</P>' z  R# M3 l. n
    <P>    if( m_dwLogLevel &gt; 2 )
    # m* t) X$ @' {$ k+ x& e    {3 V- L% q& Z3 D# i$ A
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    ' p' b6 G; L6 \: \    }
    & L: a' B( Z+ \: t% x    else if( m_dwLogLevel == 2 )
    $ F+ c' Z. O( {7 e. {    {
    0 P1 N# O* }* M% a" i        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    * A0 i% z" k" ?" u, Q' B        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )
    ' A4 i: s6 \4 t- R        {8 H4 y' T  R& h+ Z
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );% e* [, L9 ]6 Z" ~* V' ~& g: Y
                pFromPlayer-&gt;fLastDisplayTime = fTime;/ z' c8 y% }3 U
            }
    & ]; }% {6 }: v3 l. `: U: r7 o- E    }</P>; t: |% m" J' g, o# U6 W
    <P>    // Unlock the playerdata3 t- r- w3 q- S& o9 {3 ^
        UnlockPlayerData( pFromPlayer );</P>3 r7 j. A, U6 L; y( ~. B
    <P>    // Send acknowledgement back to client, including list of nearby players
    % d( C/ C) _9 r7 O5 N/ y  G    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));+ r, V, i" Z* }$ _  e. m

    ) o1 s& l7 h" \0 ~" \2 A) a    // Pack the buffer with dummy data.0 z$ S1 ~0 U& G( ?9 }0 }
        if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)
    0 w' t( V. h. U2 z( b. S( R8 U: u    {! r6 O3 y3 g# ~5 C! X% A
            DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];. |4 \! A' E4 W1 n' v
            VOID*   pTempBuffer = 0;</P>
    4 y) o3 S) _: }: M4 V1 s0 _1 d<P>        pTempBuffer = malloc(dwBufferSize);
    * _5 v: Q; b' i3 t2 x- U        if( NULL == pTempBuffer )
    % ]& W* q7 r7 j; ~. v7 K  l+ J; ?6 y        {
    " x8 k5 S8 P) W9 J            //Out of memory
    - B1 N/ r4 s9 w4 S4 X            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
    / @$ m; B/ H8 k: u( Y0 v# o            free( pSvrAckPack );
    , p2 e; S2 v+ R            return;7 y$ D. O7 U% c& T
            }</P>
    0 G7 y3 ]" L8 s5 \9 R<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');
    7 U! o+ n& k$ k  @        memcpy(pTempBuffer, pSvrAckPack, acksize);</P>
    . L6 b# m' C1 z6 V$ L0 v& A<P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );
    0 E- h! E! Q5 s5 n% \   
    ( j, {! t8 ]2 r        free(pTempBuffer);0 e( {+ K, s+ _, m# P' `& {! y
        }   7 R! L  t1 ^& L* ?
        else
      d9 ?9 q/ y( s/ I* Z    {
    ) z# K' l( X$ t9 Q4 f        SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );; p+ z4 [( f, ~
        }</P>
    3 Y" T1 t! O7 o<P>    free( pSvrAckPack );</P>
    : X4 L' o6 P$ m0 a0 \<P>}</P>
    ) d# o3 b' d, i+ h$ \) m( a& N: K" B: d: L: g! @6 B
    <P>, K( p3 ?5 m; i- @4 `' g
    //-----------------------------------------------------------------------------
    0 Z+ e+ e7 @" u$ m1 t: d  J// Name: . K0 P0 ~9 ^7 m5 ?3 L' ~# g
    // Desc:
    # V2 N5 x5 P2 l  v) `//-----------------------------------------------------------------------------+ a3 R& s4 d* u! Z4 @
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )/ o( t- q! r1 p( n
    {1 ?: S6 ]8 O" ~- _5 a. Y1 c% \4 D
        // Grab playerdata for this client and lock it/ u" G1 c4 t' p4 T- `
        PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
    ( g7 F  E2 U3 e6 v0 L1 L- }; s4 g  c    if( pPlayerData == NULL )
    " q' G* p9 [% U  _* q  Z        return;: E3 E  Y2 `" E. @) c, ^/ k
        LockPlayerData( pPlayerData );</P>' G3 t/ j4 S8 p- I
    <P>    // Record the version number # h% K8 m& z& C0 s3 v
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>* \  J& X) G" h. }
    <P>    if( m_bLocalLoopback )
    0 [  _  K% Y( @' Q: [6 j% p        pPlayerData-&gt;bAllow = TRUE;
    2 _# P" u  G% c. H' F: I% u, b    else
    % E$ ~# B, C; Y, V6 X( t        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>* |% b$ \8 y/ ^& E  ?8 [7 U9 s) {4 n
    <P>    if( m_dwLogLevel &gt; 0 )) ]1 m! n6 F/ b
            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>0 a+ M, P7 h' I* ~  J
    <P>    if( FALSE == pPlayerData-&gt;bAllow )
    " j9 }+ ]! f; K/ ]! G/ Q    {
    7 Z6 j" \  N) S+ `% [2 Z) U        if( m_dwLogLevel &gt; 0 )
    7 S+ O% j; m* J6 P+ E, K            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>. P! N4 M) u" c+ _3 P; _& j
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );( f8 @2 m/ r9 W1 P! g
            UnlockPlayerData( pPlayerData );9 V; o5 t3 p* D9 [1 L; H6 ~2 Z
            return;
    & ~6 c5 y+ ^% [8 V' R    }</P>
      f. M# A3 g4 N  H+ N! y<P>    // Unlock the playerdata3 H! L# I+ G1 I2 z
        UnlockPlayerData( pPlayerData );</P>
    $ p, }% f8 u; t, H5 b; ?<P>    // Send acknowledgement to client that the client was either accepted or rejected4 C0 T" L9 v4 f9 N8 r, W2 o/ N
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );3 H# m. K3 r( ]' Z0 ~8 l
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );  ^" i% A; v  ^8 C' v1 \* G' |8 _4 F
    }</P>$ C! q9 T& O2 p5 g6 [) S" ?% Y

    ' E% t, L$ i: }3 l) K9 f<P>
    + J7 k5 L4 v$ G/ M8 h0 _//-----------------------------------------------------------------------------
    % ^+ N; \$ h4 L8 Y// Name:
    0 N0 f, Q6 p: ^1 s! ]: \// Desc: - r4 B! |- E7 R* i- F( M) x
    //-----------------------------------------------------------------------------% G7 u( ]' n: w! O) v
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
    - ^/ p1 d9 q& A# R{6 [4 X, G- O# n  g
        switch( dwClientVersion )
    $ {. g) G* @4 y) `- h+ g7 ]) L, z    {
    : g# _, C) O; b" u0 j7 _. P9 ]% m/ r        case 107: // only v107 is supported
    & j& V# x) K  u( V0 J( }            return TRUE;
    ) |, i5 ]1 T/ C; `4 e5 `8 A        default:8 M( n; \6 s5 _+ p- n6 J0 c
                return FALSE;
    7 N7 `/ @& b6 ]9 d# V3 ^; T6 p    }% ^. T+ J+ r6 D9 D: z. E5 @
    }</P>3 G4 A2 m7 |: b: }- R7 g
    1 B) u' R) j0 ~7 [* R# D. R
    <P>
    + P5 J+ U# }1 n0 B3 u$ j& e- W//-----------------------------------------------------------------------------( y2 v% ~: U% I& B- X
    // Name: $ x9 b+ a1 P0 p% x; `3 a2 f4 I; S: `& J
    // Desc:
    / t$ q: x4 S" e, _3 z3 k+ `//-----------------------------------------------------------------------------. a+ }8 F6 |, Q
    void CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )! z/ d3 j) H- A
    {
    + z* b" J* T% ^3 t0 v) S& P    if( m_dwLogLevel &gt; 1 )3 ]7 ^! i4 [; B- r
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>
    * L# P. g+ s5 l6 y<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );$ A$ I  Q. N( t' Q
    }</P>
    0 ], C+ u- F3 S8 y# {  L# j
    2 Z# B' _4 ^; o<P>! z+ J# s6 A5 r0 _+ ?
    //-----------------------------------------------------------------------------; e  S3 v  j; c2 M* M
    // Name: ! f# \& ^1 l: `# ^4 u' G- l
    // Desc:
    - s  B1 r9 U, @& i& m9 R0 X//-----------------------------------------------------------------------------" P8 S; M9 d% y# t
    DWORD   CMazeServer::IDHash( DWORD id )
    : ?( [5 m- U2 ~$ N6 A( m{
    + t* v  r5 [( P- {0 b- C+ Q8 v    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);/ ?' R* C3 [/ p! f9 D
        return hash;
    ( b" i6 o$ o2 V0 i}</P>& O2 A) K4 U( Y' w: c$ l% U. Y" s0 e

    ( k/ J( G: c# S5 P. Q8 s<P>
    4 n. L: N. C" J0 }: y//-----------------------------------------------------------------------------) Y  G! p& _4 O% ^0 T
    // Name:
    . }4 K6 H$ ^7 m( b6 m// Desc:
    . L8 u- }# V2 x//-----------------------------------------------------------------------------
    # [- L) o4 S* n. o/ Rvoid CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
    ; ^( w% T0 j2 q- f- e{
    " T" o$ s3 e. w& y+ ], v    // Hash the ID to a bucket number
    4 n2 d* [; }6 A+ |2 N- B! i7 u4 L; ~    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
    6 X; f2 `1 Z, N7 G1 H5 I+ x4 z<P>    // Lock that hash bucket
    4 Y1 s$ j. w' W/ x# d    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;) q  b' d, T- D* r; J
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>$ t" C3 Q$ A' n% }; ]4 h
    <P>    // Loop though players in bucket until we find the right one0 E4 w" E1 `6 R% g* \
        PlayerData* pPt = m_pstIDHashBucket[bucket];6 G/ q' V& q4 a& b* m
        PlayerData* pPrev = NULL;
    2 X* U' T& }: ~' S3 a' Q+ W    while( pPt )1 P4 G: N8 u4 J
        {) ^4 w. P! H1 l! d) T) U3 b$ ~
            if( pPt == pPlayerData )
    - s8 a1 ]! y) }+ |& F            break;
      I$ N! k3 c8 c1 N        pPrev = pPt;
    : P/ W' k2 D8 f) g. _- r5 e0 o        pPt = pPt-&gt;pNextInIDHashBucket;
    - b9 x1 |. X* F( H    }</P>
    $ u3 n1 v5 k7 ]+ H, n. t<P>    if( pPt )" {8 ~/ f' a# A6 l  q
        {
    0 E4 k1 y7 [; u  ?7 z: p5 {8 @9 e1 B        if( pPrev )
    " p9 B+ y3 Q! k: M: {1 I            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;
    5 B" p, K0 S9 ?+ v! N( g        else" ~8 B& i- d" e, C6 x( O4 t
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
    7 y8 h( O. @* {: i' m+ H        pPt-&gt;pNextInIDHashBucket = NULL;; X3 O" ]/ T' q" }
        }</P>
    8 U0 z# o3 [7 U7 o5 [. r- d' a4 W<P>    // Unlock the hash bucket
    5 w# t+ r6 I+ ~" M" Q( A( O    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();$ f3 T: a+ K$ A. n' @% U
    }</P>) ]/ s  C; r- c  d+ m, h! t

    2 P6 N% S: w" F$ [<P>* j  c4 w, w8 g  Q7 x% v# L
    //-----------------------------------------------------------------------------
    / k% E. V2 o1 D. A. V// Name:
    ! b5 b3 r3 K% J" O# n// Desc: 3 h0 W) Q8 Y4 W. |
    //-----------------------------------------------------------------------------
    " v4 A7 u% g% ~' K6 b4 E8 Avoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
    * i7 j1 @3 O& m% t{8 \9 z" ?# i) g% J9 v: Y3 ]5 U' l
        // Make sure this player isn't added twice to the m_pstIDHashBucket[]
    & R+ \9 Y+ r( S; _0 u4 l    // otherwise there will be a circular reference0 w) ]- C0 R$ F2 t( w; [9 s
        PlayerData* pSearch = GetPlayerDataForID( id );
    ! O  a% q+ H0 y; t, Y    if( pSearch != NULL )
    5 _  ]: F6 {2 r# k+ ^0 |        return;</P>
    * q! _" J; ^7 |  m0 k  K! Z<P>    // Hash the ID to a bucket number' m3 A4 ^, H+ e. ]! F1 W& X
        DWORD   bucket = IDHash( id );</P>: w! r+ f* F) g( S) n9 ?8 o/ p4 Y
    <P>    // Lock that hash bucket. e2 b  P) C' Q$ P- X
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    0 i, }/ P& H( b: x    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    $ E! x2 X: j: u<P>    // Add player onto hash bucket chain
    ) [! F* v- p& R  w' |; H9 ~* ^    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];
    5 q& n* \% H$ C/ k; [: i8 ?    m_pstIDHashBucket[bucket] = pPlayerData;</P>
    1 d1 F) S2 E1 M: z7 J( h$ }' e<P>    // Store net id in player- `. ~: Y4 }3 W. R9 X: H7 ~  d
        pPlayerData-&gt;NetID = id;</P># L4 K; C. V  c) }8 F; }
    <P>    // Unlock the hash bucket$ W, k' Q/ |# l+ z! P1 B0 |% }
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    * V0 R& H: M" a6 J5 w5 q" l}</P>
    , T! ^, D3 F3 j, A7 A7 ?* T9 a! z' r& R/ c, G
    <P>
    6 t  S# H- a% `; O//-----------------------------------------------------------------------------# I3 e& \1 `; H3 r6 {
    // Name:
    1 s. h0 p& O; O3 b4 U// Desc:
    6 g. h  f4 d) }  t% l//-----------------------------------------------------------------------------
    , [% i: F1 U4 _+ C0 Y6 j5 iPlayerData* CMazeServer::GetPlayerDataForID( DWORD id )
    ( Q( a% e. v8 o- g, `& E; H{) P6 P! l$ |# y& S6 p
        // Hash the ID to a bucket number
    , W" [+ W% g6 w, ^: d    DWORD   bucket = IDHash( id );</P>
    3 X0 L2 S. W; G$ O4 V7 j# N<P>    // Lock that hash bucket
    - g. |* G) s* E2 F3 }    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    0 m4 L  `+ E( {- t4 Q" W9 w    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    # \" E/ p/ c" `<P>    // Loop though players in bucket until we find the right one
    1 C! r; x8 K5 a) U- T& W$ Y    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];9 s7 u$ i  B9 C/ M8 k* @
        while ( pPlayerData )
    , d) K( D* a, S+ K- p1 Q* I    {
    - l8 d+ t: t% O5 U        if( pPlayerData-&gt;NetID == id )
    - E7 p1 F3 c; [$ B- e* f            break;
    2 u4 F, p! q9 t. l3 E        pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    $ R! ?/ l! H$ o( H3 j    }</P>6 v4 h  H+ r, ^$ D
    <P>    // Unlock the hash bucket
    , `% v* f9 `$ |: a- p9 i& Q% H    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>' }7 X" n! J7 h. X5 B/ Z1 z$ }3 j
    <P>    // Return the player we found (will be NULL if we couldn't find it)
    + f* F6 z+ k5 K# b' a+ {+ [    return pPlayerData;
    ( e7 Z3 W, G7 K# z; h}</P>
    ) ~0 B+ c* @* G" i6 d' y: g0 L; _& k7 l
    <P>/ O; {8 m' I& ~; U7 U
    //-----------------------------------------------------------------------------
    : H4 `2 W% n) H( M; M// Name:
    2 {# U+ C; |% A2 [0 E% H6 E, c7 ^// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner
    3 N% }3 ?- H5 j8 W3 I. G: K//-----------------------------------------------------------------------------" |1 S" ^; P  b
    void CMazeServer:isplayNextConnectionInfo()+ D2 U* a! u+ r: x. ^6 w3 S
    {
    : F: h% N' D: J    if( m_pNet )& H5 c, n, t, _' b. h; ?6 M
        {+ m9 q- X5 T9 B# z7 P/ k% n2 R8 }
            // Find the player that was displayed the longest time ago, and display it.7 Z; g/ A9 @) `+ ]% J+ f
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );% d- T' [+ k4 b9 i' d. l
            PlayerData* pOldestPlayerData = NULL;
    & y" `& o  [7 A        FLOAT fOldestTime = 0.0f;</P>
    ) v! B7 Y- z5 k5 c- c5 O9 V<P>        m_PlayerDataListLock.Enter();</P>4 M2 C* c8 L$ x0 h9 r4 @* G& Q
    <P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;+ N% `1 S# o+ X. q% b! y
            while ( pPlayerData )
    $ z  m6 Z$ J; U+ [        {
    ( s+ f5 }$ k1 A( h) G* i            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
    ( H: D( k4 D1 r( ^$ D' f7 h            {! M/ y- U- P4 p$ g
                    fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;
    6 u$ S' c. d- v) g                pOldestPlayerData = pPlayerData;
    9 _' v7 l9 Y2 R) l5 B            }</P>
    / I5 }6 L3 @  E% u& q( O* b  g<P>            pPlayerData = pPlayerData-&gt;pNext;' o4 b" T) r8 a+ h* _9 h8 h
            }</P>/ X, Z( _; {+ L6 [  @6 w
    <P>        // Display the player with the oldest CI field, and update its CI field.
    + F8 @# F1 ^. C6 L        if( pOldestPlayerData )
    " \- H8 J. ]% v2 t( [$ o        {& C4 ?. n" O2 m
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
    + p  v( }' D( [; ]% Y. B$ S! Y            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
    $ r2 ~, B) P( r% V            pOldestPlayerData-&gt;fLastCITime = fCurTime;
    ) S! }7 j4 ]5 G& v" H6 ~$ k% u2 s* s        }& G. d4 z& h* _( d. [
            else
    % ~. q4 {. D/ P" w3 P, j        {: K. l6 D' R9 h8 J0 i, Z
                ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    6 z$ }$ H6 \8 {8 S& ]) i        }</P>$ Q7 n8 O" _- B1 [" |
    <P>        m_PlayerDataListLock.Leave();
    , ^% V% |4 _: y& H: P! E    }
    / Y+ o  a$ Y, m. d* i& @" e2 I}</P>
    1 l' E+ [6 L% F" z+ Z
    2 Z1 _0 {  E  [  Z7 l<P>: N* U; f' p9 a, m# ?, R3 V, U
    //-----------------------------------------------------------------------------
    / ?2 C2 u! K$ H, i4 _* h# g! r// Name: ' e6 B/ R9 K: M% r6 o% D& r  L
    // Desc: % Y- s- X+ K- y3 p" |1 S* s
    //-----------------------------------------------------------------------------" S% h4 Q) A6 R) Y; L' ]6 I. h% Y# b3 N
    void CMazeServer:rintStats()
    5 \; u- H; e8 H% p7 G{) Y% u) `9 v+ e5 e1 T3 A
        ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"), # V$ S( o1 _9 ?1 C. B  M
                                        m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );6 r  @" W1 k; ?" D) ]
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),5 r/ s3 I+ p0 ?' o# j* j( L& q
                                        m_fAvgThreadTime, m_fMaxThreadTime );
    ( B. b5 @# g. Y+ W    ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );) O- Y" h7 g7 x/ F- R( k8 g
        ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );0 ~/ P) K" G* B. C
    }</P>7 u0 v" Y! V: C0 J  {0 J

    $ Z! u! o# Z9 V( r3 _  s! E( k0 b9 ?<P>
    3 `2 n( P" n; V- ^( f  }//-----------------------------------------------------------------------------2 c4 T1 D6 X2 S  w; A% [$ m
    // Name: , N* r* a9 g( c" a4 M" o
    // Desc:
    8 k$ E$ y3 o8 r7 `9 @# W) s//-----------------------------------------------------------------------------
    + C# Y2 j' a7 U3 gvoid CMazeServer:isplayConnectionInfo( DWORD dwID )) Z  p( w( `) N% C& O3 C
    {
    / F& Q  Z6 V1 A* I. k9 T( w    TCHAR strInfo[5000];
    . J, k% c# T) z( J9 n    TCHAR* strEndOfLine;
    * K) f+ A2 ]( @6 ~    TCHAR* strStartOfLine;</P>
    5 A: N/ S. t: Y$ G* `1 x0 u% U<P>    // Query the IOutboudNet for info about the connection to this user
    + ?6 b! r. e+ G# y    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>/ A9 j/ [8 u5 X
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );
    . z1 y: B5 u' o6 f" y4 a    ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>9 R. G  A# R: |
    <P>    // Display each line seperately
    ; ^( \  W( w% Z2 A9 O% N    strStartOfLine = strInfo;
    # s  H/ t4 U% X+ b' F3 T    while( TRUE )3 g1 |- q0 _5 L6 }7 p# h
        {  Y  p+ |- T! J2 W0 Y
            strEndOfLine = _tcschr( strStartOfLine, '\n' );
    ( {4 M. B& W: j( }. t: ?/ ^        if( strEndOfLine == NULL ). E0 q" }7 s1 t1 u
                break;</P>; O) }$ W4 D" I
    <P>        *strEndOfLine = 0;: ]3 D) Z3 f+ G
            ConsolePrintf( SLINE_LOG, strStartOfLine );
      H. [  f% Q+ o4 c" g1 I) @7 u/ W        strStartOfLine = strEndOfLine + 1;
    1 D# I- V. F5 t/ {0 r6 S    }
    + Z* Y+ ?6 y6 Q# |  k}</P>
      N8 ]" R* n: ]- x* ~( q+ X& W5 \) r0 x9 o* q
    <P>- _" P. j& B$ _9 z9 Z' q
    //-----------------------------------------------------------------------------
    ! q5 C1 L( p$ ^3 W* [  q// Name: + {! e7 M' r( w6 g
    // Desc: ' M5 W. i" |& [5 O8 k
    //-----------------------------------------------------------------------------
    4 u6 E: V, H8 r, R; xHRESULT CMazeServer::SendPacket( DWORD to, void* pData, # M. r/ ]" e& f3 \; t, w& f& V
                                     DWORD size, BOOL reliable, DWORD dwTimeout )0 G' ~  E( t5 S. R; s, [. Z* \
    {: O( l' k/ L$ s7 x! P4 z; V
        // Chance of forcing any packet to be delivered reliably
    4 J- @( ^% z" d5 \9 J6 f: r    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate ); O/ L9 J; s- M
            reliable = TRUE;</P>6 l" h  V) }" ~- R3 l
    <P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );# ]. i8 W6 m- M) ~7 O+ X  i, A# a
    }</P>3 f( P% V' ~  ?, ?. O

    9 J5 ]- E9 s3 h' B" a' o2 f<P>$ v: i8 O" Z6 V( A7 W* M
    //-----------------------------------------------------------------------------
    ( {4 X/ H) Q8 H4 m) d6 M& M1 s// Name: 2 F, C% a2 D6 @: m4 T. @% b  z8 L
    // Desc: 3 t, V0 R$ X1 Q% }0 s5 O- Y! b
    //-----------------------------------------------------------------------------
    - T" R5 m6 M+ l$ zvoid CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )4 _( I; B  r* q' a, g: l  |
    {
    * d) Y& o& {$ T  ^1 w    // If we're up and running, then send this new information to all clients
    ! G2 T3 _8 a* P+ J! N- O5 h, _    if( m_pNet )& K- P) k4 }  y2 @
        {
    : l+ q) A# R: F        //Use the AllPlayers ID( m1 g2 g# x5 u9 C
            SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );' f, P9 i, z, ?- R1 c# m6 z! \6 W9 ?
        }
    ' ^) D8 _, O2 s$ Q}</P>
    7 l2 g* b0 j) u# u1 Y( |, {
    6 w: [$ }4 K8 M/ t7 B; _<P>  ?' z+ x# Z6 X* ~4 R
    //-----------------------------------------------------------------------------: L3 A6 B8 c+ B  U: z
    // Name: 1 L: M0 i3 r0 o0 l
    // Desc: ; P+ W1 C- I* n: [
    //-----------------------------------------------------------------------------
    : X! I' f2 U1 u0 _void CMazeServer::SetClientReliableRate( DWORD percent )
    * J- J% e! O! y: ?{
    " V0 \! |( d$ @4 L, C0 |    // Update client config, and build packet containing that data/ p  ~$ r0 o/ N  C) n' n8 k
        m_ClientNetConfigLock.Enter();
    " `7 Z. \; X+ h% a$ k' y    m_ClientNetConfig.ubReliableRate = BYTE(percent);
    ' l' D. W) x; A6 e) N    ServerConfigPacket packet( m_ClientNetConfig );
    6 X* Q" c. u$ u% K* o6 u    m_ClientNetConfigLock.Leave();</P>
    & }" I) j' q4 ~) B3 w<P>    SendConfigPacketToAll( &amp;packet );
    8 Y- {5 n6 Z1 l7 L& y}</P>
    # U0 L# w# A4 M4 D1 ?7 d" w0 z8 o4 R1 o8 x# D, x
    <P>
    3 }- X8 r: A( z: D& \' b//-----------------------------------------------------------------------------/ D9 K% h- O1 z, d0 V$ n1 p1 f# L  v4 q: ]
    // Name: * N: F+ X0 Z, Z2 y
    // Desc:
    6 ]# x- E- g1 n; k9 n& s+ O//-----------------------------------------------------------------------------  ^, s# U8 r* T. [% Y
    void CMazeServer::SetClientUpdateRate( DWORD rate )( m" S4 D7 T3 M& o; o' Q
    {
    7 S, g6 `4 B" ^6 R; |( J" ]    // Update client config, and build packet containing that data
    5 s# e* A% M* ~2 a    m_ClientNetConfigLock.Enter();
    ' k" q' F( e) H% H8 n3 k2 @5 P7 c    m_ClientNetConfig.wUpdateRate = WORD(rate);0 h' N6 H) t( i- T7 F
        ServerConfigPacket  packet( m_ClientNetConfig );$ G! A& ^1 F* Q4 m/ G
        m_ClientNetConfigLock.Leave();</P>( V% H( f  c1 n0 {* j6 `7 n
    <P>    SendConfigPacketToAll( &amp;packet );
    - P/ Y* M1 v. N' @+ M8 Y* W}</P>- m9 [$ a. C  k# ?5 [# {

    3 `( s8 A3 C# M6 B( }+ j/ i/ R1 w. W<P>
    & C8 i) a' M9 w0 |//-----------------------------------------------------------------------------
    $ d) P7 ^0 H8 j6 r& e9 Y* g// Name: : Q4 M; e3 R5 x/ T
    // Desc:
    ) w; H: v/ G7 N6 F1 V//-----------------------------------------------------------------------------
    , {  i# k2 F2 ~0 T) xvoid CMazeServer::SetClientTimeout( DWORD timeout )
    8 I/ @% ~8 I1 _' t, z9 r9 h{- V7 R" |- i4 j4 `" Z  F/ |3 p6 j' m# h
        // Update client config, and build packet containing that data4 C" r) w( J& N: _
        m_ClientNetConfigLock.Enter();
    ; u, [; Z9 S0 h3 D% Z' E; U    m_ClientNetConfig.wTimeout = WORD(timeout);# v/ {: Z# b. c- ]& u) y7 [
        ServerConfigPacket  packet( m_ClientNetConfig );
    . ^0 e8 G$ D+ a$ E* ~    m_ClientNetConfigLock.Leave();</P>
    , H- u+ k% W, P# m, {<P>    SendConfigPacketToAll( &amp;packet );; `& t) C- S3 i( S6 U
    }</P>
    6 W2 ]+ t) f) d, J" p* b( R+ j/ y& U! J* ?4 Q9 e# S1 X
    <P>" ?/ c+ r1 o/ O+ q
    //-----------------------------------------------------------------------------
      l+ r) K1 c+ M: T" w- p7 `/ `// Name:
    4 a% B/ e$ y% B6 k% ^" ~' v// Desc:
    , v) t7 J1 C( B2 U# }//-----------------------------------------------------------------------------4 ?: X/ K, B8 ~8 O
    void CMazeServer::SetClientPackSize( DWORD size )
    6 o+ [1 a5 @( v7 x{
    ! q) b* w, e$ `2 q- E    // Update client config, and build packet containing that data. t: D6 j3 Q$ y( Q8 F8 r
        m_ClientNetConfigLock.Enter();
      ^, @; f5 x- w    5 \: n1 ]3 z; u+ J' V4 o- r
        m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.! b* A7 m% n% p/ i
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   / e9 H2 A7 l9 f4 m( T' _
            m_ClientNetConfig.ubClientPackIndex = 0;</P>
    : c7 f  M1 Z+ G2 }, ^( F<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);
    9 g' T# s' ~, ^) w    ServerConfigPacket packet( m_ClientNetConfig );" M6 Q0 l( N7 E! ~
        m_ClientNetConfigLock.Leave();</P>7 l. S6 v) [/ m0 Q. D
    <P>    SendConfigPacketToAll( &amp;packet );
    4 w- e5 f/ Q% f9 V1 Q}</P>/ _2 E4 q& m+ A5 `7 Z1 C/ j2 k# C9 `( i

    # r( B; Z( T4 l/ D$ T<P>
    & }) y" N% E+ r  W6 _//-----------------------------------------------------------------------------! x5 Y/ s+ U; \" P4 a0 q
    // Name:
      X" Q7 A' O' S, f* B1 b% [// Desc:
    + y& t+ ~. b1 S, F3 e) G) o) J# H* s//-----------------------------------------------------------------------------: B# R; G- F/ u3 Y
    void CMazeServer::SetServerPackSize( DWORD size )
    3 s" M1 u& m* M  T{' y  q4 Y+ g" M* ~2 I
        // Update client config, and build packet containing that data
    - a. w' P) `4 `7 R4 {$ c    m_ClientNetConfigLock.Enter();+ A9 Q. x/ |+ j, ~7 Z
       
      L" u1 Z6 X& r) M) X0 J    m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.- T. d% ^- b( H! |) {$ R9 e% z1 Y  K
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   . j+ A# @& U% q) ?0 s7 @% ~+ q7 n
            m_ClientNetConfig.ubServerPackIndex = 0;</P>/ m9 b! B: Y$ W5 X1 V, N
    <P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
    ( G! d7 n$ ^( q    ServerConfigPacket packet( m_ClientNetConfig );; U5 S( ]! B! A  |5 c) z7 S1 A, s
        m_ClientNetConfigLock.Leave();</P>3 Z7 R2 }' {- Z" w& r
    <P>    SendConfigPacketToAll( &amp;packet );
    + w! ^6 T7 K/ e& K2 ]}</P>
    ( @2 G4 u9 p: D& k; u; ?1 @, |0 e2 t<P>
    / v2 f9 ~4 O" p- i: ~2 ^$ x//-----------------------------------------------------------------------------5 k" F% s% |' Z  L1 Q3 e5 k
    // Name:
    ( I& U! g5 F+ R3 j7 C// Desc: ; S' q# i2 k9 ]" r8 ^8 T5 s; O
    //-----------------------------------------------------------------------------
    1 M3 r8 x  z2 Z4 Pvoid CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
    % j( f/ f! p# o) I{
    6 ?# y, I4 H/ I2 |% E    // Update client config, and build packet containing that data  t% N1 p! c- b9 l5 M
        m_ClientNetConfigLock.Enter();/ U1 M' h& s$ Z/ q+ P7 J/ z
        # t" e( |2 r6 V  r" U
        m_ClientNetConfig.dwThreadWait = dwThreadWait;* h3 E1 ?  @* {/ ?' f
        ServerConfigPacket packet( m_ClientNetConfig );
    : a5 u2 `8 ~) B, I0 @7 [7 a    m_ClientNetConfigLock.Leave();</P>
    6 x: W8 u' |- h- [+ n<P>    SendConfigPacketToAll( &amp;packet );, V& Q9 t6 p: ^' i& v1 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, 2026-8-23 05:49 , Processed in 0.542232 second(s), 51 queries .

    回顶部