QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4248|回复: 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>! I& Q" k+ e( M/ \$ F
    <>// File: mazeserver.cpp/ L5 [4 U/ \! ~- z- k
    //
    , C' [% S- |% {/ |6 S2 l2 Z7 S- l3 L// Desc: see main.cpp2 G0 x! V0 u! y# \" g" {
    //+ x* l5 J# h9 _2 E/ g2 L
    // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
    % Q# ]1 R9 X: V: R9 V1 u//-----------------------------------------------------------------------------
    1 X$ ]. N0 {0 o' @9 o2 B# F#define STRICT& n; Z1 \3 U) _1 K6 N) ~+ I
    #define D3D_OVERLOADS
    * T; y1 o0 o3 _) F4 X; [#include &lt;windows.h&gt;
    1 o2 t. y! l& N8 \#include &lt;d3dx.h&gt;
    6 q7 O* R5 ^, B& t+ Z2 r) Y: C+ ]#include &lt;stdio.h&gt;
    $ D6 w4 H1 G' ^3 n#include &lt;math.h&gt;6 j3 G# h6 s0 \) u3 ]
    #include &lt;mmsystem.h&gt;
      n7 f, \; m0 N  z8 L#include &lt;dplay8.h&gt;
    4 z: W* S; }( ~/ C1 b5 n#include &lt;dpaddr.h&gt;
    - Q6 f( t, \! q" R  W; L; m4 j#include &lt;dxerr8.h&gt;) ~9 c; X4 G* m; `3 z$ h, e
    #include "DXUtil.h"7 [7 _& s2 {2 |% }
    #include "MazeServer.h"
    ! N: {$ }7 \3 j/ j/ k) K#include "ackets.h"; J! U" l: C9 Q
    #include "Maze.h"
    + B8 r, a4 I/ j" q#include &lt;malloc.h&gt;2 w2 v5 i+ L( q
    #include &lt;tchar.h&gt;</P>
    " b* ^/ i. T) F9 p3 w8 n* y8 q
    - _8 z0 P8 ^# l<>//-----------------------------------------------------------------------------
    # Y6 L! c5 V" ?- Z$ ~8 L- p5 f// Name: 8 `5 ]3 _1 N/ K+ i* }
    // Desc:
    ' b: L5 }' |7 Z3 ~; K//-----------------------------------------------------------------------------6 I' [) `, N* [7 D3 K4 @6 [
    CMazeServer::CMazeServer()
    ( I8 R; g/ b4 |* m2 D5 a% t" }) o! ?{% L1 j7 L& X8 z8 V0 \9 C/ c  n0 h
        m_dwPlayerCount         = 0;6 t% r& M" P* [# _. I
       
    6 r( ^- v* P( B- Q5 F0 T# C    m_wActiveThreadCount   = 0;8 r5 `) N3 L* {" ?+ C6 V$ f
        m_wMaxThreadCount      = 0;0 w5 m9 D4 m2 ]% N$ q
        m_fAvgThreadCount      = 0;6 s- O& _( w- s4 o# ]1 B) d
        m_fAvgThreadTime       = 0;4 u6 O* X; N  f1 B" D
        m_fMaxThreadTime       = 0;</P>
    . N1 B9 B$ O7 J7 D<>    m_dwServerReliableRate  = 15;
    0 \3 a  W/ n9 |+ c+ c: w" H" h    m_dwServerTimeout       = 150;
    % M$ i. D! j: }    m_dwLogLevel            = 2;" C/ C' {2 T: X% R; K( S6 t
        m_pMaze                 = NULL;</P>7 \2 b  m8 L4 H9 L. B6 }. b) {( y
    <>    m_ClientNetConfig.ubReliableRate = 15;; N: A3 P( t. o5 H$ j
        m_ClientNetConfig.wUpdateRate    = 150;1 O% l" t. p* f2 v5 T
        m_ClientNetConfig.wTimeout       = 150;</P>/ |' J: K9 U2 y' ~: V: r  q
    <>    m_ClientNetConfig.dwThreadWait = 0;</P>
    0 \- ?! M: _4 G: G0 c<>    m_ClientNetConfig.ubClientPackIndex = 0;
    7 F7 o1 Z6 H/ A5 Q+ m    m_ClientNetConfig.ubServerPackIndex = 0;
    6 O+ t- k9 R: V) x    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)# _# D* N  {) t. B9 X% W
        {
    / Q4 C. X3 B1 Y: r4 C6 s        m_ClientNetConfig.wClientPackSizeArray[x] = 0;
    0 X) Y7 h1 f0 a. e; N( w2 W        m_ClientNetConfig.wServerPackSizeArray[x] = 0;- f8 C# R! E3 p" Q; B
        }) ~- y3 n8 B; c; v
    }</P>
    - U2 ~7 W& C8 y) w. `( ~8 R. b' |; N! [5 d( h) w* J
    <>
    , n# [. C' b: J* {& t2 M* E//-----------------------------------------------------------------------------) f. d9 O: l# S* B8 ?
    // Name: * U  Y! `( h3 m8 |9 S, x( b
    // Desc: & [9 ^5 ^5 x3 {4 }, q
    //-----------------------------------------------------------------------------/ u8 a: M9 c' m- ^9 x4 x" w
    HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )
    $ X5 R- M, s7 g) u$ r{4 I, D1 Z" J+ p, U9 K
        m_bLocalLoopback = bLocalLoopback;6 d5 V. q. z7 w& r+ E
        m_pMaze = pMaze;
    ! I$ E5 N& Q8 t: b: e% V9 \    if( m_pMaze == NULL )+ n2 \! B- s4 U0 U$ z0 B
            return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>' i' ]0 ]9 V' W' n7 i5 q: Y9 {
    <>    // Grab height and width of maze
    + E2 @' f5 g  a$ @. @2 T    m_dwWidth = m_pMaze-&gt;GetWidth();! A, }: `  U- g# M/ ~' c! Z
        m_dwHeight = m_pMaze-&gt;GetHeight();</P>
    * |" T9 v) B! `8 z) J6 j<>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    3 g) B1 a& a) Z- ^2 W6 N0 x9 G    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
    & K4 n2 A% Q$ g' w' q6 K<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.
    5 m' O" _& G( Z$ B. Y    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    ) J- t, P0 X# O" a4 K1 \& Q        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    ! A! D- i' O3 y  M5 T& s% Y, Q; P    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )3 H! A) b' i* w
            return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
    ( V& U# J8 ?8 D4 S! T) q<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;1 z8 j$ Y3 Q7 z5 j( U+ Z
        m_dwMazeXShift = 0;( i2 i" A  U# [! [* B. s0 }$ K0 x
        while ( (scale &gt;&gt;= 1) )  E5 `+ n' K* C$ a# J8 f9 |0 b
            m_dwMazeXShift++;</P>6 h% D1 @2 \" }2 l' U+ t, V0 @
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;
    " \; x# `% j- m    m_dwMazeYShift = 0;* f2 C. `2 Z4 i. ]0 E) `
        while ( (scale &gt;&gt;= 1) )
    + W* r% e6 B! a8 R% k        m_dwMazeYShift++;</P>  _( n. v; [3 ^1 R. r
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||2 }% s; }% u3 ?, V4 X
            ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )
    / G  U" F1 v- f/ v        return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>
    ; ]! n3 ]( E4 }" l  }* q* k<>    // Initialise the player list6 x. H" K5 `; X& M" g. D' b
        ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );
    0 ?3 t* M# H. m2 ~' u    m_pFirstActivePlayerData = NULL;. @  ]1 n) f6 A( Y
        m_pFirstFreePlayerData = m_PlayerDatas;
    5 U6 S- @  ~( F2 K. ?4 g    for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )0 Q4 h3 R3 ~' G7 `
        {( M" n1 B3 W$ |: g. S( [
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];, ^9 `$ c' L8 H. t2 v# F  n( s
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
    3 a. X) Y9 O7 ]$ K    }</P>* F" H' V  B. _# Z  I. y
    <>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
    ; g$ y) `4 ]- i& _6 @    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];
    " q* q9 y1 K7 v( P2 z& j% p    m_dwActivePlayerDataCount = 0;
    4 g+ B( V2 }% l& L' k( O8 t1 Z2 Y4 ?    m_dwPlayerDataUniqueValue = 0;</P>+ _; U8 h! p, j7 d$ G
    <>    // Initialise the cells
    / _$ M- p, \: a    ZeroMemory( m_Cells, sizeof(m_Cells) );4 D# J' ]( U. j. v' P% s7 D
        ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>% s/ e0 H" ^0 F3 q6 }  g0 e
    <>    return S_OK;4 I1 U: w7 H& w$ ^; ]7 G
    }</P>) l* z: Q( k) d  ]( \- t
    ) a( i4 \6 ?" K9 `  [) z
    <>% n4 ?1 _$ q' k2 ?, h  D( Z
    //-----------------------------------------------------------------------------* o2 I  ]) A3 S) V$ p* d2 b
    // Name: ) A' A# `  H1 r
    // Desc:
    0 n, Z- b& L* S7 Y: Q//-----------------------------------------------------------------------------9 C1 R8 `" J  v
    void CMazeServer::Shutdown()& {4 E8 _# W! g
    {
    : e: ~8 p1 D7 E7 o5 r}</P>
    # }0 I* [* d1 p; Y! H
    # `- y! K; }3 H8 V1 ^  A, W1 j7 N<>: U: i  i( x/ A1 q) M3 F9 s
    //-----------------------------------------------------------------------------( S" L" @1 |, K& N
    // Name:
    - T) n4 r- m+ a1 J% m" v, d* G// Desc: 3 g& f4 I$ F0 N. o' v2 ~6 R8 H0 B
    //-----------------------------------------------------------------------------3 _, _' F( k4 D7 h' Q: I
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    $ V" Z4 y) T1 g: [{
    & c$ D+ B3 J0 R; X8 m+ v    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,7 V0 k% R. s8 L$ H+ c- N- W
                              x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    5 K" `/ D8 v, w0 V9 K5 T}</P>3 L& Y$ J5 U! ~/ ?6 ]" ]& H

    , Q! [6 p+ g/ v: D% g<>' Q  B: r  Z4 W
    //-----------------------------------------------------------------------------$ z1 ~4 n! ^; B0 _0 h2 ~; s9 v
    // Name: 3 R; h! o5 U( O& {& m- Q
    // Desc: ( [* ~7 [: s+ W2 `/ S- t0 Z! d. C
    //-----------------------------------------------------------------------------' I8 d- I7 X1 t. t' D& M
    void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )- K( A9 X! `& S. V3 B
    {
    * U" r+ _) l# O; t- G    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    ) K1 _; q8 X$ U; A                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    9 Y* Y9 u! V7 i- C9 N; m$ \}</P>
    # V2 e* Q; e) Q
    % G" p5 ]1 r9 p; p3 n( |- }<>9 [! L1 q5 N: ]' D3 o9 x" g; k
    //-----------------------------------------------------------------------------7 I' O' y( A( e2 r( D
    // Name: ' t% [$ Q/ }2 U% f7 B- ]
    // Desc: ( _/ k2 i" ~* i% E8 ~
    //-----------------------------------------------------------------------------, _1 W, ?% d9 e6 [% j0 [3 P
    void CMazeServer:ockCell( DWORD x, DWORD y )
    / \: G4 E; P& N$ t{
    % h' n; E7 L: s; i6 f    if( x == 0xffff )
    0 U$ k# K+ E" h        m_OffMapLock.Enter();! J- |' |; V2 S7 [( x3 \! h8 ?
        else- L4 R* }) |" c6 ^( Q) c7 U
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);3 ]' d% S4 W! l0 b1 N
    }</P>
    2 h- M7 I6 S. c3 }& c  I' U" k( u, P! o% o
    <>- O3 x4 w/ L  F+ t# y" C$ v
    //-----------------------------------------------------------------------------
    : I% [( F; B7 S( x// Name: / Y9 y! F* x# j1 y, y3 @4 @
    // Desc: 6 N& h( Y+ L( o0 q
    //-----------------------------------------------------------------------------
    0 R1 o$ f  q3 `* y, w" {" bvoid CMazeServer::UnlockCell( DWORD x, DWORD y )
    + f$ r) b8 R' x1 B' t{1 V0 \+ l% u* r) e+ w
        if( x == 0xffff )' C$ S% a; k/ b" J  s8 |
            m_OffMapLock.Leave();
    ' j/ {) w: o7 A* |+ m3 ^7 X, }4 E    else
    + h" `) |. s( }; F; L  t( ]2 k% z- l        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);0 i# N+ ^( n; S& x' ]
    }</P>
    8 Z  G& ~# B# @7 U, O
    : K& U. K9 ^7 e* n# K" |& k<>, f9 h( V; @) t
    //-----------------------------------------------------------------------------& B  E6 C( {; @  ~, L
    // Name:
    5 v7 Q/ _0 x4 l5 l$ x( |& l# y// Desc: # o5 o  U  |& M9 g, Q2 I+ y
    //-----------------------------------------------------------------------------3 l! L+ @2 C/ l2 k0 M2 k
    void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    : T( `5 \3 Q7 G" ]3 b{5 y% J* |* C9 l8 I4 R) ^& k8 I
        if( x1 == x2 &amp;&amp; y1 == y2 )
    9 M* Z* J" w2 K+ V    {6 y, X0 \' ^  G
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )& h5 [; {( g+ d5 c% V
                LockCell( x1, y1 );
    & m8 W0 T  }: S0 L* e, `        else0 }' _* y5 M! k
                m_OffMapLock.Enter();</P>: B# G- ?, C0 C" O8 z! W. `
    <>        return;
      o! s. u5 t1 c    }</P>
    + D4 f* h) }( q+ T& A2 ?: W<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    ! I" J) _) v- ]* f" {! r    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;1 x% i+ l: A) h8 K) ]
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;9 R8 ?  b( q" m6 T
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>4 ?+ }$ e4 f7 P
    <>    if( x1 == 0xffff )
    6 U. z% p" s6 O- \: Q    {/ g+ S( _! r8 Y! R+ N- Y
            m_OffMapLock.Enter();6 a* E( z8 D6 P' x
            m_LockGrid.LockCell(x2shift,y2shift);4 Z$ [1 D. g8 Q
        }
    2 D$ n+ x  o3 y* w( U- ]    else if( x2 == 0xffff )
    ' p* Z9 \- _- [7 z3 q    {
    . h  L9 U( q3 r  u6 l        m_OffMapLock.Enter();
    $ i/ }5 H8 R5 D& o! [: B        m_LockGrid.LockCell(x1shift,y1shift);4 Z4 F" ^% V& F1 K5 A7 d" C6 Q+ ]- K
        }
      q- w. _' y( F9 T' {! n    else 9 z* d' B& }. F6 b6 B3 {. P
        {
    & A7 x  ]4 b! T! a        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);
    4 C! t0 B; m: D; L. d, b0 K    }* t( V+ U  ], W; a/ ]& i0 ^
    }</P>+ L# @, E2 t7 [: c9 r/ n
    - a: o9 C& y/ I
    <>& _, y' t$ U& a+ `. M5 F" z
    //-----------------------------------------------------------------------------. f- h% B$ y- @5 C9 K
    // Name:
    # v/ M. h+ n6 [' i// Desc: ( o4 S7 }0 C) ~* r
    //-----------------------------------------------------------------------------
    : t3 O9 i* `3 b  X0 X- avoid CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
      C3 ~; q% v# a{/ _$ c) ?5 l3 I& E8 j, }; g! E" O
        if( x1 == x2 &amp;&amp; y1 == y2 )) _9 E. v# F+ M6 R. q0 X
        {. _; d) w4 K7 W+ F! }$ `
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    4 y, P( H# L) r0 t            UnlockCell( x1, y1 );
    / i4 J$ E6 M5 d3 P        else
    ' \( P; _  o; M( p            m_OffMapLock.Leave();</P>
    + U6 X6 e+ o9 r0 p<>        return;; S( Q* \( N3 [' T. q5 ~2 m0 R
        }</P>
    * D3 S4 W- z2 g& E# I) ]8 K<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    ' I2 }' R5 _+ n' _9 i$ i% ?    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    " ^% t3 Q- u( ^; w    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    ) A7 G2 z- |4 I$ ^8 K  c& P+ K    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    / k, L* t* q. x$ B$ D0 e/ n5 }<P>    if( x1 == 0xffff )  @+ k2 y! L# J' _( f3 \1 H" Q
        {
    " F. Z: A* X9 {; n8 P        m_LockGrid.UnlockCell(x2shift,y2shift);
    2 ?9 W2 I% c' q2 h9 ?        m_OffMapLock.Leave();
    " }4 Y# O5 |4 M    }+ [$ A3 b2 T# D8 J) G# X/ w; l/ x
        else if( x2 == 0xffff )
    & Q5 |6 r( V( f: L. X: Z* X; z    {$ u) ~8 `. H% |6 D
            m_LockGrid.UnlockCell(x1shift,y1shift);
    : v7 L$ R8 O: k- E4 d8 E, ?! s        m_OffMapLock.Leave();
    8 V6 g  H% F. B    }
    $ r3 N* W$ V% \0 e/ n: T! ?    else 4 w  w! j1 E" t1 [
        {" R+ |8 _$ P" t; v  G2 K+ F
            m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);, i$ s  b& @+ m1 Z! E/ K* [- v- M- J
        }+ }# i# C# j* J3 G
    }</P>8 e& U; ?. X! v: m+ a

    ' j. P0 c* X7 d: s<P>
    & P3 ?2 v) @% J' ~  v" y3 G' s% u" Y//-----------------------------------------------------------------------------  H& w) K' p9 L% ?. a( I4 {5 y
    // Name: ) ]# j8 ]' t6 s+ v7 F# U/ @
    // Desc: 4 r6 s5 v/ Y: Q5 r
    //-----------------------------------------------------------------------------3 `/ ^% o) A7 ]7 @- E  N
    void CMazeServer::OnAddConnection( DWORD id ): K: W; p8 c) I" r
    {
    ( r; u% p: h# Q9 k    m_AddRemoveLock.Enter();</P>( i2 |; f7 p* j1 Z
    <P>    // Increment our count of players6 a, b" ?. E& h: f; I
        m_dwPlayerCount++;9 o2 k& ~0 D/ [8 a* g7 n# z6 A7 }
        if( m_dwLogLevel &gt; 0 )1 D) R6 J7 E6 O; O9 _  P5 `" x
        {$ S2 P6 p! S. S% u
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );0 b3 H- J8 A8 q0 i! y
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );& [: U6 [1 `9 V! @
        }</P>6 b! i- n% d7 z- e# C
    <P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    ; n  W  ]& r: }7 v7 [4 C, Z        m_dwPeakPlayerCount = m_dwPlayerCount;</P>
    " L, N% z9 z: [  f<P>    // Create a player for this client
    : c7 E4 u' n/ s; r& _! B+ Y  D    PlayerData* pPlayerData = CreatePlayerData();
    . q- i' v" r) w8 c$ N    if( pPlayerData == NULL )
    * Z  e) u2 H2 H: Z    {
    ) i* N  D2 G3 Q, m2 N) V7 P  e        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );% P7 k. e2 z/ ?' B
            DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );' W1 B# J% x3 K  g
            m_AddRemoveLock.Leave();$ a9 S# c0 D# ?' x+ v; I
            return;7 k1 r6 n4 H3 m/ u
        }</P>
    1 M9 ^" T: f1 ]% m  R4 D<P>    // Store that pointer as local player data. i# Q7 R+ D# u0 K4 [$ Z$ e
        SetPlayerDataForID( id, pPlayerData );</P>
    / `: @: r- j. }/ F4 |- Q4 B<P>    // Grab net config into to send to client2 d$ i# ~) s5 M' p0 @7 T
        m_ClientNetConfigLock.Enter();
    8 W; }$ H6 Y4 \0 C& l    ServerConfigPacket packet( m_ClientNetConfig );1 G8 a' x0 b) I. T$ ~4 s
        m_ClientNetConfigLock.Leave();</P>
    6 s/ k8 r% h7 S2 ]4 {' D<P>    // Send it
    ' p7 s. H4 O8 K    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>
    / p8 O; v% T8 |4 U- `6 }1 [<P>    m_AddRemoveLock.Leave();
    ; J, x# n" z8 d" ^}</P>8 w) z7 \% N1 o& D6 W3 Y  I8 z8 K
    . O& l, N/ E) H6 ?+ W
    <P>
    0 H+ v: k& [8 w- [) i//-----------------------------------------------------------------------------
    / P" q# Y5 U7 C3 h/ G// Name:
    / g9 v. f6 f' P7 V. v# P// Desc:
    % G: N; y% i8 F8 j$ ~& o3 D- P$ ]2 }//-----------------------------------------------------------------------------
    2 s. P# o3 N, s9 U8 L) ~2 x2 tvoid CMazeServer::OnRemoveConnection( DWORD id ). R/ U& j" d( A* q
    {
    . E0 S' M* u8 O* i5 ?7 D# }    m_AddRemoveLock.Enter();</P>$ n* g) y) o( ?/ j' L4 Y6 p2 U/ Z
    <P>    // Decrement count of players
    % n" J& n2 a0 Z6 Z0 Y    m_dwPlayerCount--;</P>
    % ?2 {' V, l* @. ^; x1 I4 r% Z<P>    if( m_dwLogLevel &gt; 0 )+ y# n* ~; C7 p8 k& ~9 {
        {
    % p! c5 L; L; _- b" s: W6 P        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
    " w3 B2 z0 y3 |        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    $ |, n2 {) t# N8 B    }</P>
    2 z/ u, s3 w6 m' g; S7 x4 s1 E5 U* C<P>    // Find playerdata for this client
    : s7 V- J6 }2 i. ?& y6 ]    PlayerData* pPlayerData = GetPlayerDataForID( id );
    1 t/ b+ M5 N1 h' L0 ]. B% M) n& j6 h    if( pPlayerData != NULL )" d0 E5 ^# {9 x2 G1 M1 q0 f, a
        {) ?3 Q* c. T  u" L% o. Q3 v
            // Destroy it4 L+ K( }9 V0 h* _
            RemovePlayerDataID( pPlayerData );
    : G; l5 F8 F( E# O* ]# T7 N4 s        DestroyPlayerData( pPlayerData );4 X' O& m, p/ J9 t
        }</P>. \) J" y- ]$ J7 m# R1 {) `$ C4 k
    <P>    m_AddRemoveLock.Leave();
    6 U7 d. p& {, Y2 M7 G% {1 z}</P>
    . T2 T0 n* z* Y' t. j
    ' \+ P* O4 Z: t<P>) K2 y) p! U1 e' I
    //-----------------------------------------------------------------------------
    * N8 e5 L* z( W, J1 V% |3 l// Name:
    - H# Q! }8 ^# C. U% g4 Q// Desc:
    3 |+ G8 {9 S8 E//-----------------------------------------------------------------------------
    5 n# P9 ]" |+ d; |HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )2 [( Z0 C) {1 k% Q9 a1 t
    {
    ; V5 u6 Z: T1 O+ X4 G% _1 E    BOOL fFoundSize = FALSE;</P>
      r, y; L  D% |' Z/ M4 O<P>    // Increment the number of thread we have in this process.
    + k1 R+ Q" w5 h( }% B    m_csThreadCountLock.Enter();</P>' q: h% ^/ `8 U$ E8 }5 \7 {
    <P>    //Get the start time of when we entered the message handler.
    1 d7 [6 r! P1 R; R% h1 Y    FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
    " M1 j0 r6 ~' u  }) v6 ^0 m<P>    m_wActiveThreadCount++;5 @, m* i  `: n. _" O+ E) S
        if(m_wActiveThreadCount &gt; m_wMaxThreadCount)
    / |1 r8 S! W+ y  D        m_wMaxThreadCount = m_wActiveThreadCount;
    7 ~$ W* a5 P. D: ~( V    ( v  i# G: E* w) U4 b
        // Calculate and average.
    * K7 S( B' _! s! p    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
    ( @: L( G0 L, ^* N( B    m_fAvgThreadCount += fdiff/32;. x; i1 V$ T# \; M- o
       
    0 l1 Y& T+ l: r! W    m_csThreadCountLock.Leave();</P>
    % a1 w( g: Z7 ?. O/ J- I2 ~7 Q& i<P>2 G: w: k. L1 N6 }- G+ H0 L
        ClientPacket* pClientPack = (ClientPacket*)pData;
    4 G  f! e; x2 T& z9 H    switch( pClientPack-&gt;wType )
    6 i- q8 S. K) P% k& z/ `2 l7 I! A    {
    4 P: U7 e  k# s' H4 C        case PACKETTYPE_CLIENT_POS:
    % U' G& X+ }1 n9 I; P3 P8 X            ( q+ E# {6 y0 N
                // Check to see if the packet has a valid size. Including
    7 I* d2 O- ^* u0 b            // the custom pack size.6 m: ]" |$ h0 [
                if( size &lt; sizeof(ClientPosPacket))
    6 y9 y% C- V/ c  ]5 }+ Y- f                fFoundSize = FALSE;
    7 I4 x4 o+ Q0 R: V- x9 I            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))! X0 Y  m1 e6 G6 Y% Q- ^4 R+ o4 z+ H2 P
                    fFoundSize = FALSE;9 }1 R" l& }; U4 Q% U9 N1 }0 [5 V
                else! X2 U4 m# b9 B
                    fFoundSize = TRUE;</P>+ \  b9 p& _1 K. T3 N6 e
    <P>            // If valid sized packet, handle the position.0 Z* w6 ~; b" ]6 I% r5 |9 i
                if(fFoundSize)
    8 u% Q8 t8 }& l5 i* R7 M                HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );
      h7 y( F! L8 o            else
    0 X8 U1 P& ?/ \, \                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
    * O, n$ \! y8 A$ f6 [# K8 A! d3 k<P>            break;</P>7 L3 T' A( w5 w0 R
    <P>        case PACKETTYPE_CLIENT_VERSION:
    3 |& W9 k8 S% u, Y            if( size == sizeof(ClientVersionPacket) )! Z% Z0 }+ S! r7 r5 W2 {
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );
    3 g) t$ g: Q% G# M* j( V2 D            else
    4 j+ a' ~$ v0 T1 i                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    3 g! u) l8 S( r3 d1 Q: q4 m0 J            break;</P>
    4 [) I% ?1 i' e; Q  ~8 v: Z( y<P>        case PACKETTYPE_SERVER_CONFIG:</P>5 ]  f( W$ s8 b, C. ~
    <P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>
    * _0 T9 Z: Q9 i8 J1 N<P>            break;
    : W3 u* l1 V5 ?        default:
    3 U; V7 o2 y* ^! q, K            HandleUnknownPacket( dwFrom, pClientPack, size );
    + f* C% a7 f2 R* G1 @/ L" d            break;
    & ]  J: l# A% I% R; e' P4 d. F    }</P>( N) n: O# a& I( v+ u0 L+ i. [
    <P>    //If the user wants to hold the thread, Sleep for given amount of time.$ |' [& }- T- B, U- l% p
        if ( m_dwServerThreadWait &gt; 0 )
    8 t5 }/ j4 n3 n4 F    {
    9 M$ b0 }1 z7 l        Sleep( m_dwServerThreadWait );
    2 N; X! n$ r: U; j2 _$ R& R1 P    }
    ! W& T5 N# q+ b0 B: d   
    9 f9 e' Z/ d$ Z/ s: }8 ?- K7 C; t    // Retrieve thread data for this process.% f! {5 _% Q$ h4 ~2 ~
        m_csThreadCountLock.Enter();</P>1 z  ^6 @9 }. g9 m/ T
    <P>    m_wActiveThreadCount--;</P>$ p  f: {' w# ?5 ?/ M1 v. ~0 v
    <P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;- P5 e- p* X1 g" j& P' d
        m_fAvgThreadTime += fDiffTime/32;</P>. n1 p3 |" A' U5 i" X7 G# ^
    <P>    //Get the Max time in the thread.
    / w2 \! m! S* p4 b; {1 P    if ( fDiffTime &gt; m_fMaxThreadTime )
      g0 b0 o& P- S, T% ?/ G    {
    1 T# h  s2 m0 S0 ~8 ]& [( e0 b        m_fMaxThreadTime = fDiffTime;
    $ _+ }% e9 n: I) G6 e9 L+ [    }</P>
    - s, t5 P' E& d<P>    m_csThreadCountLock.Leave();</P>
    . C& c% S, F) [<P>    return S_OK;' L1 d  h$ L/ e
    }</P>
    8 ?8 J6 s% z% H3 z( `
    ) f. p: I3 A, W<P>//-----------------------------------------------------------------------------
    % |  r6 ~* I3 j+ u( q1 P# ^// Name:
    0 M7 z. ]. G; W! Y% W9 G// Desc: + W0 z4 ^2 P) U7 W
    //-----------------------------------------------------------------------------' @. a1 B) [, W: g# ]
    BOOL CMazeServer::IsValidPackSize( DWORD dwSize )
    4 S: q! {6 U# W% Y3 f9 R{
    6 N  P" _% S; f9 R- V    BOOL fFoundSize = FALSE;
    . c$ z) z0 W4 I! _2 E3 E. x    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;
    ; i  ?, l1 R; A% _. M* y/ Z* z   
    : K& h5 b* V9 B; Z  h    // Check through the array of valid pack sizes.* v4 P. e0 h7 E0 I5 H6 ^3 p6 }  J
        if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])2 N7 v3 k2 o( `9 a, k5 B3 {3 H
        {0 s7 P3 n+ c! X6 [! Z# {9 M
            for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--); h: `) v1 {+ E2 \( _
            {  h5 F6 y9 b* S9 ]0 A2 `. z
                if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])2 T  t% f% b) y+ T/ T
                {, H5 c5 w5 t# d1 [9 B0 V/ i5 A
                    // Found valid size in the array." v3 _$ {6 p( {$ c/ T; Q3 |: J
                    fFoundSize = TRUE;! ?0 W- E( P5 U/ s
                    break;
    5 }; N" s& w8 }6 L* E9 K, F" D            }. _4 P* A6 W# L2 T; l4 a- d: }
                if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
    8 p0 P" i. x* ]6 v7 }$ q/ ]& a        }. t% t8 v- A+ W  }+ X5 j: C  S# j
        }1 F- |9 G  @6 e+ R( r+ }0 `% M
        else
    ( o. t# g5 x0 L7 z( n, _    {
    ( e. u0 B8 \* H        fFoundSize = TRUE;
    : x+ F, m5 S& c+ m4 D) {$ Q' N    }</P>
    5 ~1 O/ J# \; `1 M- ^/ Q<P>    return fFoundSize;3 \! u6 W; U+ m5 \; F9 L
    }</P>
    " G" A& m! L  p' V8 m* O<P>% h! D! }7 O' r  L# c7 n& `) Z
    //-----------------------------------------------------------------------------6 E4 C  Z) j: a% Z: J  L
    // Name:
    $ p: f( t) s! J% b0 q" V( N// Desc:
    $ p' |2 v1 z& D" F) p! B//-----------------------------------------------------------------------------
    % T8 w5 m8 F# a- E1 ivoid CMazeServer::OnSessionLost( DWORD dwReason )
    & p9 s9 [# |! R' i) M( V{
    # f* u# h, z  Y2 m) ~7 i) [    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
    * v; |8 u3 I. m4 }9 k& A+ D}</P>
    : @; _8 `" g& G) C6 s, y$ @5 E9 Q& B  H$ f7 C! B$ O
    <P>
    1 b) k9 q; U/ u//-----------------------------------------------------------------------------, V' _9 Z1 _7 ^" }
    // Name: ! `, N  b* \3 u$ G/ K( z
    // Desc:
    - v% p: W6 ]" J. u+ x4 i) _//-----------------------------------------------------------------------------
    9 y) a" }' O# |: C# F, U8 \% mPlayerData* CMazeServer::CreatePlayerData()
    0 B5 i: w) G+ S* U) X, r7 P9 b) b{
    - u3 X1 R5 n( s1 L: L* W% R' [    m_PlayerDataListLock.Enter();</P>6 l# j1 l$ [. W& I5 V* W
    <P>    // Grab first free player in the list$ N3 d, v% I" U- n$ Z
        PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>$ ]! p3 ?! M" |9 L7 b' {; w
    <P>    if( pPlayerData )
      q+ [6 ], [. l& c    {
    , O+ Q) A* S, s* U        LockPlayerData( pPlayerData );</P>$ d+ F$ O/ H" O1 I
    <P>        // Got one, so remove it from the free list
    / f7 v: B+ l- u4 L        if( pPlayerData-&gt;pPrevious )6 D! \: _' ~% k0 S0 N1 x
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;/ ^4 ?5 @; e  T; S% Z" `! B
            if( pPlayerData-&gt;pNext )
    ' m# ~4 D0 _. b& P. |) F( U            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;5 g' w1 `  j% \2 L( K
            m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>
    : K4 T4 r8 k5 E. B" F' q<P>        // Add it to the active list2 `" b8 F- H) G& _% z
            if( m_pFirstActivePlayerData )1 b0 n9 Z' D7 M8 |
                m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;# R5 j, q/ o( A( C' @
            pPlayerData-&gt;pNext = m_pFirstActivePlayerData;
    6 x" u: _/ P+ u- z# Z% h# D        pPlayerData-&gt;pPrevious = NULL;5 N9 k% o; ~! d  e3 F0 E( `
            m_pFirstActivePlayerData = pPlayerData;</P>, ?6 F7 y; P* }! e0 G& \
    <P>        // Update count of players+ v+ l; F1 J- i
            m_dwActivePlayerDataCount++;</P>
    6 [- s; L- ~% `* M2 Y2 O" r( N<P>        // Generate the ID for this player4 W9 W/ c% F0 [
            m_dwPlayerDataUniqueValue++;
    $ g9 v; x! i! D& J4 T        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>& a+ O1 {$ J: z; J1 A6 g
    <P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;' O& l' J1 X) F1 J! M
            pPlayerData-&gt;NetID = 0;
    % ~  s2 u! B7 d7 @; o/ R6 H* E        pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>/ m" k4 `$ [, o! K  l
    <P>        // Insert into the "off-map" cell* y- C6 H& n" ?9 b4 l9 y
            pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;7 n  s/ C( Z4 J9 _
            pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;* M3 w- B' @2 {0 Z
            m_OffMapLock.Enter();& x! G/ Q. w  D# y/ s
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;
    2 X( W0 M: F4 N6 U2 m        m_OffMapCell.pFirstPlayerData = pPlayerData;+ |5 v. o: |  F
            m_OffMapLock.Leave();</P>* {- b" C( S: {
    <P>        // Mark as active
    ; q" |1 t  X1 Z$ \7 H' b+ ]3 N" m) T        pPlayerData-&gt;bActive = TRUE;</P>5 a- f5 x! Y4 N
    <P>        UnlockPlayerData( pPlayerData );
    : q' T) v; W% k7 O9 r* ~0 W, g    }</P>" M; U+ v" p( w/ d$ f, h$ Y
    <P>    m_PlayerDataListLock.Leave();</P>& q$ E. B8 T7 l6 H
    <P>    return pPlayerData;
    " I7 L- |/ Q" ?) p}</P>
    + N3 R1 R# J" i) c+ C/ D
    . w8 n7 |7 e/ B) b3 R" ~0 t<P>0 c% O2 b. n5 g: F) W
    //-----------------------------------------------------------------------------. L" K" {) m2 B/ b  \
    // Name: ( C, ^2 P' u8 Q$ U0 K6 ?4 F! ^
    // Desc:
    + m5 i/ z2 Z% O9 h! m8 y% @//-----------------------------------------------------------------------------+ S/ v' Y- Z7 w% u5 }4 j
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )$ A  T2 X# p7 Y. w7 ]
    {
    ) x- ]( W  q2 W+ y    m_PlayerDataListLock.Enter();
    - {8 I5 z3 @9 B. x- w3 Q3 }    LockPlayerData( pPlayerData );</P>" d7 _$ G8 u; [& m, g7 j
    <P>    // Remove the player from its cell
    $ Z1 O5 M8 Z; A- y0 J% T$ q    RemovePlayerDataFromCell( pPlayerData );</P>/ f! n2 w+ y/ A4 L  B
    <P>    // Mark as inactive
    * h' U' \4 M, i: t% u    pPlayerData-&gt;bActive = FALSE;</P>
    , L% P) y; T6 k8 @$ z<P>    // Remove player from active list
    4 w& S1 O4 g' S. |% t6 \% O    if( pPlayerData-&gt;pPrevious )
    7 Q2 l7 {  c! D        pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    ; o& h& j# t* n* }    if( pPlayerData-&gt;pNext )
    : `# }( b, y, j4 y; ~* h        pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>) d0 F2 s& b( ~! e; u
    <P>    if( m_pFirstActivePlayerData == pPlayerData )% H9 B/ c5 A+ m: b
            m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>7 p9 e) f. [% m7 b
    <P>    // Add it to the free list
    - c# ~. o3 C9 \1 @0 @    if( m_pFirstFreePlayerData )- v  G$ z6 [0 p. v) u. f% v. h
            m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;2 V3 c6 O+ f9 `( \
        pPlayerData-&gt;pNext = m_pFirstFreePlayerData;
    2 m8 [- }8 d5 b1 C% F    pPlayerData-&gt;pPrevious = NULL;" b; A6 v9 K: m: c- G. p6 H; F
        m_pFirstFreePlayerData = pPlayerData;</P>! _6 c% h. G1 [; ]7 e
    <P>    // Update count of players
    / H# |+ _: Y1 M+ n8 k    m_dwActivePlayerDataCount--;</P>
      @- p( `1 C) u6 k& v  |5 \3 d<P>    UnlockPlayerData( pPlayerData );
    / h3 m1 Z8 J- |+ `8 s, a    m_PlayerDataListLock.Leave();& L" `1 V$ ], S% n, C' V
    }</P>8 f: m" v3 b$ m: a8 h& y. D* ]

    / {  J# X8 J4 A  X' d1 O; Y. W. K2 u<P>
    5 E! [+ Z. L  G% U+ u/ [$ A* c//-----------------------------------------------------------------------------6 {8 W- I7 T. `9 d
    // Name:
    2 k( j. k2 y$ S) y9 A// Desc: ; A* m2 {; s  B: `9 N: V
    //-----------------------------------------------------------------------------
    7 n& n6 T  H% [4 c4 evoid CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )
    . }0 }1 N6 c4 A7 N{4 N% N! n- v3 U
        // Lock the player8 E; b+ p4 j, P7 o" |2 O
        LockPlayerData( pPlayerData );</P>
    , X/ R) I/ h' u1 R<P>    // Lock the cell the player is in7 e5 n; E( c5 o& `: m0 L
        ServerCell* pCell;& |) y# S  F9 v% Q. O9 A
        if( pPlayerData-&gt;wCellX == 0xffff )
    1 F$ h4 f! c' s4 A5 E    {& ^7 l2 z* U2 i! J7 Y# b
            m_OffMapLock.Enter();& E+ G  E& j' k; P* Y; l
            pCell = &amp;m_OffMapCell;0 H5 y. u! o7 O, {
        }) I7 i( \( _' W7 V# I
        else
    $ }8 h) s) b: U2 `$ {, F: P    {( t# W1 \4 u, \. k
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );; R1 i( M/ l$ l# q8 W* c
            pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
    9 U& k; q) y; ^7 _2 k4 b- g3 b  d* ?    }</P>) _( e3 _/ i, l8 ?1 L
    <P>    // Remove it from the cell& P& W8 h7 S: a" @1 O5 |+ C  z
        PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    5 L1 u& `3 @5 q3 A    PlayerData* pPrev = NULL;. O8 u/ w7 N- x; i2 j
        while ( pPt )$ N% _6 i4 j" D$ Y( L* a
        {
    . T! i( ~. q; K9 M        if( pPt == pPlayerData )! Q/ G, E% H( t+ ?) e+ N/ u
            {. P6 f/ W7 l4 n+ W6 J% i
                if( pPrev )) M7 `3 _5 ~) \4 g
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    $ e6 Q. x- R/ C1 o7 s# h            else
    ! A9 Z+ _' b/ ?+ V+ z                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>5 B& @$ E: U- k0 P8 ]0 Z
    <P>            pPlayerData-&gt;pNextInCell = NULL;
    - `- @) I. W& n$ L& g1 f- F            break;
    - S! O0 N3 O0 y+ a1 y7 Y0 D1 Y        }
    + x4 ^7 K, d. y) K        pPrev = pPt;
    ' S( N5 `7 X/ T0 \, p( X        pPt = pPt-&gt;pNextInCell;6 `- u1 g& h7 |3 B: i9 m% b) A
        }</P>
    , o1 y* e* H5 S( ], n3 n<P>    // Unlock the cell
    9 m' I! ]8 u, ~, a, s    if( pPlayerData-&gt;wCellX == 0xffff )+ R* `" r9 a, C
            m_OffMapLock.Leave();
    2 p2 h) _* C2 h! a4 |: U    else9 [# D" H0 ?+ r6 ~6 ]/ a
            UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>
    - E( `  l* |* E8 S, t" `# H<P>    // Unlock the player" B  A( Q5 l- y; v5 N# U/ |
        UnlockPlayerData( pPlayerData );% n9 N* D  R) |) j: Q; Q8 x' k$ N5 f
    }</P>
    ' `/ ^, e: G) }5 w9 g$ g
    . h! @' z; o1 o: e* g6 t  r# \<P>
    ; v5 @' p, {% T; F9 T//-----------------------------------------------------------------------------
    ' ^' L6 s/ f, }) c// Name:
    3 R. ^7 c- c' S5 ^/ ?// Desc:
    + u" C, h& ~. g3 s# j//-----------------------------------------------------------------------------
    . l8 @* C/ l" K) h% R, l% rvoid CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )5 h: v2 [: e, K* N2 Y
    {
    8 ]5 S* R$ N% l, W6 J    ServerCell* pCell = GetCell( pPlayerData );
    ) }; c. g# H8 F3 M! s2 D: S- D    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
    + r' U8 V, A# H5 |; q0 Q7 Z: l    PlayerData* pPrev = NULL;
    ) z+ L: t: h% o    while ( pPt )6 o2 ?- G  X: s$ f
        {& q/ u$ b: w# H% g; B
            if( pPt == pPlayerData ), W9 ~( h. Z/ \4 K) n0 L
            {
    2 `; E' e5 t2 A1 ]            if( pPrev ): V' Y0 u/ U, k2 \$ \% \. h# H0 q
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    , w& m( W9 y" a! [0 o            else" ~; O- L* N$ n6 A
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;
    + u/ Q/ U- a; U0 {( O            pPlayerData-&gt;pNextInCell = NULL;
    ( E; Y4 j& x4 |% w- s. K            break;
    0 X! x) l, c& q$ m3 E0 }' x$ o        }* B6 F# Q* f( S9 y% Z2 h  X
            pPrev = pPt;/ s2 K# S! @- Z4 b+ F3 _2 L' |! v& ?
            pPt = pPt-&gt;pNextInCell;
      b% I2 q4 ^% T; g- v" c    }
    / f  w2 D& N6 p# n}</P>/ u. I2 ^0 E. ?/ C( O' Q0 ~

    , B1 ]& p, F  Y% `& p1 `/ f<P>
    5 m2 M. i4 C1 S  B//-----------------------------------------------------------------------------2 K( ]- [; p8 a& c& ~$ }
    // Name: ! ?. \! ]6 J, q9 o* _
    // Desc: - n! W( v6 y+ D1 V/ @
    //-----------------------------------------------------------------------------6 E2 Y2 a# |! W9 v9 h
    void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )2 i. B0 v3 F0 i4 h% B
    {
    0 ]4 d2 M% m9 R% S5 j    ServerCell* pCell   = GetCell( pPlayerData );5 I# R4 g+ Z# u; K& R8 Z  ?8 f
        pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;
    $ L# P( G5 j  j0 s: X    pCell-&gt;pFirstPlayerData = pPlayerData;
    ( V; p1 D. N1 G* u" t}</P>, F& S" e8 d1 e/ E5 ^) C
    ! c9 a1 `- }: f
    <P>
    . ~) V. x9 C' j; v//-----------------------------------------------------------------------------
    + k, B* f2 a( s; }/ I  ^, Y$ I, @// Name:
    7 u7 ^) _% C; s: {' e4 A// Desc:
    3 S+ v$ ]9 n' n6 i- A//-----------------------------------------------------------------------------" j0 Z& w7 N0 j/ S
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )0 y# V- W, x/ e. Z$ V6 [/ {; F# {" M
    {
    % P* B: N. J$ @  ~3 O4 I    // Grab player for this client and lock it$ S2 g6 N! K* {. N+ t
        PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );' Y# O/ I; F& K9 y; |
        if( pFromPlayer == NULL )
    ; B5 y) i6 N' M8 e( Z  J) r* Y    {  H' m) w4 B% ~) l
            if( m_dwLogLevel &gt; 1 )# \" w- Z4 r4 ]. f( s; p6 A
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );* G) z2 x/ U: }* Q* o% X
            return;
    - p7 L3 T% |! d8 d    }</P>" c0 Q& t- g) O' i, V
    <P>    LockPlayerData( pFromPlayer );</P>
    # w: f0 t% t: q+ ]5 l<P>    if( FALSE == pFromPlayer-&gt;bAllow )
    # r3 c+ U. p$ ]$ X$ L4 U9 e( f: v( w    {
    ) U/ V; V9 z. C/ L$ E% A: }        if( m_dwLogLevel &gt; 0 )
    , f5 ]' v6 W1 T# b* G            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>; h1 C  o! q0 V% s2 ~  l$ ^
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    7 I; m$ k1 ?  ]3 ]1 r( F0 b        UnlockPlayerData( pFromPlayer );# j2 B; q# ~; }" s9 U# h6 a6 a
            return;
    2 |. z4 W$ T5 m8 N* R7 s4 a7 j) w2 `    }</P>
    4 i" I" F: @0 E<P>    // Compute the cell the player should be in now
    , O3 k- L% q/ ^* i; V    DWORD newcellx = int(pClientPosPack-&gt;fX);4 |0 v  ?% q; ^$ F2 K+ s
        DWORD newcelly = int(pClientPosPack-&gt;fY);
    - e4 q' M8 m' V' Q" o: G    DWORD oldcellx = pFromPlayer-&gt;wCellX;
    8 a* `7 ^$ L" [7 w    DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>' H4 N2 [, Z5 C
    <P>    // Have we moved cell?
    ' h- E/ B/ m) k( M! c    if( newcellx != oldcellx || newcelly != oldcelly )
    , @9 A4 F6 _! x4 S5 \/ W% q- U    {0 I: b- Y. X9 d
            // Yes, so lock the pair of cells in question
    & H: X1 t) b9 K* d        LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>: d5 _4 x* k) ?) e! y7 ]$ n: i- c, C
    <P>        // Remove from old cell and add to new cell2 P+ N" X& c& d
            UnsafeRemovePlayerDataFromCell( pFromPlayer );% W, v7 Y/ t4 @  R- e& R" G
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    5 z( x! c( F& K: }        UnsafeAddPlayerDataToCell( pFromPlayer );</P>' u& `# M5 M( v' @% A& l" [& }
    <P>        // Unlock cells
    8 N4 z( ^9 a) F& m' X        UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );
    / j+ i9 V4 z  ]  r* B& H    }</P>! S, ^' ^0 k- R* {
    <P>    // Update player position* X0 |/ o1 j; p* J
        pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
    ; `7 {5 h* e& R! C4 d    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    " P* H% }& `; l1 U1 S* \: _' ~    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
    & K. p& o! O) L+ L0 I9 f<P>    // Allocate space to build the reply packet, and fill in header " [9 |0 Z" M+ A$ {% E+ x0 e  [! z2 E
        DWORD dwAllocSize;
    ; I' C0 Q2 o* w) J/ V# V    ServerAckPacket* pSvrAckPack = NULL;</P>
    1 O# S4 Y5 A5 M<P>    // Begin by allocating a buffer sized according to& @0 C5 V4 ?" e+ J1 I% b
        // the current number of nearby players + 4.  This will give
    9 k& J' [6 T7 N% c    // a little room for more players to come 'near' without resize
    - y! R. c# K" \% W& t/ i    // the buffer.
    & J9 e4 E5 z- v' l    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>
    # E4 a! ]" a; R" C! P9 x<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    * N4 i- v1 Y5 |+ F: o. T# v: [    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );5 n' d! {; f& ^1 V0 s* ?# C
        if( NULL == pSvrAckPack )& i+ o4 [! L. C. q
        {( V. d: q% v( h. Y# W- C  Q% a
            // Out of mem.  Cleanup and return
    7 P: p5 l2 g5 Q* P8 t        UnlockPlayerData( pFromPlayer );
    / u* r/ g) e) e- A4 [& a$ S        return;       9 `+ ]5 d1 V+ X. K( R  I* F5 _
        }9 t0 B% v1 p7 J) n" L  e4 f. v; Q% `
        ZeroMemory( pSvrAckPack, dwAllocSize );</P>
    7 V+ x( O  F* R! Z9 m2 `<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);9 ~/ L# T6 u7 \
        pSvrAckPack-&gt;wPlayerStatePacketCount = 0;: Y$ \, x; Q! Z! ]9 l4 j- z
        PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>
    ( ?# b0 c: }( Z) a<P>    // Compute range of cells we're going to scan for players to send
    % H, J' U  j: n! M+ D2 |3 H6 k! H+ O    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;$ v6 b0 t# _5 j
        DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;" q% J( P' ^0 c. T: j( w
        DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;
    9 f2 k4 \2 T. m1 H4 n& o, [    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>! z  d2 e7 j, R; b( X; y7 B
    <P>    // Lock that range of cells
    8 G7 {/ b" l- \+ }    LockRange( minx, miny, maxx, maxy );</P>0 P& K& s8 y7 n3 v: \& b( h
    <P>    // Scan through the cells, tagging player data onto the end of
    ( _7 U. C$ C0 b, [( Q, O. R    // our pSvrAckPacket until we run out of room
    1 z! T# ?# b) ]% |( ~) N2 ?    for( DWORD y = miny; y &lt;= maxy; y++ )
    + G* Z1 n; B; _& }3 F5 q4 x3 k0 ~. D    {
    ' G! a2 `4 b6 w+ J        for( DWORD x = minx; x &lt;= maxx; x++ )- s0 y  P, |  ], e; H  y, q0 h
            {) I* J2 v2 i% Z; m
                PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;
    / p" B4 v& P% U2 k            while ( pCurPlayerData )
    5 a2 Y9 e& W1 _7 f            {2 c" D' V; h& G9 ~5 v& h
                    if( pCurPlayerData != pFromPlayer )& C$ Z, d4 M2 q9 F" b9 b: G4 W1 S
                    {
    2 e2 }, h% {! }# D                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )' r' x* x* m' @' v
                        {6 f0 `& b, K. W; H4 D6 a7 {. k7 v
                            // Make sure pChunk is where we think it is
    7 t9 x3 B$ S; W" k0 {  b2 J                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>
    ; N0 Q0 y7 h: v5 c0 L5 K& Q/ f* f<P>                        // There are more than just 4 new nearby players, so resize the
    - g4 E4 g3 M7 v' W9 }- O3 N                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
    . _' ]$ G; H+ F, E0 t2 w                        dwMaxPlayerStatePackets += 16;
    * Y" N/ z) ~" R* Z3 ?5 ^                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);8 `0 b" r8 e2 ]5 n8 u, t  D
                            ServerAckPacket* pNewSvrAckPack = NULL;
    & s! {/ U; g9 r                        pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );7 U7 U! g# ]4 Z6 k! Y
                            if( NULL == pNewSvrAckPack )
    ; J8 h6 l/ F; }* G. @                        {! E8 ^& t; g2 E1 K
                                // Out of mem.  Cleanup and return
    4 `" @' |; |& [+ @! h2 }0 W4 s% c                            free( pSvrAckPack );
    + P) j  M' W" {0 Y% F                            UnlockRange( minx, miny, maxx, maxy );* @8 r) ?9 o/ H7 g' J
                                UnlockPlayerData( pFromPlayer );
    8 N' |) e1 y  S* R; ~5 l& C" x9 }                            return;      
    9 b7 z7 D- a/ W5 C- h                        }</P>
    * N$ c: ~% K/ i% e8 d7 K; O<P>                        pSvrAckPack = pNewSvrAckPack;
    ; H  D: n+ M; ~8 c3 K6 U7 D. l                        pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
    # |. D0 w2 U( S2 J/ T) z<P>                        // Make sure pChunk is still where its supposed to be
    . W/ |! b2 C7 B/ i; C5 E/ G! e: z: i                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );
    # U: C$ V1 _" r& \                    }</P>
      A# Y* i5 l) G7 m<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;) I2 t8 i. t8 w8 z( C
                        pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
      E! A0 H' \9 ~                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;6 W. X# A6 j/ k' c( d
                        pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;' X; i( I; }3 [4 H+ c6 h; c
                        pChunk++;
    6 h  R: }0 T" l4 c/ Y: }8 s" m( M                    pSvrAckPack-&gt;wPlayerStatePacketCount++;! z& ^" n3 `! d) l5 _; h
                    }; ~8 B8 g5 N5 C
                    pCurPlayerData = pCurPlayerData-&gt;pNextInCell;9 V6 S- U; H+ G) I; S& v; g% _
                }6 B, H3 h9 ]- v* Z
            }
    " O, F* J1 C( e% s  w    }</P>' U  H5 R, g/ X
    <P>    // Update the dwNumNearbyPlayers for this player
    4 @' J6 c3 x$ w    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>4 }( j$ p; g3 R; l% h- ~' r
    <P>    // Unlock range of cells) ~9 ~5 |0 C; X
        UnlockRange( minx, miny, maxx, maxy );</P>
    & h, S2 F. _- i* ^$ C<P>    if( m_dwLogLevel &gt; 2 )3 \1 s6 W( d% Z9 z
        {
    ! E+ O% M, R; k. W        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    9 D7 @* l4 T# [    }; M$ b) a1 X* F7 m* D& c2 T; J' U
        else if( m_dwLogLevel == 2 )3 x7 L: ^: T/ k6 L
        {, O0 l+ S/ [- y! ]) z7 P. v1 e
            FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );4 A5 A$ |" L: \! m
            if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )
    % i, o- l4 X' I1 j) F5 u( `        {
    : d5 E5 `$ \/ |. q* T7 x            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );- Y- ^; s! _0 D' U# q
                pFromPlayer-&gt;fLastDisplayTime = fTime;
    3 X' D1 [. c- L6 k1 K  B+ I) S        }  B3 B. c5 _: X; t" R7 X
        }</P>1 |" q3 r# Y, M  w/ ?$ l
    <P>    // Unlock the playerdata3 o# W' R  c; i& w
        UnlockPlayerData( pFromPlayer );</P>
    4 W7 q$ Y! T9 i! k$ W3 Z# }) m<P>    // Send acknowledgement back to client, including list of nearby players
    9 |" U2 {' v# R+ H0 ~* c    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));
    , C: N" G- J; w8 M% @, g8 d , G' A/ C' f+ g: E2 ^3 q- A
        // Pack the buffer with dummy data.: S3 x4 ]* T' B+ Q! e( M
        if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0); i: ^5 H% t4 d& K8 C# l) l; l
        {; t2 a2 k4 e9 W, ~; {, n
            DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];
    7 n' E+ c- J5 Z3 @        VOID*   pTempBuffer = 0;</P>
    . Z* I" `/ o* a<P>        pTempBuffer = malloc(dwBufferSize);. @/ w/ d. f; H
            if( NULL == pTempBuffer )
    & S* L: U* V& l" H  f        {8 R3 e' F) K: R  [9 I3 v3 ^
                //Out of memory& h6 {: x" {8 d6 \  D
                DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
    ! ?2 O9 x/ E" m3 i# a. I            free( pSvrAckPack );
    7 W$ p/ g7 {- }4 H( |6 H            return;6 O  }0 v4 `6 X  s& k
            }</P>
    2 |. ~  }/ A$ e! a( R' c<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');9 B; M0 t$ u9 [7 b, |
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>: Y5 i  J0 {! l, N
    <P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );
    * r( Q5 J/ D  D- @2 e. I0 N' M    6 b6 y! r6 W, l: X5 x2 r! P
            free(pTempBuffer);
    ; o/ t0 ~! y% S4 v  I' t) ?& H    }   
    $ e7 H; c  x9 A8 `5 _    else6 U% H% Z  }6 _$ k
        {
    & b* S+ b  B/ H1 H% W        SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );
    7 }9 ]* }; b$ f3 Z    }</P>
    / |( W0 ^, ~4 V* J. K. E* V<P>    free( pSvrAckPack );</P>
    : O3 X' I2 F- W' i2 g<P>}</P>
    , j3 d+ U/ D7 T2 X/ ?/ x# _* s$ j2 [& W, B, I. y/ K* M
    <P>5 D' E, f- y, h+ |
    //-----------------------------------------------------------------------------5 k  t5 i) B2 D2 A( j# N0 V
    // Name: , A, P1 Z) V$ i
    // Desc:
    8 H, e: [+ T. i/ o& s! ?# A) w//-----------------------------------------------------------------------------8 A4 i/ E, z2 M' O8 I4 D2 l1 p% z
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )* V; f9 d5 A3 o
    {4 @8 j$ G& P4 @- a; j- k
        // Grab playerdata for this client and lock it) z: K* o) |4 h8 h5 o
        PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
    # G0 C. L; S% H$ r2 q    if( pPlayerData == NULL )8 w6 y9 s! y. k  w5 ^# _5 M  p
            return;
    " z+ O* {; q+ K) ^7 A0 y    LockPlayerData( pPlayerData );</P>( H! c5 c4 Q/ T
    <P>    // Record the version number 5 ]2 B- V4 L% d2 q
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
    : Y/ A/ T, h5 \2 E<P>    if( m_bLocalLoopback )( l4 K. D0 C: O# Z
            pPlayerData-&gt;bAllow = TRUE;
      Q4 D( l% c% h& x8 v* U1 t4 ~0 s, ^    else2 M: u$ `8 v' s2 c: h8 O+ C# h& \3 G
            pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>
    7 }4 g  x4 F9 {4 y( I2 i! f4 J$ w<P>    if( m_dwLogLevel &gt; 0 )
    0 |+ W" G4 v, P# R        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Client version=%d (%s)"), pPlayerData-&gt;NetID, pPlayerData-&gt;dwVersion, pPlayerData-&gt;bAllow ? TEXT("Accepted") : TEXT("Rejected") );</P>
    ! U! [# C! @2 ~/ C+ j* L<P>    if( FALSE == pPlayerData-&gt;bAllow )
    ) g4 ~! G6 v, P. ^# M    {
    0 A3 M5 X7 |7 ^) \- j        if( m_dwLogLevel &gt; 0 )4 j5 L% x7 e; ]  D( o
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>7 B# u9 `6 s, _, Z0 K
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );8 ^, f; I) \, I* {
            UnlockPlayerData( pPlayerData );
    3 t. f. z# [( t! @: W) l1 k+ v4 i2 r        return;
    + L. \  f, U( b+ ^    }</P>( B" ]* P9 O" b1 N
    <P>    // Unlock the playerdata. i. U1 I" |3 h
        UnlockPlayerData( pPlayerData );</P>
    " S, }% T0 ~0 \% U& j* E<P>    // Send acknowledgement to client that the client was either accepted or rejected3 e) v! i' \2 @& P
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );$ Z6 B+ H* H7 O& ^$ B6 H
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );6 Q2 s2 W9 c* y% B
    }</P>
    6 S, h2 p1 O. R& _' }0 Y: w2 r% z* G/ m* h* H
    <P>( @( ]6 S+ E- K
    //-----------------------------------------------------------------------------5 a6 g; v% ]. z9 ^* D
    // Name: 7 ?4 r& n( A' L
    // Desc:
    5 y7 n/ H4 P8 Q9 y" s//-----------------------------------------------------------------------------8 X9 |; u* J+ E( {/ k. l7 g) J9 y
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
    # e- _5 I: B+ W6 ~  X3 \. A{! T9 |  R9 R& c+ w; N! j$ n
        switch( dwClientVersion )
    . A; Z9 `* x' P9 A7 W& H    {; Z- }% j. t, h& ?  n
            case 107: // only v107 is supported
    & Y9 X; M6 P3 q' s( D# n1 E+ j            return TRUE;
    % S* z0 o' X, T1 f; e4 c* t1 j        default:
    , Z4 a+ H% O8 f            return FALSE;
    . r4 i. \- U; d    }4 N' i; y  _, Z# e3 W( S5 o
    }</P>
    - x; \; ]3 Q, M0 {9 z9 \& o4 v! q$ F9 t. m0 L+ y
    <P>
    8 E2 A; B. T6 F//-----------------------------------------------------------------------------
    3 g6 w4 i0 B* `. k7 o+ s// Name:
    8 q# @: |0 B. V# m) p2 x+ K// Desc: 8 t, B5 |$ n9 s7 c6 U
    //-----------------------------------------------------------------------------
    : v3 F1 [  I2 F/ Fvoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
    . I' x) x7 J# a# x$ U{  J& e1 n: [8 W- J) F
        if( m_dwLogLevel &gt; 1 )  _  ^) ~2 l3 b& p  I
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>
    0 N; A# y) D% o. A/ S<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );, O4 @' a! ?( Q4 T! U
    }</P>
    ; m' s$ g; C# h. {) a0 Q4 j" ?% m1 R+ X/ w- u' w2 [5 r
    <P>' G- a6 |! v) x/ n" ]( L
    //-----------------------------------------------------------------------------) z. J% u8 V. H" ~5 J$ Q
    // Name:
    " Z0 s* p+ u. r6 @  T// Desc: 8 `' L2 c  M; y- j* f5 u' o5 T
    //-----------------------------------------------------------------------------
    & t" F. F) x0 {DWORD   CMazeServer::IDHash( DWORD id )
    ! e3 J$ s& Y+ g( E{& u$ Q  r0 F  H3 \" V
        DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);
    ' \6 p. E. h7 Y( [1 |$ O; e    return hash;
    ; {/ ?& H# W" f, p0 y  P}</P>
    0 `" r+ b" Z+ |9 c, v# }5 k
    1 ]/ J7 G  b. q0 u<P>
    - Z5 u6 K) ?+ x( S; a9 V# p//-----------------------------------------------------------------------------
    & ^" J$ H3 K+ G' N// Name:
    " @. ]& i0 {2 y// Desc: 3 X6 |( n2 \7 H& M
    //-----------------------------------------------------------------------------5 w) B" J: [* N( N  y" M5 P
    void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
    7 ^+ h; U% Z1 }2 e{
    7 U. q5 C  Z# @# H8 K% k! f    // Hash the ID to a bucket number! ]1 s/ Z7 }) X3 P1 ]
        DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
    2 N( }& a7 E; G% N+ r* y7 E: O<P>    // Lock that hash bucket
    # K* Y/ m6 i" m/ X0 ]' @7 _    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;. M; [% X& x3 F
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    ! M# G$ f: ?2 H' _  B/ I, z8 p<P>    // Loop though players in bucket until we find the right one  m1 L  U: O5 q7 F) Y* m
        PlayerData* pPt = m_pstIDHashBucket[bucket];/ l/ D$ z; u6 p  S+ X2 i& L$ [4 ^  C
        PlayerData* pPrev = NULL;1 }" \% ?5 `7 J5 G
        while( pPt )
    / O# s2 j% P( ]  c4 B$ w0 Y6 L    {
    7 Z- h+ d) G# C8 j( b! h* t        if( pPt == pPlayerData )
    - g0 e' V" a2 b% o- m            break;
    2 b  V  A/ U* P, Y! ^& V( P5 a! p        pPrev = pPt;$ K4 P" Q7 p- Z
            pPt = pPt-&gt;pNextInIDHashBucket;
    ( E' O" s3 b$ T/ b    }</P>
    2 J+ l' i0 U* Q! G1 Z5 o9 {<P>    if( pPt ); U2 c; O; T2 q4 C. R+ Z
        {
    5 {# M% }/ }) D, v: ^        if( pPrev )& l8 f5 \# L& z# ^, N# \; E* Y5 `
                pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;
    ; d. H  C# G* \2 o' D' F        else/ r2 f/ R+ E7 a( c) b0 O" O5 C
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;2 S2 P: e$ g. k9 c2 P: h
            pPt-&gt;pNextInIDHashBucket = NULL;
    ' K" R! M* A# d    }</P>7 T" |+ h$ h* w3 ]  u8 P8 E' C
    <P>    // Unlock the hash bucket; \$ P2 C: c2 q* Z! b
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    . }, b4 v0 v. D' T# l2 \( o' l}</P>
    9 s( I% a9 Q1 v4 S# ^* I- t. u" Q+ _2 E  W1 y7 h
    <P>+ z) T( J% f4 Z3 E
    //-----------------------------------------------------------------------------( N" x$ A6 g3 L* g! A* V6 {: J
    // Name:
    % W+ P  ~$ \% D) |& r# f// Desc:
    : ]' ?$ o- c' t5 V, S1 A0 y- ^//-----------------------------------------------------------------------------
      V- I$ O* G8 Rvoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
    $ ]& }5 Q  J5 l1 v{$ }( F! _. I5 g6 [" \2 x7 b6 O
        // Make sure this player isn't added twice to the m_pstIDHashBucket[]
    / y0 {/ u  z7 R& i5 _3 t    // otherwise there will be a circular reference. E- F# [9 m- G4 l; i6 m; A
        PlayerData* pSearch = GetPlayerDataForID( id );8 a: Z7 p6 B! S7 V6 N# ^
        if( pSearch != NULL )- @+ _+ \' y( ]6 S
            return;</P>
    5 @# F( M' N1 _3 v6 U& t<P>    // Hash the ID to a bucket number3 w2 A) C' A! w. z8 o4 n
        DWORD   bucket = IDHash( id );</P>
    + h" ]. q: v. x, I! J; O<P>    // Lock that hash bucket
    8 s9 z: A! t6 m$ ]/ S1 X+ }    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;4 [  ^% }. D1 \- q- u: D& f0 `' C
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    - v; g  N5 J1 r0 m<P>    // Add player onto hash bucket chain
    3 ^7 u6 m/ ~+ N( U    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];
    7 B: ^/ b; X" }/ w* _/ _    m_pstIDHashBucket[bucket] = pPlayerData;</P>
    ' c0 F- k) a5 U3 e( ~* h4 _<P>    // Store net id in player
    % a0 D- |- p5 e* c+ p    pPlayerData-&gt;NetID = id;</P>) J1 G4 ~$ b! D# b- A! V, D1 \
    <P>    // Unlock the hash bucket2 J  G" e. n4 H" S
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();  n6 S/ F  m* d  S
    }</P>' r# N; B' U0 D( N8 e

    9 l; H) |0 O7 v- t1 o& B  v1 n: z# H<P>9 w! I3 p, S$ w8 W, J- D$ T# t
    //-----------------------------------------------------------------------------: z# n3 |5 v9 I" S$ ]4 ~
    // Name:
    & H# n# r) K+ ~7 Z5 B3 z: P% I- R// Desc: / [) ~5 `( K  V& U! ?1 J4 o  \
    //-----------------------------------------------------------------------------
    ) J3 P6 g8 w" t6 pPlayerData* CMazeServer::GetPlayerDataForID( DWORD id ); G- i* k3 Y5 p$ Y/ P" `
    {
    & G& K2 g9 W) i( K" Q    // Hash the ID to a bucket number
    4 O' g& d% E" \- l' Z    DWORD   bucket = IDHash( id );</P>
    6 x/ D- `/ Z1 R5 O7 g<P>    // Lock that hash bucket
    1 s. X1 A6 P+ y3 v7 n8 K# f    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    % q- u0 z$ a' j1 y# ~    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    " C# ?! F( d2 b; J<P>    // Loop though players in bucket until we find the right one. F7 E0 Q( r) y9 v' F
        PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    1 c( o6 g! K) `* i: }; _6 F! Z    while ( pPlayerData )
    % [2 O0 x1 |6 E$ C% I# K5 _$ u( _    {; j* ^- e. S6 [
            if( pPlayerData-&gt;NetID == id )
    5 q- }  S$ Y" K& j, h8 W; O+ o, N/ q0 Q            break;) i) c' f8 J$ X5 i. M, V1 a
            pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    ' |4 R2 N& G5 G: L% A5 f+ Z7 [    }</P>
    7 t( u5 @( q# B, l& }3 @' k<P>    // Unlock the hash bucket
    0 A6 n  A; F/ e* G- Q' ?    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>
    " |& p- m1 _, R" A<P>    // Return the player we found (will be NULL if we couldn't find it); L& W6 Y0 v* S6 O6 T0 E
        return pPlayerData;
    0 Q( ^8 M1 D$ X1 x+ x}</P>
    4 e3 C+ g6 K" q0 W6 F6 c  J# X% d: i, S  `
    <P>
    0 w3 C+ R6 o2 m1 I. i//-----------------------------------------------------------------------------% W4 b7 a3 v. _* m
    // Name:
    # `$ G% [5 q: [, Z. M6 ^( w2 j// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner
    $ G$ _. I7 S4 T: j; Q: t& ?9 j* }//-----------------------------------------------------------------------------3 T" a+ k% d( K) g% }" T7 }$ Z
    void CMazeServer:isplayNextConnectionInfo()
    ' Q6 r' H7 `$ M. R: ^$ f) T7 V{
    ' n' F  h8 q8 k4 `; S    if( m_pNet )# u$ W- H6 R/ J# T0 m; |
        {
    ) U- {. Q( a6 x4 b( [% }" `        // Find the player that was displayed the longest time ago, and display it.# L+ ^0 B* }2 b/ x8 H- ^6 m0 Q
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
    # ?2 }/ s. h, c* B% u5 F2 H5 X# S        PlayerData* pOldestPlayerData = NULL;
    $ P7 ?2 s1 n7 U6 s5 k0 o        FLOAT fOldestTime = 0.0f;</P>8 x- q) r, w/ ]
    <P>        m_PlayerDataListLock.Enter();</P>
    ; B! J; D9 j" i" b. J) W# p<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
    + |5 I: o6 k; |3 Q% i        while ( pPlayerData )
    ) Y2 ~( b9 K1 H/ S' h1 i/ j        {. e; B- m: ?4 V. R5 X7 G* k
                if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )# \- E. t( q+ `- l
                {
    ; X* e1 v5 \9 O) T                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;
    0 s! y$ U+ C* F! T                pOldestPlayerData = pPlayerData;
    3 d% a; |( A5 J; `  A3 g            }</P>* n, c1 A! H( \  q3 w
    <P>            pPlayerData = pPlayerData-&gt;pNext;
    7 ^& K% c3 r0 d7 {, e9 a) g2 H8 ]        }</P>  `; @6 I( ?2 \, }  ?
    <P>        // Display the player with the oldest CI field, and update its CI field.
    , u, ]" S' b+ M/ i6 b        if( pOldestPlayerData )
    ' z0 q8 h' _1 |, X        {
    8 }4 c' s% a& r' T            ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );. W# H5 E  G/ E' }; q
                DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );% y( Q4 P& e6 T' r7 P* Y2 Y0 z2 P
                pOldestPlayerData-&gt;fLastCITime = fCurTime;4 f% h  X" W4 O$ F& p0 G
            }
    0 B+ z; Y- z! N! g        else
    $ i/ \( w7 V! K' A- ^        {
    # B1 n( t" D; d) R/ U# Y9 T            ConsolePrintf( SLINE_LOG, TEXT("No players found") );) g* j0 F: c8 y5 M
            }</P>
    5 d7 j9 @5 p7 R4 F5 e+ i! Y<P>        m_PlayerDataListLock.Leave();
    $ U( h. b$ K2 d- V2 q* _0 |: L    }
    5 ]4 W: z! z8 |. m}</P>
    / Y+ n$ h4 L" g
    . p% b' A% A' q% P" a- K- v<P>5 [. {& B. N: O* Q5 P
    //-----------------------------------------------------------------------------
    ' A) `, k1 Y0 o8 |1 l// Name: 2 Y' U0 \( N9 ?/ m
    // Desc:
    : v2 ]- b7 M2 V  ~//-----------------------------------------------------------------------------
    $ S$ y8 J) u; l6 }  P4 n$ h+ ~  Ivoid CMazeServer:rintStats()
    " r9 ?" _3 Y+ [{+ b6 q- X- i* R  ~$ w7 J
        ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"), ; g0 D6 M$ Q& H3 G) ^6 d+ ^+ N" X& H$ w
                                        m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );
    1 M4 c# ~& s9 P$ X5 [+ {7 a( C6 Z    ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),% T6 I: Y% q# a( s/ n( ]! g
                                        m_fAvgThreadTime, m_fMaxThreadTime );
    . @3 \+ v) B9 t+ z: ]# m2 Y    ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );2 z4 d8 G/ J% g- R9 [4 p  P
        ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );7 x( X3 n- i$ ~( \) u% Y
    }</P>( Z0 `* k3 _1 j$ a9 p8 ]8 N  S

    / r1 y& `  H1 w# P6 v" |<P>4 P% W  b) K" A& D( t% I
    //-----------------------------------------------------------------------------7 M! t: h$ Y5 K) w- _
    // Name:
    $ l) `7 V# g: o" ~! \7 Y// Desc:
    3 B- [. j" j2 o4 W& ]//-----------------------------------------------------------------------------
    7 S& n. ~1 _6 v! `3 s% v1 Lvoid CMazeServer:isplayConnectionInfo( DWORD dwID )
    ' w4 K" o3 U0 L4 `1 A1 t- K{
    ' L$ Z# K* J1 r1 R! x7 B* x    TCHAR strInfo[5000];
    / J( t2 a" v: g3 x    TCHAR* strEndOfLine;) |7 w- h' f" E# h9 {
        TCHAR* strStartOfLine;</P>/ x( V5 ^& w; A5 T7 m; }: y
    <P>    // Query the IOutboudNet for info about the connection to this user5 ?2 A6 A+ t( T3 Q1 l
        m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>
    : s, C9 l, ?1 b1 i" _: T<P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );9 L- Y2 W( X# A4 b+ y+ |* F6 x$ x
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    8 t; s( E+ x- t( v2 v2 v) ^) F<P>    // Display each line seperately
    ) F" v, ?. C4 o7 c$ Y) u8 E/ n2 O    strStartOfLine = strInfo;- S; r% v# p* C+ l/ \* y
        while( TRUE )
    , \% Q- e7 E: `& D( v    {* j. |* @' Y$ f/ e1 Y& i
            strEndOfLine = _tcschr( strStartOfLine, '\n' );
    7 O# V4 g' ?3 ?0 o. i8 y        if( strEndOfLine == NULL ). I; g% [& W0 `. E2 H6 i8 Y
                break;</P>
    / v" D( R- B; B2 E  {<P>        *strEndOfLine = 0;
    , \; i& |; z- C% z8 l        ConsolePrintf( SLINE_LOG, strStartOfLine );
    % w* \! |% e5 \  V$ l  E9 P        strStartOfLine = strEndOfLine + 1;- o9 {, B. D6 B/ X3 d( w) p# N
        }
    3 Q: ^2 w0 j1 A" @}</P>+ }. Y/ Z) Y  F

    / V& k+ L) n8 s5 z0 h<P>
    / s5 v4 d' g, W  H% G//-----------------------------------------------------------------------------: }2 S, m% U( j: g" f/ I8 [5 E( ]- O. i
    // Name: 6 A: k8 @, p( T8 m$ l
    // Desc:
    2 \& V  N$ ]% B  Y" r) Z. ~. c//-----------------------------------------------------------------------------
    ! j: z) Y6 x+ C5 x& q: {5 bHRESULT CMazeServer::SendPacket( DWORD to, void* pData, 9 Q) {8 I- e/ {1 o8 Z4 \
                                     DWORD size, BOOL reliable, DWORD dwTimeout )
    4 U  J9 u+ ]* q6 P- p{
    ) \3 n+ z+ ]8 s    // Chance of forcing any packet to be delivered reliably
    7 p' s2 @+ t1 J3 e& t+ g" w9 ]0 M    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )
    3 K0 P$ ~& r' @& T4 E        reliable = TRUE;</P>; B% X9 L; O3 o4 S
    <P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    + Q' \! n0 m  m" J& C}</P>$ h. f$ E/ _' p% s" r6 X; Z, k+ X
    ' p% E- e. |8 u* |% V8 D6 _% t: P
    <P>+ ^0 g3 ~' s( g2 |; r
    //-----------------------------------------------------------------------------
    9 Z9 q4 j/ Q% a. b// Name:
    + D" N0 D& n/ F& G8 t1 Z" f- X// Desc: : i% |! J4 s2 |3 j& H+ h8 _* B
    //-----------------------------------------------------------------------------
    8 t, u" n) ~2 q0 ?0 `8 Kvoid CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket ): a( D* I$ G, }) I2 t, e
    {8 e* e7 B& j6 K; ]/ R! E" K
        // If we're up and running, then send this new information to all clients
    6 |; h: u3 T. S  J6 N    if( m_pNet )
    9 \: G; o! S* k4 s" \    {
    , B4 z! e# b) n        //Use the AllPlayers ID
    8 ^  G$ Z4 D1 r' s; N8 m; A        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );
    9 q& {4 ~6 e3 t    }; O5 R+ ]# P$ P6 D: F1 r
    }</P>
    : C9 e) \; [) Z. L8 ~9 l3 W0 x- o) s
    <P>! e2 v4 M; i8 X; Y0 B" ~
    //-----------------------------------------------------------------------------
    & D: r# a" M! z: u1 i// Name:
    . l3 Q# u3 B9 g// Desc: : g1 r  R  }& {9 A9 e- L+ U
    //-----------------------------------------------------------------------------
    ( p' J7 ^% _% I- T" n2 |& R# mvoid CMazeServer::SetClientReliableRate( DWORD percent )
    + s+ Y% L( `0 B+ N: J# C* v6 Y{
    ! b6 u# ?5 ^1 w    // Update client config, and build packet containing that data  i( `0 N" |& G, s- K
        m_ClientNetConfigLock.Enter();
    . _( K/ B+ w3 W    m_ClientNetConfig.ubReliableRate = BYTE(percent);" J8 u2 a' h1 l) g# m
        ServerConfigPacket packet( m_ClientNetConfig );+ O% @) b- r1 c" _8 z, ~3 I
        m_ClientNetConfigLock.Leave();</P>8 X/ w* u& C' k* b' _4 ^( B: `2 r( `
    <P>    SendConfigPacketToAll( &amp;packet );
    % L' m! Y6 I  v+ x/ X}</P>
    / I9 p8 }1 e) G+ Y9 g$ O8 f
    8 E# t0 E- V# ?& P<P>. g  l; v/ S0 _8 f/ }' ^( F7 V; ^
    //-----------------------------------------------------------------------------
    : _1 Q1 h. H  {! M// Name: $ U( q5 C: x5 c. j4 e* N3 j3 O
    // Desc:
    5 ^8 K5 C+ U8 Q6 e//-----------------------------------------------------------------------------1 M' P  J5 u% m9 C& N
    void CMazeServer::SetClientUpdateRate( DWORD rate )
    ( Y$ D7 G# }8 W" Q5 y/ P{
    8 F& _) t& w$ ?- l    // Update client config, and build packet containing that data' z8 c6 C2 d- V# \7 c7 r
        m_ClientNetConfigLock.Enter();
    % G1 D: t4 z% f1 P    m_ClientNetConfig.wUpdateRate = WORD(rate);
    : n' P7 f2 [# S1 E" b    ServerConfigPacket  packet( m_ClientNetConfig );/ f( q, h5 E. R; w* V
        m_ClientNetConfigLock.Leave();</P>" Q9 H& R5 T' R+ _8 t& e8 Q. x5 M8 N
    <P>    SendConfigPacketToAll( &amp;packet );& C$ n, ?) n5 V$ |. W7 E8 K
    }</P>7 ^4 s9 n$ F! f
    8 M* k/ i9 |9 Z
    <P>
    : v% `# W9 [( P* T//-----------------------------------------------------------------------------; ]1 F8 Z' o) Q* s1 Y5 d( O$ z
    // Name:
    ) W! X- Z: n: }// Desc:
    $ K1 v4 A* D! g7 D2 d  ~# R//-----------------------------------------------------------------------------
    5 s( m0 U0 y4 B8 ?0 Rvoid CMazeServer::SetClientTimeout( DWORD timeout )% m2 A- J; a; }, X4 T
    {
    ) P5 U" t# I. V    // Update client config, and build packet containing that data
    0 S" c1 K8 T0 x3 D9 D$ X/ ]    m_ClientNetConfigLock.Enter();$ r7 o( e( r% k; {* }
        m_ClientNetConfig.wTimeout = WORD(timeout);* E+ u- R  i# s
        ServerConfigPacket  packet( m_ClientNetConfig );% \# U' L0 k  v; P8 c$ e
        m_ClientNetConfigLock.Leave();</P>
    3 ]% Y* G& x0 b<P>    SendConfigPacketToAll( &amp;packet );1 q4 j8 r5 V# Q! R9 S
    }</P>
    9 y+ W" z% D* x( L( `6 v' X* d& V4 ]: c9 E
    <P>
    " }- p: K8 j6 f9 f( K# g! R/ B' Z//-----------------------------------------------------------------------------4 Z# l3 o- Z2 g1 ^; L0 G$ k' j3 ?
    // Name: + c& L& d' K& B: j- [
    // Desc: . s7 \2 ]  y& J9 n
    //-----------------------------------------------------------------------------
    1 Q' \( L) n1 x) m$ \2 X" H% ]void CMazeServer::SetClientPackSize( DWORD size )/ X" h% q" J0 a2 x8 Y
    {2 m3 a0 j1 F; x- ]
        // Update client config, and build packet containing that data$ O* S: x; V( K8 f+ {# d
        m_ClientNetConfigLock.Enter();8 T: L3 C" B! {
       
    - Q, I1 Z- L" e    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.  C3 l! A7 [: X0 {- n4 D" O- k# _
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   
    8 f9 n; |, y; w) F8 e$ J        m_ClientNetConfig.ubClientPackIndex = 0;</P>
    * z* o- ?4 F$ M4 m4 @# Y7 h<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);
    # V$ ?: c3 z+ B2 B+ s    ServerConfigPacket packet( m_ClientNetConfig );
    , l! l  {8 J9 e0 M/ \6 W    m_ClientNetConfigLock.Leave();</P>
    , T) K7 u1 `. ]6 H& K, m# f<P>    SendConfigPacketToAll( &amp;packet );
    ( w. k9 V. f1 H  O* X}</P>2 d# b9 c; K6 }/ g
    ) N3 I. W1 @$ G: d
    <P>+ M  g/ w% I- g8 o: E
    //-----------------------------------------------------------------------------5 T: s# r3 J- `3 U+ p! _7 k0 j+ F. R
    // Name:
    ! W5 F% ?6 D6 h! z! o5 C$ S// Desc:
    - i4 p: b0 Y( x1 G' |//-----------------------------------------------------------------------------
    , U& O% B1 I' ~- V( l7 |/ avoid CMazeServer::SetServerPackSize( DWORD size )
    7 z1 C% B' z0 \" @{9 I! p1 @% r3 K, L+ F+ w
        // Update client config, and build packet containing that data
    9 x3 I6 D6 [  i: u4 S7 ?$ Y    m_ClientNetConfigLock.Enter();" ~* ~8 L0 A/ q" Z
        9 L  m9 R# G; d+ ]+ U: D4 x& \
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.
    & ^8 B+ `& h; r6 g# `) l    if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   
    5 U; `" Q) l- k. o0 A: ?- ^2 c        m_ClientNetConfig.ubServerPackIndex = 0;</P>/ p& \& N4 M* W; @. G0 ?
    <P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);1 o5 T( D; v' B3 L# Z& v
        ServerConfigPacket packet( m_ClientNetConfig );0 P5 e& M$ N8 r% k4 b  J
        m_ClientNetConfigLock.Leave();</P>
    + ~- [: \. M2 |) t# E( o<P>    SendConfigPacketToAll( &amp;packet );
    ' P" j" f( q9 Q9 y# B  B}</P>
    3 U0 ^% N8 }) a7 d<P>
    & G  f+ H. k( p2 T: F: Z: g9 G' J//-----------------------------------------------------------------------------
    2 Z  u& r# c. p' f1 c2 a& i3 V// Name: % V- {- v. k' o- {2 a/ S4 k
    // Desc:
    % S6 k, i0 B  D; j" O//-----------------------------------------------------------------------------& M0 w1 v" @1 l  W5 D
    void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
    ( ^1 t% c6 b# p3 P2 h1 ?{3 D+ A8 k& ^4 b: g
        // Update client config, and build packet containing that data
    ; x  o! c# s7 o4 d6 f    m_ClientNetConfigLock.Enter();
    ) P/ q$ w6 f. X, l    & \# g/ t: P6 O7 Z* I, q2 Z
        m_ClientNetConfig.dwThreadWait = dwThreadWait;5 F+ h6 p. p' Q! `8 s% n
        ServerConfigPacket packet( m_ClientNetConfig );
    ! H4 T: z# g7 Q9 [' l; H9 e    m_ClientNetConfigLock.Leave();</P>
    0 ?4 ?9 y. g, Z- d# y& v2 L<P>    SendConfigPacketToAll( &amp;packet );
    + f9 [7 a: m4 e- c}</P></DIV>
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-10-9 11:37 , Processed in 0.741206 second(s), 51 queries .

    回顶部