QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4178|回复: 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 G% z! y; E% a& \/ a
    <>// File: mazeserver.cpp1 L5 }& R# U0 G! w0 O4 \3 S# f
    //
    1 C% J; P) u6 j" {3 d' H5 D// Desc: see main.cpp
    / {9 ]0 Q4 r( z) w. [: |( g6 }//3 l% `4 v5 b' @: k/ p" m6 e
    // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
    $ Z0 e0 z1 u0 y0 ?( K% o( Z//-----------------------------------------------------------------------------
    ) S4 h$ }5 T0 p# d, V#define STRICT
    " O2 M2 V; t  n" X) M" t3 D% X, r#define D3D_OVERLOADS4 l. Y% X1 y9 u: N
    #include &lt;windows.h&gt;$ B& ^- `5 F- V/ b$ @
    #include &lt;d3dx.h&gt;( e3 L# A/ |- k$ j. `
    #include &lt;stdio.h&gt;
    . |8 H' w+ l& [5 M0 W. N6 `$ ^6 y8 z#include &lt;math.h&gt;
    ' v$ r+ w7 W( f4 P$ o$ A0 ?#include &lt;mmsystem.h&gt;0 s& M, r$ v8 M) V3 d
    #include &lt;dplay8.h&gt;
    $ @7 [0 Q  d8 e7 J) G" W#include &lt;dpaddr.h&gt;
    " G- X4 _/ x: z( T+ `% O#include &lt;dxerr8.h&gt;
    3 Z1 ^% B% T5 x& ^5 r3 m#include "DXUtil.h"# ^/ l: S5 k! O- G% o4 ^* T
    #include "MazeServer.h"( C  p) P" j! e3 E
    #include "ackets.h"" z9 d0 ~3 Y/ [9 n
    #include "Maze.h"
    , X5 `% Y* m' X9 e& L& U9 l4 P#include &lt;malloc.h&gt;
    8 A  }' ~7 U4 }6 c/ ]* s" `% }#include &lt;tchar.h&gt;</P>
    ( N0 G) E: r4 F# x/ I1 R( f9 D- s! ?  t
    <>//-----------------------------------------------------------------------------
    ; M+ H! h4 U, \# e/ s// Name:
    $ J, j0 k: X5 A// Desc:
    # ~7 r7 ?0 x  @4 G1 ~0 {9 r  x//-----------------------------------------------------------------------------( p+ l" Q8 ]* N7 o
    CMazeServer::CMazeServer()
    ( T& R' L  t* {5 U& l{
    " f! m8 I) N' e; N* j    m_dwPlayerCount         = 0;: G* n% P* n, n/ f" m+ o" [4 E8 S2 R/ }
       
    ( Q7 |" ?# D7 A$ R7 v    m_wActiveThreadCount   = 0;
    2 L- K' b# _, g    m_wMaxThreadCount      = 0;
    6 E1 m) d4 n9 I- u    m_fAvgThreadCount      = 0;/ m# j3 S( _3 N
        m_fAvgThreadTime       = 0;% c% k8 T" {0 I: |5 k' _
        m_fMaxThreadTime       = 0;</P>
    - C0 i( x5 o3 i5 Z6 y% i6 i<>    m_dwServerReliableRate  = 15;
    9 F* G5 A' n7 s  X' S2 x7 X" I6 F    m_dwServerTimeout       = 150;7 e" ]" }; ]: F! x) G" s
        m_dwLogLevel            = 2;8 e6 N7 F% g9 X9 S- G) p. x8 h
        m_pMaze                 = NULL;</P>
    , @# g( D9 Z4 B: f, y<>    m_ClientNetConfig.ubReliableRate = 15;+ x" e! E" H- w% r; _) ?
        m_ClientNetConfig.wUpdateRate    = 150;- j$ h7 @0 P% h3 l3 t
        m_ClientNetConfig.wTimeout       = 150;</P>! \5 H& E1 _( j. ?3 J
    <>    m_ClientNetConfig.dwThreadWait = 0;</P>
    - O; P3 B0 z/ T, j9 U5 @<>    m_ClientNetConfig.ubClientPackIndex = 0;& \" P, |* X8 b* `9 t9 v' k4 l. |  Y
        m_ClientNetConfig.ubServerPackIndex = 0;+ v5 ]/ W8 J& G( t
        for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)" d* X1 O& v: K  Z
        {
    , I5 V+ O' s: f# {' Y& A        m_ClientNetConfig.wClientPackSizeArray[x] = 0;* Y7 `. {, p% }# F' j/ \/ f
            m_ClientNetConfig.wServerPackSizeArray[x] = 0;
    ' F3 g2 a, h- h( V( m  \# F    }
    # \9 h4 Q: E4 \* ?& a$ b  Q}</P>
    6 E- g5 r7 }1 R% ^; U' r
      f3 c$ r$ X3 [8 t2 p<>
    4 t* t4 k4 f' ?, l//-----------------------------------------------------------------------------+ p9 o5 F0 m* T+ n* b6 ~0 [" ?
    // Name:
    8 f) n# O0 b, Y% n( }8 _1 a// Desc: $ O3 g. J: [6 Z
    //-----------------------------------------------------------------------------
    / T  _6 y1 l, ^0 SHRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )! ~, Z3 I( @4 I3 _
    {4 n& s" x9 w9 `" V9 v
        m_bLocalLoopback = bLocalLoopback;- y$ v& Z' C" B. {
        m_pMaze = pMaze;, Y5 U& f* D- v6 n, i6 \
        if( m_pMaze == NULL )
      [" M0 n" t  `3 ?        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>, F2 |) p7 q" f  w7 H
    <>    // Grab height and width of maze" L, S1 E% C, V2 R) ]1 j# h& o* z
        m_dwWidth = m_pMaze-&gt;GetWidth();
    & m' _7 c9 U. q" m1 N# }, h    m_dwHeight = m_pMaze-&gt;GetHeight();</P>, T% `5 g# T, }) r/ Y0 I- ~# S
    <>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    ) X# ]# D1 F! G( Z7 w% z4 G    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>' U  m' d" b3 ]
    <>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts., V" ~5 \/ m7 o. n$ ^* w' C
        if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    6 \( Y8 T$ h5 }. Z' N" R! {* f/ v4 u        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    , p% M- F" D: E( l3 V1 o( }3 P6 D    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )# @2 V! V" _( k# v, U2 k
            return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
    ) g% O, a* k$ D) p) e& `' o, ~<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;7 H' \* a4 K+ a& c3 d' T
        m_dwMazeXShift = 0;
    * N7 s! U" |. ^) W' k. i( \8 T    while ( (scale &gt;&gt;= 1) )( V8 c) A( c6 |4 I
            m_dwMazeXShift++;</P>
    ' k7 a' i1 W7 X4 o% Q7 ?+ a6 M<>    scale = m_dwHeight / LOCK_GRID_SIZE;7 l8 E( s0 ^# b# g6 J% _0 ~2 s
        m_dwMazeYShift = 0;
    0 G9 y2 T' ^* f* J    while ( (scale &gt;&gt;= 1) )
    ! d( |8 Z3 _1 a        m_dwMazeYShift++;</P>
    ; ~; v. x# Q$ z* r0 @<>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||/ e6 k$ z6 y5 ~( T+ P9 K
            ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )- D9 k1 }6 E0 |2 O0 c# \; _4 v
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>
    & Z4 z6 x- p( ?<>    // Initialise the player list& Z) x. k3 U0 J& w# C
        ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );% p8 K% H' [, T# A1 Y
        m_pFirstActivePlayerData = NULL;
    4 `0 ]+ {' R$ t. a2 r+ P9 _% l' M    m_pFirstFreePlayerData = m_PlayerDatas;* d; \) r: H. }# f4 o% S/ Y8 C$ ]
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )5 H) c/ u9 K/ \: R
        {1 J, }+ o, Q" ^
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];
    % m& o$ M5 i1 h. D) v# o        m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
    7 N4 y' r! O$ p3 W. ~1 Z    }</P>
    0 Y& |$ S8 ~9 |; z<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
    5 G1 e, T# T" q- O& M    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];) h' O4 u* V! z/ e& r
        m_dwActivePlayerDataCount = 0;& x+ r% ?$ o) X3 A0 o2 U
        m_dwPlayerDataUniqueValue = 0;</P>
    - ^' ^3 Z& |% d, q& ]3 ^<>    // Initialise the cells
    " d' Y2 b# ?( T  ]4 a: }" u+ K    ZeroMemory( m_Cells, sizeof(m_Cells) );
    / n( k8 y0 n/ t$ W  o: u9 s    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>
    ) s9 U% E/ o8 t1 Q# s<>    return S_OK;2 I5 I, v; Q7 `4 r  u& ^
    }</P>
    % G! C/ S7 w6 `  |) M. a' u+ j: T5 P) `- ], P; d( E
    <>
    7 R# B$ {) a) u7 d4 W9 o//-----------------------------------------------------------------------------
    # X. {) [  H; y9 {( r5 J// Name: 2 {3 ]3 B7 [3 H) s$ B1 |' j/ B5 k
    // Desc:
    / O+ G& X9 U2 o* T0 x. U5 ?/ z//-----------------------------------------------------------------------------( T* i4 N4 c" t# b& F
    void CMazeServer::Shutdown()
    1 J& r( N- [$ A0 q2 }1 g{( W- v; Q/ V9 u$ C* F+ h
    }</P>
    # F7 x* M7 z+ \2 f' d" u: `  g
    - N+ R6 ~, N  P" N2 I; H<>3 k( P4 O. ]* r% x6 H# R
    //-----------------------------------------------------------------------------
    7 |0 q1 W& Z7 z. ]+ ~8 [& ?; ^// Name:
    6 s# {$ t- I3 J// Desc:
    . A* J, S5 l# a/ v//-----------------------------------------------------------------------------
    # b" w3 Q! m7 E, J/ h7 r6 [( o6 ?void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    & m9 I; B4 ~, [0 c6 M{' o9 {7 ]: R6 `, t" q
        m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    ! I1 E! ?# ], }; T$ c                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );! l, ?* b6 }' g+ E8 w6 Z9 y
    }</P>
    0 ~9 L* b: t4 \& _  t# X) P1 m- j2 S6 L; \
    <>) F! _) U6 L" t
    //-----------------------------------------------------------------------------
    7 z" x$ r1 ]7 K// Name: 8 A- i+ B6 D( {: r2 s6 n4 X2 e; t% l
    // Desc: 2 o3 @5 G8 Q2 @% a) O9 r+ \. G& W
    //-----------------------------------------------------------------------------3 P8 N: D" T4 Q1 _
    void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )2 e, H6 w% n8 y' r) v- h6 C
    {
    . s8 L3 F& Y; e    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    6 }3 ^& N& g4 p$ U* c                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    7 `1 w; n/ E2 B4 j$ f3 S* c}</P>
    * T' O7 f" ^5 V1 E  \9 _& r
    $ @4 s# [' B  O4 c0 `; Y<>) b7 Y/ @2 f2 g% [* [2 D
    //-----------------------------------------------------------------------------
    0 x4 Z4 d- K# o7 o8 l3 r; h$ g// Name: 8 W; |- X/ z% v5 B% A0 \
    // Desc:
    1 F, E% l; g3 N$ W//-----------------------------------------------------------------------------
    ) z: B* I: y9 @& M1 l% k8 Uvoid CMazeServer:ockCell( DWORD x, DWORD y )- B) w. e9 X- ~' j- n* n" i8 O0 R  ~
    {
    4 ]. L' z$ C6 \# m# i    if( x == 0xffff )
    ' z, K1 P) q9 O        m_OffMapLock.Enter();
    " H8 L' k- Q  F  m    else6 n( U4 {* O  @
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);3 m, l; \: ], p6 t
    }</P>! q' J0 w3 m% i9 N$ {
    6 g. c/ U+ p( y5 S
    <>' w3 ^+ b6 B" A2 k/ N3 s% x
    //-----------------------------------------------------------------------------8 |' h  k% e. j" |5 [) f1 X
    // Name: 5 `, A- {3 v$ V2 h9 {0 R2 X
    // Desc: 4 K# ^  w5 o, c; U' B
    //------------------------------------------------------------------------------ s5 O9 Z& N$ ?7 k. p7 B
    void CMazeServer::UnlockCell( DWORD x, DWORD y )5 D. Q  `: c5 {5 P! R
    {8 M7 x& M& ]8 Z4 `7 ~
        if( x == 0xffff )
    , F9 ?/ g* M9 D, y( w1 r        m_OffMapLock.Leave();
    4 G1 ~$ c8 M/ t+ E& Z; L    else: @: [  U, B1 y1 ?- v
            m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    - `9 B8 K/ t- \9 b- c& N# x}</P># l) M+ n+ B5 T2 W0 H$ j* U3 ]
    ; B7 D3 y6 \8 O6 p
    <>2 r2 @- A3 v+ p) M9 W; G  J5 h
    //-----------------------------------------------------------------------------! {! I0 t# V' [1 q( m
    // Name: 0 n* N: y7 d" Z+ Y& g- B. a& O
    // Desc:
    * c- G, z7 t9 Y4 x* p; u3 P; h//-----------------------------------------------------------------------------( R; E  K) C, }1 j
    void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    + `. f9 _# s1 Z9 n7 X$ M/ G9 X{' v( I4 R' x8 N+ n, V: U- T7 W  ]5 @
        if( x1 == x2 &amp;&amp; y1 == y2 )% }' O) F# @% q
        {" a, E5 u( D. o0 b: B
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )3 _& G4 b) \9 V4 a0 I
                LockCell( x1, y1 );4 V, c' E6 ~) [# A* a  m
            else
    0 y' l. \  v4 D5 X  G            m_OffMapLock.Enter();</P>
    & z: D6 S) Z! D' S<>        return;# ]0 z4 X2 @2 K" S$ l
        }</P>
    6 c, x* T/ E% J6 u<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    3 O+ E/ l, `1 ?% G) m    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    / g) ~8 h! z0 k" t) N    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;- d$ N: W3 Y6 P9 S1 U6 q4 K
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    4 v% |1 H6 _$ x<>    if( x1 == 0xffff )7 i0 i' e0 `% Z
        {1 a' r- O  O( Q
            m_OffMapLock.Enter();9 r1 o4 Q/ E) z' |* t1 k* {6 i
            m_LockGrid.LockCell(x2shift,y2shift);0 c0 }$ h' p- \! I
        }
    1 m3 A5 w1 w4 e; b    else if( x2 == 0xffff )
    9 S1 s) `/ @( F4 ^    {+ J5 z: x) w9 t5 T2 f4 a+ D: l2 ]$ c0 d
            m_OffMapLock.Enter();- x1 g1 w$ O9 K
            m_LockGrid.LockCell(x1shift,y1shift);" O7 \# [1 l8 X
        }' ?8 f) X- D8 U5 ?+ a
        else
    ! L- J* e" w8 N, g' O    {
    6 q" e. E* j: h: }        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);3 H' v- P) y* l/ L2 D) ?; m
        }
      i/ X3 D0 |6 a! V' g0 F4 O1 V! _}</P>
    + z( C9 V. Y1 Q4 O/ t& s# l  W+ z7 X& M
    <>
    9 [; _: x. C& ~- v& Y2 I- _//-----------------------------------------------------------------------------
    5 y) h0 g" Z' g0 Y- g8 J% U  k// Name: 1 `) \5 v! V6 c+ ^
    // Desc: 6 b" H% Y- {: L( F- P
    //-----------------------------------------------------------------------------0 k7 r* O5 P8 V. W# f
    void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    2 Y* D+ d" O  H4 t; B" a1 W{
    4 r( N" r0 I( ?' n: ?    if( x1 == x2 &amp;&amp; y1 == y2 )
    : [- R" m) R9 E% u# |, i8 K& F    {7 B8 p0 g" P; V8 k; m& `
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    * _+ v, E6 I* ]+ G' h+ M2 O- M            UnlockCell( x1, y1 );& P, u/ c* l' ?  O
            else7 O. J! A8 p) [( {* j7 Q9 O& h
                m_OffMapLock.Leave();</P>
    & P2 {* R) t$ S1 n* w; I- A* t<>        return;
    ! q" V# o* C) x) q; d    }</P>
    " o3 f4 x8 y- p- F1 j4 j# E<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;/ _% h, t  j3 K+ a2 h2 A
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;, T+ }/ b" ^$ `9 d4 l
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;, W! r8 B$ J# k
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    0 c8 X, o! e7 E" a/ Z<P>    if( x1 == 0xffff )
    & z) m5 O3 [& R; q. G1 Y    {9 ^7 q! `( r5 @
            m_LockGrid.UnlockCell(x2shift,y2shift);
    0 a& I, R6 W. m. @8 b        m_OffMapLock.Leave();- s  |9 Y2 ?/ ~" N, O( @' |6 k  O
        }
    & L$ T# U7 ]% I. `' B( K    else if( x2 == 0xffff )& t) \( k) x: W7 b6 w2 W6 X) n
        {
    3 b* g6 g- q0 f  `& ?        m_LockGrid.UnlockCell(x1shift,y1shift);* I7 a0 O- t  d7 x) m
            m_OffMapLock.Leave();3 ?; P# g* `, L
        }
    ' W& ^" |& B# {/ X; S) ]    else 6 E% I6 H: k7 S
        {
    ; ]' |! A* }* M& R) d2 ]0 s6 S9 L& M        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
    2 X! Y6 M% Y. b) R+ S    }  `: [' K( n' X
    }</P>, ?% t0 _& Z" n8 m
    8 y. k- H4 Z+ n% H) r
    <P>3 C6 S0 j' ~) p% ^( x7 z3 x
    //-----------------------------------------------------------------------------
    - B/ v% H5 m3 ?  s* |4 t# k0 G& @* }: m// Name: : n( m# T) X- W, z7 b; y) F
    // Desc:
    0 h) v% v$ T  \; S1 g//-----------------------------------------------------------------------------7 f! i/ K3 o$ N4 [6 C
    void CMazeServer::OnAddConnection( DWORD id )& @8 e1 H2 K' ]
    {2 R' W# J3 |, {0 M% R
        m_AddRemoveLock.Enter();</P>: L3 o& a- Z/ B* k3 [6 D0 n
    <P>    // Increment our count of players+ H4 b1 ]. e  K5 s9 k
        m_dwPlayerCount++;6 d; I- b: o" M
        if( m_dwLogLevel &gt; 0 )
    - R3 _& F6 z" L8 v& g8 j4 @, R    {
    * N* S4 s$ n2 h, g1 o$ _, D        ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
    ) V+ a+ k' p5 j" C1 `        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );- h5 D( D/ Q0 A
        }</P>' F2 ?* a) T' A4 l+ n% n
    <P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    9 V* W! `4 ^3 O6 r0 |  P, l9 O( e        m_dwPeakPlayerCount = m_dwPlayerCount;</P>5 s/ J$ b* |9 _
    <P>    // Create a player for this client0 C  P0 x, ]/ b9 P
        PlayerData* pPlayerData = CreatePlayerData();
    # U8 ^# G$ _) {$ ~# h; L    if( pPlayerData == NULL )* I% g1 {  s+ e
        {, i" T* L& o% t3 P0 a
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
    - N' k# u, _, O) M        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );4 S$ e+ k- y" h: t% z, |
            m_AddRemoveLock.Leave();
    $ d- l+ P, W  f# j        return;% O" v( Y+ F8 `! T5 F& T
        }</P>
    " E; ~& a- y8 W! Q<P>    // Store that pointer as local player data
    4 A) Z# y! R' y; @    SetPlayerDataForID( id, pPlayerData );</P>/ h. q# ]0 i  W3 K
    <P>    // Grab net config into to send to client0 i, Y+ H: m1 f; g
        m_ClientNetConfigLock.Enter();
    * H# t4 {5 Q' c! F& h+ I6 p    ServerConfigPacket packet( m_ClientNetConfig );3 c* B' f  Y3 X) X! {
        m_ClientNetConfigLock.Leave();</P>/ t& J/ ?  P# j# @8 V7 ]! {3 W$ P
    <P>    // Send it* T1 J3 U5 F4 x
        SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>
    * }. Y4 c! V) @( s+ ^<P>    m_AddRemoveLock.Leave();
    6 J! X* b. A' e' c}</P>6 S1 M  {# z9 A7 R1 J( u  K
    " r. S  P0 ?. H8 {% ^
    <P>
    7 n0 b; H) \  ?( I7 g: Y! D//-----------------------------------------------------------------------------( A6 b3 p, a4 }% i" }$ I. z
    // Name: / V6 |+ i3 ?- }# h4 g& J+ ^: Z( C/ r
    // Desc: : [3 L7 |) s. J( q7 y5 o
    //-----------------------------------------------------------------------------7 W& d3 z4 N" |( @5 v
    void CMazeServer::OnRemoveConnection( DWORD id )
    ! Z, Z: d* H  e: `4 C, d: y: l{
    4 C, s: D4 L" v; x    m_AddRemoveLock.Enter();</P>4 _3 W+ I! k& S3 q
    <P>    // Decrement count of players
    3 p) b/ z$ ^# K0 P: a. s" C8 M    m_dwPlayerCount--;</P>
    ! j# [3 b% L& l+ N5 u' K  T! C<P>    if( m_dwLogLevel &gt; 0 )
    ( X7 j  D, J4 v: T    {
    & Q0 d5 j+ l( A9 e6 s* j4 W2 [        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
    + K1 B) `. o8 C7 {- n        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    6 J: J- R  y0 a; `/ `* e  [) \    }</P>
    ' x( l* @7 T; t( z  v<P>    // Find playerdata for this client, a; j! d7 V5 u$ U
        PlayerData* pPlayerData = GetPlayerDataForID( id );0 r. S$ ^' d" d& N
        if( pPlayerData != NULL )% R+ e. T+ c, ~/ }6 R* x
        {* L/ b8 \- Y. M/ d, f+ I" }6 J
            // Destroy it) `5 F0 V1 b+ N7 d
            RemovePlayerDataID( pPlayerData );3 U* \2 i) Q, ~6 `! u
            DestroyPlayerData( pPlayerData );
    ( G5 T1 A# w3 D. }$ k2 d+ b$ M% X    }</P>
    1 L, ^) g1 }6 x8 G<P>    m_AddRemoveLock.Leave();- J4 W; V! B3 i, v
    }</P>
    6 y; |" ^/ a8 A
    5 Y- |" v" C4 F- k+ s<P>
    1 d+ f/ K) r& V) H. X# }( v; A8 G3 {//-----------------------------------------------------------------------------
    / P" _' ~: N- _4 F# O  N1 z2 v- l// Name:
    % X, e0 r# n# L$ u: l// Desc:
    3 i; U  g# D8 \9 l" [//-----------------------------------------------------------------------------
    + b# X. r4 F+ m! h- PHRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )4 e% b- ~6 l1 z0 Z6 }" C
    {
    " K' y+ [, o6 B& H5 {    BOOL fFoundSize = FALSE;</P>8 @9 p: Y! u9 n* I1 T7 s
    <P>    // Increment the number of thread we have in this process.
    0 q: f+ T4 A: g    m_csThreadCountLock.Enter();</P>
      G! k  \- K" t8 R' u  o2 n* r<P>    //Get the start time of when we entered the message handler.
    3 e4 y1 @3 ]) s/ x9 B    FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
    + \! m+ z4 b% z7 P. f- a<P>    m_wActiveThreadCount++;
    : {9 |7 _1 V, n$ f' S    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)
    6 F5 f" i6 }( [: |  I, U; H3 `        m_wMaxThreadCount = m_wActiveThreadCount;) F1 |7 f+ U8 O/ ~8 a1 s9 R$ T
       
    $ U& m& k! C# I0 W) B1 S4 G" S    // Calculate and average.
    : Y6 g1 P8 a* b4 A  s    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
    + g. ]0 z/ ?9 J    m_fAvgThreadCount += fdiff/32;
    0 \- p5 W% J% _9 Q( I* Q9 a% O9 _/ ~  Y3 L   
    1 k# Z4 s9 w0 ~% o  W* g3 V    m_csThreadCountLock.Leave();</P>
    + O3 g) {/ y3 D<P>
    7 Z  ], V6 `* ?2 h3 d    ClientPacket* pClientPack = (ClientPacket*)pData;( w, P% h" A+ K2 ]' R. W* C
        switch( pClientPack-&gt;wType )
    + L" [, Y# P9 n    {
    ; F) {5 ?5 M5 t: O& \        case PACKETTYPE_CLIENT_POS:
    : |9 g+ t! d6 }/ e            6 F- B7 }- E$ m% s9 m, P6 W6 B
                // Check to see if the packet has a valid size. Including
    & ]7 E8 ~6 N) E! l. i/ K) d            // the custom pack size.7 O! X# w3 J4 K8 `% l3 ?8 K( A
                if( size &lt; sizeof(ClientPosPacket))
    6 @9 B+ \( a+ `3 C4 ?0 R                fFoundSize = FALSE;3 J' u/ J2 g+ B
                else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))
    0 O  g# q; N5 c* k                fFoundSize = FALSE;
    ' ?6 _$ `& A2 a" l, w+ w3 F            else
    * `. N( t5 f3 K7 b                fFoundSize = TRUE;</P>
    . y9 U9 B" T" d) N<P>            // If valid sized packet, handle the position.
    # B3 C* A- D$ j0 U            if(fFoundSize)
    " m+ k5 _9 C2 _                HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );
    . u7 q! R6 |4 `* A" C            else
    * t$ U( R2 q8 P2 k                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
    . e6 W/ H% v7 [& L- g<P>            break;</P>
    : L- Y) G) a! E# l3 B3 d; W<P>        case PACKETTYPE_CLIENT_VERSION:
    ) b$ X; J- Z6 b, F            if( size == sizeof(ClientVersionPacket) )
    , R% Y: z, f, ^. F! P) d                HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );
    % Q7 {3 J+ Y) n            else
    5 R; C; l( l2 h  `- ~" F- w                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    - h6 u& L+ m. b9 t% c9 s. x. i5 Q& Q            break;</P>1 I* R8 S. {5 |! _" B
    <P>        case PACKETTYPE_SERVER_CONFIG:</P>( s( W# @. K7 O2 _6 }( ^4 H( p, W
    <P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>  m# y% E+ L( c! f
    <P>            break;+ ]1 Q" A5 n- p/ Z) J
            default:0 w/ C4 ?$ `2 ]$ F) i5 y
                HandleUnknownPacket( dwFrom, pClientPack, size );, y7 i6 J$ k3 w0 ~* J0 ~6 s) H
                break;
    * w3 q9 e2 H% b0 S    }</P>
    0 t. Y% {1 P" X; x" l) B<P>    //If the user wants to hold the thread, Sleep for given amount of time.
    6 I: A9 f, G; y9 z- F+ }1 g    if ( m_dwServerThreadWait &gt; 0 )
    " A8 h$ B9 Y2 Q% a    {
    ; Q+ p/ o! d( l# o- Q8 O        Sleep( m_dwServerThreadWait );' I  ]1 m: Z$ F
        }
    - B$ W% s& w. `6 g   
    6 R' R0 }9 s8 j5 O8 _    // Retrieve thread data for this process.& @9 L2 z% l7 t& j
        m_csThreadCountLock.Enter();</P>
      R0 }% g6 ]* P5 I. e3 i9 ^; e; ~<P>    m_wActiveThreadCount--;</P>% `+ |! f& A2 f. `
    <P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;. d% A; A. k! N/ H$ J. ~
        m_fAvgThreadTime += fDiffTime/32;</P>
    3 a6 j4 C# B; H% ^* W, s! M<P>    //Get the Max time in the thread." W, N" E- N1 h
        if ( fDiffTime &gt; m_fMaxThreadTime )
    4 {" Q* z5 T2 D. O/ I( P' e) [3 n    {9 b0 u7 k7 w" H3 k3 T# f
            m_fMaxThreadTime = fDiffTime;; ?8 E0 ]8 k5 s, m0 E3 y8 F0 G
        }</P>
    8 k' K$ P( }& X7 m& ~" d<P>    m_csThreadCountLock.Leave();</P>0 N+ V2 z3 X8 [& a3 |
    <P>    return S_OK;
    % t- t7 y( C" X, M) o" e; D, s}</P>, l  [- o- Y  L9 |+ N/ ~

    & F3 z4 e2 V7 T<P>//-----------------------------------------------------------------------------$ d5 i5 H5 U9 t) u3 M. b
    // Name: 0 S3 k6 i9 Q9 M  r
    // Desc:
    3 m. c+ F7 f0 H! Q2 S9 T//-----------------------------------------------------------------------------) p5 E% {( t3 S( U% U
    BOOL CMazeServer::IsValidPackSize( DWORD dwSize )/ }7 Z# _6 L3 D3 S* W  L5 s: t- J
    {! C/ y1 Q* U# b
        BOOL fFoundSize = FALSE;
    , f1 l  c6 @2 ~. w0 U- z; a    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;1 [7 X5 I5 N# @! t' x1 B1 `. \3 V
        ' Q# F+ h8 Y# G3 L2 P
        // Check through the array of valid pack sizes." a. F" M: {9 C2 ?
        if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])% C/ v' S, R" v" s0 G% h1 z
        {! ~+ I: b: ^* A2 _2 \( z  x
            for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)
    8 {& x* Y" E# b9 a+ j. `+ |        {0 a) I: l1 p" ?; i9 U2 h/ a6 Y
                if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    # c- q  W  [& F3 `; f5 V3 N            {' V/ ^$ J6 n! l4 h6 w! \) ^1 ~6 v
                    // Found valid size in the array.
    4 R% G9 @4 C" F8 J                fFoundSize = TRUE;
    * d' F: F7 |9 C. c1 ~& D* i. K                break;2 d; _3 k, j5 ]" Z
                }3 H  D# E  |; I, v
                if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
    ( {/ C# B" I0 t+ e: h0 H        }
    $ \3 `5 |2 ]; P+ c: S4 G, v    }, Z+ F4 P: ~. z
        else% G4 `6 l) J; y+ y$ M" A1 F7 r
        {0 R6 ~- _) G3 ]6 c9 p
            fFoundSize = TRUE;
    * g. O0 L/ H' I- U    }</P>
    5 P6 x; m) }$ k<P>    return fFoundSize;6 n2 G8 E0 x* E
    }</P>  X7 w1 w# `: b6 Y. v
    <P>4 z7 G: R+ c1 r# `  d+ u* p. L3 m( j/ |
    //-----------------------------------------------------------------------------
    6 e$ E- z  h( J! h/ t# e4 y8 ?// Name:
    6 A) t1 y* N$ u: O0 H; ?( y// Desc: ( e# ]# d' L1 j, S3 L3 B- b6 s0 f
    //-----------------------------------------------------------------------------
    2 a2 d( e; x/ @3 {% M3 m8 l" Kvoid CMazeServer::OnSessionLost( DWORD dwReason )
    ' g1 x8 W: W4 k" M$ i! d{+ n8 Z% `3 [% Q# B( W+ C# I4 M5 u* J
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
    5 o: ?6 t" S  R0 T3 q  B4 `}</P>: c2 D1 a' o* M$ m( ^  \9 _' n7 o0 s

    6 i( T$ n% K0 p  z* d<P>* X4 C& {) P3 M9 k
    //-----------------------------------------------------------------------------# u3 {  L' D2 C9 B7 j$ ^4 A; h; s0 t
    // Name: . d0 ^" V) B8 L' c& R: }1 a+ R
    // Desc: 3 d8 {) l4 Y4 L) g3 c7 y6 ?
    //-----------------------------------------------------------------------------! m5 o+ y3 i1 f* m" S
    PlayerData* CMazeServer::CreatePlayerData()
    % b1 d) n. c! W' ]{1 Q. [! d# d! ^* @  q2 l
        m_PlayerDataListLock.Enter();</P>" v7 F# @5 B4 f5 g( S& I0 N, E
    <P>    // Grab first free player in the list  N  g5 E5 ]! x5 Y5 n1 m2 h
        PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>+ Y( I: Y; ^8 a( h- d! T
    <P>    if( pPlayerData )
    ! u! n" g8 a1 `    {
    4 b5 ^. f2 p% b3 x# q        LockPlayerData( pPlayerData );</P>) X- s7 k  z# Q: u8 y4 y1 x: [
    <P>        // Got one, so remove it from the free list! D- p6 D! R5 M* }$ @: M% ]/ K+ f
            if( pPlayerData-&gt;pPrevious )7 ]7 J0 D2 ?" A* p: b# |
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;2 s3 c4 I' ~" w
            if( pPlayerData-&gt;pNext )
    2 q. B* H7 H2 z( O8 J            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
      o# r+ m4 t1 [        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>* u. e$ b3 o" D, I
    <P>        // Add it to the active list
    # h) \& y1 X7 a        if( m_pFirstActivePlayerData )
    0 n9 Q% ^+ m9 g4 N% l            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
    $ n# F+ ~$ X6 ?* P        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;
    ( T& V- h4 c1 w, S7 O" m. I  w+ w' \        pPlayerData-&gt;pPrevious = NULL;# L2 ]- y; V3 y$ @; T$ f
            m_pFirstActivePlayerData = pPlayerData;</P>0 e' f1 j8 z- Z. V8 H3 ^
    <P>        // Update count of players5 l0 a' {1 g2 D4 Y
            m_dwActivePlayerDataCount++;</P>3 U- y" ]  ?! L. ]) K1 o6 n; O
    <P>        // Generate the ID for this player0 S" J3 _7 U4 ~
            m_dwPlayerDataUniqueValue++;
    . R+ O2 W$ O8 }6 ^8 [6 E, q/ ?        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
    0 I' x1 B, ?& W9 c# @( G<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
    7 u# f& S4 |# u! _' M        pPlayerData-&gt;NetID = 0;% \! W8 X% t6 d( B) ?4 J& }
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>6 C' `: q0 f( [
    <P>        // Insert into the "off-map" cell7 A' G1 H8 @9 D9 G9 [- v
            pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;* S) o- s1 @8 D3 z3 W+ V" ~* R" a
            pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;
    5 ^, H/ J$ I1 P" ^4 `8 i        m_OffMapLock.Enter();6 K" Z) h- D8 `. a! t
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;" L0 u7 n6 Z2 \+ K& Q8 e0 ?
            m_OffMapCell.pFirstPlayerData = pPlayerData;  j  P/ e" f! F. s/ o) s- i7 ~
            m_OffMapLock.Leave();</P>
    ' y6 e, V0 v4 e& b8 w8 Z; N<P>        // Mark as active
    3 J& U0 t$ I1 ?* I# K4 u/ z7 T( \) ~        pPlayerData-&gt;bActive = TRUE;</P>4 Z2 U/ n9 _6 S4 s# {
    <P>        UnlockPlayerData( pPlayerData );. A0 `1 y& Q3 N% c; S
        }</P>, A  X' [. W; O
    <P>    m_PlayerDataListLock.Leave();</P>
    - l' M2 \6 X9 @<P>    return pPlayerData;) Q  K* Q4 S: A
    }</P>" x$ I4 w5 v1 y+ X. t6 R) s( k

    ( y( \8 N2 t7 I<P>8 R. b# |* |% U3 x
    //-----------------------------------------------------------------------------6 o# d2 N5 N# _! Q, d& @
    // Name:   `) f8 H& J8 H
    // Desc: * Q% `: [0 b, r
    //-----------------------------------------------------------------------------/ A# [3 @! C( k, f0 T: k
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )
    ) R6 \2 Y" ]4 `" K' U8 O{
    ) k( {1 V* S+ L0 a* h$ i0 V    m_PlayerDataListLock.Enter();
      ~" v+ |4 R4 |) L; A" W/ Q9 g    LockPlayerData( pPlayerData );</P>( O1 R5 A( ]7 H4 N2 o
    <P>    // Remove the player from its cell: {: ^( n$ z4 G( t" H: e
        RemovePlayerDataFromCell( pPlayerData );</P>
    " F% X; y! U  E% X. \+ H* A1 a<P>    // Mark as inactive
    2 H+ N/ e" B* U' f    pPlayerData-&gt;bActive = FALSE;</P>
    9 H7 m) |8 Z! h/ D! J<P>    // Remove player from active list0 v% o1 p! m; W2 H
        if( pPlayerData-&gt;pPrevious )
    1 O2 ?- b# R5 S: ^) y9 I        pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;6 F5 z; _" C$ y' O2 p; P1 t
        if( pPlayerData-&gt;pNext )5 f- F0 t- L) Y3 f* X9 C
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>
    7 H8 t/ k( _9 ]<P>    if( m_pFirstActivePlayerData == pPlayerData )8 g5 `5 S, `5 ^/ b8 |+ C
            m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>9 E- |8 e% F( p
    <P>    // Add it to the free list5 j- ~* f* j+ U9 G- O6 U+ S1 p
        if( m_pFirstFreePlayerData )1 y5 P7 h% [  b- [2 L9 c5 R: I
            m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
    ' J+ z9 V, J5 L/ P3 q$ F/ Z# K    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;
    9 a5 @7 {8 L$ V9 Z6 U; K    pPlayerData-&gt;pPrevious = NULL;
    # t7 r9 i+ d1 _# f. q    m_pFirstFreePlayerData = pPlayerData;</P>
    ( P- b* V# W; n9 b0 ~<P>    // Update count of players
    8 ~+ U, G% L8 f) S    m_dwActivePlayerDataCount--;</P>5 n' z( r% A2 P6 W
    <P>    UnlockPlayerData( pPlayerData );+ d" _( i( ?% j( G* C# ^! D
        m_PlayerDataListLock.Leave();
    & j% q8 b; p1 @+ V5 B& [: d0 t}</P>
    7 m+ ^. K& H% ~! I( x# A8 X
    ) ?& |3 s. f% [4 M<P>0 ?6 C4 l, I" g/ `; ^+ ^, z' k; D
    //-----------------------------------------------------------------------------
    " W( F- x& S# n// Name:
    6 R* T, \+ W; O// Desc: 2 _3 s3 B  {' e9 A: F& G
    //-----------------------------------------------------------------------------
    5 C/ z, t; J. x+ u' `# yvoid CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )- C& g, p+ ^( ~, y
    {
    . U; ^" O! W8 T1 I    // Lock the player/ d1 a* L( T% ^/ r* b4 ~5 _
        LockPlayerData( pPlayerData );</P>
    3 U" d1 j" R8 e4 T0 x& t<P>    // Lock the cell the player is in
    3 X! O% ^1 Z5 e. v" t    ServerCell* pCell;
    + P! e- t( ~8 `    if( pPlayerData-&gt;wCellX == 0xffff )
    " @5 }8 ]) |' d0 @    {
    3 Q, p6 J) }4 ~$ A        m_OffMapLock.Enter();
    6 W8 V4 G. L/ H0 _% ~8 C/ p+ O* E        pCell = &amp;m_OffMapCell;
    " ?# o4 R+ b* C% s    }
    2 z  ^% C4 s- R4 p. G5 o    else
    6 i9 J3 F! {; |7 \9 Q( N) o3 v: C    {
    0 I/ }$ f; S& _( s, N9 ]7 R        LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );0 v7 |$ o  L/ G# c+ T4 i; D( R4 D( Q
            pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
    * @2 d% r: y' J# L4 F) ~    }</P>' c0 }% ^9 f/ P. x
    <P>    // Remove it from the cell1 A! O* C3 P9 y! B
        PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    8 ?( F( j) \( W# n9 X# c    PlayerData* pPrev = NULL;
    : P0 ]: W9 y$ g, D! b! Z    while ( pPt )( a9 T( F# g% a# S- V/ o8 y
        {
    ! D( r7 O+ d2 r9 }5 Z        if( pPt == pPlayerData )
    : Q1 D' b% f. Y% X0 a) d        {3 {( t7 q& j$ i/ c8 N4 Y2 ]
                if( pPrev )
    6 w, H/ C1 `. Z/ U                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;* \/ A6 i9 D- U4 l
                else# F8 h3 L" Q  B/ ^  r
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>2 |" z2 d- o8 E
    <P>            pPlayerData-&gt;pNextInCell = NULL;
    6 _7 q; B2 v- G2 t4 }. [7 B0 _" e# I            break;! |9 {( Y9 ~9 i( U7 M
            }. U6 Y9 _9 Y& h$ k) A' {; o4 {% z
            pPrev = pPt;' j( `; Z$ P& ~9 j& x) L
            pPt = pPt-&gt;pNextInCell;
    : S+ d- k5 u. H; g8 F    }</P>
    6 C' D- U5 f& ?( Q<P>    // Unlock the cell% \/ d) W) D' T& _6 a
        if( pPlayerData-&gt;wCellX == 0xffff )' U. a$ r" d- g) n
            m_OffMapLock.Leave();
      q0 x- Z: r/ J1 k    else
    : `& d4 K5 W5 D8 m7 J% ~9 f9 J0 A        UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>
    3 J: k! [$ |3 |9 {# A3 D% j2 ^<P>    // Unlock the player7 K6 Q- W8 U! I; V+ P
        UnlockPlayerData( pPlayerData );) }. n  t3 k) C" {8 q& n$ w2 H
    }</P>9 [* f2 B' a( a( z' w; Y
    8 d, `. ^& B+ t0 t' ?: k
    <P>/ E% a% V5 k1 x* ?- V' q' {
    //-----------------------------------------------------------------------------
    / V! {5 s( |1 J5 l$ C// Name: $ t) x# }  F3 e5 a8 P+ G
    // Desc: " i" X( g# h) V3 O6 V. f
    //-----------------------------------------------------------------------------: X& d% Q/ P0 r
    void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
    / ?1 y5 F! j. w0 b2 w{' f9 [+ b. f" v2 E; I
        ServerCell* pCell = GetCell( pPlayerData );
    ( {' f: e: x5 R8 ~    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;8 b7 ]7 W' ~( J- ?+ |
        PlayerData* pPrev = NULL;
    . m% y' z2 G5 ^% t) `: @    while ( pPt )
    & O4 ^) y3 ^2 f& v. J3 V% O+ F    {
      q% u+ m+ j# {7 {2 ^0 @" @3 z        if( pPt == pPlayerData )
    " \' J) a" h( I  z+ g        {
    6 v- }# z4 o3 u9 Q            if( pPrev )! W9 i" n  _, g$ s
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;, d* T$ s4 ^" K. Q4 P
                else# m: n, n  T' Q2 E6 D' ^* i7 Z* @1 J, ^
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;
    + ]0 l/ X( \' S( r. J+ q            pPlayerData-&gt;pNextInCell = NULL;  f/ V+ Y8 a- B* [5 I
                break;
    6 @; W1 J9 J1 p- }: R# h        }2 _9 [# n8 ?+ N  z# w: A
            pPrev = pPt;
    ) r( _0 p9 m' A- r. C        pPt = pPt-&gt;pNextInCell;- f& t. ~" z6 W5 K4 ]* z3 X% C
        }
    ) ?7 d6 b+ @( x  z# p! [) O% F}</P>
    $ q, |0 x! R- z- y" L4 c6 H  J5 b) c6 [8 U" p) x
    <P>
    % c5 u. x& x6 j//-----------------------------------------------------------------------------  I( s- @, x( X7 W7 Y/ y
    // Name:
    3 t4 r: [2 Y) A: A# M# {// Desc:
    4 v# L, {8 m+ v/ J//-----------------------------------------------------------------------------
    $ t" d5 ?) }1 _! U. u7 Cvoid CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )
    * s2 ~, `- f$ u8 K# O# A{
    1 Y3 w% n, t  ~3 C    ServerCell* pCell   = GetCell( pPlayerData );0 |' [* D$ {2 N( H. e% b
        pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;0 X/ y  [7 a6 X3 u
        pCell-&gt;pFirstPlayerData = pPlayerData;! ?, U6 _) o' t
    }</P>: s' B6 x' I$ ?' z
    . k  H# t! f  a
    <P>
    . A4 b* ?5 d' [; G8 U# d7 M//-----------------------------------------------------------------------------/ f4 x% g" B7 L
    // Name: 7 E. x& `( S3 o1 y' F6 {7 e" T
    // Desc:
    4 B8 S: }: P* Z  i* l+ [3 r( _//-----------------------------------------------------------------------------% `# S. g/ b( B' @
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )
    5 r% f0 c8 x- h) `5 v& z+ D$ {{
    - v+ K: y3 w9 e, p& u- t' B    // Grab player for this client and lock it
    . n$ T, R/ r0 K' H. _    PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );
    ! d+ D% p, |9 c9 F2 M: i1 _    if( pFromPlayer == NULL )# s1 |  A9 d+ ^& j  x, `4 ~
        {
    ; R4 U( E9 K# H        if( m_dwLogLevel &gt; 1 )/ E8 |$ j* L. L6 V8 F) ^6 }
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );# |3 e* Y! F" S- c& z
            return;
    ) k* E6 }  G; u4 [    }</P>
    4 Q6 G  ]9 h' u3 `* [  f  d/ r- `<P>    LockPlayerData( pFromPlayer );</P>
    " v6 j& G# t9 F; g9 @/ @1 S5 Z<P>    if( FALSE == pFromPlayer-&gt;bAllow ), X- q7 [+ A. `( }% w
        {2 k% x( {- S* W& [1 X
            if( m_dwLogLevel &gt; 0 ): Q  ^3 x! C; @/ K, N, k5 ?
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>+ [, Z- ]- H; D* L$ z
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );8 ?! u+ Z' Z# I
            UnlockPlayerData( pFromPlayer );: {- S, V0 b, t6 Z: c4 r$ V. ^
            return;$ y/ r1 p8 t4 Y1 i" V2 W9 U
        }</P># h$ [$ Y) ^% U7 ^7 H
    <P>    // Compute the cell the player should be in now
    6 @. @  c* k" f- o0 N% j: Q    DWORD newcellx = int(pClientPosPack-&gt;fX);, U; ~( g* }. b1 J, |4 K
        DWORD newcelly = int(pClientPosPack-&gt;fY);
    ! b% I3 r, F2 H: F  D    DWORD oldcellx = pFromPlayer-&gt;wCellX;5 _7 ^/ F4 B' q. _& H
        DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>1 R# Y$ B. E! ^) R9 e" b4 ^* H
    <P>    // Have we moved cell?$ p" K9 J4 _! A1 G5 w" b8 M7 `
        if( newcellx != oldcellx || newcelly != oldcelly )5 o0 |+ y) ]" P9 O/ H" v
        {, [, H$ v9 }2 C; u# o) F
            // Yes, so lock the pair of cells in question
    5 h% W( q: e4 E) Z0 J6 n3 V        LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>2 @7 G) X6 @. d) K* b
    <P>        // Remove from old cell and add to new cell" i3 C& C8 q1 Z' c. [$ w
            UnsafeRemovePlayerDataFromCell( pFromPlayer );8 Y; U1 j1 g/ r
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    % l- m$ y- O; G# u* q        UnsafeAddPlayerDataToCell( pFromPlayer );</P>
    ; U! ^' g1 b# c  o3 l* h) b: H<P>        // Unlock cells
    & Y6 @  F1 G: K        UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );* F8 X. x4 x6 y& u5 N# `
        }</P>
    # Q4 \  a6 k. r4 C3 ?% s" v* C+ ^<P>    // Update player position
    4 e" F: d% D3 N& c/ U+ j    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
    # ?+ f  D! l  K0 u# Q  o6 M    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;) {' Z$ g% f: O+ p8 |2 O
        pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>9 S$ J6 c. g) d" o8 T5 E! Y- I
    <P>    // Allocate space to build the reply packet, and fill in header
    & _' z8 r, J2 c7 t    DWORD dwAllocSize;1 a- {. [( Q+ `" T( H' K
        ServerAckPacket* pSvrAckPack = NULL;</P>6 [" i2 o! i$ `1 {2 [4 \4 Q+ |. n8 e
    <P>    // Begin by allocating a buffer sized according to
    0 o! ?% W% Z" \3 u' b5 y2 _+ k    // the current number of nearby players + 4.  This will give
    0 e& E6 t- S* K/ v& G    // a little room for more players to come 'near' without resize" y/ d% G. `, h& ?" g! _+ D; g( r
        // the buffer.: M' \/ _+ ]0 a) A" h3 o  w6 Z
        DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>. I0 ^# D. ]" D' f
    <P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    " T- K9 o. V4 V4 Q) j# d7 M    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );" W5 S; G1 c2 Q7 G8 Y
        if( NULL == pSvrAckPack )
    : i2 n, ~$ t. J) Y0 ]4 Q% q    {
    0 z) Q# z2 i9 m" B0 W        // Out of mem.  Cleanup and return
    ( S! L* I: g; C0 h        UnlockPlayerData( pFromPlayer );
    * g! J/ S6 a. x% R# t8 p/ @        return;      
    2 M$ g# i2 E' {    }
    ! r2 w- h. g% L: @    ZeroMemory( pSvrAckPack, dwAllocSize );</P>
    % \& Q. U% R, `) ]% F<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);
    ( l7 ~4 u6 Z7 ^7 h; O- S    pSvrAckPack-&gt;wPlayerStatePacketCount = 0;. f1 v2 R7 \. n& P
        PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>  {9 Q  Q! M) C6 T) X
    <P>    // Compute range of cells we're going to scan for players to send: t6 y: H3 u& p# h6 u4 g
        DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;
    : p4 S9 q& J+ t) D( ?6 M    DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
    * [7 D" E, }* b5 C3 L9 \    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;, v3 {. W& l$ g3 {2 J
        DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>
    , H( w. b1 ]5 G7 T5 W<P>    // Lock that range of cells7 q# t8 g! ]) u( H
        LockRange( minx, miny, maxx, maxy );</P>
    " [4 m4 i" `# O7 K<P>    // Scan through the cells, tagging player data onto the end of
    - A4 N9 s8 p5 W) v: G    // our pSvrAckPacket until we run out of room) ~) @1 ?  ?! m3 D
        for( DWORD y = miny; y &lt;= maxy; y++ )2 s4 q/ c( C: F: S
        {
    2 {' q3 E% g# [% o; f2 N# \        for( DWORD x = minx; x &lt;= maxx; x++ )
    ) |# {/ v: F- a        {5 [! j: x2 x( W1 p
                PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;; }9 R( k  p4 U% U1 ~2 n7 D9 v
                while ( pCurPlayerData )% h1 ^% S  m+ I, H- U
                {  ?$ b6 O  Y. Q' s( f  f
                    if( pCurPlayerData != pFromPlayer )
    : Z# y$ M& `" O# Z3 H' @6 M                {" B: Y' r: V" Y/ H0 ~( L5 x' c
                        if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )! O9 w5 N0 k  l2 z4 K  `( Y
                        {* ?2 s6 h6 T( \# b
                            // Make sure pChunk is where we think it is
    6 v% s+ m% r$ }) B; C# N6 @                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>4 _$ r3 `7 V! ?0 G: P
    <P>                        // There are more than just 4 new nearby players, so resize the
    ) A1 n6 ^) s7 G9 R  g( Q1 }- a% y                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
    3 s0 z/ d$ W! a4 p0 Q/ @' b# X7 N                        dwMaxPlayerStatePackets += 16;8 e" |  Y6 k& y' d
                            dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);( u9 }& l" V" A# |+ r+ t
                            ServerAckPacket* pNewSvrAckPack = NULL;- n3 w1 s( ^9 J4 R% N9 {
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );( \$ m- u; |7 x+ u% \
                            if( NULL == pNewSvrAckPack )
    % B) S# M; X7 O6 B; z# P/ V/ u                        {
    0 ~2 I) Y  x; E% q' _( u# I, W                            // Out of mem.  Cleanup and return
    $ n+ d$ C; e4 \; S8 g                            free( pSvrAckPack );
    + z' j8 W2 J$ K, {& H                            UnlockRange( minx, miny, maxx, maxy );$ I+ \/ k* `: S  R, Q. b
                                UnlockPlayerData( pFromPlayer );
      [' D8 z2 D8 P. n/ f) y                            return;      
    , }; E3 `( M+ S: ^* V( A                        }</P>) D* [0 v' U) t  N. \% o
    <P>                        pSvrAckPack = pNewSvrAckPack;
    ' ^1 b+ n$ c2 v& G5 P+ n8 r                        pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
    1 J3 v3 s4 N5 y! c+ q1 J" q<P>                        // Make sure pChunk is still where its supposed to be
    ( H  o! t, G! g% \% m& Z$ N                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );$ E: L: W6 M" y) H
                        }</P>: K8 s0 e- J1 W, _
    <P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;) y6 W& \) \0 Z) U
                        pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;$ ?0 l) \) p6 A! c' P# V
                        pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;
    . t1 Y7 h* e' a7 V                    pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;* A1 s" o* |6 L6 w( n- Z- n! M' J
                        pChunk++;
    & u  `& y5 K4 s7 }3 ^1 c7 ^                    pSvrAckPack-&gt;wPlayerStatePacketCount++;% ^+ m. z6 ]! K5 B  ^
                    }2 w% h, K. b' `# ?) x- X% Y
                    pCurPlayerData = pCurPlayerData-&gt;pNextInCell;9 i  t& P+ _+ |1 z# t$ U7 y8 f
                }7 x4 h. `7 k1 q3 W% i9 c
            }
    1 M) Q6 ^% o- O. f5 a# r. u, S3 k    }</P>
    7 S0 |; [" I& U: p5 Q<P>    // Update the dwNumNearbyPlayers for this player) B" Y: l% C9 o, R, M
        pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>
    % n  R/ E3 H) m7 s<P>    // Unlock range of cells2 F$ T; J' Q6 u9 x, P' W
        UnlockRange( minx, miny, maxx, maxy );</P>5 n% t+ G# Y3 \/ t
    <P>    if( m_dwLogLevel &gt; 2 )
    $ f3 L3 ]& s/ T- s    {
    9 S* o) ]/ P: e, b        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );( F4 |# f& z0 X1 n2 Z/ i
        }0 ?' J4 V% s! U# e
        else if( m_dwLogLevel == 2 )6 P& s/ [' v' e; i0 D
        {
    3 z/ M" \) X5 p& |8 q& L. V0 n9 W        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    . n& U- e4 y; y! P/ u$ R7 y1 n4 w/ e        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )2 i# E# i/ v: F) @
            {
    ; H2 I0 O1 A! W9 l            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    ) y/ @) e( P4 Q, b. [' L8 T' z            pFromPlayer-&gt;fLastDisplayTime = fTime;
    : f. ?- D( {. B) f7 i! ^) B        }8 \2 k! v) P, V3 R  C6 v
        }</P>1 R7 |. c' }% M7 a& d. q7 u8 N
    <P>    // Unlock the playerdata0 Q; s' M& y" z& u# l
        UnlockPlayerData( pFromPlayer );</P>
    , |$ I4 h  p$ `$ w4 s+ g<P>    // Send acknowledgement back to client, including list of nearby players ( ?( ?; H7 ?; z0 f4 j
        DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));6 v$ w* V8 F, W5 M+ `+ b

    5 }2 e4 n/ j) y/ p. B    // Pack the buffer with dummy data.
    - U/ Q* E/ q2 C: U9 A, W- u/ t    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)
    * ]" f+ Q/ ~6 r9 ~, B5 q    {
    : \, P% _% S2 I; _        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];9 O+ E. D2 U$ }# g; O0 |
            VOID*   pTempBuffer = 0;</P>
    6 a4 V* R$ a7 Y! P3 |/ \3 _<P>        pTempBuffer = malloc(dwBufferSize);
    5 [' t& v7 y  w$ w# n        if( NULL == pTempBuffer )& J' x( K+ k$ o" S3 X3 v
            {$ m: `7 E& ~3 X8 }; I. @, q" C
                //Out of memory
    " \2 U& h' Q) w% e2 E  g            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );) R  h# {0 B! r2 m; T( @
                free( pSvrAckPack );: w% ~" K8 E% z) \# M
                return;( i: v& L8 r* X4 p+ r. S. Y
            }</P>
      o. R/ z- X3 N; n<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');
    ) Q' U  Q8 _: s8 a7 `6 u4 q- T        memcpy(pTempBuffer, pSvrAckPack, acksize);</P>3 U$ L. N+ N) E! \$ u( ^
    <P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );8 R- n! Y2 x0 `, z9 ?! [( Q1 Y
          E+ U  h2 ~* k: ~& x4 @
            free(pTempBuffer);
    + |) y: A, I& n! p' C* R' S6 v    }   / x% J4 X, @$ S2 f7 h, C
        else
    / Q  D4 E3 v8 N    {" I$ }- o0 M- `% q8 {! d& Z
            SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );% ^( C1 s5 ^# \
        }</P>+ x; t$ ]* Y0 Y* S& d/ J0 U) g9 K
    <P>    free( pSvrAckPack );</P>
    7 \6 c6 b9 G2 p# W+ C2 T3 L<P>}</P>$ d( }8 M0 V0 }$ Z  b) ~. D
    ! B0 s- a: b) w: [7 @
    <P>! r# G" O* g9 L8 `  e% O
    //-----------------------------------------------------------------------------5 L& a& h1 W( @$ _5 t" L2 J  K
    // Name:
    ; o' y  `: X) `+ {# w9 K// Desc:
    9 Z! T' v5 p9 F$ U2 p+ m//-----------------------------------------------------------------------------( `5 w2 V1 V  c2 T7 g$ M
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )6 T  h# \7 ?5 Y4 {1 Z8 p
    {& W9 e* k9 t: E! x* N1 }, v9 [
        // Grab playerdata for this client and lock it
    5 G: P! t0 U. A% Y! `    PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );' y+ l  ^5 a. }3 E& a6 T" g
        if( pPlayerData == NULL )
    9 s0 o2 b2 e6 I        return;
    & n7 I" o6 W7 v    LockPlayerData( pPlayerData );</P>
    . P* G" Q* \5 O/ ^5 D' I<P>    // Record the version number
      J+ `- i4 |1 N9 Y/ N    pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>) ?) E% {$ [% F, M8 e$ Q
    <P>    if( m_bLocalLoopback )3 s& m" r* s& O) `% O, I3 E* \5 J7 q
            pPlayerData-&gt;bAllow = TRUE;
    5 v- s0 @. s- ?" i1 Q. l    else' N8 X% m& t% d
            pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>
    0 L) n# |9 B  ~1 Z; e<P>    if( m_dwLogLevel &gt; 0 ): p4 v  W" S) n0 {4 W
            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>$ _% M  K+ I  T- W2 B
    <P>    if( FALSE == pPlayerData-&gt;bAllow )
    3 J1 F/ q+ ]% e/ @/ h4 u    {
    * f  @' ^" V* @: q  o1 @        if( m_dwLogLevel &gt; 0 )
    . s' v$ h/ T, p3 @5 `            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>/ d5 w' E; J8 {1 G
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    5 _! Y. D6 t1 |2 A        UnlockPlayerData( pPlayerData );
    ' V# ~( \; E. v        return;
    * U' j$ G0 f) F2 }    }</P>* i, U* Z' b3 N9 i5 ]3 J" d
    <P>    // Unlock the playerdata
    6 g$ G, }! Y* v; j. y1 n    UnlockPlayerData( pPlayerData );</P>. g  V, ~( H, Z( F! X# u8 s" `
    <P>    // Send acknowledgement to client that the client was either accepted or rejected# E, i6 I$ e) H8 p3 N
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );7 @  M( ?2 t/ p( a; E
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );; v8 |2 J+ S' S" B/ w  Y% F7 |) y
    }</P>' j) u2 M9 w3 T9 x; I3 l
    2 Y8 L8 Y) R3 F2 C
    <P>- `8 y" h7 ?+ i4 r. j) V
    //-----------------------------------------------------------------------------
    . B7 n! g6 c, ]5 Q/ A- ?// Name:
      p! Y0 E3 r, W6 S// Desc:
    . W' h! i7 j; n9 J! X3 ?//-----------------------------------------------------------------------------8 C, v% E/ m. i& n( B0 O
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )* \" I: [3 r1 M& ~7 n, h# o, n
    {
    2 M' r( N5 F6 d1 K    switch( dwClientVersion ): ?% @; e6 k. z7 U! }: a' ?% c
        {/ v& @) t9 p7 R: W# W
            case 107: // only v107 is supported
    0 @8 q. O- C+ Y3 u            return TRUE;% v1 m4 o1 @$ R  l  ]
            default:5 m+ S+ @$ Z( n! r% X! k8 Z
                return FALSE;
    9 S6 g" _# r/ Q# ?0 M    }
    % I2 z$ Y9 r  O5 F7 k: G9 I8 P}</P>
    ) {3 J4 q( A1 W- `8 W! F1 f4 x
    1 W. ?! }0 Q; U3 ~# i" x<P>) `- M  h! B; Y1 z' B, s7 K
    //-----------------------------------------------------------------------------
    * O4 L- d0 X9 H3 l8 G// Name:
    3 g5 k( V  W' n3 f! t$ e7 `) w// Desc:
    6 E3 X; w8 q. P//------------------------------------------------------------------------------ v# O* n  c9 v
    void CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
    ( N% l; ~5 [) W7 h+ x{; I6 U5 U4 R3 R8 I5 j# F0 m- p0 q
        if( m_dwLogLevel &gt; 1 )
    : [9 ^5 B6 K& d! m        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>
    2 `- _% Y( Y$ T4 U1 f( A; Y<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    0 q9 m- d! A8 O- h/ F}</P>5 V5 \1 o; ?- e0 \

    8 Q4 N6 p  ]. Z  E- [<P>
      x6 C: D8 \" T, M//-----------------------------------------------------------------------------
    , J% p. z- G, l9 o! O' R: i3 e4 a  b. @// Name: 9 i# z; F! G8 l: W0 U+ y9 e5 e
    // Desc: 7 [8 S& X: g- ^" z: Q/ r
    //-----------------------------------------------------------------------------! S) i4 m" K: o, t
    DWORD   CMazeServer::IDHash( DWORD id )3 i/ B% W0 U# e4 A& I# ?
    {
    $ f8 `0 _2 ^' \+ g4 `    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);. E4 ^8 H) g+ V7 Q
        return hash;
    5 D6 ~0 L' L" S# W. y/ _}</P>/ G$ K7 u( C! i$ z4 s
    ( z' A, z% v1 Z& Q8 W: Z
    <P>
    / q* a! N# Z/ U1 J0 ?& N  _' p( E//-----------------------------------------------------------------------------8 h' n: P* u0 w2 a# |
    // Name:
    9 r1 p9 s1 C5 L, m( c" ^5 l// Desc: 4 A, g0 v% f- G
    //-----------------------------------------------------------------------------
    9 K9 v  j. R* y+ `- ~" ~! k. [void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData ), B+ N  T! g& y4 ?$ J; a9 @# v1 q
    {6 B, U5 |& F+ O7 P3 a0 S8 }
        // Hash the ID to a bucket number4 r7 Z; b7 \  C+ Y5 B* f" G3 X
        DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>1 q9 U$ g0 ]( L! C) a5 G: |/ n' P0 B
    <P>    // Lock that hash bucket
    4 d; B! o5 p& G  z3 j( B, T& U1 i    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    + W5 x$ `/ j2 z/ k2 E    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>" R& u( W( d  f6 m2 R5 q$ ^4 \3 }
    <P>    // Loop though players in bucket until we find the right one
    ) A# P* Y3 W. K& c# C+ c- B) _    PlayerData* pPt = m_pstIDHashBucket[bucket];
    0 X$ f, h1 b2 j; W7 z- I    PlayerData* pPrev = NULL;  R$ Q. X+ L+ x* P
        while( pPt )
    7 ]0 I" g; C& Y0 J, K, @; b    {; M* E1 F9 p) G+ ~+ ?
            if( pPt == pPlayerData )/ k/ i$ B. r5 s+ }
                break;1 n' _" Y2 |! K1 t% C, h7 s
            pPrev = pPt;
    * i. _" m( J* W& G6 k: w! a- T$ q        pPt = pPt-&gt;pNextInIDHashBucket;
    7 _8 T, b, U$ q2 C4 }! h2 _    }</P>6 |! Y+ S, a* ^, Z
    <P>    if( pPt )
    $ U% s6 N) A5 O    {4 o+ Y) U, Y4 f! X3 G
            if( pPrev )- K" A# `) o4 l* Y+ q- T
                pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;5 i$ [0 K  B3 R. L- `( o
            else
    8 y2 F; m$ D, W! G' G8 W            m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
    5 x% P8 {7 a2 @4 `# H* M1 m        pPt-&gt;pNextInIDHashBucket = NULL;+ E3 s" j* t3 f
        }</P>
    , Y0 V( o5 C  [- F# M<P>    // Unlock the hash bucket
    ! X' T( j( O; w8 W* u! r* {    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();$ O4 ^$ g- _( h& j* J2 w/ H: A
    }</P>6 C% i4 u" e- R9 x1 w

    8 j% k6 g8 d. X" H% M<P>3 y; ?% d8 ]# Z9 `" ^
    //-----------------------------------------------------------------------------
    ) y7 q" h7 u3 q( b- w+ q8 ^' A, ^// Name: / T8 Q3 L. ?5 h
    // Desc: $ q' }8 Y( c8 y0 Y" Q9 x
    //-----------------------------------------------------------------------------
    4 u0 z" x2 C0 V0 {" h# W) avoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
    : L* E" m" J3 _- {0 N3 @7 u{
    1 v1 ]- I" P7 \3 z  s3 m    // Make sure this player isn't added twice to the m_pstIDHashBucket[]
    $ ~9 d  G& r+ y( f2 H    // otherwise there will be a circular reference
    2 ]. i4 \2 l/ p    PlayerData* pSearch = GetPlayerDataForID( id );
    ; K) a5 D1 w& u' s$ K    if( pSearch != NULL )
    9 ~4 i1 b7 z% V, K        return;</P>
    8 h. G9 S$ _; Z9 O3 g<P>    // Hash the ID to a bucket number3 c. V- X+ e( b4 k' h% w& k4 _0 P6 t' e
        DWORD   bucket = IDHash( id );</P>  r3 z  u! H* G7 Q3 m! V* s$ S" _  ?
    <P>    // Lock that hash bucket# f1 P) J- w1 [9 c# J
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    6 u6 T. I2 R0 {; ]$ T9 {    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    9 ]5 X& S# N6 T/ A: O' b$ r<P>    // Add player onto hash bucket chain7 M2 u5 N% C" S
        pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];
    * s7 A2 e5 a, R    m_pstIDHashBucket[bucket] = pPlayerData;</P>: N- q( x  m: w, u1 Y
    <P>    // Store net id in player( M/ J" r: C! M( p7 G, Y: {# ~
        pPlayerData-&gt;NetID = id;</P>
    3 @  G3 `& y" E<P>    // Unlock the hash bucket
    * m! F3 ]' i+ B# }    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();, `) |' P5 e! v, }( i2 b! X
    }</P>
    . e4 P$ T7 w/ E9 z3 N& {: r7 i8 ]7 ?
    7 U. \' O2 d. k9 d) z. T<P>: W3 u& y$ h0 [4 n7 a$ z% S$ E
    //-----------------------------------------------------------------------------
    3 O1 A5 ?: w4 C* D( T/ R// Name: 7 z( j/ F3 P5 C! G: I) v6 `& B' |
    // Desc:
    9 `# v! m  {9 t' ~. t- E* q//-----------------------------------------------------------------------------/ u0 Q1 M& g# Y/ u' T, b
    PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )7 n# H) f" F8 i0 x) o5 h/ ^- z
    {2 t/ k+ h1 s* [+ S# Y6 {* d6 |2 ^
        // Hash the ID to a bucket number
    8 y, p2 y3 X- E! ]$ a. l, @    DWORD   bucket = IDHash( id );</P>( K. k; I* {4 X+ F
    <P>    // Lock that hash bucket
    " U  A0 V- T: [3 D% ~' L+ `  v; `2 L    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;  p& h$ |6 ]3 S4 z! u% z1 M
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>4 L- X2 K9 @9 p+ c+ z  z
    <P>    // Loop though players in bucket until we find the right one
    . h: ~" l/ j# H% C- [    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];- v0 K4 j. o* }4 k6 |+ F0 o! T
        while ( pPlayerData )2 ~0 C, Q( |! r: b* l
        {
    : C+ ^( Y  x5 F: L# _. `7 E        if( pPlayerData-&gt;NetID == id )! p7 B0 N! i$ ~9 X
                break;
    5 ]% g+ J/ Y  e( e        pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    0 {: z- J1 v4 t3 c7 K7 c    }</P>6 r8 Q" X% Q- y- U* b
    <P>    // Unlock the hash bucket8 {" M* H2 O+ S# c% w; W$ k
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>
    . w0 p; X' T* U9 e$ b<P>    // Return the player we found (will be NULL if we couldn't find it)! e6 w6 Q: P9 n& ^: }$ ?& c8 q2 R
        return pPlayerData;1 S( ~$ _5 |- Y$ a* k) l5 u
    }</P>
    & K+ O- ]* N2 z# c! X& w: K4 ~: ^0 V9 r
    <P>+ C: ]( K6 f4 y/ B* x) q8 G5 G/ W
    //-----------------------------------------------------------------------------) c- ]3 K, b# Z5 ]9 v& B
    // Name:
      [/ C! c6 G5 l! v8 `, n+ q// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner
    $ [9 Q6 A' v* T4 B7 B//-----------------------------------------------------------------------------+ I% o# V9 ^4 M: G/ f" b  F
    void CMazeServer:isplayNextConnectionInfo()  @; M0 y$ ^0 n9 I% K
    {
      t- _1 n. S+ W' t6 F6 C3 _    if( m_pNet )* q' L$ L% b3 I, j: z3 `4 d
        {
    0 d# M, M+ m  T9 Y2 C! r        // Find the player that was displayed the longest time ago, and display it.4 ?1 e7 v: ^3 b! V4 x3 s
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );& o2 p# Q. `' Q5 |# i5 A0 a
            PlayerData* pOldestPlayerData = NULL;8 Y! S% u8 u/ I! q! y0 R
            FLOAT fOldestTime = 0.0f;</P>
    * B4 ]/ h( g- S: g<P>        m_PlayerDataListLock.Enter();</P>/ x2 C& n$ k/ g! r
    <P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
    ; s5 K6 R, Q1 m% o        while ( pPlayerData )9 P0 ~( h0 W# [8 K# l& \9 u
            {
    ' H% F( Z& B1 c1 X7 J$ N; v) z$ ^& b2 ?            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )$ x. c9 f8 x4 l: O/ x5 d
                {
    + M, [8 h, e/ b                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;4 I0 _) c; L. l) f( s/ M
                    pOldestPlayerData = pPlayerData;
    ; D3 C$ s6 X: p5 g            }</P>3 @$ V; R- o, n* p8 m
    <P>            pPlayerData = pPlayerData-&gt;pNext;
    * N$ ^" w! V8 l6 Y" r* Z        }</P>! U8 o$ Q8 M! k1 ]
    <P>        // Display the player with the oldest CI field, and update its CI field.
    ) I/ K: M" A, Q* S* J' {0 x: l        if( pOldestPlayerData )
    , S3 i% b4 O. |" H5 Z3 b        {
    9 v4 a" u$ d2 X1 ^6 c( M            ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );5 T' N) m+ \0 d2 |. v
                DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
    6 f3 F4 Y. F$ v( a  g' g" k/ H            pOldestPlayerData-&gt;fLastCITime = fCurTime;
    ( X) B( U! d) l0 l6 E: N5 N8 s4 ]1 k        }: `, y' H8 C' |# n4 w
            else
    + ~" [6 n" h6 `0 @! x        {# k7 h+ h' B. f3 T
                ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    : U: a) p5 E+ S. {( V        }</P>; c4 Y/ a* F- f/ H2 H
    <P>        m_PlayerDataListLock.Leave();
    / g) v. z% A0 t" y% g# w    }8 J2 C# P3 R. b
    }</P>" L7 v! r- s6 C9 O" J: g; Y( m
    0 l6 E- v0 V& l6 I; p
    <P>
    0 j' n3 }. f  p//-----------------------------------------------------------------------------
    9 ?. D( A& U" Z6 i! w0 r  y// Name:
    , c( {' ^" ~+ v% Q// Desc:
    ; Z, }- N/ _9 f, \//-----------------------------------------------------------------------------
    / `+ Y7 f5 A) svoid CMazeServer:rintStats()% _' d7 q1 e/ Z3 G" U
    {* |. `/ ]" A9 G
        ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
    ; w8 N/ j7 c3 X2 a; @# o1 {& m                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );/ f: o( ^% K+ v2 c$ G, q8 ?& c" w& c
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
    1 W/ R. {# ~/ b. i                                    m_fAvgThreadTime, m_fMaxThreadTime );+ F- r, o4 ?' T" V0 o; g
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
    , a8 n! s' R" n$ Q0 j$ B9 o+ q    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );: a6 @/ o1 w0 o5 d* C
    }</P>
    ! h+ v! J8 g* E* b7 M0 B' x3 E
    4 e4 L/ n* R: A  M7 O6 E( K* s<P>9 h, L. V, Z# S
    //-----------------------------------------------------------------------------
    + j9 g6 J# v+ Z6 J5 m// Name:
    . D" l9 m! g) x. x' U3 A* L// Desc:
    " O/ U5 e( U" B4 |2 `//-----------------------------------------------------------------------------
    8 j  N* p. E4 E( Vvoid CMazeServer:isplayConnectionInfo( DWORD dwID )
    , R# o5 [2 P0 Q4 O  u" ]* ~; Z+ T{
    1 Z  c- W/ B: {4 a: n    TCHAR strInfo[5000];6 V. K, N+ y9 a( _" _& V% d
        TCHAR* strEndOfLine;
    2 g2 S1 A: P! F8 ^' x* C/ [8 L8 I    TCHAR* strStartOfLine;</P>* U. W( x$ y8 f& z. V  w
    <P>    // Query the IOutboudNet for info about the connection to this user
    8 _3 A6 V* ?: M4 I+ q! m" e+ J    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>
    ! e# K# v! g) q1 K# S<P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );
    - a) ^+ a8 Y" T# x    ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    3 }' T# i( r: W  B( C* s<P>    // Display each line seperately
    3 q( d9 i4 M: _    strStartOfLine = strInfo;
    0 E% j* Y7 X5 V' g    while( TRUE )' _/ m/ H; C8 R
        {
    9 N1 `9 ?5 e6 o" p+ F3 I- |, F. R& ~) F        strEndOfLine = _tcschr( strStartOfLine, '\n' );
    , `  `4 \# c  Y! j" m0 c: |6 h+ I- L        if( strEndOfLine == NULL )
    # |1 v, f& t7 ~9 u8 \) j            break;</P>: ~! l* X, X5 w# D- [  I' R" u
    <P>        *strEndOfLine = 0;% D9 c: b0 g# g4 C
            ConsolePrintf( SLINE_LOG, strStartOfLine );. K# \0 h) [0 K
            strStartOfLine = strEndOfLine + 1;9 g3 u9 J3 d" [4 J! {) {6 s, T; [
        }7 w. \: P, v" R5 C+ [
    }</P>: P0 L9 p- Q: c- L  N3 t* x
    6 t  Z. G9 S, K& J1 O3 M1 C
    <P>
    1 N6 x+ o0 \2 ~& r2 z( p0 E# Y//-----------------------------------------------------------------------------
    : Q# R5 M, U6 S; p6 ]0 \. g// Name:
    / p) ~& g, p! ^7 K// Desc:
    3 w7 D3 E/ y& V" ?) m( i% y- P8 m//-----------------------------------------------------------------------------
    6 A/ Z) M- C) N# Q5 G, D, WHRESULT CMazeServer::SendPacket( DWORD to, void* pData,
    ; a+ T5 M3 U( ^: t/ s                                 DWORD size, BOOL reliable, DWORD dwTimeout )
    " |- m( r5 v, N4 }0 E{
    & l+ \8 s# {& ]    // Chance of forcing any packet to be delivered reliably
    8 G, y3 K/ q% x" r    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )$ e6 }2 M" i: [8 I( c
            reliable = TRUE;</P>. M7 z* ]) U* |. Y
    <P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    : F) Z% Z- o8 {, \- `! w8 e}</P>$ O: |4 V4 f5 S, H: p; ^9 j: C

    1 h2 a0 m1 [7 ]7 k' `0 @# u. {<P>7 o; i1 ]6 C1 g  H2 L! A& O
    //-----------------------------------------------------------------------------
      T+ t5 c% E- O- K  ~// Name:
    ! {; `' s+ @  M1 v" j// Desc:
    , g) d; x  u5 D) o. [9 |+ b//-----------------------------------------------------------------------------
    3 L' B  `  U; @void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )1 d7 R; n2 E, Z5 a8 m/ w: @( k
    {
    ) b5 M  L2 \# g" d, W8 s4 f    // If we're up and running, then send this new information to all clients/ h0 G! Z5 C' Z* D' Y
        if( m_pNet )
    2 k* Q' j& j# m0 S2 q. n    {- w+ b8 _2 [) \+ j- j3 L# e
            //Use the AllPlayers ID
    4 u' M, g4 H% J# p# j+ J        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );/ R$ r; h) K( F" V$ o9 J' b
        }
    * A' y0 a& a$ C2 V! }}</P>$ T9 M% p) L, {! c) E3 m# \

    + `% o( H% J' N7 H/ \3 T+ ]<P>
    7 S! n; d2 p' w' }//-----------------------------------------------------------------------------5 ~) R# ]5 h. M. K! h
    // Name: * E, b4 G, a7 P$ h4 ~
    // Desc:
    # E4 v6 Y8 W+ M! u1 u//-----------------------------------------------------------------------------6 I) G8 l9 t- o2 a+ U2 T
    void CMazeServer::SetClientReliableRate( DWORD percent )
    ! h. p1 ]" m6 |; C2 L8 e# ^{7 _" q' g2 m1 D  ]# h. A. z2 k
        // Update client config, and build packet containing that data
    5 Z7 W" f0 ^- u, h; o# _    m_ClientNetConfigLock.Enter();
    1 [9 |- @  z# i' n9 `2 d    m_ClientNetConfig.ubReliableRate = BYTE(percent);
    6 l5 S- K. o6 j- l6 n0 _    ServerConfigPacket packet( m_ClientNetConfig );" L0 v0 ]& S: I( r
        m_ClientNetConfigLock.Leave();</P>
    6 ^' g+ Z. a" r& I( t3 j- ]6 C<P>    SendConfigPacketToAll( &amp;packet );
    * X( U! e+ A5 Y, I4 H}</P>
    % e' v7 X( E  u( b
    ) R% c( {3 M; c: o0 s' A<P>
    + y0 F1 c5 [8 N2 p' o8 h! s//-----------------------------------------------------------------------------2 G; `' H) I% D" V# ]. x! O
    // Name:
    * X3 o( _6 \' H* y' e, ?// Desc: 2 {; s' U9 e2 |5 l+ i! f9 N
    //-----------------------------------------------------------------------------) z0 `7 s  D# L  Y! t( A& ?( D
    void CMazeServer::SetClientUpdateRate( DWORD rate )
    , Y/ C% P1 Z$ X! e/ t5 j# x/ G/ w{- J6 E- B8 [% g# g
        // Update client config, and build packet containing that data
    ' |4 y, z' z; C0 r: f    m_ClientNetConfigLock.Enter();' r3 i6 L! G4 e
        m_ClientNetConfig.wUpdateRate = WORD(rate);
    + J9 x) ?5 ~! e/ j0 M0 n    ServerConfigPacket  packet( m_ClientNetConfig );
    ! g' v3 }8 `& Z; e: `( B    m_ClientNetConfigLock.Leave();</P>4 v0 }; @& m7 m3 x. ], p* f2 x  u
    <P>    SendConfigPacketToAll( &amp;packet );* D2 |4 i' `1 s3 G, h' q
    }</P>* v$ H, B' ]3 {$ o; ]+ w) s1 J8 M

    & z- D) C+ J9 Q<P>0 x5 l9 D; k% D2 W7 b1 a; E' H* @
    //-----------------------------------------------------------------------------! R( y  v- L0 ?0 E3 o) U
    // Name:
    2 q& c# {1 O! p. t) {& {// Desc: ! h% Z: f7 f! ]$ p- s" [& I
    //-----------------------------------------------------------------------------& a1 o3 U# Y- |! Z7 c: V
    void CMazeServer::SetClientTimeout( DWORD timeout )
    9 N9 u% U4 z2 G$ _: j& H7 w{- ~! G6 {3 ~& T0 U
        // Update client config, and build packet containing that data- N9 j5 m; Q! N& ^" [+ }
        m_ClientNetConfigLock.Enter();5 q6 f. r  R5 f- t5 ?
        m_ClientNetConfig.wTimeout = WORD(timeout);- c3 t4 L5 ?1 R: [( A6 C4 k% `2 J
        ServerConfigPacket  packet( m_ClientNetConfig );
    " e8 A* @0 G% H4 l6 r5 W    m_ClientNetConfigLock.Leave();</P>! ]9 [/ ]+ y7 S
    <P>    SendConfigPacketToAll( &amp;packet );6 l6 j" R1 X( B( v  G% ]
    }</P>! N+ `! \: `3 H/ N* r

    " s& k3 G- ^( s<P>8 V) L% e  g; ?
    //-----------------------------------------------------------------------------+ w. r2 f& K- o2 h5 F7 B) u
    // Name: 0 S5 p3 X2 N! I& P9 I3 A
    // Desc: + V; N0 O1 v' M4 ]
    //-----------------------------------------------------------------------------
    % s! g3 x( T& M( W" P$ y) cvoid CMazeServer::SetClientPackSize( DWORD size )9 ^! {, w6 z0 m% O; O
    {
    6 J/ \7 k2 `- k# R* y    // Update client config, and build packet containing that data
    ! g* I, U) _5 C! a7 ^" q    m_ClientNetConfigLock.Enter();
    : ^: d" Y+ N" m2 N% C/ }# `   
    , ?, z. s! V2 N4 |3 F  X( Y* f! W    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.' I' t8 E3 p! n" Z1 Z
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   , J9 E& F2 }9 a3 a; x
            m_ClientNetConfig.ubClientPackIndex = 0;</P>
    4 N7 B  C  i/ |0 g( L7 f8 C  `2 ?& G<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);# b, y2 O9 d" ?
        ServerConfigPacket packet( m_ClientNetConfig );" k/ h1 H2 h. s) X) o- m% h2 V  e, @
        m_ClientNetConfigLock.Leave();</P>' D% a& A6 F& @" @  H4 T& f& U; c
    <P>    SendConfigPacketToAll( &amp;packet );8 i. `  E6 C# C
    }</P>
    0 z. c. F* G, f$ |! |
    4 ~. o1 Q6 z6 ]2 U+ E4 L<P>4 l3 d2 |/ F! @8 x- W* t3 }
    //-----------------------------------------------------------------------------
    0 |+ X  Y" g! b/ ~; m// Name:
    $ K6 A" E7 @: G// Desc: % ]/ a! @* B% F
    //-----------------------------------------------------------------------------
    ( m" C/ T. E6 I  l' ]- `& mvoid CMazeServer::SetServerPackSize( DWORD size )1 T4 J/ }! V+ W2 G9 N
    {7 \& V  |5 w3 W, C* ]3 ?/ {1 L
        // Update client config, and build packet containing that data# a- b. P5 E! Q; {$ h
        m_ClientNetConfigLock.Enter();9 j/ ^- i7 w4 d; Y/ c, z1 Y
        ( k/ N" \7 m- D8 N; Q$ [
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.
    7 C, e! f3 F. f, O: p# k  F    if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   
    0 T7 a& S6 |& D4 ]5 a* p( y        m_ClientNetConfig.ubServerPackIndex = 0;</P>. A4 {2 M& i/ \4 l/ j/ _
    <P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);- _& O0 I" o: U1 _5 ^, T6 ^7 d( c
        ServerConfigPacket packet( m_ClientNetConfig );
    ! x% A% }1 `6 {! y    m_ClientNetConfigLock.Leave();</P>4 W. Y% w7 Z* O1 Y8 }
    <P>    SendConfigPacketToAll( &amp;packet );& n) m) ], r. H5 |0 W& r1 E0 f
    }</P>& I! g. V1 E/ D; ~5 Y& d
    <P>
    " r* _7 Y4 v& \. L//-----------------------------------------------------------------------------
    8 K; B1 ~" c% V% Y5 Y// Name:
    , V& R3 `0 r* A9 S* ]' b# y// Desc:
    2 J3 O4 V! o# }8 w0 e//-----------------------------------------------------------------------------
    " z, N+ ^+ Y1 nvoid CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
    3 N5 p6 Y, T1 o: E6 K& C- X& @{
    ; q4 {, p1 s( n+ L/ x  ]* H    // Update client config, and build packet containing that data
    . b" G  F* H+ J, R    m_ClientNetConfigLock.Enter();
    * H# M/ K: q. w) O; ~* |    * p$ O/ V* l; e3 G# V! j3 o
        m_ClientNetConfig.dwThreadWait = dwThreadWait;
    ' S0 m, M& ~, z* c) J# D    ServerConfigPacket packet( m_ClientNetConfig );
    6 |9 Y4 Z& s2 Z% ?- d7 P/ m" X    m_ClientNetConfigLock.Leave();</P>
    1 K$ \3 r( ?, G4 q! D/ M9 A<P>    SendConfigPacketToAll( &amp;packet );+ A  B2 K) _( {6 R/ v1 N
    }</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-6-11 11:37 , Processed in 0.428877 second(s), 51 queries .

    回顶部