QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4162|回复: 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>1 X) x, R- f5 P( f
    <>// File: mazeserver.cpp+ t$ ^8 [' \% I% I0 P8 l5 s
    //
    * o5 }' A) Y# ?9 ?' H5 i8 \// Desc: see main.cpp
    & _2 h- Y& r, Z+ |. k//" R' Y( R0 w1 h, i6 l& V% e% W
    // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.1 {! _* \, F; A- b" C0 ^
    //-----------------------------------------------------------------------------: K1 k7 D$ X, s) R7 z1 z, c3 t$ i- s
    #define STRICT* x2 O0 Y5 }/ |* E3 N( H& {
    #define D3D_OVERLOADS/ A+ g8 f7 t' {* m! E& N  A
    #include &lt;windows.h&gt;* i" j# v; c) f4 B8 M  s
    #include &lt;d3dx.h&gt;
    $ K9 @' K) G3 K! X#include &lt;stdio.h&gt;
    ' k+ ^6 r* A; J( ^, v. K#include &lt;math.h&gt;
    " R) K( V2 U, D; _#include &lt;mmsystem.h&gt;
    6 U, K, t. l" k3 R" _: c$ d#include &lt;dplay8.h&gt;( I% C  _$ M- K7 E' V# h
    #include &lt;dpaddr.h&gt;/ V; Y& h6 D; y- ~+ Q3 `5 }- o
    #include &lt;dxerr8.h&gt;/ z9 s  |  J* h3 q
    #include "DXUtil.h"0 \* y' G) W$ t% V$ ?
    #include "MazeServer.h"5 D6 X) D5 S! N+ q% l! @6 n2 K
    #include "ackets.h"
    / k' s0 p2 @: ?#include "Maze.h"
    - i) y1 p6 Q4 w( C5 D' ]1 H+ T#include &lt;malloc.h&gt;: N3 ]+ s+ D+ V
    #include &lt;tchar.h&gt;</P>- h: l) T# \8 @- n9 X8 c

    5 D0 |" t. r; h- g<>//-----------------------------------------------------------------------------' e3 `+ ^3 y3 v
    // Name: ( {" L/ t4 y+ F
    // Desc: 8 X& p' }# q9 ?( M) y
    //-----------------------------------------------------------------------------
    ) [8 c+ k3 E$ WCMazeServer::CMazeServer()7 f9 o1 b1 p& x. D# l- w! R
    {
    ' e% ]( l2 ?. l: b- Y" A    m_dwPlayerCount         = 0;& R- |8 @. L0 e1 g2 V6 r+ z# x
       
    ) X9 a! {, Z- U4 i; ?  `$ A6 }2 H    m_wActiveThreadCount   = 0;
    7 _3 J$ |1 J" m+ O% |2 z" ?# p$ c    m_wMaxThreadCount      = 0;" m0 {0 ~3 \; f0 L
        m_fAvgThreadCount      = 0;
    ; j' x% e0 a' r  t$ H    m_fAvgThreadTime       = 0;8 A: X7 s9 _8 Z8 ?1 u
        m_fMaxThreadTime       = 0;</P>! f( z: i! s. G* ?9 F" @
    <>    m_dwServerReliableRate  = 15;/ J% E0 W0 d# h+ N' K: w
        m_dwServerTimeout       = 150;5 F1 ^/ V% _0 C/ Y. U
        m_dwLogLevel            = 2;
      y& N5 h3 ~4 v( v    m_pMaze                 = NULL;</P>- a: ?" T! ]% q0 |
    <>    m_ClientNetConfig.ubReliableRate = 15;0 f* F# S' {8 s8 I( z$ l2 W/ t( w- v
        m_ClientNetConfig.wUpdateRate    = 150;
    5 c1 ^' Q( ]; t9 t+ c    m_ClientNetConfig.wTimeout       = 150;</P>
    : K3 N9 i! v2 c/ p: H. A<>    m_ClientNetConfig.dwThreadWait = 0;</P>  R! K% x& M7 G8 `
    <>    m_ClientNetConfig.ubClientPackIndex = 0;1 [6 Y  p: G8 a" v5 s$ t  M
        m_ClientNetConfig.ubServerPackIndex = 0;5 j0 B+ a. y$ d$ I$ ~
        for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)
    % F" s" |; P5 A3 v! t% H) v    {
    7 m" k$ G& W2 s% y7 v+ w        m_ClientNetConfig.wClientPackSizeArray[x] = 0;
    ( u0 R& ?# g1 _, g+ P1 Q/ I        m_ClientNetConfig.wServerPackSizeArray[x] = 0;! r! P8 U+ P  d2 B! ?+ v+ `4 a
        }3 [- w3 S, u9 T. p  U
    }</P>
    1 w* t$ V1 u( \% u) b( L8 Z( m  \( s& f
    <>: ?9 @% d; ?% t& o3 n! Q/ H
    //-----------------------------------------------------------------------------
    9 b  j+ c- Y; b' f9 o// Name:
      N9 m5 B  z7 }3 ]: u// Desc: , b$ |7 A: o' J# w4 T+ K# Z' S
    //-----------------------------------------------------------------------------2 x' G! H5 c2 L3 P$ G  W
    HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )
    , g5 Z; @0 S0 }) ]3 T& d{
    * v$ j* f6 [+ i+ Y5 F+ {, ?    m_bLocalLoopback = bLocalLoopback;* f. c' _1 z! P* n
        m_pMaze = pMaze;' |' |) \  V+ ?' V# H  G  S
        if( m_pMaze == NULL )) R/ z+ o: O2 W" s$ G4 n4 O
            return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>$ a+ U- L! ^9 S) K9 w
    <>    // Grab height and width of maze
    6 t; o" J# T7 _' g$ w    m_dwWidth = m_pMaze-&gt;GetWidth();
    3 b! h4 O7 T  I7 Z    m_dwHeight = m_pMaze-&gt;GetHeight();</P>
    . e3 u0 Y. b" V+ A1 }2 s<>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    + @( A, t& p1 m  e, ^    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>3 ]7 k5 U/ K' ~& r
    <>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.
    * H. i) W5 j; W* g3 c    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )7 {& A, w8 G' F2 _" \- r
            return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    , k8 r2 V% J+ B) J! X% W5 f    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )% k% ?- O7 u8 M. x, \
            return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>3 g9 m+ q4 y( ^0 [: D* U
    <>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;2 T  v$ C$ P9 N. W& a
        m_dwMazeXShift = 0;
    $ j+ Q7 G2 ^( o/ n    while ( (scale &gt;&gt;= 1) )5 |6 E" i: V; f
            m_dwMazeXShift++;</P>' F, W* p7 t3 D6 y9 G; W- p
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;
    3 Q7 v# W& v( j, C2 }- A- [) G    m_dwMazeYShift = 0;1 A' z- l1 h5 U% T0 H
        while ( (scale &gt;&gt;= 1) )
    ! _& D, A, N8 N7 _) {        m_dwMazeYShift++;</P>
    0 e$ L. F) j# u% I  n% U& s% R( \  n<>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    0 p0 N6 J1 b+ r# r0 n' g% a        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )
    ( Y1 w2 x) S) c, F6 P        return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>6 N0 k6 h: l8 Z. R" g$ L
    <>    // Initialise the player list
    ' ^: x  B, `3 O4 s, c2 y    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );' B9 v5 V. t7 u0 m
        m_pFirstActivePlayerData = NULL;( |9 p8 T  d& }
        m_pFirstFreePlayerData = m_PlayerDatas;! j( X5 X+ V; m; d# N& e- |' P
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )
    0 p; a! O. s# r, m5 z: p$ ~    {" T) F8 }2 E' a4 ?1 n: L
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];  R0 h2 ]# z9 f5 m$ |
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];" H# k% @: P" q9 n, A  G
        }</P>8 Q; B' S5 i. o' `3 f, J
    <>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];: a( _/ h) u9 t3 ^
        m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];/ Z$ |( x$ n3 o% z. v3 s/ A
        m_dwActivePlayerDataCount = 0;
    # I0 J! J2 V2 U, `" v    m_dwPlayerDataUniqueValue = 0;</P>
    1 j. v2 F) T( M) c3 v5 J1 L<>    // Initialise the cells
    " q+ Q( e: }( g. ]: a8 P    ZeroMemory( m_Cells, sizeof(m_Cells) );
    # l" V$ `9 i2 W* u    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P># @6 e, A  |) H3 A6 {: Q
    <>    return S_OK;
    0 j0 g2 r/ n- V7 z' [}</P>3 x, k2 V5 @4 E% w5 g: \

    , T9 H6 h9 {+ I2 L<>$ i* x4 Q3 s1 x  Q, G7 K
    //-----------------------------------------------------------------------------, r  H6 [2 u- p# r9 c) \* d
    // Name: ' n8 ?' @# T- q0 P
    // Desc: ! }* g9 r' H. q! p2 R
    //-----------------------------------------------------------------------------  t- P5 s3 g1 z0 p6 t
    void CMazeServer::Shutdown()$ F+ J! t! v! X+ y  e
    {
    6 R* f2 `5 v, Z4 z3 V6 _$ Y}</P>
    7 T$ L, Y1 D+ u* A9 ?- Z6 x# {" n, t; n  A% u* E3 M* X9 T
    <># L' [9 b+ x5 r
    //-----------------------------------------------------------------------------3 r& J- {: E4 b; `3 J
    // Name:
    8 X  B/ U6 z- L/ F// Desc: + k4 G4 F0 V; e# \6 b
    //-----------------------------------------------------------------------------$ E" q, q" {+ c# A
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )3 }! C! e, ]- r  N7 a5 _
    {
    9 T$ e8 K/ Z, P    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    & `& n- Q! F3 `$ B6 B% v0 t+ ^                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );' y( D- Z: a' u% G9 a$ |
    }</P>
    2 m6 c( m+ ^6 t' u# y9 v6 e
    2 _7 b7 }# u8 ~1 |4 q3 m<>
    , R4 [* A( m' ]  r& p//-----------------------------------------------------------------------------
    . c, [' j+ |, g; H8 c( Q// Name: 8 q- c- a3 S! R8 O* j$ V+ |
    // Desc: ( S4 G: B) y( h% l9 s
    //------------------------------------------------------------------------------ }7 h0 I; d2 e1 b- q8 c* Q: S
    void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    " Y3 R4 ^5 m8 a+ ]/ y) z8 D7 p{
    " g2 {! G# \1 I  D    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    ) Y6 [; W+ A- S7 Z* o- a" k                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    % d5 x$ Q# |4 o+ p* G: R' t}</P>; z! m1 M$ P7 ?( R, r

    4 C  f8 e* P. |7 o8 v<>
    7 z& M; S8 w+ W# Z! D7 k//-----------------------------------------------------------------------------/ `1 L$ n, j! v7 S  c1 H
    // Name:
    5 S4 x1 V, |* e" H4 n8 K// Desc: % k/ e* G5 i( i% P: [  a5 ]
    //-----------------------------------------------------------------------------
    # c' t: S2 a, E7 V$ ^void CMazeServer:ockCell( DWORD x, DWORD y )
    9 q! v0 n  s2 F, L{
    " w, u$ J3 b. j, A3 M5 q# A; d  W    if( x == 0xffff )+ ~  a0 K, K9 t
            m_OffMapLock.Enter();* b# M8 G* ^; \; t
        else
    ; ^1 y7 f1 I/ J4 @* ?        m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    ) Z1 D6 I/ v* e- N" b}</P>; i3 w4 s2 w6 d8 R4 E% w4 W
    9 y1 Q  N! {$ v) h
    <>
    , T! [: H! Z% c, D- C- l& P//-----------------------------------------------------------------------------4 b3 g6 N8 S$ N& @4 @
    // Name:
    7 E+ _8 i9 A1 E& y" E// Desc: 3 }" e, }2 q. G, G9 h, P; p% w
    //------------------------------------------------------------------------------ A3 E$ q: D. H+ e
    void CMazeServer::UnlockCell( DWORD x, DWORD y )7 z6 i: r1 q# \4 j
    {, V- b+ r1 f- n! W- |& I. ^
        if( x == 0xffff ). A' K4 I+ s7 _; L& _: R
            m_OffMapLock.Leave();) P$ {: S! o6 \2 Y( r$ W  \) z
        else
    ! w1 k6 Z3 J7 X        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    + b" y3 q7 Z8 q* r- x# w9 U}</P>
    : c) C3 I! m/ q( l! b  i8 f# R/ u6 d
    <>
    % f/ T1 o, ?6 ~: e$ s9 r//-----------------------------------------------------------------------------, x0 y  B6 d  S7 }2 @
    // Name:
    . A: J, o( o; \, Z$ Y3 z// Desc:
    ; Y4 Y! U) z$ W# L- B  ]' i//-----------------------------------------------------------------------------
    * \3 }9 h! {. x4 dvoid CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    4 ~: f5 [/ J- L6 X) K{
    ) f$ c' x  k# a- f+ Y& `# t    if( x1 == x2 &amp;&amp; y1 == y2 )
    1 l5 U+ v9 @! `1 g+ W$ p    {) ^4 _3 h* {9 P* Y7 k5 a6 G  L
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff ); c7 E& ^7 u3 X) \, b
                LockCell( x1, y1 );
    & ?- u$ ~# Z1 R7 [        else
    + s# o1 Q1 S1 }* q: Q! F            m_OffMapLock.Enter();</P>
    2 u5 T, \4 N. f2 v9 V% y8 E<>        return;& [; z' W# y2 g0 I* C
        }</P>
    % Y0 M0 [  x3 ]8 L<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;0 ]/ Y. S5 O* h& u5 B' m
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    % R9 Z9 L3 z# P1 G" @! T$ s6 V    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;3 n9 X$ a, F/ o* K8 r. ]+ M
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>6 u, v. V5 w' ^
    <>    if( x1 == 0xffff )
    ! @( i2 |/ ?" s0 O6 Y( e8 U3 l    {7 b9 o$ @0 x/ F9 _" T
            m_OffMapLock.Enter();8 o' x; u2 b- D7 e4 e" X. B
            m_LockGrid.LockCell(x2shift,y2shift);
    ; ^" }" q" K& ~4 o/ d$ i6 [/ V8 J; a    }7 m% R# |, ?" ^- f/ Z$ O, z
        else if( x2 == 0xffff )
    & A- Z# G5 e3 |6 e4 C    {
    ' i# }, K! t: B' h& Y        m_OffMapLock.Enter();( \' I- I2 h6 @% E3 @0 B
            m_LockGrid.LockCell(x1shift,y1shift);0 y  R) i- n) K. w' k5 t
        }% f# \3 P1 N* s) q9 }# O
        else " ^& C% T' X/ y( h1 ~8 ~
        {
    ( ~* E' _5 v( d& {4 h- L# K" W        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);, Y6 k5 Y, _6 P9 ^6 J" M
        }8 ^7 h- r, z8 R
    }</P>
    * B' Z: r! y8 J+ E6 i7 U
    ) I# E$ T: _/ R. l+ f<>
    8 R% w; x) I( m: R1 \8 U//-----------------------------------------------------------------------------
    $ T9 M0 m: X! A2 n// Name: ) o9 [$ j9 s5 \% C
    // Desc: 2 [4 ]. Q2 e  @  [7 T0 O
    //-----------------------------------------------------------------------------, W: I* D' G  i! _/ c
    void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )4 }0 ~/ m0 n! B* I. \! ~
    {
    ) G4 y. U# W' y" S    if( x1 == x2 &amp;&amp; y1 == y2 )1 r6 o+ n0 M$ F( U8 k" ]$ L0 w1 ~7 K
        {
    ! B. A+ a; C7 I- f  {& u        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    6 U& s7 [; B, y4 p            UnlockCell( x1, y1 );
    , p. N' H3 Z% N! h; r% G( L8 ?        else
    9 u$ }1 w1 E5 ]) w4 a            m_OffMapLock.Leave();</P>" ~& c+ h9 ~" s( @
    <>        return;
    8 C9 u  B8 g& H1 ]$ E( J    }</P>
    2 _- W$ e% ]$ A% l. T( E0 [<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;0 t! t: |8 p& \4 J3 _
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;, h0 ]' B5 z( z% z: I
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;+ e1 `3 B# r+ [% ]6 Z
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>0 R+ v# q, G# |
    <P>    if( x1 == 0xffff )
    5 F9 P: w. Q5 C    {) }! W( @, ^% e4 v! }! j& O2 P* n
            m_LockGrid.UnlockCell(x2shift,y2shift);' R  e+ U1 B( `" O" r- G/ L6 z
            m_OffMapLock.Leave();
    + _5 r8 o7 H9 ?% n    }
    ; ~  g. h" a; I7 F, J( K7 }+ w    else if( x2 == 0xffff )/ e5 O  z7 M' c& Y  A- d
        {
    , w1 q: q; k0 ^) V        m_LockGrid.UnlockCell(x1shift,y1shift);
    " w8 w/ r; j" D! I& z        m_OffMapLock.Leave();
    ) E, \/ E7 ~+ T+ {" T' a  ~    }
    0 d# ^4 ]8 B  ?( c    else 9 A9 W! {  [- k5 h1 y" b/ M- Z
        {9 \# S* W2 J  q9 X% c( N8 `
            m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
    % w) b1 m/ x! o. p. {9 p    }
    ' ]/ h2 ?$ g7 f) k}</P>" Q  D0 s, A, ]. x
    2 D$ J" t! c2 @: x2 _( X! Y% M- @
    <P>+ t  k' s+ x/ O8 X
    //-----------------------------------------------------------------------------
    - O4 ?; H- ?; C  T; R* V// Name:
    $ \  p3 X# o! o// Desc:
    * h, p7 |- N3 d* E4 V+ O9 o//-----------------------------------------------------------------------------* I% N* d5 a# }# s8 i3 P; c
    void CMazeServer::OnAddConnection( DWORD id )
    & W" Y8 u2 L7 i  V" h. \  |/ M{) H0 f  d: O& c1 ~+ s
        m_AddRemoveLock.Enter();</P>( |2 h3 K' {: w7 @: d+ d9 i
    <P>    // Increment our count of players) M5 o! n0 \) R3 U- `7 c, Q
        m_dwPlayerCount++;
    . _& I: }6 `8 U9 n0 i! W" C% D" U    if( m_dwLogLevel &gt; 0 ): t( }& J' G) {. `
        {1 h# L* t+ C4 q8 d7 U
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
    & ]( J2 s( t( t! K. F        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    2 ]3 m" _% t# ^. Z+ |    }</P>& }; }  W0 V5 G' c* x' B' o7 F
    <P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    ; w; I( j  p+ g7 r        m_dwPeakPlayerCount = m_dwPlayerCount;</P>
    * \; d, v( f, W8 ~<P>    // Create a player for this client8 k/ t* J% F+ V
        PlayerData* pPlayerData = CreatePlayerData();
    ! ]) Q# I" W, U. W1 z    if( pPlayerData == NULL )' {! ?; S5 m% R6 _- Z
        {: _7 G1 l# e5 Q  T3 I% i9 g
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );4 K- J- M/ _$ U9 L4 Q$ G) X
            DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );
    & R: S( v# h/ I1 W( |: e' ~' ~        m_AddRemoveLock.Leave();
    1 E! z8 Z* U7 o        return;5 ^1 p+ n. k  v6 [- \
        }</P>. C6 l/ M) e, I; `
    <P>    // Store that pointer as local player data
    " M9 ^: {4 r  D/ _  k( m! e    SetPlayerDataForID( id, pPlayerData );</P>
    , S7 p5 @+ }7 |& r$ l. R" q6 z' d<P>    // Grab net config into to send to client: \0 F1 r! s2 ]& N' y3 G
        m_ClientNetConfigLock.Enter();1 m  a7 `4 H. u0 k4 Y# M
        ServerConfigPacket packet( m_ClientNetConfig );0 P. }+ E% p7 j# [- ]9 L
        m_ClientNetConfigLock.Leave();</P>
    , ]! t( W& |" `1 ]6 g' ?& M<P>    // Send it
    1 x- R" [$ `) u6 R9 d+ W. ]    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>0 m: Q1 j, e2 Q
    <P>    m_AddRemoveLock.Leave();
    0 u$ c% d% V" W/ z4 ~1 H}</P>- ]+ l; C# k; @7 K) h- A$ ^
    * o3 J( N1 R0 O* w8 K9 U7 ?% G/ R6 {
    <P>
    * o4 V) g( @1 M" L0 G- [5 L//-----------------------------------------------------------------------------4 R. ?5 |; i; b5 c1 I
    // Name:
    & P# [! ~# H8 E0 G! F$ Q' |// Desc: : A2 _4 d0 O3 T  s
    //-----------------------------------------------------------------------------
    7 m) G6 y' j: l2 ]6 \. nvoid CMazeServer::OnRemoveConnection( DWORD id )
    & h& ?/ b, ?* C7 `+ V, }{/ v/ K5 C9 }- ]7 i2 @4 X  [5 I
        m_AddRemoveLock.Enter();</P>% E9 F- w2 L& T3 K/ y: Z
    <P>    // Decrement count of players5 j2 P+ ^4 v) ]
        m_dwPlayerCount--;</P>3 B) w& r0 ?% h: A& g# Z+ a, Q$ v
    <P>    if( m_dwLogLevel &gt; 0 ). L2 c" v9 ?+ ^8 T6 i
        {6 f. }! B. |6 a
            ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );. x  S+ b+ }) L$ z/ U3 @
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );* O1 z1 H; S# ~; D% d6 q
        }</P>' D" U9 x) }+ N$ ?0 ~+ B7 L( |
    <P>    // Find playerdata for this client
    9 d/ j; D$ i9 M3 Z4 K* [8 }  L- m    PlayerData* pPlayerData = GetPlayerDataForID( id );
    / j8 @6 {* \" v2 v+ x1 j    if( pPlayerData != NULL )
    8 \+ `0 r; X2 e' P    {0 M$ W7 m' H7 I. x
            // Destroy it% Y3 e+ ?: j) p% u/ E6 ~& `: C4 p
            RemovePlayerDataID( pPlayerData );  V, x3 ?4 ?2 R
            DestroyPlayerData( pPlayerData );0 U2 t  X- f7 y9 w5 s
        }</P>( k7 ~7 a/ a, [. h
    <P>    m_AddRemoveLock.Leave();3 p; R/ X' ?+ ?' j4 ]
    }</P>
    4 P) x& V/ k( L9 B% c" r1 w4 N+ H, t, P5 b
    <P>8 d. j! E' R6 [+ Z) Y/ ]
    //-----------------------------------------------------------------------------
    ) s6 M% K+ {0 [  ?; U  @, a6 V// Name:
    % q4 [4 Z1 H) t; x/ u' _$ t! ^// Desc:
    9 K6 \" _$ [/ _//-----------------------------------------------------------------------------1 {3 G! j/ X, q
    HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size ). l% A" F2 x+ a5 @
    {
    - A6 c7 M6 R# T; {! |6 n( q    BOOL fFoundSize = FALSE;</P>
    ; Y2 T  \  k3 B6 Z4 B/ Z<P>    // Increment the number of thread we have in this process.0 n" q* y: m: |) a
        m_csThreadCountLock.Enter();</P>( Y* h/ y  l- V9 t
    <P>    //Get the start time of when we entered the message handler.
    ! Y9 g( @* R0 [; o' c. u) ]& R3 ]    FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>; ?! _  E- e6 B' M& X
    <P>    m_wActiveThreadCount++;
    9 |( {: o9 n8 D; l# k$ B- @' Z    if(m_wActiveThreadCount &gt; m_wMaxThreadCount), ~( L  s/ G" C8 X
            m_wMaxThreadCount = m_wActiveThreadCount;
    3 s# O4 F  S5 Y+ `0 p    % m, z# {% t1 w' v
        // Calculate and average., v7 r0 S! b7 [8 f9 s; A
        FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
    ( `$ K0 o9 {* v% K# A# \, ~+ C0 a    m_fAvgThreadCount += fdiff/32;! J, G( a7 N) g" A2 ^: i
        / H& g; y: J  W+ s9 P" D/ K
        m_csThreadCountLock.Leave();</P>1 x2 R* m8 s6 w  c4 ~4 {' N
    <P>% q1 B2 w: f5 ]: `! J% ~+ d9 I
        ClientPacket* pClientPack = (ClientPacket*)pData;
    & u; ~' t# z$ p' t    switch( pClientPack-&gt;wType )2 D$ p5 I) ]7 X. a) n% ~
        {
    , O6 C( F' d. ]- q( U( K' b        case PACKETTYPE_CLIENT_POS:) S9 ^) |% F1 d1 d8 e3 U
                
    : o, l$ k% a( S  u9 K2 m. l7 W5 H            // Check to see if the packet has a valid size. Including ! r: W# W0 Z+ z- t" b
                // the custom pack size.
    9 w! J2 Y6 Z' X/ P2 c( Q! X            if( size &lt; sizeof(ClientPosPacket))" E: w" {- ?) r* b4 O# x
                    fFoundSize = FALSE;3 S* d% k6 o. D) N/ b' T- K
                else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))! H" b6 w, s/ p  o2 R( q9 Z
                    fFoundSize = FALSE;& \9 H$ ?9 Z0 A5 U8 @9 }
                else
    / }& d* t- p7 S# f1 m# Q* l                fFoundSize = TRUE;</P>
    " A- R' Q1 o" S, h; d- @5 @& q4 y<P>            // If valid sized packet, handle the position.
    ; Q7 j6 J4 }0 N$ \            if(fFoundSize)( t8 P. Z, D6 G
                    HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );- l2 a" _) s. ]1 g4 k5 v% l( W
                else
    $ B! @. j; [- m3 x" W                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
    , y5 b( S! ?8 [' E<P>            break;</P>$ l$ R5 A9 f6 c: n+ Y- S) [6 l. A( ]
    <P>        case PACKETTYPE_CLIENT_VERSION:
    9 E0 a5 B, V" n& g! f5 x            if( size == sizeof(ClientVersionPacket) )' S$ \/ \% J! M, H" @
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );
    ' q# K& ]" w1 _/ D) h' y" B            else
    9 S9 {1 R8 l$ U3 y                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );- Z9 t6 ~) V& w  T- W: a! k( w
                break;</P>1 u4 W/ C9 _  c. }
    <P>        case PACKETTYPE_SERVER_CONFIG:</P>
    ' e3 O. u. z3 u# @<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>
    : K5 W. P4 m3 T' ^; W' U<P>            break;
    # p0 t- J6 \8 l$ u1 b        default:
    2 L! N5 P" p- T            HandleUnknownPacket( dwFrom, pClientPack, size );
    8 p( h5 l4 z' v- e! I; T            break;$ M/ D* x- P) R) f) A% o4 C
        }</P>, D! o1 G, T# C* T) M# r
    <P>    //If the user wants to hold the thread, Sleep for given amount of time.
    & |2 g! l2 Y# x3 K. G2 P( Q; L3 M1 h    if ( m_dwServerThreadWait &gt; 0 ): V5 B( O! A1 [, M  a
        {" H' `" k& T) g- c* k5 i! m
            Sleep( m_dwServerThreadWait );
    # ]3 N% H" J8 O4 Q' i5 p7 B2 R. K    }+ |( m  w( G' m9 b. e6 O0 F+ ]3 |
       
    + q6 E- H  ~7 o- R    // Retrieve thread data for this process.
    - ]& @6 z" e  V# r/ M; K5 [9 t    m_csThreadCountLock.Enter();</P>
    , S/ Q+ W( Z0 H1 M0 n' ^* G<P>    m_wActiveThreadCount--;</P>  l( h  F4 {5 c* Q" @, x6 K
    <P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
    " B* S- ?1 [2 B! S8 V: \7 }    m_fAvgThreadTime += fDiffTime/32;</P>$ w. e1 `' Z  f4 d3 n
    <P>    //Get the Max time in the thread.
    0 O" m! i# j) a7 w    if ( fDiffTime &gt; m_fMaxThreadTime )
    : r, I: |) a+ u+ y5 `9 I$ ?+ ~    {4 u- j. q' e1 p0 |
            m_fMaxThreadTime = fDiffTime;7 n5 D4 X* _0 V' w9 `
        }</P>- _) k" M( m1 m; U! y$ a/ Z# K+ v5 J8 K6 U
    <P>    m_csThreadCountLock.Leave();</P>
    1 O" j- k+ v  e7 h' c5 [7 R<P>    return S_OK;; U" \/ d: }5 J( Q* C2 @
    }</P>" R0 i$ c$ ~! T6 Y) H. d
    5 W% ^) V+ M- v1 j: E
    <P>//-----------------------------------------------------------------------------  c' W1 [& R7 X1 s) `' J
    // Name:
    8 Z  T9 f& M7 c1 F; P9 H// Desc:
    7 Z/ R0 c5 B! U0 r//-----------------------------------------------------------------------------
    % j2 M) `7 L0 N2 T8 m8 t* o9 ~BOOL CMazeServer::IsValidPackSize( DWORD dwSize )( c# R% P( S3 H, r
    {
    4 N) [; z* T9 K. h% D, H    BOOL fFoundSize = FALSE;2 [4 w1 N9 m' G. b3 [$ @$ \
        BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;
    - b- Z$ T; |0 v1 z2 ?! @/ O3 }    5 z' Q0 H7 Q% c3 e1 j
        // Check through the array of valid pack sizes.
    2 ?) \' u0 b3 X% x7 V    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])" U8 D' V/ y- G$ e0 u6 `, y0 W* c
        {
    6 H4 X, Q) a+ c) {- j+ p        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)
    ; E* H' ~% m3 u# _. C- z        {
    ) k, ]4 _$ s6 a4 m! o  h            if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])0 @9 d0 Y$ ]; u" X# K/ C, ^7 C7 e
                {9 F, Z5 m/ s& k) i
                    // Found valid size in the array.
    : V( s' n- d$ H                fFoundSize = TRUE;' v: @/ {& G$ E5 }
                    break;
    & T& i( U& s; P  R) S/ S9 `            }
    % W) B  q) C# `4 {# o9 j            if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
    1 D+ V& E9 i" z, i        }2 Z3 R. @/ B' S5 l; Y# O, R8 g# S0 t
        }
    0 X- q: l- |$ j5 e- `7 y& w3 v    else' Y5 l, A2 V& T6 n8 H1 p
        {
    5 H* N* c! D2 i5 B/ w* X        fFoundSize = TRUE;
    7 X# Z9 a6 E8 P1 E( n8 K    }</P>
    1 F/ ^& @# g8 h6 m; ^: h- g<P>    return fFoundSize;  }4 r4 T# B. Q. g3 G
    }</P>; C- `* e3 K, |. ^1 _0 k
    <P>/ y- ~- [5 M* ^! C
    //-----------------------------------------------------------------------------# Z: S* Q- ~4 o- Q
    // Name:
    4 _/ V; V' ~7 N9 J4 a+ Q// Desc:
    1 N6 t9 T! z& _; z//-----------------------------------------------------------------------------6 A( K3 h" T' R
    void CMazeServer::OnSessionLost( DWORD dwReason )
    / j# W; K& W2 b{" ~8 A1 S7 Q0 N! N- u  o3 o
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
    / p, ^3 C) Y+ a) f1 }5 Z7 p}</P>1 X5 `+ d, i5 O" [; w

    # c  r0 ]# d; f! O+ h/ B4 I$ l5 t1 O<P># i" L; S. ]' L5 S
    //-----------------------------------------------------------------------------: j% @1 l1 F% x; t1 y
    // Name:
    3 z$ x' {6 g: }// Desc: ; z0 o7 o7 G4 i6 {& y
    //-----------------------------------------------------------------------------9 M1 |  I- Q9 x" |5 Q1 m
    PlayerData* CMazeServer::CreatePlayerData()
    6 J+ `0 v: w% _% ^8 ~{
    4 ^! Y7 |& g4 z* I; k    m_PlayerDataListLock.Enter();</P>) K3 Z& u, B5 l
    <P>    // Grab first free player in the list# t! ]5 n. Q  b/ y8 }3 p
        PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>% r$ I" u4 I, v9 E6 c8 o) E1 n
    <P>    if( pPlayerData )
    6 d9 ~0 L5 m+ `' m    {
    4 L9 l2 l, Y' p        LockPlayerData( pPlayerData );</P>
    0 f$ a  B( U+ |<P>        // Got one, so remove it from the free list: u1 ?! S/ @' A0 d* y
            if( pPlayerData-&gt;pPrevious )+ Y+ \  X7 ~- C7 f
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;6 {" s# o( v# q( U% c; r
            if( pPlayerData-&gt;pNext )* a- [. w3 t5 C* E) J8 k
                pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;: _2 `& B# A, M- l+ e8 ~
            m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>6 N& p( [2 y5 q* u: G6 U0 [/ ]! z
    <P>        // Add it to the active list
    ; P, @! r. r; h; ?1 b& _9 t        if( m_pFirstActivePlayerData )) d4 v8 w+ O# J% e* W
                m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
    8 y( _) a* `3 Z1 j4 r        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;3 {! R% w1 s; n/ G0 T% i7 P  h
            pPlayerData-&gt;pPrevious = NULL;
    : M- S$ i) ]$ w! A2 o        m_pFirstActivePlayerData = pPlayerData;</P>6 k- Q  c- z( j1 {/ a6 F6 `" M2 S- r
    <P>        // Update count of players1 _: Z8 n, A* X" H
            m_dwActivePlayerDataCount++;</P>8 h4 b- L  e0 `# g$ m/ N; D
    <P>        // Generate the ID for this player
    3 a, K9 t( a7 Y  I        m_dwPlayerDataUniqueValue++;
    - S# ^# g5 c6 ]. l4 c& u/ f5 d/ p        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>9 E0 ^1 G6 n8 k6 d
    <P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;6 r% u3 a% _' S0 Z7 n) h* d5 C
            pPlayerData-&gt;NetID = 0;$ P5 K# J: p# K' U0 [. h2 ^
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>8 K/ }" Z& C: \: K! F3 f% P
    <P>        // Insert into the "off-map" cell  Y/ F, v: M' `& Q" `
            pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;2 J- N; Z( y  u2 A
            pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;" s) W% f) q+ q
            m_OffMapLock.Enter();6 j+ Y2 G8 ~8 i4 R3 O, w
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;& \( E( B  _3 l+ \
            m_OffMapCell.pFirstPlayerData = pPlayerData;: h- d0 t& Q' b
            m_OffMapLock.Leave();</P># H* D5 p( f5 J9 ~) w( ^& A" n
    <P>        // Mark as active
    ( k$ Q( z  ^! `. J        pPlayerData-&gt;bActive = TRUE;</P>8 ^3 g! _0 S! m; K7 t
    <P>        UnlockPlayerData( pPlayerData );
    ; y+ z8 J* _2 l' a3 ]* v5 Q# ~  U    }</P>
    , o: j9 X; p7 ^* B6 h<P>    m_PlayerDataListLock.Leave();</P>
    . H% N* V2 t0 h8 G2 U! ^<P>    return pPlayerData;! P0 v; [# F0 E
    }</P>6 J, u8 p/ W8 e/ E
    ; A2 _" [% v$ P+ X6 e
    <P>! f. s; x! C6 j; l# n7 v' c! k
    //-----------------------------------------------------------------------------( F  N8 W, O& q* E8 `
    // Name:   c$ h4 S5 l5 G7 V% C
    // Desc: * A6 S& E2 k- o0 p. L6 f
    //-----------------------------------------------------------------------------
    - b% K; f7 Q9 Q1 Z: w4 e; x: Q& Zvoid CMazeServer:estroyPlayerData( PlayerData* pPlayerData )
    7 Q* p+ ]; u( A) G# J4 x) ]{6 C: j( B! G* E8 Q3 j4 M( L% Q' G
        m_PlayerDataListLock.Enter();
    : x% M9 s$ l& p' u0 Y" \7 `9 y    LockPlayerData( pPlayerData );</P># V* [: ^2 \4 m* ?) t" B1 E
    <P>    // Remove the player from its cell) p. L. K, Y; {1 C4 T7 B4 _
        RemovePlayerDataFromCell( pPlayerData );</P>) d8 d8 b8 f- `4 g0 x4 c* N; f) @
    <P>    // Mark as inactive
    + y! L7 [' Y' l6 v4 [1 _# [    pPlayerData-&gt;bActive = FALSE;</P>* y; n* N+ I. F% b
    <P>    // Remove player from active list
    ! b8 H, K+ |* z# ^" t    if( pPlayerData-&gt;pPrevious )
    & Q! b+ m, W/ G: D  |        pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    : D0 g, ~" Y/ t" L9 C! T    if( pPlayerData-&gt;pNext )0 q% l# I& z- M+ C
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>& I: v* ?; G( a6 l% A/ H: u
    <P>    if( m_pFirstActivePlayerData == pPlayerData )! h+ ~! Y  ~$ {0 L* \; t7 C
            m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>
    # s4 K+ w/ |1 q& |9 Y/ O5 N) O<P>    // Add it to the free list3 s( i' m2 z( T5 r7 Y0 y
        if( m_pFirstFreePlayerData )
    / E( ~( S( h) ]4 T; H7 R3 {7 g4 B" z        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
    3 ?2 p. ?5 P9 X- z1 h) m9 N    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;7 Q$ V: ?7 X1 M  C' B- _$ ?
        pPlayerData-&gt;pPrevious = NULL;7 B; s5 ]9 g$ x1 b/ v
        m_pFirstFreePlayerData = pPlayerData;</P>
      e1 j( }+ f  e1 K0 |<P>    // Update count of players
    : h8 m3 A! C2 b% A5 P1 H    m_dwActivePlayerDataCount--;</P>
    # K& G' I8 C, I0 H+ @<P>    UnlockPlayerData( pPlayerData );1 F5 F. D& \! J' Y
        m_PlayerDataListLock.Leave();
    ! a' Y# m9 ~# N0 d* U! M}</P>
    7 r7 l; E0 e9 u% [+ c# ?) u8 u3 n0 H& a+ D% S) _
    <P>" {- D& j! y  ^. L; y' o
    //-----------------------------------------------------------------------------
    & a0 E' ?. o' ~- {: o9 H// Name: : R7 {& Y$ x2 A+ k
    // Desc: 9 w* N7 T- P8 R% f0 A. e
    //-----------------------------------------------------------------------------$ N- S* y9 M% ~5 a
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )
    - K3 H. E6 Z. V$ r6 W{
    3 E9 P5 s. e1 Y( f    // Lock the player9 g) `5 X4 ?2 ^$ Y& H$ B/ v
        LockPlayerData( pPlayerData );</P>% a: ^0 g* J" k" l, W4 F% V
    <P>    // Lock the cell the player is in
    % O. z; c+ R" }$ F    ServerCell* pCell;
    9 b. Y9 Y# U/ s7 A! @& V8 _    if( pPlayerData-&gt;wCellX == 0xffff )% o: F" X  S# G4 _. ?* j( Q
        {
    1 \$ A/ t8 w% P        m_OffMapLock.Enter();
    & o, ^& x, x, B7 U        pCell = &amp;m_OffMapCell;
    / i) Y1 w' Y. Z/ o7 t    }
    , O+ \6 n3 Q! n& K- ~" F, Z    else
      w5 ~/ g0 G; Y/ s+ U    {5 X5 U  a& X0 k0 |# S# O
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );
    : H) k; s8 v0 M        pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];; j* ]  D5 ~& {. m7 p1 u
        }</P>
    7 k* F# s/ H) e' |<P>    // Remove it from the cell3 K4 b5 v4 E$ S& D
        PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    7 H! G$ u4 f7 q5 w8 N3 T2 T! q    PlayerData* pPrev = NULL;
    5 O4 ?) h# P" d6 Y0 w# F- Z1 e    while ( pPt )
    $ I! Y7 |+ x) J8 K! ^: a, q1 ?    {
    6 i: [8 w( M  J; G. |* ~        if( pPt == pPlayerData )8 F3 F! C, M4 ]/ F
            {9 J( T( Y& P, E
                if( pPrev )
    : D2 Y. I1 h) B                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;6 k2 f) P8 Z; ~4 ^
                else- J" \9 f$ Z9 j, D
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
    ) ~  I% P7 y6 d, B  S! \6 l<P>            pPlayerData-&gt;pNextInCell = NULL;( y7 z& X! ?3 \" i, E  w
                break;9 F; m! G6 M9 b& F, A# u5 S8 h6 k
            }4 z0 Q4 A- ]: F3 \, F; x2 }* Z
            pPrev = pPt;
    ( `2 g( `5 E( C' Z, j3 _8 Q        pPt = pPt-&gt;pNextInCell;
    $ f5 y! F7 B" ~8 R' a    }</P>
    ! `2 k5 Q8 h. m" n* Q7 a! H/ ]$ O<P>    // Unlock the cell
    4 i! v3 O: s3 N: f% P1 p  n& \    if( pPlayerData-&gt;wCellX == 0xffff )
    ' @6 l6 H4 W# Y1 e3 `6 N0 e        m_OffMapLock.Leave();
    % D8 U: J; U  ]* _  z. _    else
    # _3 u* z! e+ b! \        UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>
    % {8 f- D$ U* s+ g  G- L% U. d4 b<P>    // Unlock the player
    4 M" Q% R# ?2 D# J    UnlockPlayerData( pPlayerData );! V- Y+ ]/ ~' I& I
    }</P>
    ! W" {* q. f* |7 e% v+ i
    + ~, {; p9 l8 V! z  p' {; `<P>
    9 i1 W2 H' F9 h( e: W" T. D: L4 z//-----------------------------------------------------------------------------4 g% x9 v) [+ u7 i- u% N7 {8 X
    // Name: ! o. K. x: K* {: Z0 v
    // Desc: 1 k% M7 l: J+ q
    //-----------------------------------------------------------------------------
    ) Q! S$ I- r5 k+ j9 [7 S# B$ t% M- p4 ^0 Cvoid CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
    # X& }$ P4 y9 Q8 M& l{
    2 {1 t8 I" j; t    ServerCell* pCell = GetCell( pPlayerData );
    " N* X' Z8 e6 x$ d% t    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
    ' E( j* `$ k( \' i) `0 c+ q    PlayerData* pPrev = NULL;- d+ V# K) ~+ ^; D9 y& r' m( _2 K
        while ( pPt )
    9 q" a! F( Z& s3 a    {0 g3 q. m4 P% U
            if( pPt == pPlayerData )
    6 X4 b7 ^* P! w7 K8 D( U        {* s) H; N# N0 u+ x/ C8 u2 [  H% R' ^
                if( pPrev )
    * d5 T/ {% B4 K% w                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;* u  e8 c$ g, o  A% b5 ~
                else9 i! {* T2 M9 [% _) x
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;
    5 _: J* Q7 R/ K( c2 X4 K            pPlayerData-&gt;pNextInCell = NULL;' [: d" Y& A8 a8 h$ }
                break;0 P) J' t- s5 C1 I4 O  @( s" Z
            }
    $ f. `3 i- O" ^$ V6 [# R        pPrev = pPt;
    ) b% r7 z1 ]9 y        pPt = pPt-&gt;pNextInCell;
    4 S3 n/ t1 j4 g% p5 ^2 n$ e    }
    2 M1 Q. k( }( s}</P>
    2 z. R: y# X) m) M, q3 G: W! @$ h/ p1 U! d5 `6 C6 e+ ]
    <P>, s/ F" Q" Q! k4 |/ B
    //-----------------------------------------------------------------------------8 a3 H5 W) Z6 p
    // Name: ' {* d  n; a# Q) ?) `6 Q! g
    // Desc:
    # `% d6 i3 G" O  U  X7 u6 e. k# O//-----------------------------------------------------------------------------7 p* W2 o% U5 f
    void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )/ g7 W1 ~  F+ m: W( h/ k6 Q& c$ G
    {
    4 L7 N; I8 ~8 }' [& U2 n, s0 M    ServerCell* pCell   = GetCell( pPlayerData );& O4 P7 d: W$ Y" j
        pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;
    ( A$ g4 b% a; S1 J    pCell-&gt;pFirstPlayerData = pPlayerData;' t) ~. m8 M! d+ Z2 w
    }</P>
    ' [5 R" Q0 L6 h5 G# M$ X& G6 Y
    9 h8 S' P# x3 M$ `4 u/ I9 e<P>
    6 m7 a! H% D+ |" @' J3 }//-----------------------------------------------------------------------------
    $ J! r  |8 r5 l+ H. h' N' `  P// Name:
    3 {6 ~+ Z/ I; d& j( g0 L- F// Desc: 2 Z$ m& M0 J- P& d
    //-----------------------------------------------------------------------------
    $ f. p5 q, W2 x' Y9 {, wvoid CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack ); V. d& }8 q: n' I3 L# v# n2 [
    {* P: b9 f1 F, m) E9 m9 R% d
        // Grab player for this client and lock it
    . D  L; H' b* U5 ^( F) ]9 ^    PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );7 u+ E% T# j! m: R
        if( pFromPlayer == NULL )
    5 {# q% S6 Z; ]; T    {7 P- H6 T( v! g: b$ P
            if( m_dwLogLevel &gt; 1 )
    5 p! T& Y- `  C% x            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );/ w: q8 R* b+ N, G3 R0 n1 g+ F- @
            return;9 a, q3 }) R# [$ x& q
        }</P>
    : t0 N! U1 i4 d! J$ |( ]& S( F<P>    LockPlayerData( pFromPlayer );</P>' G8 Y; z3 {! Y- }; J# Z
    <P>    if( FALSE == pFromPlayer-&gt;bAllow )3 C% d6 }% @1 R2 U
        {2 ]% ^8 X7 E9 r( V
            if( m_dwLogLevel &gt; 0 )
    4 J/ c" a. Y  E8 y$ v' {! P            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>+ R9 ?! ~' c1 ]) ^+ z' R- F
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );' q/ A  B' g; k( O
            UnlockPlayerData( pFromPlayer );
    ' ^' _: ~9 M1 N  G        return;2 c3 W: r8 O) s1 `2 Y4 a( w+ D- ~
        }</P>
    8 Q, i! {* J9 g9 M+ T  Q; F<P>    // Compute the cell the player should be in now
    4 ^  p  b. c" x    DWORD newcellx = int(pClientPosPack-&gt;fX);
    7 ~1 D; I/ ~5 x9 b, T) O    DWORD newcelly = int(pClientPosPack-&gt;fY);
    7 o1 {9 R8 n. m: t8 A4 T7 b    DWORD oldcellx = pFromPlayer-&gt;wCellX;5 y8 I- `* l' c% m1 M2 r2 t
        DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>
    + }8 w7 M: V) \) B8 v# y9 `/ P<P>    // Have we moved cell?
    6 G; T; r- V! b) `- g- w2 |    if( newcellx != oldcellx || newcelly != oldcelly )0 o; W* Z0 I. t) j, a) H
        {  c: `# t1 t8 {  G
            // Yes, so lock the pair of cells in question
      n7 J& m5 D( r! S7 n9 {        LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>; C3 b: E2 H% ]! D
    <P>        // Remove from old cell and add to new cell# P6 I" g1 L- d1 G& u" {
            UnsafeRemovePlayerDataFromCell( pFromPlayer );
      D: H9 V- k+ E        pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    : V! c) f3 P$ y# ]6 w, M: B        UnsafeAddPlayerDataToCell( pFromPlayer );</P>
    ( `/ ^/ M8 c! ]7 M9 f1 h<P>        // Unlock cells
    " h, Y6 _/ ~9 ^& Q# Y: B" T        UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );
    " c5 m) j: d/ Q; r/ H    }</P>3 R% u+ @$ z5 }7 O. C0 L
    <P>    // Update player position. [, W1 n+ j6 a4 M& e3 W- Y
        pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
    2 L: T. o$ L! [    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;, L" E0 N' N- \7 s9 z4 N: R9 A6 X! a
        pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>" _4 F8 U# o' I7 d8 I- C9 B
    <P>    // Allocate space to build the reply packet, and fill in header
    * I) ?/ E' O0 G" a/ e* H4 n2 t    DWORD dwAllocSize;, w. H# E) F; T1 _" B
        ServerAckPacket* pSvrAckPack = NULL;</P>/ @$ v: V$ {' I% E- U9 @
    <P>    // Begin by allocating a buffer sized according to
    & R% b7 B0 v7 i4 l/ i* h1 I    // the current number of nearby players + 4.  This will give - r  @/ N4 N$ f9 t" c' ^
        // a little room for more players to come 'near' without resize
      a1 F5 ?  x2 K3 u% R: O    // the buffer.+ k: k# D3 x  l; i
        DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>
    % b! `' T3 A  @9 t: l8 U<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    5 a7 n8 {2 D  h; g    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    9 T. k/ g3 v+ i    if( NULL == pSvrAckPack ); S$ ^' r3 X% h
        {2 L) G/ L0 t3 C, o
            // Out of mem.  Cleanup and return! k) ^  X; j3 t) m1 V& x# n
            UnlockPlayerData( pFromPlayer );  p" `# n2 L2 M- K. n. L
            return;       # p. D  ]9 [$ f8 X$ `" b$ c
        }, g/ y7 Z1 Z0 p
        ZeroMemory( pSvrAckPack, dwAllocSize );</P>
    ) s, U0 G  A3 ?2 R: X<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);
    3 I- ?- u/ D% d4 w  [, }+ _    pSvrAckPack-&gt;wPlayerStatePacketCount = 0;
    / X8 Q8 C( m" c( f; Z    PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>; U! C3 W" ~7 o
    <P>    // Compute range of cells we're going to scan for players to send2 c" S5 }6 i. i7 D& O# a* G6 e
        DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;: C7 c& O: S. T) h
        DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
    , |8 G/ h3 j' \) r, @7 E    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;* G2 ]) [3 j9 a# f9 j
        DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>8 {3 H; k1 X$ X$ `7 T' _' H
    <P>    // Lock that range of cells( i+ w% W& I5 z# Y& Y# T/ A$ q  A- H
        LockRange( minx, miny, maxx, maxy );</P>
    & C" a3 m' j" t7 |7 F) p<P>    // Scan through the cells, tagging player data onto the end of
    2 m: Y$ O# G* n' D3 A% |    // our pSvrAckPacket until we run out of room  w9 U/ w$ Q8 W+ ^
        for( DWORD y = miny; y &lt;= maxy; y++ )& W% z; \! B3 j! L2 @
        {2 i! ^/ r: Q5 ~/ _1 i  L" {
            for( DWORD x = minx; x &lt;= maxx; x++ )
    # f* F* p: S" k8 R6 ~* m4 t        {
    , G+ N) p* E2 D# _4 p8 g            PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;+ J% r( \" G- W: p; }( P
                while ( pCurPlayerData )
    3 [- t" W. V% _: g* {6 u" b            {
    ! G* R" ]. v9 N, s6 i. W                if( pCurPlayerData != pFromPlayer )- r$ P0 R; a, {( n/ z
                    {
    " P6 f: u% p5 |                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )0 E, s  f! q0 I/ m' Z+ w) l6 _
                        {
    2 [( y' a5 G5 Y/ k" {: {                        // Make sure pChunk is where we think it is; u1 u9 q$ G' h
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>5 J8 x, z' O* J1 }
    <P>                        // There are more than just 4 new nearby players, so resize the 2 S/ r1 v8 i4 ]/ t
                            // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
    8 r% p8 t- i/ ^! l& q$ U7 m" ^                        dwMaxPlayerStatePackets += 16;
    3 z2 j: r3 m" P: E                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    * G+ J6 g: c5 V: {) k( W; C                        ServerAckPacket* pNewSvrAckPack = NULL;
    & @: s  a2 G! L" H* |                        pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    6 K/ K6 T$ S1 P                        if( NULL == pNewSvrAckPack )  }8 B1 c! X) L- `5 h. b2 p' }  i
                            {
    2 T& ~, k# z* o/ S) Z$ D                            // Out of mem.  Cleanup and return
    ( x6 S4 n) f( C6 b: u- b                            free( pSvrAckPack );
    # v8 ^: }* g. z( m) j                            UnlockRange( minx, miny, maxx, maxy );1 X3 n7 _, q5 C7 u5 K4 g; v
                                UnlockPlayerData( pFromPlayer );; n# k% z$ U, h) \0 L
                                return;       % J. g: y1 k7 b" S
                            }</P>
    5 W7 P2 R/ e7 R. x<P>                        pSvrAckPack = pNewSvrAckPack;* I  f9 U, X; T7 n; g
                            pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>  n: C! t# d: b% t- ~
    <P>                        // Make sure pChunk is still where its supposed to be& {: y% Z6 F4 m7 B4 y! z; V; |
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );
    ! y9 r: ]7 X5 m                    }</P>
    ( O7 S( k% n( M5 b/ D4 r5 E- V<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;
    9 g3 ^9 U- Q# {* K( x% M) z                    pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;! O- T1 ]$ P, s/ \. R1 @. g4 [. F
                        pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;
    & [  |( T( s! v' [) q3 ~* D                    pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;
    ' J2 e/ k/ P* z. I( u( o) l0 Z                    pChunk++;! X) P% r& S! \3 o! V
                        pSvrAckPack-&gt;wPlayerStatePacketCount++;
    & x0 P2 e, j  d3 z8 F: B                }
    : f. L2 `" [& X/ C                pCurPlayerData = pCurPlayerData-&gt;pNextInCell;
    0 A  `/ c0 a! X  d; i- T' {) T$ x            }
      G1 F! U$ D. N: K* J* H# C        }* `% B8 A: W% ]* U5 R; X
        }</P>2 G6 U- ^8 z7 L$ z2 k* n7 Q8 U: l
    <P>    // Update the dwNumNearbyPlayers for this player
    / H+ o. s' @! [1 }0 @' g+ d4 z) I* N    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>7 U% s6 u: b1 i. O7 `
    <P>    // Unlock range of cells. r: I4 j( E$ v6 u8 U2 f: A
        UnlockRange( minx, miny, maxx, maxy );</P>8 ^6 r. h7 f. Y! l5 M6 K( y
    <P>    if( m_dwLogLevel &gt; 2 )& U4 y$ @, }- }- I' A+ E3 P/ S2 l
        {
    $ B$ h1 D8 F4 z9 `2 g# U        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );; A7 `; o. n8 @) r
        }
    ( Y' k: Q+ I" A) A; d1 B    else if( m_dwLogLevel == 2 )5 Q/ ^+ J; ]6 x/ X/ z! j
        {9 l( x, ~, O' `
            FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );% J3 W. t, {- g- F* F7 Q9 m
            if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )4 z" d4 l* T. p" e; q9 S7 m
            {
    1 {$ G5 a( X' j1 V" s8 y            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    , t2 U0 |! _; [$ V- _) y: _8 i# H" ^$ `" Y            pFromPlayer-&gt;fLastDisplayTime = fTime;9 x$ `% W) D% z6 F1 e1 S
            }! l1 c' Z* W2 U+ W- s' U, U3 ^# u
        }</P>
    ! Y- i9 H2 Z+ Q( T8 o( G- x<P>    // Unlock the playerdata* L6 Y  K6 _, J
        UnlockPlayerData( pFromPlayer );</P>
    . Z7 A5 Q* c+ e" z4 d<P>    // Send acknowledgement back to client, including list of nearby players
    , w3 J3 N4 V; u8 O3 T4 ?; i. d( u    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));, e0 h1 k7 g+ ]% ^+ a
    / V& X- Q: S* J$ V4 |7 r% _# k6 E
        // Pack the buffer with dummy data.
    : Y" Z( b0 d* q    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)3 F" r2 F" O& a
        {
    " Q' E& T* t' ]; x6 p7 O) e: ~        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];. q& z0 P0 j: c6 n9 E
            VOID*   pTempBuffer = 0;</P>' }1 M8 W$ v8 g
    <P>        pTempBuffer = malloc(dwBufferSize);* F. y: U1 M' y) b1 e1 T0 _
            if( NULL == pTempBuffer )
    ' `* L) A5 H( }" l; o. X        {
    * ]% N; V- k, i. |. w; [            //Out of memory( Y( ?. A7 u1 U0 R* q
                DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );- b( Z& d) t" ?5 y- i/ O
                free( pSvrAckPack );2 l; k' i5 ~6 E7 N$ @1 i; @
                return;
    1 |9 R4 q; X1 q- K' Q        }</P># S0 Y5 W0 `8 k' d+ l) n& z
    <P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');7 N. v* W6 a& ]% r! u
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>- q4 @8 G; a/ K# N- }+ b( l
    <P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );
    5 k: ]1 \7 t: v9 P  e! z6 P   
    & s* _' e8 W$ y! m1 @        free(pTempBuffer);' m  t1 T% N- H3 B. b
        }   
    0 l) h4 g( E( k. x8 W8 ?- p    else
    ' v$ H2 l# \  t* f) E    {
    ! ~5 O: H) \' \* ~# A        SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );
    4 ~1 z" O0 L  N+ k& r( O5 b, W+ W# p    }</P>3 ~' h5 u3 Y1 [) @3 }4 @% w7 F+ Q
    <P>    free( pSvrAckPack );</P>
    4 B7 {+ Q* }0 u" o' e& y<P>}</P>
      A. R; y7 r, n; I; b
    1 Z# K* a6 A4 I  t! I' u<P>
    - B$ h( F; B1 k& K+ l3 m//-----------------------------------------------------------------------------
    + u- `; C5 S/ q; p// Name: 3 c2 h/ K3 H5 h& V9 i, k. b
    // Desc: ' Z4 Q3 f6 ~( K
    //-----------------------------------------------------------------------------. u8 w) @- L: Q0 |: K
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )& H' h4 U9 @, D* m! i
    {
    & O- x" z& i, o3 J% d    // Grab playerdata for this client and lock it
    1 r& w8 b! t/ j) ?3 h    PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
    * l3 D- K, q  `$ }+ U    if( pPlayerData == NULL ). N8 n6 e4 u9 p+ Y3 W1 k' z
            return;; y3 K& m! S- u: \& P: W. g
        LockPlayerData( pPlayerData );</P>
    " _" b* L9 P" J<P>    // Record the version number & B( o) @  X1 ?. b' m0 q
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>" g8 o" |6 k- f$ B
    <P>    if( m_bLocalLoopback )6 S& z! B2 {( ~6 B1 U
            pPlayerData-&gt;bAllow = TRUE;
    ; g. Z! y# t4 Y5 R0 F    else; L7 i+ V, c' n
            pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>
    ! J$ l5 ?, ?; `. H" J<P>    if( m_dwLogLevel &gt; 0 )- q4 y3 H; E( U# J3 H
            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>
    ! p5 Y& a- v% X<P>    if( FALSE == pPlayerData-&gt;bAllow )
    9 [- W$ k8 K' _, s/ v% k    {$ `) u+ b" W4 h; y( g' |
            if( m_dwLogLevel &gt; 0 )
    1 l9 |/ X  ^: N' q7 h5 u8 t            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>" c4 G( Q4 f9 f; \
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    2 S3 {$ ~. T% E+ \6 i  [        UnlockPlayerData( pPlayerData );# q9 b) c8 Y  _# W. ^, B6 B( `' \
            return;( H7 t! @: _! O% Q; `
        }</P>
    : o6 [) v. O4 {. |( A1 J<P>    // Unlock the playerdata# z; {0 z  v- K& z8 M9 C0 n
        UnlockPlayerData( pPlayerData );</P>
    # g% w5 _$ {4 z<P>    // Send acknowledgement to client that the client was either accepted or rejected. A/ v" S7 }1 S: H% P8 Y
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );( I$ f- Z7 v5 ~6 Z7 N
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
    ( |" z7 k7 V2 p}</P>
    ( k1 x: f1 q/ M5 y" r  D# `
    . l$ X0 L: M9 {* y5 Q2 j<P>; d, P4 ^1 F2 D5 r; O. T
    //-----------------------------------------------------------------------------7 X* d- k. X/ |4 U9 h3 _& h6 k, M
    // Name: : F* G3 P4 b6 k' A
    // Desc:
    8 k# [0 S% E5 J* F//-----------------------------------------------------------------------------
    * o8 g+ \( j" EBOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )* Y3 s6 L0 c! ^! d
    {( F# T; V9 ^7 `& H% ]0 w( f
        switch( dwClientVersion )" o: k8 q% ]3 Q1 d6 \+ a; ?
        {5 _. p7 d1 o- i# ?( Y1 C7 z# q6 G) ~) k. W
            case 107: // only v107 is supported
    - Q0 z0 y- R* s- P0 {/ b            return TRUE;6 J  y& J: e( k# [, ^
            default:3 L( d/ s! U- N' U
                return FALSE;) R. f0 Z+ _6 x' B: Q, c( s
        }8 }2 k8 T0 ~7 U
    }</P>
    ' p9 J, p9 [2 q- _0 l
    3 v4 p) N5 n( j3 g<P>0 ~) S/ Z0 m/ q4 B3 H7 f
    //-----------------------------------------------------------------------------
    * m: ^8 p1 v9 q6 I8 [& Q// Name: , x0 |' i& P. [
    // Desc: & \; O4 e) z( k6 C. G7 Z% H7 Q
    //-----------------------------------------------------------------------------$ e5 x/ r, l! s5 r$ t+ `
    void CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )6 @. p" V, m% A
    {
    ' i* o0 u4 ~- `    if( m_dwLogLevel &gt; 1 )
    , F* S0 T5 \) C" w' U1 N        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>
    0 K- D, X' n6 K9 O- C0 K! X<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );% N3 N0 l4 R$ o8 V
    }</P>
    1 R1 K$ z* g/ r. U# ^! Q6 I
    / h) [& x7 K+ I' c* x<P>" P5 d3 t1 m4 f; S7 Z  R2 U
    //-----------------------------------------------------------------------------  V" ?- K5 G8 L9 x0 K% S9 l' L7 R
    // Name:
    6 [& L" X6 o- ?  o" |. d) O3 G// Desc: ' j  q" O' }' O2 y
    //-----------------------------------------------------------------------------; U) a. `( g6 _$ y% ^+ {& B: j% e
    DWORD   CMazeServer::IDHash( DWORD id )% h, {, a* m5 V& ~  j
    {
    + }; _# Z! Z& H: s( H; P& {, `    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);
    : J0 P& J4 Z$ g2 t, @    return hash;
    3 {6 j& n9 a7 V7 G  ]7 Q; h! f}</P>
    - A, x& i9 ], U& k' y) |6 a& S/ p& {
    <P>" c* f+ k' S2 ]* a: U0 L
    //-----------------------------------------------------------------------------9 C; I" S. m* @1 {7 ^( k* r8 c
    // Name:
    " @3 ~* M+ |2 w// Desc:
    $ I: p$ F9 |* h% A4 p//-----------------------------------------------------------------------------# S  \9 x9 [! w- g4 M% [
    void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )9 l; n1 u7 R# u4 B4 U* k
    {; C! t! s( U# h- o& k1 H1 e
        // Hash the ID to a bucket number
    + L# |& E$ `9 J+ o    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>7 u" k, H! \* w1 ], q& D5 X
    <P>    // Lock that hash bucket$ k) s# T7 _$ b, e; K
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;3 a* j4 e5 |/ w
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>, p  J1 S+ H) V4 `4 y4 i
    <P>    // Loop though players in bucket until we find the right one
    5 A  Y; @" V- ~) y8 s; D: i    PlayerData* pPt = m_pstIDHashBucket[bucket];2 o+ D+ |% I5 l6 W$ J
        PlayerData* pPrev = NULL;( h# b6 r! m- H  l
        while( pPt ): A% D. v4 t0 u; e- K
        {
    ' l) u+ N# p8 w- ?* e& L0 k$ w5 v        if( pPt == pPlayerData )
    $ L& a5 F- k8 Q            break;- X2 Y0 Z( L9 o. K
            pPrev = pPt;
    ' v! _# [8 n* `8 f! r2 g! r2 L        pPt = pPt-&gt;pNextInIDHashBucket;
    : X# Y: e) ^; r$ Y    }</P># W  A( ^; L- e% _
    <P>    if( pPt )! W  s0 A6 L. x# y! {$ U# G( Z# _
        {
    ! T" e  J) _3 _& _3 h4 Q+ g        if( pPrev )9 a% I& P' l+ Z; u- e) m4 i7 |) i
                pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;4 y6 o" `. b  K7 W; T$ e. ~
            else+ W  w& e- Q1 n! Z7 t
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
    4 l% F9 A+ X' g4 t) {9 v' V        pPt-&gt;pNextInIDHashBucket = NULL;
    ; O: t  E& s1 A! w  g    }</P>
    ! _2 Z# e5 G" {, P$ ?<P>    // Unlock the hash bucket2 g- O) e3 [+ t
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();8 |- ]9 q( E  X) e+ v$ N
    }</P>7 w4 q+ U7 f5 S$ g  R0 o9 R

    * i$ _" r  x7 t0 d  e& L; R<P>
    , c/ J- m$ R5 r! D3 t) R//-----------------------------------------------------------------------------
    ; V, A. n, b$ _0 |% s4 S// Name:
    8 K# W0 w# B9 ^7 H9 V% J// Desc: 1 C( k4 F" L0 N' i0 x
    //-----------------------------------------------------------------------------. Z, N! e# [4 ]; G$ O5 `' L+ |
    void CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )( {! l- W+ ^( S& j( K4 g* T5 y
    {
    ( @1 O( r8 v. ^" G, g. ]6 h: h    // Make sure this player isn't added twice to the m_pstIDHashBucket[]
    5 E5 E% V- h9 y; D3 B    // otherwise there will be a circular reference
    3 X7 N8 `4 \1 a2 P; |    PlayerData* pSearch = GetPlayerDataForID( id );
    ) S* ~/ a- g+ n& ?2 B    if( pSearch != NULL )
    . i- ~4 n6 h- x1 n' g3 P$ B        return;</P>. q' R/ K+ y0 W. g4 m! Y# u2 O) g
    <P>    // Hash the ID to a bucket number
    ; e8 p2 q! {# @    DWORD   bucket = IDHash( id );</P>/ q& j* O$ q$ d- S
    <P>    // Lock that hash bucket
    ) k/ i" z& e3 h' y0 v    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;2 `0 B, |7 H- V  O* x
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>* ?! c7 r: W' p5 r
    <P>    // Add player onto hash bucket chain
    ; m$ r; m' y9 k+ }1 ]    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];6 R2 W0 W/ D7 W2 p
        m_pstIDHashBucket[bucket] = pPlayerData;</P>
    - J0 C3 j! q- \) b<P>    // Store net id in player
    9 `% _+ j) {( C5 D/ l+ }    pPlayerData-&gt;NetID = id;</P>
    9 c& r# t9 p1 E; ]' b<P>    // Unlock the hash bucket
    ) N) b2 l4 p/ h& r, P" e    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
      K# @/ G: z' n& t# E7 G}</P>
    8 Z/ V: A2 }, H6 c2 C( ~; f; P: z2 C# B' f% ?
    <P>' K  n- f6 ~# X0 K3 F9 P; W  i( o
    //-----------------------------------------------------------------------------1 \! W0 F& c" T0 N6 a
    // Name:
    ; |. l$ w% {( K/ p// Desc: ( }* M) Q, @% S# d. u" \
    //-----------------------------------------------------------------------------
    ) b2 e9 z+ }. F5 Q' gPlayerData* CMazeServer::GetPlayerDataForID( DWORD id )/ b" O1 P; X- n: X! O
    {
    ; b4 A2 X2 S1 t    // Hash the ID to a bucket number
    0 |6 t3 Y, W  a- b- g: [9 A( U    DWORD   bucket = IDHash( id );</P>
    " ^0 k, f! |1 V% S; {<P>    // Lock that hash bucket* @/ |, m& X0 b) m4 I; @
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;  J- u: L6 ]' m9 e/ U
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    , A/ O; ]# O+ `" K# N- Z# z3 M<P>    // Loop though players in bucket until we find the right one
    1 {' _' S$ h- v( `* s( K: r    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    ; ?1 d8 u1 Q9 _. K, W: c- y  W    while ( pPlayerData )
    & ^1 C" V. X0 \% y! z0 j    {1 ]( {7 Y4 g, H/ v, y2 Y1 `
            if( pPlayerData-&gt;NetID == id )
    * E0 |; \8 J" ^3 v- J. Y7 D            break;' R0 c6 F$ j* ^, {
            pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    9 c0 _5 j8 w) l& Q4 z. }! x9 \! w    }</P>
    , r+ ]8 }, B* E<P>    // Unlock the hash bucket
    : ]3 D+ z) i$ e) M5 {    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>
    + k. j; ]; ~# ]" i5 L7 O% h<P>    // Return the player we found (will be NULL if we couldn't find it)
    ) D' E1 E. `4 J% t; n    return pPlayerData;7 V  ^6 H9 @' l
    }</P>
    - O4 _' ]+ F% r
    + j2 q( g4 w: n/ x+ h. {" m( i<P>! H) B' Y0 l8 H8 z: G  }8 g  M
    //-----------------------------------------------------------------------------+ Y; [5 g+ x1 u% q5 z5 _# R, D! G
    // Name:
    , P% x' E4 x! p9 T// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner$ f$ }) r6 N0 o4 @4 l$ E
    //-----------------------------------------------------------------------------
    ' [( y3 c  J& Uvoid CMazeServer:isplayNextConnectionInfo()6 n, u; U. V6 s% C# }
    {% y+ b& b, |0 m2 @8 Y& V3 v
        if( m_pNet )
    ) L- P8 U, H! \% e. H0 S8 }    {
    6 Z4 [) f9 ]1 b' O3 X# E7 l+ o        // Find the player that was displayed the longest time ago, and display it.
    7 I; W; t( u7 n  x6 N/ q        FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
    * v# r$ V0 S% K3 Z0 o        PlayerData* pOldestPlayerData = NULL;
    ) t! l" w0 _- W1 ?( E        FLOAT fOldestTime = 0.0f;</P>: |2 E: B1 |0 ^/ D) z
    <P>        m_PlayerDataListLock.Enter();</P>0 I; \+ s0 d- ?  G7 s- B  @; k
    <P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;; M+ V. L  D; D; n; D* s6 h
            while ( pPlayerData )
    & k% h; E" u9 r3 c( i& Q- y/ l2 X        {% X) l# c  K- e+ U. c, Z; j
                if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
    , i8 F/ z  b7 b# y: q- t            {
    + p1 L% V( ~9 y: Z                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;
    ) }* g. Q7 N* I" m$ A                pOldestPlayerData = pPlayerData;* d( A- p" n/ V8 s
                }</P>
    6 _( U+ U3 k8 n<P>            pPlayerData = pPlayerData-&gt;pNext;3 c' v$ y. p* S5 y7 X
            }</P>0 `' c! b, \! B! w# g8 r
    <P>        // Display the player with the oldest CI field, and update its CI field.
    + z  E9 R. P; p  K) Q" Y: T        if( pOldestPlayerData )
    . x8 o$ e0 [6 p. H- D        {
    5 d- s/ [/ E( G) f5 i1 c  l4 [, i            ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
    9 A* V8 e: I' d" Q: J            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );: D6 U% i8 g5 Z& d8 z
                pOldestPlayerData-&gt;fLastCITime = fCurTime;
    , c! N, G6 D* A( m0 b; C        }+ v5 x" S( N: d$ d+ T1 n9 L7 D
            else% N( z: }  w$ M" A
            {; d! s. Q! b3 i$ K
                ConsolePrintf( SLINE_LOG, TEXT("No players found") );, R8 [2 y* y2 M, g+ p- y0 Y: Z4 D
            }</P>
    ' _6 {$ C' R. p" i- o/ G. X<P>        m_PlayerDataListLock.Leave();
    0 S9 I4 g& a+ C0 W- E6 c    }
    : H7 N9 Z/ I3 t- e( [% R+ J}</P>; w7 h, A0 `  _3 M5 e8 a
    $ l% K% `/ F/ }5 x7 A1 r; c9 U
    <P>
    6 h  y. r. W2 p" z+ U//-----------------------------------------------------------------------------
    & c" f" l8 Y2 j9 `' v  b3 c// Name:
    ; g1 f# ]" t3 E- c$ c// Desc: ; b3 m4 h9 }3 s, m5 j
    //-----------------------------------------------------------------------------% U# ~9 v  n/ g0 I* Z# O
    void CMazeServer:rintStats()% _; |, h/ |' p* [" M
    {5 L6 ^" F+ g2 H/ b5 C/ A
        ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
    : Z6 s- j9 `& N& Y- ]2 X5 r! O                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );1 t- R# L5 [; Z
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
    ! O0 v8 H, f( O! c0 K                                    m_fAvgThreadTime, m_fMaxThreadTime );$ T, ?4 F4 j! R2 H
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );9 ^2 b+ h$ \. k; @0 p
        ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );
    % j1 }# ], z! U2 A. u' ^( v# J}</P>
    # \' |- y# d6 \/ C
    5 v1 q. l4 L4 U- h3 p* K( r5 B. }: W<P>1 }0 _7 ^5 D* X# {9 p+ V. e0 h! E
    //-----------------------------------------------------------------------------
    / r( t0 U8 c( p9 F  G. R// Name: . O6 |6 M$ P" g# O. L; \, \, H5 s
    // Desc:
    , k! S/ T$ w$ b  S- N; f) k4 }//-----------------------------------------------------------------------------: F2 _' i: L+ A
    void CMazeServer:isplayConnectionInfo( DWORD dwID )
    5 A6 z6 L$ i; ?! A$ d* Z$ T1 Y{3 o2 t! M$ m1 p1 C& Q/ H6 ?6 s
        TCHAR strInfo[5000];, L% u7 O5 n& O1 c8 E+ @0 A
        TCHAR* strEndOfLine;
    6 y- k5 h! P- Z* Q$ U; d$ m; `  h    TCHAR* strStartOfLine;</P>
    + H" e! T) a7 L+ g<P>    // Query the IOutboudNet for info about the connection to this user8 b3 O" ^1 b* {. M
        m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>
    , I/ V% o: T) q- A4 @<P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );
    6 j  A  A- k7 L' m  g& z/ t    ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    * O$ t. E2 B* o4 m  N# e4 U<P>    // Display each line seperately
    # X- H2 D0 C5 e  F" Q1 t* `    strStartOfLine = strInfo;3 s5 _  {! g9 J2 _5 ~! S1 t* p
        while( TRUE )
    5 O3 o5 P0 R& Y1 q0 r5 ^    {( Y! p( h8 N4 _5 m/ I4 U4 n& b
            strEndOfLine = _tcschr( strStartOfLine, '\n' );
    8 U. Z( w8 B9 C3 p& J) c. z1 c! [5 O        if( strEndOfLine == NULL )
    " S) U; S6 `/ V            break;</P>1 B4 S9 Q  l# X' j: E; U$ ]5 Y
    <P>        *strEndOfLine = 0;
    8 T$ j9 D9 i7 X2 ^* n8 _        ConsolePrintf( SLINE_LOG, strStartOfLine );
    " Z! u) c+ v: R/ U: d        strStartOfLine = strEndOfLine + 1;  z3 ]8 N! E9 I
        }
    / s& D% C) Y) Y- a}</P>8 ^% [% s# n3 v) S9 T
    7 t$ y9 f& @1 M. L" I& z4 Z
    <P>
    9 Z' X% w4 W- J$ d0 M//-----------------------------------------------------------------------------# _& N' F$ P5 ]+ I8 \8 G9 l
    // Name:
    ' H3 z" {; }) m0 G// Desc:
    5 \: y4 V' k' {4 N4 n7 V' r//-----------------------------------------------------------------------------
    3 C  G# o7 A& L) j! UHRESULT CMazeServer::SendPacket( DWORD to, void* pData,
    / Q& _0 v& E3 p) a5 N                                 DWORD size, BOOL reliable, DWORD dwTimeout )
    ( Y9 t- A% g4 v% G  I5 U{
    , k) ~5 q! j. K) ^! k5 {    // Chance of forcing any packet to be delivered reliably
    . h- f. R8 C# J5 j+ d1 ^4 e. l    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )5 ~" d7 I7 Q; w) I& j6 P) Z! ~9 l4 N
            reliable = TRUE;</P>9 P; X& h  L6 Q" e/ v# }+ m
    <P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    6 i2 F1 y+ e* {" A2 ]; T  W}</P>
    5 T5 K/ r2 [: g* u
    % |+ O! h: s# X# B& A# X<P>
    - i3 `; X7 D* N1 v) E# }//-----------------------------------------------------------------------------4 g6 T' i! V+ {; C0 H% O
    // Name: 8 A& g2 b+ B& w- e
    // Desc: ; |1 r& Z( \5 m: p" V, Z
    //-----------------------------------------------------------------------------* e1 X2 C6 E( ^, K5 q/ X
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )+ z: L& a/ D# a0 Y5 b
    {
    / Q& h9 e9 a4 n; E. P    // If we're up and running, then send this new information to all clients
    ' _! K8 c6 G( a    if( m_pNet )
    " T1 w6 v) I6 ]8 E7 T2 v    {
    * q/ @2 K2 k! H        //Use the AllPlayers ID
    6 F1 w: u& B; T) v. J! c+ h& q        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );
    - a; V( H/ M9 R" Z# B    }
    - N8 C# E' ?% z}</P>$ N* D2 ~2 a5 O0 Y2 N4 A

    3 E# K, i- `2 o2 g- ]3 q<P>
    3 n0 Z4 d7 e+ m//-----------------------------------------------------------------------------) j- |* v" d" Z0 ?. n
    // Name:
    % ~6 l% t  J1 r) f// Desc: 2 k' t/ g: h6 G; }
    //-----------------------------------------------------------------------------
    3 Q0 L9 k7 W1 h' D2 mvoid CMazeServer::SetClientReliableRate( DWORD percent )! z, y8 v. N- o. f2 ?
    {- [0 v9 G: y: u0 ?
        // Update client config, and build packet containing that data
    9 E& W- N( D5 C% }. N. p    m_ClientNetConfigLock.Enter();/ x" r$ o( Q+ _0 z( i
        m_ClientNetConfig.ubReliableRate = BYTE(percent);
    2 D4 T; p0 c: {& E    ServerConfigPacket packet( m_ClientNetConfig );2 V4 _$ X+ f! `: p$ x3 N6 F
        m_ClientNetConfigLock.Leave();</P>
    . U0 J! y( R# a* u# ^<P>    SendConfigPacketToAll( &amp;packet );% Z- D9 V# Q7 D: k. w" l
    }</P>- x$ ]7 ?% |: C" K

    ) d/ E& B( [' R<P># {  _  n" b4 f- X
    //-----------------------------------------------------------------------------1 D# S( O$ Y. s' r, h) e2 c% z9 h
    // Name:
    ; O2 N. l- |- P1 h) \* P7 a- t// Desc:
    - V3 j! F# D( B# p) s//-----------------------------------------------------------------------------
    3 R& A" N4 Z. n, B- svoid CMazeServer::SetClientUpdateRate( DWORD rate )
    2 F, `! l% o5 a2 m  e. \3 E1 U{% }, j% M% t% R* I" v4 M( ]8 c/ |* }
        // Update client config, and build packet containing that data
    & t+ f& N* Y7 i4 f! g  e2 _    m_ClientNetConfigLock.Enter();
    : _& U: [0 _( W7 d: f, W4 z' r    m_ClientNetConfig.wUpdateRate = WORD(rate);
    ! ?. o' t1 G5 d" c! \    ServerConfigPacket  packet( m_ClientNetConfig );
    2 y& k, P3 |- T# \# z, B    m_ClientNetConfigLock.Leave();</P>. c' s2 I4 E# h% O% E
    <P>    SendConfigPacketToAll( &amp;packet );
    4 n. }! v, e2 Z8 s}</P>9 |8 _$ g  G5 I% q3 T9 h6 w: y4 L

    & W" m7 J+ A, b7 L6 d<P>
    + q  y% e, c( O//-----------------------------------------------------------------------------8 Z  m  H, I: N$ b. l2 V
    // Name:
    . z, O* p; @7 Q' j9 I// Desc: " R' {% ]5 d/ o5 U
    //-----------------------------------------------------------------------------
    ' v7 n( f2 u4 ^void CMazeServer::SetClientTimeout( DWORD timeout )
    0 Y+ ~5 I4 O" K: Y5 T{
    ; P( G# b& v2 V4 v! T    // Update client config, and build packet containing that data# ~# p" ?: M- j
        m_ClientNetConfigLock.Enter();( e- w) ~& F* v1 t' P
        m_ClientNetConfig.wTimeout = WORD(timeout);/ P) r$ R0 O7 z: W% O6 ]
        ServerConfigPacket  packet( m_ClientNetConfig );
    8 K# A( a$ ~7 z" K* C8 d3 k/ o    m_ClientNetConfigLock.Leave();</P>4 B8 r9 M, o' w+ l3 H8 Z
    <P>    SendConfigPacketToAll( &amp;packet );
    " K$ q- Y6 B& ~# E}</P>$ D5 s: n2 l% _& B- l

    9 V; Q+ C, ^2 V5 K) Y, a( j<P>
    & _+ H. b9 r% f8 M! b% I, p, _//-----------------------------------------------------------------------------. q1 h- I4 f% z/ p6 z; v
    // Name: % ]6 @' t! J" X$ c
    // Desc: , y4 @& q% p7 w1 x
    //-----------------------------------------------------------------------------
    9 n+ v3 z) x" V7 A. Mvoid CMazeServer::SetClientPackSize( DWORD size )$ y3 z3 Y' d2 u( |( K4 Q1 z4 H+ O
    {) I4 b& A* O9 m1 q. I6 t/ L
        // Update client config, and build packet containing that data
    6 L# e' Y+ a4 W, M" d. O% h    m_ClientNetConfigLock.Enter();
    2 ?' C# u  Y6 ?& z  v; {    0 j7 t: U, \7 ~  J
        m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.+ ^% A/ t$ h( o+ E( o8 S3 }  }
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   
      Z! j; I; W/ X        m_ClientNetConfig.ubClientPackIndex = 0;</P>! I% i3 N4 B, p
    <P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);* S1 d7 G+ r* ^$ I* N! W
        ServerConfigPacket packet( m_ClientNetConfig );" ]. i2 b1 M9 o5 O" t
        m_ClientNetConfigLock.Leave();</P>
    & t( _/ p7 ^' b1 Z. f/ k0 y<P>    SendConfigPacketToAll( &amp;packet );) F: a  F, p! s; q* {9 y
    }</P>
    9 q2 `; b/ f- m# t8 ?  X6 }9 ~
    1 B3 G1 O. k: a4 k+ q" t<P>0 s1 ?& _7 p! H" n* e* J4 p
    //------------------------------------------------------------------------------ N) X- q9 D0 S9 H
    // Name: + d% y& k" b- [* q/ o* [
    // Desc:
    2 Z$ w$ k5 m. ^" X//-----------------------------------------------------------------------------8 F* ~) r6 M$ D. n
    void CMazeServer::SetServerPackSize( DWORD size )
    , }/ m9 q% S+ ^7 A6 N{
      D, G- ~7 c$ g4 m# I0 d$ Y  A& Q) A3 B    // Update client config, and build packet containing that data
    1 X- H4 O7 Z1 `- ]  h. ^8 n0 @! E/ K    m_ClientNetConfigLock.Enter();
    . n1 }) L6 {& |5 X$ M6 R3 d    ! N; W4 r; S. f7 m
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.
    ' z6 a: E2 I$ j$ U    if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   
    0 z: f4 X! _. @) V1 E! y9 z7 }        m_ClientNetConfig.ubServerPackIndex = 0;</P>* B" \. m/ v9 ]$ z, s
    <P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
    0 v1 G% T$ U' k) ~# W" c    ServerConfigPacket packet( m_ClientNetConfig );" h$ r7 O3 n# S" B- `# |3 U+ W! d
        m_ClientNetConfigLock.Leave();</P>
    . H: H  X. P- B9 j<P>    SendConfigPacketToAll( &amp;packet );. W$ o1 ~5 P' v1 j  k6 X; f3 J9 B
    }</P>: T1 F5 W; p) L1 x7 x6 A" H
    <P>( h3 Q& r% v9 p- j1 H
    //-----------------------------------------------------------------------------+ l/ y- E9 S* ^) \4 w! B5 M: D
    // Name:
      f+ r) \- R6 h% Q/ W& ]  d// Desc: $ P  `8 x, P8 Q% E3 h! z4 n  C
    //-----------------------------------------------------------------------------
    9 I8 i# ~3 i) `9 {' |5 jvoid CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
    ; k  u! h2 e1 [: ~* }+ m4 A{
    . d. v1 R; t9 U, a    // Update client config, and build packet containing that data
    0 k, S4 Y' I3 B# S4 a0 P    m_ClientNetConfigLock.Enter();
    / t' y  Y& ~0 _  o; C% t3 ~   
    ( L/ G# i* |1 S7 u8 |% o    m_ClientNetConfig.dwThreadWait = dwThreadWait;
    7 h+ @; n. g" a' Q    ServerConfigPacket packet( m_ClientNetConfig );
      O- T! Y0 K! u2 w0 C    m_ClientNetConfigLock.Leave();</P>; a% Q4 ]8 i. c. y& O' C) |! @
    <P>    SendConfigPacketToAll( &amp;packet );
    0 z# J7 y) o5 I1 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-4-10 06:35 , Processed in 1.070864 second(s), 51 queries .

    回顶部