QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4183|回复: 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>
    8 I! q) g0 g4 F<>// File: mazeserver.cpp5 |; I8 D, k7 Y/ v
    //( m9 R$ P" v  v) {* n% T; q
    // Desc: see main.cpp
    ' L/ r+ K2 W: r# T# b8 o& u//1 Z) [# ]$ B" E* C7 m) W
    // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.3 r, y) g) ?, |7 s
    //-----------------------------------------------------------------------------
    7 G9 G1 y6 t' u& w" f; T5 \8 o0 W#define STRICT
    , [$ O% R7 j+ Q# D#define D3D_OVERLOADS
    0 r& y) U( G$ }9 |: T5 @- U#include &lt;windows.h&gt;( \. n; r% N6 Q! Q* q
    #include &lt;d3dx.h&gt;( ^; O  c; ^; l, Q
    #include &lt;stdio.h&gt;2 A. V  I9 c5 c" x) u& a
    #include &lt;math.h&gt;
    . c" t+ a& G4 X#include &lt;mmsystem.h&gt;
    1 x( d: i( k' u( h- q#include &lt;dplay8.h&gt;2 ~0 y: |4 }' i
    #include &lt;dpaddr.h&gt;) ?4 l1 W) L8 ?4 U1 q) z
    #include &lt;dxerr8.h&gt;4 X! t2 f1 ?; c/ H7 I; U0 H- F, a
    #include "DXUtil.h"2 B6 W; z5 k9 U; q: A0 S; D
    #include "MazeServer.h"+ S* z1 A4 F2 O2 V
    #include "ackets.h"
    : U2 m1 M; \( ~, O7 V8 k#include "Maze.h"
    4 {& r: A/ o$ L9 x# H- ^! h#include &lt;malloc.h&gt;
    / Y5 e9 c* W9 Z  U: W9 Y#include &lt;tchar.h&gt;</P>3 Q" B2 K4 g6 @" H

    6 c# k2 {' H, a* l8 q! x<>//-----------------------------------------------------------------------------1 R5 p' c! G6 r1 ]( O9 u8 p4 [) h
    // Name:
    " V- a) B' j7 f* t// Desc:
    5 i! x+ T- g: P2 C, B  k7 l//-----------------------------------------------------------------------------
    , |# n& M* m7 c: x* b* X. sCMazeServer::CMazeServer(); n! L( ~  x5 y' E
    {
    3 a: _1 y& E, B    m_dwPlayerCount         = 0;9 p  {% c8 f) Y
       
    2 K0 z) A( f8 _; z4 E    m_wActiveThreadCount   = 0;
    : y# N- r4 n7 I/ A& w    m_wMaxThreadCount      = 0;
    ) c9 z; i5 M7 U2 a    m_fAvgThreadCount      = 0;
    6 p$ J0 d- Y/ i' \% e5 j0 U( F. X    m_fAvgThreadTime       = 0;
    2 D* l: O5 I" X8 {- c- R    m_fMaxThreadTime       = 0;</P>
    9 A  e- n7 ]/ s$ `' s<>    m_dwServerReliableRate  = 15;# `* I5 @2 X$ ^5 S$ ?
        m_dwServerTimeout       = 150;, `" k4 Q0 R0 B  F' k
        m_dwLogLevel            = 2;. L9 r4 h+ I* e: W( k; E
        m_pMaze                 = NULL;</P>
    2 s0 ]( Z, ^2 j/ `9 U<>    m_ClientNetConfig.ubReliableRate = 15;7 _0 A4 _2 p# b" c
        m_ClientNetConfig.wUpdateRate    = 150;
    - a. O' \3 Y+ Q( a. f$ T    m_ClientNetConfig.wTimeout       = 150;</P>5 H2 `  O+ ]* n4 k  b% D
    <>    m_ClientNetConfig.dwThreadWait = 0;</P>
    9 [  ~9 g" p/ d0 I0 E9 r<>    m_ClientNetConfig.ubClientPackIndex = 0;
    ; M' y/ F/ r# v) a    m_ClientNetConfig.ubServerPackIndex = 0;
    3 o7 l/ T' o; ~2 [! p! T    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)
    $ h. V* c% n) ?6 U    {
    0 ]3 \0 i. h9 r/ V/ k6 n        m_ClientNetConfig.wClientPackSizeArray[x] = 0;
    6 X- a$ T$ I- j# d- B/ R. R        m_ClientNetConfig.wServerPackSizeArray[x] = 0;9 C/ }, v& t2 F. ~  r+ c& @
        }( ^: f% _$ w% f
    }</P>
    6 ]8 O! o/ T! r% A: J7 M4 N* }, E) j, Y6 r
    <>; q" g# _& z; t' y, n0 s& Z
    //-----------------------------------------------------------------------------
    4 t! |' t5 o0 Q. B* [7 z9 e6 q: {// Name:
    5 z& A; o' p; a3 B/ L// Desc: ) T# [* [6 }- }1 [$ p& l
    //-----------------------------------------------------------------------------
    " D" o  Z# A0 L0 a/ yHRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )% n. N3 Q6 m' p& k* I/ i2 S/ T
    {, j: i5 a: \# G* y2 R! w; [
        m_bLocalLoopback = bLocalLoopback;) |9 b- L3 L% O% v0 p8 q$ l
        m_pMaze = pMaze;
    ( l. H1 m% v" r- }- j% V, h2 j0 h    if( m_pMaze == NULL )
    5 _/ r; _  `1 a" i5 o) Y        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
    & w' C1 }" U( ?0 e" h5 j<>    // Grab height and width of maze' D% b7 w1 @4 F8 W  q# Q
        m_dwWidth = m_pMaze-&gt;GetWidth();
    ) T3 i, J8 ?4 `  s0 j5 H& c7 s$ w    m_dwHeight = m_pMaze-&gt;GetHeight();</P>$ |- Y6 z1 K1 n, g; I3 b% _2 p3 P3 N6 i
    <>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    - }, U: v6 ?* Q5 @    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
    5 m+ }9 L# @: b6 t0 }& w; B- B<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.# B3 [( o: [) L& u* S
        if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    & _2 R) g& i* e- S0 h$ o        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );* V7 J" d* Z1 R5 |% ]# v8 I- s% ~$ n
        if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )2 e' C! B2 Y8 q' f, f% g
            return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
    3 j& M& ~4 H* Q+ y4 L1 W<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;
    * `1 O/ E' k) v) v6 p    m_dwMazeXShift = 0;
    ! w  @9 w4 V3 F' y% M3 \    while ( (scale &gt;&gt;= 1) )2 y  p6 v1 Q$ F9 P
            m_dwMazeXShift++;</P>3 E6 e  {3 X" q5 l: Q: |
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;% T8 n0 g2 A) g( W+ C( [, g
        m_dwMazeYShift = 0;8 z+ e- @" X; r+ ~8 ?
        while ( (scale &gt;&gt;= 1) )
    3 Q( E6 |6 Z6 C9 n; x        m_dwMazeYShift++;</P>+ t8 e6 e/ b. ~! m% ~/ h
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    & S3 G0 v2 Q* A+ l" ?0 l        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )# m! Q0 S& z8 {$ I$ ^2 M, H% M5 R
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>3 i( v5 u* S; D8 L5 g" c) K
    <>    // Initialise the player list
    / @" a# r) U3 }, y) G9 ~    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );$ k! @( a$ V* Q  T
        m_pFirstActivePlayerData = NULL;6 K$ w4 m- z  L7 g3 ]9 M! s
        m_pFirstFreePlayerData = m_PlayerDatas;$ w7 c1 K9 W. k4 m8 ?
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ ): W: ?+ O' a# @- D
        {. y: Q- d, s* F, t6 E$ D, y
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];0 H9 q9 @6 i' m  ~# P
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];6 M) ?6 z6 _$ J$ {# Z5 S
        }</P>3 Q( G! S0 k5 h6 t' k/ z( i
    <>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
    $ x# u( V0 D( s: @% V    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];
    ) d$ E" F" Z1 a! V- q/ {3 @" N4 X7 O2 T    m_dwActivePlayerDataCount = 0;5 T3 d3 A1 j' P' j  i
        m_dwPlayerDataUniqueValue = 0;</P>9 x4 M1 g/ ?9 z! ^
    <>    // Initialise the cells
    2 M- r7 p. [, T4 o0 }7 a4 }    ZeroMemory( m_Cells, sizeof(m_Cells) );
    % z; a8 y7 T) k" S* T    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>
      o! i! U* T; l* ~6 x- ]( f<>    return S_OK;0 m" X! i; j0 C" A9 \
    }</P>
    ! T" p( D+ L+ i" m6 e4 n/ L
    8 T2 I4 @; D: ~. S  j: S* _8 n<>
    # q/ x3 ?% I/ Z. ?* y! I//-----------------------------------------------------------------------------! q' }: {- O1 _" a. {' ~9 R4 R" A
    // Name:
    + B* [: ]6 Y7 ?! n// Desc: 0 K1 A, z: n- I3 O: X
    //-----------------------------------------------------------------------------
    4 u5 G5 ]1 D3 c" Z9 R/ Nvoid CMazeServer::Shutdown()
    4 d1 h, |: V. U2 l{
    , y) M; \& G; N}</P>
    6 o/ ^1 t+ p6 z" ?5 F0 ~- g5 d0 x; P
    <>! \. W4 G2 P/ m2 E8 l, N7 w
    //-----------------------------------------------------------------------------
    - F* M- v/ M3 q4 D// Name:
    ; R, S+ u1 k2 Z$ ^+ ]// Desc:
    8 d6 ?* L5 `/ H$ D7 s//-----------------------------------------------------------------------------$ U0 v' m9 E/ O  v) b$ i
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    6 B" \# Q; T2 G. I{% a2 ^- n, v' F( o1 \
        m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    - T  j- e; {' w4 L                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );2 w8 ~7 l$ r3 w, X# x
    }</P>
    * o4 T0 J1 A5 E* e$ p" H
    0 [1 V- D: h! L% J6 x/ c8 G<>
    & q' G. C: W! b9 _. l//-----------------------------------------------------------------------------
    # N* w9 e9 |+ ]+ d// Name: 0 u' J3 O+ U* q
    // Desc: , g0 n& e  [6 n. E1 ]
    //-----------------------------------------------------------------------------
    ! S3 O$ V" y" z4 q3 Zvoid CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )* i9 S  u! a% s
    {$ I2 ~) \. }, t# ^' ~$ K+ Q7 E
        m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,* ?& u! ~: ~" J2 Q: o/ a  e  |
                                x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );$ F3 |2 s5 g6 P3 `
    }</P>
    ' f$ Z& u5 G+ o- C1 y1 e2 G  x. d  k- s% p; G/ I# ~5 Z
    <>, A1 a& n+ E, y& T7 O: Q
    //-----------------------------------------------------------------------------3 b: A: k1 F  ]7 X1 p9 v
    // Name: 7 V- y. ], F1 O# U
    // Desc: ' Y0 z+ d' p$ T6 G: O4 S) v! g
    //-----------------------------------------------------------------------------
    5 F$ W1 g% t. T8 jvoid CMazeServer:ockCell( DWORD x, DWORD y )
    * e9 A! }; Q0 q$ y{
    , M1 O! y( L" e& q    if( x == 0xffff )  t4 R& U; M+ b
            m_OffMapLock.Enter();
    4 i4 z/ h. D1 j) Y. Q$ q    else* A8 M  E$ a" u8 h! x' w( B- @
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);) k, L% u7 P& B: V
    }</P>! t4 q. y8 f$ ?" B' I! p
    6 a1 D( U" M% U; X
    <>
    + w$ v0 l' M* k/ U- r- l//-----------------------------------------------------------------------------
    " f( {6 I% J9 U' R5 P// Name: 1 D, l- |' ~, D/ O6 u8 a4 N9 ]
    // Desc: , R0 z  o0 W0 Z/ ]: P4 e6 h
    //-----------------------------------------------------------------------------& b' r8 U+ T% S7 ?
    void CMazeServer::UnlockCell( DWORD x, DWORD y )
    - @2 u7 `+ C+ O( N! i3 K" B2 f  D{$ u3 j6 Q5 r+ f- c* W
        if( x == 0xffff )$ m: S% c& w, c0 `8 U; T2 b! `( V5 N% O
            m_OffMapLock.Leave();1 J! L1 \0 ^  T# `  ?8 M
        else
      w1 M6 P/ z3 K0 [        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);% H" }% J3 B2 l, r7 r: X! _5 \  t; }  \
    }</P>, p/ |# }3 T7 s* v; v1 S8 n# ~" p

    + b  y# x8 o/ T; O. w- k<>
    " c. W- c. t( D. a1 R//------------------------------------------------------------------------------ G) [- R& U# x; |) l6 }0 m
    // Name: * q" Q% X% B" J8 V* z6 E  I" J  F( v1 p
    // Desc:
    ) c7 H; b% H: G9 l+ n$ G: I//-----------------------------------------------------------------------------
    * P9 C6 }; h7 @# h+ m4 V+ k6 n& nvoid CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )' u) `/ w" k& }
    {$ H$ z8 g& g0 P6 n2 H% k, Y4 P
        if( x1 == x2 &amp;&amp; y1 == y2 )
    6 U! O; Y6 e* D: s    {5 [+ M, O0 c$ v
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )  g5 x/ Z3 S/ X1 [+ Y
                LockCell( x1, y1 );# A# _1 W. R% z' H2 k' f1 L/ @+ [7 v
            else6 U5 v8 h; l5 T! H
                m_OffMapLock.Enter();</P>; ]4 `+ Y) D; J! l
    <>        return;2 d; j6 o) F# Q
        }</P>
    / L# o% G! c* g8 ~<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    " M7 k# S2 G% B) a! m( A    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;, I0 H4 e$ a# Z7 }4 w; Y: D+ P, D
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;9 T7 p" _. W8 s# ^
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>) u; ~( C2 S) }
    <>    if( x1 == 0xffff )
    + X7 ^5 d) G/ n    {
    3 L4 `$ u7 q9 }, G' N9 {6 Q        m_OffMapLock.Enter();
    ; M1 j- N% a/ @* O- c' w: V        m_LockGrid.LockCell(x2shift,y2shift);! b& [) b& w$ K* F0 I
        }; z( x* ~; W4 r5 q
        else if( x2 == 0xffff )% K% ~, g6 j! P/ f' Z
        {0 G4 B! t2 E, a8 p5 [6 P) u/ F
            m_OffMapLock.Enter();
    ( B' a& N0 x% m# @6 V        m_LockGrid.LockCell(x1shift,y1shift);
    % h4 y+ q; [- F2 q4 P# ?% A    }2 g) l6 _: N! m( W4 h
        else ; B/ U( ~8 }8 h; o+ R
        {
    1 B% W0 o- o7 U8 ]  M4 @        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);
    , A  B7 _4 k$ j5 x5 K0 @; S! H    }
    * D. r3 m* Z9 O  i& d; S* n) B}</P>0 k, S  Z9 B# }4 ?

    ) `* @0 ^  k9 D8 G. N<>
    ( _; e* [5 v2 z//-----------------------------------------------------------------------------1 d+ S6 }: y  F) p
    // Name:
    7 X0 F4 }) s! n0 ]9 I% o// Desc:
    ; U4 K; R$ m* Z) _* k7 m//-----------------------------------------------------------------------------7 z9 B) z" u( G& w7 z. o, Z
    void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )4 V+ |0 u! ]( H4 N
    {
    " J% p0 B' i% |( P    if( x1 == x2 &amp;&amp; y1 == y2 )
    " x8 ]. k% E% c    {4 |  j- O6 M8 S0 o
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    6 U) P+ b! U. t6 a            UnlockCell( x1, y1 );8 @1 U/ E9 m# @3 K: \( Y  H+ D
            else
    $ ?6 H7 D/ D2 \* ~/ Z9 p" f( A            m_OffMapLock.Leave();</P>
    2 \$ C+ r, Q" `- u<>        return;
    + S: ]+ C# Q8 D, X' c    }</P>
    4 U) ^, Z/ V# E9 B( e<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    / p3 u# N7 v6 k( }" \- L8 V( j    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;& Y! B2 n: S: M9 K& `; U
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    . J. Q6 y# e. c3 q% h) [' h- f2 P6 z    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>2 |' l3 D3 w1 F+ f& R1 v
    <P>    if( x1 == 0xffff ). e$ _0 C4 B" c; A) B$ L+ ?" @* ?
        {
    $ A: u0 r+ t/ C* \5 e$ X        m_LockGrid.UnlockCell(x2shift,y2shift);. i! M; L( Q4 ]6 E+ K8 e; h2 Q. H0 M
            m_OffMapLock.Leave();' i3 L$ a; [0 B% k
        }
    . n6 s( q7 k. Q% x- P5 Z* m: c* h9 V    else if( x2 == 0xffff )
      U' t6 v+ G0 ~! r# e. a# ?    {
    . g# }, l; O, A) J6 V0 Y        m_LockGrid.UnlockCell(x1shift,y1shift);+ N1 n3 J. u- T, b
            m_OffMapLock.Leave();) L& Q7 Y1 z  i; Y& z
        }
    ( ?) V. C8 j* w4 T. u    else - |% }7 J. a4 D" ~: V; ~5 N
        {4 F9 K/ t& t7 x6 p+ N$ k
            m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
    , V4 n& ~/ Z9 c3 {5 h    }
    ! }$ I/ H+ r4 R- a}</P>4 e3 e3 W4 C+ b, q

    . A8 f% |5 j& s, r( M<P>9 _9 E- G+ g* ]6 l- i9 s, |
    //-----------------------------------------------------------------------------3 d: p& M* j' {6 [# j, v' r/ w
    // Name: 7 ]) i; ^" d- G  e* z6 C7 h- e5 ]
    // Desc:
    " a) m& A5 A) D//-----------------------------------------------------------------------------
    9 G/ k  j* k3 mvoid CMazeServer::OnAddConnection( DWORD id )$ k9 j" Z! G' m$ p3 ]; t- r
    {
    : I; u# n/ |* l    m_AddRemoveLock.Enter();</P>
    3 u+ Z5 ~& G& T7 j7 _+ W$ J, Z<P>    // Increment our count of players3 f  m0 T, Y/ z' R8 s- \, ?
        m_dwPlayerCount++;
    6 ?6 ^* t" P: b& G# y( \) t* }$ t) U0 R/ s    if( m_dwLogLevel &gt; 0 )$ y* X3 h2 I6 z/ Y! d
        {
    ( J+ t, X5 `  {* b0 ^  D$ Z; s5 {        ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );# [; u: j8 g0 d  s8 R
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );$ j" `$ G' c) S0 ^3 k$ r, S4 ~
        }</P>
    6 A6 q9 W8 ~( H6 E<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    5 x2 \! E7 ^4 p: n3 ?3 |        m_dwPeakPlayerCount = m_dwPlayerCount;</P>
    . A: A" {/ f* d1 l$ ?/ b<P>    // Create a player for this client
    1 m- |; v) x9 z1 k" Q1 g! t    PlayerData* pPlayerData = CreatePlayerData();
    ( ^2 E& u' ]! _1 P    if( pPlayerData == NULL )5 B# I3 e% q2 ~+ H; p1 F
        {& m: s+ @1 m4 _% `: s; ^
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
    ) L& f5 z4 j9 X0 I/ W9 X  M# ]0 f        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );
    + O: }* r; L$ W& O2 `; U        m_AddRemoveLock.Leave();
    # b1 M/ E6 f4 _$ v+ u5 |7 e1 O        return;, O. ]7 ]1 A: {4 B  m
        }</P>. [' g- g6 ?0 x9 M
    <P>    // Store that pointer as local player data7 e# T! A9 C" p8 O9 h- Z: s
        SetPlayerDataForID( id, pPlayerData );</P>
    - c8 [7 D* ^( @$ I9 C<P>    // Grab net config into to send to client* ?" u8 h* |- B
        m_ClientNetConfigLock.Enter();- C3 i: b. ^9 V% E4 D
        ServerConfigPacket packet( m_ClientNetConfig );" F  b5 k! I3 _  S5 t% J6 \' e
        m_ClientNetConfigLock.Leave();</P>
    + Z5 W& s2 ?4 q  G3 m+ K, a<P>    // Send it
    ! z2 K3 U2 M' g+ }; Y( p    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>
    5 n1 n  e' q1 {) z6 ]) `<P>    m_AddRemoveLock.Leave();
    5 H& ^8 A# a6 r}</P>
    / h* v( L* H: }( E- O5 C. f, S: j% k5 W# S' \$ z
    <P>$ f% T. X0 }& O1 z
    //-----------------------------------------------------------------------------
    " ^8 }; Z! i5 S// Name: . D7 N  V+ n8 t( T
    // Desc: 1 P$ W% j4 u3 i4 m
    //-----------------------------------------------------------------------------1 A3 l6 q* \3 D
    void CMazeServer::OnRemoveConnection( DWORD id )' o0 _/ G) b4 R/ ^0 o+ J5 i
    {
    + _0 E2 m6 [6 G, M    m_AddRemoveLock.Enter();</P>
    * |1 t+ }: G8 E) z# J<P>    // Decrement count of players: R$ ~0 p# x. y$ b9 z: Q
        m_dwPlayerCount--;</P>& B  Q5 j) c5 o( j, [6 A
    <P>    if( m_dwLogLevel &gt; 0 ). z" x3 J+ Y8 H1 _1 ]; I$ c
        {
    . e. Y( p# l" u/ j        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
    ; Z% s3 s3 W/ k; d        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );( r4 q. g* i9 z. ~) [9 i
        }</P>4 ^% T, h( G% H) S& a
    <P>    // Find playerdata for this client
    ' o. d% q8 D5 o, O$ S    PlayerData* pPlayerData = GetPlayerDataForID( id );3 t7 x$ w: K5 F  v
        if( pPlayerData != NULL ); ]6 H. a" t+ S
        {
    / G/ K$ W# ^& g& a3 r, {$ S        // Destroy it& X7 q( Z7 L8 {! t5 U; T
            RemovePlayerDataID( pPlayerData );' Y; N5 f+ u' y% r& ?( H
            DestroyPlayerData( pPlayerData );6 Z- c& O/ r6 W" r* ], e
        }</P>
    / X3 I' K3 ?+ w9 m2 @3 f  J<P>    m_AddRemoveLock.Leave();7 ^2 ]. d/ \' e, ^8 {/ i
    }</P>
    $ v+ W6 A& {1 t" m: Q/ t, S9 ^9 m8 K' M% I1 |- A) ~1 m
    <P>
    4 S9 k9 G! y0 b5 R3 |( r//-----------------------------------------------------------------------------$ l  @3 w  F6 @& S2 u' s
    // Name:
    2 {$ |! l* j! g# @6 M+ [// Desc: ( I. C0 J) i" f6 E+ C. r* c
    //-----------------------------------------------------------------------------
    / ]) ~$ p2 }, ?3 f) j) s' ]HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )2 w' D1 ?% `; ?) O4 |- e& g9 T
    {
    / a' R+ a' `) }$ g$ n+ b+ g/ @; E    BOOL fFoundSize = FALSE;</P>
    # L0 \8 i  }4 O6 L& @; O" {/ `1 p<P>    // Increment the number of thread we have in this process.; {4 [+ D1 j3 D' M: b7 p' l
        m_csThreadCountLock.Enter();</P>' M) f; d) Q8 L1 `
    <P>    //Get the start time of when we entered the message handler.3 b1 a! T+ _( r
        FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
    & J- q' q- O4 m0 N<P>    m_wActiveThreadCount++;
    0 j& |: S4 ]- r( e% x4 {4 ~0 g    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)
    " _! h6 S  k# u- [- `- E        m_wMaxThreadCount = m_wActiveThreadCount;: y7 x* h+ x( j; L' r
        ; _8 ^" B7 P2 |
        // Calculate and average.
      {" s7 r( b2 I' u; k7 Z! y    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;+ ?. p$ D& ?( H
        m_fAvgThreadCount += fdiff/32;5 m. i0 c9 b, _& X+ a( A+ g+ ^
        4 @; K2 L! w0 ]6 D: b( Z
        m_csThreadCountLock.Leave();</P>9 z' \  S- u7 J
    <P>" R3 M4 |) a: C( b
        ClientPacket* pClientPack = (ClientPacket*)pData;
    " n/ @5 G4 D. r9 G+ @    switch( pClientPack-&gt;wType )& y* _! U6 Z! O/ v
        {5 h9 K2 W( M) S8 S
            case PACKETTYPE_CLIENT_POS:
    7 ~7 a5 O$ y; L            ) f+ m  O" o' Y# a! C7 a
                // Check to see if the packet has a valid size. Including " |( x9 p; u" P) g9 e# G
                // the custom pack size.' ?" i) y; F) R1 X+ Q1 k+ d
                if( size &lt; sizeof(ClientPosPacket))% q! J. q2 b5 r* w0 @  U! \
                    fFoundSize = FALSE;
    5 E0 i( i# q' b& @1 g) J+ c3 ^            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))3 W4 [- w. D6 x( t
                    fFoundSize = FALSE;1 J6 q0 @- @% `9 Q# B) l
                else
    1 O/ I; F4 m( I3 j  e. \, Y1 {4 w9 h                fFoundSize = TRUE;</P>
    3 {% {; b4 f: C* q# c<P>            // If valid sized packet, handle the position.$ _' E. A# R: Q* P
                if(fFoundSize)* J) u/ v  F. r5 A& P
                    HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );$ Q: A; D4 ]: j$ m
                else
    " z1 x% N; }7 r, g' \                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>  Z( e+ K. d7 [! j
    <P>            break;</P>6 H  U7 u/ E4 o. Y
    <P>        case PACKETTYPE_CLIENT_VERSION:
    - c/ A% _4 }* M8 ~$ _, D8 T# _            if( size == sizeof(ClientVersionPacket) )7 _+ N- e% j) Y1 h( f% R/ F
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );! h& z$ @  V6 d: V: p
                else
    ) t8 X4 }9 [9 g- G, F  q. ^                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    0 Z4 z% |# }- d. e            break;</P>, T# X* [) {6 ~$ b/ M9 M4 ]
    <P>        case PACKETTYPE_SERVER_CONFIG:</P>
    ! j- L1 d7 ^# Y: {<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>
    : k' I" T- E$ c2 S( N" M2 r<P>            break;# d# g0 z3 m+ n& G+ t
            default:
    5 Z8 T) J( V' e& a- {            HandleUnknownPacket( dwFrom, pClientPack, size );
    1 {6 h; \& ]6 f+ N: Z5 x            break;
    # a: p1 o1 K7 K/ u, c    }</P>
      L) j/ u% t1 V9 J1 J, M6 X6 r<P>    //If the user wants to hold the thread, Sleep for given amount of time.7 X+ Y$ G( \8 [! \7 s: L# h
        if ( m_dwServerThreadWait &gt; 0 )) i4 p# Z% i/ X7 P5 T% q1 P2 k
        {+ ?' W, l. Z' T! B# A8 O7 N
            Sleep( m_dwServerThreadWait );
    3 N( A" g0 Q6 s1 d! i. K    }7 Z3 y. z2 M9 D+ H
        : @/ S/ G; N  v, n! P3 w
        // Retrieve thread data for this process.# H( j( j+ N, {/ O7 @$ H! H# ?% {) D
        m_csThreadCountLock.Enter();</P>
    ) ]6 ^7 Z! m, z- {- r# Y<P>    m_wActiveThreadCount--;</P>
    & S% l$ o* q0 P. [# {0 R<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
    # C3 k$ l+ B# C" S& d$ I5 T    m_fAvgThreadTime += fDiffTime/32;</P>7 T+ D! Q% a& ^8 C# S+ X
    <P>    //Get the Max time in the thread.
    7 X# e- i; H' `1 F$ {: S7 W% ^4 e    if ( fDiffTime &gt; m_fMaxThreadTime )
    ; M# M% x$ w* K2 R  W& K    {  R% n8 E+ T5 f$ S4 g) ?3 i- W
            m_fMaxThreadTime = fDiffTime;
    / k2 N; S" X: J1 f    }</P>
    . M1 C: K0 h9 h- {* v<P>    m_csThreadCountLock.Leave();</P>' Z& E' S$ ?1 A" x' `- W8 _
    <P>    return S_OK;% H. ^0 [- e6 |) u9 k
    }</P>
    : e2 r$ t/ I, O" f6 f' B" S1 b6 X5 ]+ {! G
    <P>//-----------------------------------------------------------------------------/ q. Q) h. ~# L/ C7 l/ ?; f( _
    // Name:
    % b3 n7 f* a+ Z0 C2 p// Desc: 3 t: w& n( m: w' u. K
    //-----------------------------------------------------------------------------$ m( k4 G7 M* ?9 z5 K8 [  T3 E
    BOOL CMazeServer::IsValidPackSize( DWORD dwSize )/ l  o% B2 y3 `& o% Z& C
    {
    ' h- C' C) s4 `. c. Z  C    BOOL fFoundSize = FALSE;! p8 U! u% a3 h* v
        BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;
    * n' L- i" X% e5 c" i    6 b8 N3 M' k/ O" L: D1 u4 }
        // Check through the array of valid pack sizes.6 D! o0 \! t( m! E; j
        if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    7 @- Z0 [8 }7 A( W3 P    {
    % [4 |$ g2 N" I, L% v" X+ E        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)
    - l8 ?" F7 h9 ]1 b5 s        {
    1 Z& e7 I! Z7 a  D            if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    / W- u- u) u5 }6 B9 h; E* v# m) q            {
    6 r2 [7 y. [2 n% E" i! v- h                // Found valid size in the array.
    ) u/ ~# y- s$ ^. e# ~) L' m9 u; P                fFoundSize = TRUE;3 u2 l  f: T: @6 R
                    break;) t! d* _5 M( V9 S4 K
                }
    ( D9 {0 N+ X+ P; [: b            if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
    7 e7 j3 }/ \% T9 }" o: j        }3 Z2 l7 ~0 {; Y: j- ?
        }# I  ?- K9 W. \4 O) _
        else' W; E6 t# ^/ {- A8 M
        {
    1 [- P- v1 a8 i5 e; o        fFoundSize = TRUE;- C* Z6 t1 t! w% d. ^
        }</P>" o, b1 R0 |1 t
    <P>    return fFoundSize;( P8 R* U* k+ L8 |$ P5 Q$ c8 [
    }</P>1 g0 k* k" k1 A" U
    <P>
    & I3 e  V$ F* i" `0 H6 ]8 c% S* X//-----------------------------------------------------------------------------& i( ]7 ?2 ~/ w4 D
    // Name:
    - n6 M. Y' v( p7 P* {// Desc:
    & j0 G0 q6 K+ `//-----------------------------------------------------------------------------6 r& S, {, T: B
    void CMazeServer::OnSessionLost( DWORD dwReason )! X5 `( {/ A$ q- |
    {
    ) B+ g) i! e0 B' Q* z    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );8 b. Z! ?9 X- y
    }</P>
    ( I3 \8 E. i, i7 h; @1 V' z) C; ^' [  u5 m6 j! G
    <P>4 B7 f! V' }, t4 A, y) e9 Y
    //-----------------------------------------------------------------------------6 s& x) n* m. x8 w! \$ Q, B. A$ G3 {
    // Name:
    ' P! r1 I; v3 A+ c// Desc: 3 `# B: ]; O0 f0 S; j
    //-----------------------------------------------------------------------------
    0 W$ P/ S# Z$ k% s$ w" CPlayerData* CMazeServer::CreatePlayerData()0 k0 M- C* G+ w% f" F
    {
    8 H$ E' n5 b9 Q+ V3 S1 W: e    m_PlayerDataListLock.Enter();</P>+ I. |7 d/ y- ]; ^* z8 A$ b
    <P>    // Grab first free player in the list
    8 E6 n" N$ y- E0 J$ s! e    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>- a0 `8 F% C7 K4 J
    <P>    if( pPlayerData )2 v% m+ F' d) K, T1 T$ r
        {8 Y0 K, \+ X$ d& p* ~1 E5 E
            LockPlayerData( pPlayerData );</P>* W7 Y5 {" |. H3 N: f; B+ C5 Y
    <P>        // Got one, so remove it from the free list
    3 c, w+ l/ ~" n0 f* s. @# L        if( pPlayerData-&gt;pPrevious )
    " q0 d. H$ G, i8 O+ x% _( e            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;- b3 y" Q: _. X4 P* [
            if( pPlayerData-&gt;pNext )9 m. T3 [" @: v2 A" V
                pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;# q: h; }( X: L/ d- a% Q2 l8 {7 E
            m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>
    ' r6 c  d+ K/ ]( F+ |<P>        // Add it to the active list
    2 s' ]9 ~+ E: v/ y        if( m_pFirstActivePlayerData )
    1 z/ i  o* K: B! N            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
    7 a+ X* y; ^4 h3 D/ D3 s        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;
    5 o  }+ y/ r( G1 e) G        pPlayerData-&gt;pPrevious = NULL;& g' p5 I& A" K( I8 O" \; @
            m_pFirstActivePlayerData = pPlayerData;</P>
    ; Q. q5 ^  Y2 p<P>        // Update count of players& m" i* t1 m' _" d4 N
            m_dwActivePlayerDataCount++;</P>0 B8 x0 c/ k- r7 g
    <P>        // Generate the ID for this player' `5 V/ Y. Y; a+ l4 E
            m_dwPlayerDataUniqueValue++;. g. A& F6 S( X" {  ^. N
            pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
    / L) i) x9 x7 T2 S$ l<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;' G) A1 |; n, j+ @& B7 O* O
            pPlayerData-&gt;NetID = 0;% V) G) n+ V" b5 I" n0 @  d  q" |7 p
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>( ?  R& \8 L( x
    <P>        // Insert into the "off-map" cell
    + O7 D" E: a% h, j6 w        pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;* {! F: x% C, V, w1 x
            pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;  S+ `1 j) e1 f" m/ }5 |
            m_OffMapLock.Enter();
    . ~  |2 r0 B/ W4 H        pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;
    8 }# z+ f5 N# s8 ?: u; H        m_OffMapCell.pFirstPlayerData = pPlayerData;
    % |  O' Q, y; u$ F+ G8 z        m_OffMapLock.Leave();</P>
    ) J5 H  O0 r! X: }3 H' V' h5 ^<P>        // Mark as active$ K! |) ^' w& l5 Q* [7 t
            pPlayerData-&gt;bActive = TRUE;</P>
    0 w9 x3 O9 s% \% q<P>        UnlockPlayerData( pPlayerData );, l! R6 u' v/ q, K( b2 J, C6 z" c' z
        }</P>% H7 }3 ]4 @6 j9 P
    <P>    m_PlayerDataListLock.Leave();</P>
      D2 |2 p0 J5 |! e7 H/ R0 Y<P>    return pPlayerData;+ `8 ^2 I3 @4 B; `
    }</P>
    ! o4 C7 t% K& t5 i5 _5 G6 |+ B
    8 P/ q4 @: a# s<P>( L, l( J+ @$ E# l2 T" I
    //-----------------------------------------------------------------------------
    . o% K% ?' \3 k( J2 Y6 w' N- h; [// Name:
    & T8 r: N7 R) S0 Z- L$ V// Desc:
    $ e/ O6 M3 B% v4 X//-----------------------------------------------------------------------------5 k) Z* _3 h2 C$ ^
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )
    % E  U  l) Y: S% k/ o) y{
      f# S/ |' Y+ C% U6 _( L. e    m_PlayerDataListLock.Enter();
    9 a3 {: Q# Y' r5 P0 e7 f1 Z    LockPlayerData( pPlayerData );</P>( f5 ~7 d: {) w( M; G% p- E' P
    <P>    // Remove the player from its cell
    " e% @% V$ B" ^( t' t, j! ]. Z    RemovePlayerDataFromCell( pPlayerData );</P>
    - `  n9 U4 M8 T8 S<P>    // Mark as inactive" {$ ^. J9 a7 ?9 _" B8 e$ [0 A& R
        pPlayerData-&gt;bActive = FALSE;</P>, C! G% \9 \- L( s# D% k" R
    <P>    // Remove player from active list
    $ d9 z; ?9 D& E  V    if( pPlayerData-&gt;pPrevious )
    2 ~3 n4 U% ^+ R6 C5 e0 I8 u        pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;; G: t- h- ~1 k4 O5 d/ T
        if( pPlayerData-&gt;pNext )
    9 I  @) s6 z5 z+ Y% r        pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>% H! D9 r4 T, I" ?. @6 ~4 P1 A
    <P>    if( m_pFirstActivePlayerData == pPlayerData )
    * Y' s* z' _, w) e4 @) v" B        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>3 j4 w) ]+ Y! n! Q2 c
    <P>    // Add it to the free list
    ! b: K, x/ L( r6 K% s. K1 H$ w# e$ i& V1 g    if( m_pFirstFreePlayerData )
    $ F2 }% P( C5 N# y  Y8 T        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
    : M7 Z* M3 W- U  d) G    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;- i2 Y- t+ h# C7 L& W* G
        pPlayerData-&gt;pPrevious = NULL;( F, R, W6 q  ^) h* n: j
        m_pFirstFreePlayerData = pPlayerData;</P>/ {0 k  i; t  [0 I
    <P>    // Update count of players7 q' J7 G1 W. b4 P! K- M  B0 \) D
        m_dwActivePlayerDataCount--;</P>2 E  N2 c, J$ R& i
    <P>    UnlockPlayerData( pPlayerData );
    7 F) S9 f# H" ~# d: d2 `0 @    m_PlayerDataListLock.Leave();+ h! t6 l2 r" h6 @# i2 [
    }</P>; L# A  _: \9 Y
    ) r; t! w1 f4 I0 g
    <P>
    ; U$ i0 @$ V, X( @) z3 P//-----------------------------------------------------------------------------
    : b) E' `8 o& l, m* g. m+ j: A1 k// Name:
    7 g! R5 {; I+ O// Desc: $ R8 z0 _9 G3 A( H- h/ f9 @% K
    //-----------------------------------------------------------------------------) F6 f+ S' ~* A+ }7 A/ H6 P0 G# E$ X
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData ): r% {* T( s- I& q; D
    {! t  U' g* m' J( I( B) y  q
        // Lock the player
    " n6 @' ]0 W, v* E  c4 p) \, _* Z    LockPlayerData( pPlayerData );</P>
    ; l( [4 @; r6 G: _+ W) _+ ~<P>    // Lock the cell the player is in- s2 M9 x; P7 I9 g
        ServerCell* pCell;
      b# p' V. u1 t( m" o! k, N    if( pPlayerData-&gt;wCellX == 0xffff )
    7 i* C- a5 n$ g    {1 w, h" }1 B) Y8 J8 ^' V
            m_OffMapLock.Enter();
    : q. X% y+ s) B5 M+ S        pCell = &amp;m_OffMapCell;5 i5 `. Q6 W1 }- O
        }* c' Q- Y2 e) W' c) g3 M$ R
        else
    1 P0 G8 b% J; u& F3 S    {
    9 }4 O4 P: n% C4 A8 J5 g7 ?4 g        LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );+ c- ?) G3 h  l4 j$ T& j
            pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
    9 z& v. U4 B$ }# @+ h    }</P>/ N" J( A/ F/ K
    <P>    // Remove it from the cell
    + N# Z/ B% \. [7 r9 {- s* M, p7 T    PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    % z0 I! n. n: s" r    PlayerData* pPrev = NULL;
    , o+ Q+ ^( J; ]) ?. a    while ( pPt ), u7 O- j: B: T8 L/ L% P8 r/ @5 w
        {" V1 E: T' h& |# `8 {9 {$ u' Q+ W
            if( pPt == pPlayerData )
    & h* v$ H/ W" M# J7 ]        {
    ( E$ s2 G1 W9 z9 A% D            if( pPrev )
    % T# g; O4 k- V6 E9 ^1 _7 P6 i3 t                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    3 [; S" ~, X1 b. Q5 n5 X' U$ W            else/ i7 A9 C8 T! @5 F3 j2 `( r
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
    8 I4 X* q( X" L0 B9 N  t<P>            pPlayerData-&gt;pNextInCell = NULL;6 _: X7 @; R  V" P6 b
                break;, w  @5 G; J* r8 a
            }! M5 V- ^, t+ M3 A2 E
            pPrev = pPt;+ U2 k, a) s/ ^8 g+ G
            pPt = pPt-&gt;pNextInCell;2 ]) V, v9 P5 o% R
        }</P>4 y; ^8 Y; d% {( C% c! V
    <P>    // Unlock the cell" C5 r! W! G; P
        if( pPlayerData-&gt;wCellX == 0xffff )
    , Z. d+ v9 E& Y. y9 a" c        m_OffMapLock.Leave();- g- v, M+ _; K4 [6 G* \
        else
    : J/ @# {) M, w        UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>
    ' Q  L. y( {7 U6 k<P>    // Unlock the player
    ! f9 v1 I) Y3 h4 S7 g* Y    UnlockPlayerData( pPlayerData );" o& S( D% R% C
    }</P>! C% @( Z7 v" Q( Z7 Q

    $ V! V+ q; h" ]9 H3 u6 O5 j2 F<P>
    : ^! E- [7 |" Z: I6 T//-----------------------------------------------------------------------------
    4 M2 f& |; b$ d& Y. Q% b3 O// Name:
    & [0 X  E2 Q! {# \* q4 ^9 u) J// Desc:
      ~- t$ c- w+ ]5 M( }: c3 l//-----------------------------------------------------------------------------
    : v3 S! p7 M: t2 h/ o& pvoid CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
    8 ^1 U& S$ p) l{; \5 n  |$ G5 R% ~" E
        ServerCell* pCell = GetCell( pPlayerData );
    ) ]* a3 G# A7 x3 K& t6 e    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;$ }- ]% _, f* w7 m3 S/ l5 E; [6 h
        PlayerData* pPrev = NULL;+ O8 z( p) p! y0 T7 q: Y
        while ( pPt )
    / w4 e/ I9 c! F  I$ P+ R    {
    ) u$ u) _! r5 e. d3 ~        if( pPt == pPlayerData )
    5 ~! W2 X6 X- J5 l; [1 q        {2 U1 G: b2 P6 o7 [* t( q
                if( pPrev )) x8 F: g, F4 U* {. U3 \: D2 S
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    ; s( A" ^0 D9 l  F: i0 B/ n8 R            else9 q4 g% H  \) Z1 e+ W% z: X( i
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;2 t* f- N# [: j. `
                pPlayerData-&gt;pNextInCell = NULL;: z4 Y/ O2 I5 K: ^
                break;' {% }% |! A1 S( n( F
            }: W; j) N9 ~" B  ~: H  K
            pPrev = pPt;
    ( Z% Z( o8 F+ H5 s( l  y        pPt = pPt-&gt;pNextInCell;; Q; e) x. ~' V0 F! s4 v# {
        }& q# n) O. D' @, T* f) s3 I
    }</P>
    ' H2 A/ J! p3 a4 M3 z) L( p9 V& R2 R3 h
    <P>
    9 D0 g% k$ ~( G6 e//-----------------------------------------------------------------------------" T! Z' s, t+ z1 R) c
    // Name: / q# s8 o  H0 x
    // Desc: 6 I7 T1 ~2 u$ t' j' i1 m, J
    //------------------------------------------------------------------------------ }6 c9 X3 |$ D) W2 I$ b3 `: ]' }8 e
    void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )
    & i# R, m% g, ^9 e+ S% a{1 V; M- Z9 F/ Q. {/ z& `, T8 w
        ServerCell* pCell   = GetCell( pPlayerData );
    % F! _. \6 r( X+ @* w9 @6 }$ W    pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;& o0 D9 A2 A5 p4 t) O
        pCell-&gt;pFirstPlayerData = pPlayerData;* e7 M) K; d9 U4 ^2 Z  M
    }</P>
    3 Y# P) w5 c/ @* u6 V$ D5 f% t, v( \* O! z+ l/ G
    <P>2 ~( V% S$ y. ?3 U$ t2 |/ A
    //-----------------------------------------------------------------------------
    ! R1 J4 L( x! ]3 i) M9 t2 j// Name:
    8 `) M: H& v) R7 h. `& y// Desc:
    . `' d6 I6 Y1 |$ `//-----------------------------------------------------------------------------
    0 H; v4 v. C+ B4 N. S" Yvoid CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )
    7 u# I: y* @% F7 c7 E{7 S  |% t9 i% N5 ?
        // Grab player for this client and lock it: P# b2 U* }* Q( y% B
        PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );! w3 F% M! ~! p* r2 u( C
        if( pFromPlayer == NULL )$ h' I* b! M# J; c; z2 W
        {/ R6 F3 @4 V  }3 `5 {
            if( m_dwLogLevel &gt; 1 )
    # T3 D% ^4 [, ?/ Y9 @) _            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );7 J) C. K, z: m
            return;1 ^. [7 z) U& ]4 h3 P4 y
        }</P>
    9 S. h6 O- O# s4 x! w# `<P>    LockPlayerData( pFromPlayer );</P>
    ( _) w8 b8 n0 ]; F' E<P>    if( FALSE == pFromPlayer-&gt;bAllow )
    # L. p& P0 S! Q7 S( x/ D, `    {
      ?, }" _2 `, S% T) R' b( S        if( m_dwLogLevel &gt; 0 )! o" l  v9 K" l. ^
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>1 K9 W. Y& D- z) @$ {
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );0 N; q) G7 d3 h4 x
            UnlockPlayerData( pFromPlayer );
      {. ], K2 e4 F- @, }' R/ h        return;
    2 k" ]2 @$ H5 ]# E, q    }</P>
    * I" b7 t3 G2 e# T' f<P>    // Compute the cell the player should be in now
    7 F! b5 M& @$ W+ J# D5 V    DWORD newcellx = int(pClientPosPack-&gt;fX);' P' |: B, @9 V7 _* G
        DWORD newcelly = int(pClientPosPack-&gt;fY);
    : n" R" J7 p% J6 j% H0 K* d    DWORD oldcellx = pFromPlayer-&gt;wCellX;9 C. e/ k- l9 ]1 \. j- W+ U" n) \
        DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>
    ( \0 X+ S& z* o' s4 D4 j<P>    // Have we moved cell?( i" h; A1 F9 {- V
        if( newcellx != oldcellx || newcelly != oldcelly )
    2 ~2 S( E0 P+ v8 k    {* o1 I$ H6 B6 t6 V. [# @' B
            // Yes, so lock the pair of cells in question
    * [* X7 G; a3 `( D        LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>  I8 @- e  ^; l, v* G1 T- I
    <P>        // Remove from old cell and add to new cell3 N9 T& f# m! B5 p5 z9 c+ @
            UnsafeRemovePlayerDataFromCell( pFromPlayer );" P- b" c9 a1 |" z, Q* {
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    6 e9 ~1 F+ o% @1 [* F* B. }        UnsafeAddPlayerDataToCell( pFromPlayer );</P>
    + U  z- v, F  Z<P>        // Unlock cells: d4 q& B6 |) c5 W4 ~
            UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );& a. E5 [1 \$ W& I$ v4 h% b2 x2 B
        }</P>$ |! ^* y# _7 y( C
    <P>    // Update player position7 t5 V8 }% p. S" a+ h( G
        pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;0 s. s& D+ d- `1 c/ m7 s* s
        pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;% s- s+ t5 P8 ?4 }0 u
        pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>+ C8 R+ N2 F/ v5 v" b* t
    <P>    // Allocate space to build the reply packet, and fill in header . d, z7 O% U; ~" i# l
        DWORD dwAllocSize;
    % k# a$ t* R/ e* D  ]6 M( [1 O' c, z    ServerAckPacket* pSvrAckPack = NULL;</P>4 O! l7 {6 x/ q6 k8 {6 I) j
    <P>    // Begin by allocating a buffer sized according to
    $ T& W, w$ V* \5 V' {4 C    // the current number of nearby players + 4.  This will give
    6 z+ g0 \1 I* s0 Y( @    // a little room for more players to come 'near' without resize5 q3 c$ o# r8 Z0 l+ }+ ~! P
        // the buffer.
    5 s' W; e. ^* [    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>
    + v( }0 |* r7 H2 i7 ?0 _! i+ r8 D<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    ' I& G; |- V  A8 ~& M3 \6 S3 L    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    ( ~7 S0 U5 H0 o& C% t9 |& `9 J    if( NULL == pSvrAckPack )" R' ~: T) }$ Y# e3 T6 h) a% ~1 Z& b
        {
    / @3 L; o6 d6 ^& i8 u        // Out of mem.  Cleanup and return
    1 k- s% v/ _- U  j, I        UnlockPlayerData( pFromPlayer );
    % P( F% k) F; D# T        return;      
    . r: i" Y5 {, K9 F  S7 p- a    }
    8 V9 a1 q0 I' j" `: t, D    ZeroMemory( pSvrAckPack, dwAllocSize );</P>5 h9 t+ _- T( A
    <P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);
    : c+ W( h; M+ t# ]% [9 ^& J    pSvrAckPack-&gt;wPlayerStatePacketCount = 0;
    9 ]5 M' B% X6 e8 ?7 Y, d% m    PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>
    / _2 ]; W' M) Z' x: X6 b; Z9 q<P>    // Compute range of cells we're going to scan for players to send* g$ O; }) a8 U3 o* E
        DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;+ j: ^" f9 F$ ?
        DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
    4 E. b! N" [2 r) [    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;* C' B4 y) N& s6 f
        DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>$ t( y# ~; @$ W) i
    <P>    // Lock that range of cells. y5 l& H" s( l: m8 [: h$ W. d4 k
        LockRange( minx, miny, maxx, maxy );</P>
    6 n8 t/ G1 e9 F+ [1 M<P>    // Scan through the cells, tagging player data onto the end of6 L/ K; g7 S+ F; Q( r' }: V
        // our pSvrAckPacket until we run out of room
    9 S( {2 k5 E( x1 i    for( DWORD y = miny; y &lt;= maxy; y++ )
    . V3 Z& }( ~  h' ]7 D2 [9 x% A    {
    : n/ d2 ~0 f$ P% A: s5 q5 D        for( DWORD x = minx; x &lt;= maxx; x++ )7 B: ]0 j; H/ W$ h6 f3 e% O
            {
    # h" z0 O4 h. O, q- ~            PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;' o! v. |0 z) [6 `
                while ( pCurPlayerData )
    3 ~0 s5 T  d& Z0 R3 }  S2 E  i9 i            {
      j! p5 e# z, S. @6 E7 `. I+ w                if( pCurPlayerData != pFromPlayer )3 f* o  x" a; B
                    {+ a9 m0 n& X9 F3 }  M; ^0 q3 m
                        if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )3 o) w2 N% O0 |1 N% v, D! z. O
                        {
    " j2 B% i* M/ x                        // Make sure pChunk is where we think it is
    ) e  X& Z0 d, h3 Z8 L- ]. ], ?) m                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>( @9 v3 \0 ]. @' k
    <P>                        // There are more than just 4 new nearby players, so resize the
      |, `; I8 L3 r4 Z8 j- I# P                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
      O6 I! x* d* @) C' Z; M: k                        dwMaxPlayerStatePackets += 16;$ n, V2 S- ?# M8 k+ P
                            dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);& n, H" N* K: S  t6 W
                            ServerAckPacket* pNewSvrAckPack = NULL;7 d3 h. \3 \, b% |
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );  A$ m: \( v2 n9 h" F* U: u
                            if( NULL == pNewSvrAckPack )- {' P/ ^; ^+ r: a# a$ u5 J* k
                            {3 G- E8 x: ^& z4 I3 `% y
                                // Out of mem.  Cleanup and return
    4 X) M! C& Z" S" p9 _8 {0 p9 Z0 D                            free( pSvrAckPack );# @0 Z7 P. w4 x0 P) h# a% G
                                UnlockRange( minx, miny, maxx, maxy );5 s% M; D' H+ m" g& B/ Q- X) U' l
                                UnlockPlayerData( pFromPlayer );) a9 m0 {8 W' F8 a
                                return;       % v9 s. y: o! n2 U2 p# s0 L  P
                            }</P>
    6 `" r1 \/ n5 }<P>                        pSvrAckPack = pNewSvrAckPack;
    4 Y$ S4 m# j: P& }' m                        pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
      C& Z  y% W8 W: \8 n* \  C: d0 B<P>                        // Make sure pChunk is still where its supposed to be4 t6 N* O" Q, @, x/ E
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );
    8 K' U. @- Q4 ?! T  H                    }</P>
    " d2 @& d8 }: W  r<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;
    " x9 j+ x, ~2 ?5 Y& L. l# _+ I$ S                    pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
    # h1 q; u% O1 U: m2 J# x! @                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;. s# k* p, o$ I, z. `3 v/ b: }
                        pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;
    : O4 w" L' f* N& ?+ }5 y                    pChunk++;
    + x- k% w/ v" ]& f                    pSvrAckPack-&gt;wPlayerStatePacketCount++;- U* {0 ]/ g+ A  {2 E3 ~( J
                    }* I* E' M4 k8 V0 B6 h% T' I
                    pCurPlayerData = pCurPlayerData-&gt;pNextInCell;
    ; k2 a2 S3 }2 k5 a            }
    # P9 A7 _+ r$ c& R. V, P        }
    3 i2 l4 E) t) F1 r    }</P>) O( q% c3 E& R; f6 X
    <P>    // Update the dwNumNearbyPlayers for this player
    + W4 w9 b$ y+ v3 ~, P% @" d7 r3 E5 d    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>
    " X+ S& A( z2 b, s) _! M8 r4 r<P>    // Unlock range of cells
    6 I0 Z7 Q+ w, F+ {    UnlockRange( minx, miny, maxx, maxy );</P>3 K( j3 G) Y) i( q# t
    <P>    if( m_dwLogLevel &gt; 2 )
    $ Q: R+ g( l2 y* o    {
    2 ?& @9 _- I/ Y9 Y        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    . o3 |4 @) J" w- Y/ @: h    }# J3 S; B9 }: |- i
        else if( m_dwLogLevel == 2 )7 Q+ `% H& C/ O. W7 p3 V
        {1 N# S( ~6 S( W1 ]# @
            FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    * T# Z) |, i5 h3 B  X+ E$ d8 [% ^        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )7 g  M# }- Z$ q4 H) c; L
            {6 u7 R$ V; R- T0 F4 M$ b
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    ) a5 u6 W' k% i3 _$ L            pFromPlayer-&gt;fLastDisplayTime = fTime;; m; `9 b# _2 Q+ s8 R
            }
    . L; X4 U* q$ G: |5 R% Q    }</P>: E- W' G' n( h/ o
    <P>    // Unlock the playerdata
    8 l& ]' A% L) Y% L) }/ G' K' s    UnlockPlayerData( pFromPlayer );</P>: u2 z1 m( f0 G
    <P>    // Send acknowledgement back to client, including list of nearby players
    % ]/ P, I2 `5 N/ t7 E5 c0 m    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));" m3 T5 W2 I: m7 a! u- O
    / ^( E4 [. {8 F7 C, Q
        // Pack the buffer with dummy data.* K* h( Z. R( l% M
        if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)
    # z( T* Q! V/ w4 ?4 c' i. B+ M    {6 L: e3 l) v' E" d% a
            DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];
    - N% h  K6 M1 R, w        VOID*   pTempBuffer = 0;</P>
    . S' g. }" G( z$ V<P>        pTempBuffer = malloc(dwBufferSize);
    ; r: ]( g7 P/ X' a  ?1 o( N        if( NULL == pTempBuffer )
    " U5 C; S6 D' E# u3 c  E- L" \' B        {4 C$ o$ L( m6 Z3 p2 F: I: w8 \
                //Out of memory* i1 l$ I. E: E5 m$ E4 f7 P
                DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );( M# G7 Q$ T1 q" f1 W4 m. H
                free( pSvrAckPack );1 z$ k4 p, G8 p; x; s3 i3 ^, J
                return;- z8 K; f$ S, E% L9 d8 Z1 l
            }</P>
    : S& `  F% P& @& S/ T<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');6 r  o! o" D/ R8 P
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>
    2 @  {* \0 I- K; P* f2 Y<P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );( l3 a2 Y1 n0 j2 O! f$ r) l$ n
       
    2 H( K4 y$ ]) F( K. P        free(pTempBuffer);
    . i3 }2 Q5 X0 ~" Q    }   : Q) p7 z5 |7 b) @
        else
    ) ]. K& w" f. b    {
    + D; [/ E- A7 ^0 b0 P' ^0 G" J7 F        SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );
    ; q" G+ }* ^# G, g    }</P>$ \0 v6 F! L2 ]8 e
    <P>    free( pSvrAckPack );</P>- F% A$ ?5 Y1 T8 W2 @& U3 z, y
    <P>}</P>1 L5 f7 A2 f7 C6 n' x# o6 W# N

    , ^6 Q( s: f; K' g9 ?<P>
      ?0 x3 W+ R- }( c//-----------------------------------------------------------------------------
    , u' I8 M+ e( e0 A// Name:
    " h# }; q1 w" E// Desc: $ _3 v# P9 i; M- U/ W1 R0 I% I
    //-----------------------------------------------------------------------------
    . G$ W9 I: j+ Pvoid CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
    : w: a# B4 F* g0 e6 h{% ^0 j4 O2 f* m5 ^1 i: a9 }( o( |7 T
        // Grab playerdata for this client and lock it
    # @& O, d% r5 W6 Z    PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
    1 e* b; j3 }7 P5 W; O' A, \    if( pPlayerData == NULL )
    / y4 F1 U0 H6 g" N0 u        return;
    4 b- E' z) k( J& E    LockPlayerData( pPlayerData );</P># ]  z9 z! x# j4 `9 b1 I
    <P>    // Record the version number
    2 o) }) ]/ H% F    pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
    ; P4 t2 |8 I( k" Q5 X# z<P>    if( m_bLocalLoopback )
    1 I+ k% o- g* `0 u8 }% ]* @: h        pPlayerData-&gt;bAllow = TRUE;
    : W/ W+ ]" c( f5 B9 _- I    else5 F# w9 o1 u3 ^; t. l# e
            pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>5 Y: c& E6 v; J. a3 W
    <P>    if( m_dwLogLevel &gt; 0 )
    . P4 o# l9 d/ E+ C+ x) b        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Client version=%d (%s)"), pPlayerData-&gt;NetID, pPlayerData-&gt;dwVersion, pPlayerData-&gt;bAllow ? TEXT("Accepted") : TEXT("Rejected") );</P>
    6 T3 G0 |: ~+ Q. x$ o6 i/ n* `<P>    if( FALSE == pPlayerData-&gt;bAllow )
    # ^8 P1 n0 y0 B1 R% p; J% D  o    {! {; i. w/ I4 U" T2 Q
            if( m_dwLogLevel &gt; 0 )
    2 @, p2 c. h/ o3 O: k; g8 w5 u            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>; R/ O% l% ^' R5 S* H
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );: K! u& x. b1 v
            UnlockPlayerData( pPlayerData );4 w+ p5 S1 V4 e
            return;3 ?! i2 Y" f- \
        }</P>5 w& s& Y" G3 `2 p9 y3 H
    <P>    // Unlock the playerdata( o3 _; H; J. I* }4 x6 D
        UnlockPlayerData( pPlayerData );</P>$ \0 o0 s7 Q2 ~5 u& E
    <P>    // Send acknowledgement to client that the client was either accepted or rejected- r: P' A5 s/ a) _3 U1 X4 t9 v
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );
    ( |/ _6 I( s! \* u" U    SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );- ^; T4 w8 E$ M
    }</P>6 O- T+ c# _7 _" r% C5 U+ V" X* c: n
    1 ~9 L+ K0 b) C! y. V. I6 f1 j) J
    <P>
    ! k' j2 Y- G% Y4 T5 `& u//-----------------------------------------------------------------------------
    * {* w( Z& o/ Z/ k  W// Name:
    5 a$ U5 Q8 s# g, F' v, q8 t+ d1 ]// Desc:   C: i8 i: N! P& Z3 _
    //-----------------------------------------------------------------------------
    ) W( k- R" F3 j; k* U+ uBOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )* A& _, W3 Z. u; [. Q0 @7 z
    {
    % S9 u4 z) n1 E) q    switch( dwClientVersion )
    9 @8 W% \) Y. p& ?& G, C    {7 u+ F3 P5 ?+ L; ~- L0 Q( U, m
            case 107: // only v107 is supported5 S( E. ~+ y$ v5 B! S1 E
                return TRUE;
    " h5 }& g3 h4 L/ I$ v0 n3 f        default:1 o5 K* d2 B, I
                return FALSE;9 Q. l( P# X' y; k' ~  m  y
        }/ ?7 h/ {- t2 J4 z" v& `2 I3 k
    }</P>
    8 R  D5 e- ~4 o! c* S
    " r0 a! h  L  w" M1 l3 I/ x<P>1 P' W* l/ s- H
    //-----------------------------------------------------------------------------, c! \7 T! A) t9 S1 [7 P3 K
    // Name:
    3 n4 B2 ~8 N* S! C+ K# a// Desc: 6 v) I; {8 ?6 _$ M
    //-----------------------------------------------------------------------------
    4 N2 H2 s% V) Svoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )! L0 Z/ Q3 E+ m) I' `) N
    {
    & p6 y2 l+ Y# w- r% ~    if( m_dwLogLevel &gt; 1 )
    4 \( A, i4 \" C* |7 s        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>
    ; F# C4 Q/ ]( K  u8 P: P6 n<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );/ Z% t) b8 l. p3 ]  y% n& K  V
    }</P>- `6 w( |; _3 n, t. K4 e6 K  [9 O# z

    , S; J; n' {0 R* i, Z<P>5 z) M, \4 u9 K+ t
    //-----------------------------------------------------------------------------' Z7 O8 m$ j$ J5 A2 _; O% T; }
    // Name:
    , J1 Q" T) z, f// Desc: 3 R( ?2 I; T% y0 Z- X
    //-----------------------------------------------------------------------------
    8 Q4 V7 S7 u, z, `+ CDWORD   CMazeServer::IDHash( DWORD id )' T" Y5 |/ k/ j8 t% I4 v: y) k8 ^
    {
    ( _- Q8 j9 m/ ?    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);# T- V8 I4 X1 p  M8 c7 K7 ]
        return hash;5 C' k* G6 q# E# _: ~, B; i8 ]2 ^+ J
    }</P>/ z1 K  m& T& o2 _

    . C2 x% {1 T2 Z& x<P>9 F' o# Y. n. W/ D) e5 j% D- D
    //-----------------------------------------------------------------------------. J$ x+ }+ q+ S; E( V2 C/ c
    // Name:
    * s5 N# j* S4 D7 E8 f1 T// Desc:
    8 B) P* O0 S3 |+ H//-----------------------------------------------------------------------------
    - M# ^( F5 ~6 b) y7 V" F- L9 nvoid CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )' w0 p8 F% M( e2 ]% ?
    {
    + h5 }( ^0 v+ M: v; f% |    // Hash the ID to a bucket number, P$ ?" f. J- w& E
        DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
    + w6 e0 B8 T% N9 u; {  H( M<P>    // Lock that hash bucket
    6 _- L9 q' Q1 {7 m1 o7 m! A    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;2 `5 g, |  U/ x& Z3 M
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    ! d1 [0 [- i0 H7 R+ s% y3 B" x0 q<P>    // Loop though players in bucket until we find the right one
    & D% Y& H6 p; t    PlayerData* pPt = m_pstIDHashBucket[bucket];- g* @: a* ^1 K
        PlayerData* pPrev = NULL;) n) a, C- y7 J! \. _" ]* a
        while( pPt )7 o* I5 X3 P& Q! Z6 D2 h% q$ i
        {
    0 d. J+ K2 |1 @0 |. b) w        if( pPt == pPlayerData )2 Z+ `, a$ b/ x1 e. w* X% @
                break;
    ' o. i, I/ Q; D% ^: @; p        pPrev = pPt;2 J+ Z* `& |, s' p' P# E7 w. |
            pPt = pPt-&gt;pNextInIDHashBucket;9 O5 A4 v/ \2 C4 U
        }</P>
    * r" `: y$ H6 q0 F0 j# K  X<P>    if( pPt ). L* }* e: C- N0 V
        {6 j% C0 O5 `9 q3 A& f3 f1 ?
            if( pPrev )
    ) n' S! y9 v0 o$ I: f            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;5 ?' u8 ]) x, I
            else* j) ?- s8 k7 A! W+ t8 R! e
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;0 a) `9 I. b' J  Z: Z0 ~4 }5 T3 N- d
            pPt-&gt;pNextInIDHashBucket = NULL;6 B9 s* _8 G1 V6 n; `# d
        }</P>8 H* e: l: s6 }/ h9 N
    <P>    // Unlock the hash bucket8 c# Y* F. Y3 G7 u8 h" u
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    9 S! e/ ]. i3 d! Y3 M}</P>
    + b8 R: e$ P5 M: e7 S
      `5 j# s" J7 r+ @" L1 C( U" {<P>
      g/ I: L  z$ D8 p5 y! r//-----------------------------------------------------------------------------) i8 M( \5 K+ D
    // Name:
    3 Y% V8 I6 }1 N9 G. C7 E& b// Desc:
    % x) T# i' F1 J3 Q. v& k, E! d//-----------------------------------------------------------------------------  o7 T; z8 a# j% @( P
    void CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )7 d  @$ s9 I: E8 s/ a3 _5 g
    {, @: k" B) Q' O* U; s" I. @; s0 b
        // Make sure this player isn't added twice to the m_pstIDHashBucket[]
    4 C7 O" s2 D, {& R: W    // otherwise there will be a circular reference; E. {* u  K. u/ e* V+ f
        PlayerData* pSearch = GetPlayerDataForID( id );
    / U; P- G% z6 \6 C. L9 A9 I    if( pSearch != NULL )
    % f1 y$ t' V8 X5 [: `        return;</P>1 u$ s0 B; P- E7 k- `1 }. j3 M. T8 @
    <P>    // Hash the ID to a bucket number$ {7 u9 G  Z% v) T5 R
        DWORD   bucket = IDHash( id );</P>( ^+ r. U: ]+ f1 H& ^
    <P>    // Lock that hash bucket' }8 R! d; B3 {# l! c
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;& ]# M1 A# B+ W# T) B0 J& H+ ^
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    . P+ E- \$ w9 T<P>    // Add player onto hash bucket chain7 C! A# |8 B- @' D6 o9 Z0 H# w
        pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];) D# Q) L1 v: Y9 J  J1 `6 H
        m_pstIDHashBucket[bucket] = pPlayerData;</P>
    " L) Y9 K8 D* h! y+ }" E<P>    // Store net id in player
    " o# g+ f: t! S" Q" `. O4 H    pPlayerData-&gt;NetID = id;</P>& |4 [/ q' V! U( U: B, u
    <P>    // Unlock the hash bucket
    $ ^2 }  ?" J4 W9 D! U* \6 I9 V    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    9 @: g+ M' k( B0 @1 }, ~2 \}</P>
      W9 t7 A& p9 J
    " ~2 W' L4 ]$ C; j" S<P>! t" E% H4 e$ X% r
    //-----------------------------------------------------------------------------+ A: U' V/ H0 q% l
    // Name: : B; P! U( u2 Q  u4 D; Q
    // Desc: * Q6 O5 x2 s' |& a
    //-----------------------------------------------------------------------------2 o& A  [* v0 X* c: q! S1 @
    PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )
    / d% N' Q9 W1 ^9 a{
    3 M& }& b6 Z* s) j: q) `3 \! f' J" Y    // Hash the ID to a bucket number
    , A9 ]6 q! ^, ]+ `    DWORD   bucket = IDHash( id );</P>5 {( K* j4 [8 R/ C; `
    <P>    // Lock that hash bucket
    3 n6 |+ Z4 @, e$ c$ ^& A    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    - s& g: Z) ?3 W    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    9 e2 x+ b) p9 v: H8 M# n! G# u<P>    // Loop though players in bucket until we find the right one: @+ R# Q- R( m* v
        PlayerData* pPlayerData = m_pstIDHashBucket[bucket];9 |/ b7 E: V. t0 X
        while ( pPlayerData )
    ; n0 ^; f8 L# e2 ^3 o/ M$ _, @' e    {+ ~. R/ s& @; y' L
            if( pPlayerData-&gt;NetID == id )/ R$ W% V* G4 T
                break;8 d  J( v# _" [/ s
            pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    8 |1 a4 b1 L" u4 X    }</P>
    : |1 q% \; V  }" h4 T% j6 H<P>    // Unlock the hash bucket
    ; ^  u8 |/ @) v( S    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P># y6 I5 O- h6 }# J# e
    <P>    // Return the player we found (will be NULL if we couldn't find it), z# S1 Q: n' q% ]0 x
        return pPlayerData;
    # u" g" Y3 u1 O" J}</P>: p3 {1 m: N, U- V4 l* B* i

    2 P$ q* D  I+ A" A8 z' F<P>2 J3 Y" w8 Y8 z+ f
    //-----------------------------------------------------------------------------' j; c' P  D2 v3 J4 o# e9 H/ X, e9 B8 s
    // Name:
    # b' S5 R! S; h4 ?8 a// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner
    ' a* Y* l/ H: y% x% H//-----------------------------------------------------------------------------7 z0 f9 A7 q- P) n
    void CMazeServer:isplayNextConnectionInfo()  t7 h& ?! Y* ^$ Q$ i8 `2 o, s- g! ?
    {
    1 ]- M! Y! t( o9 ?, T& r$ ?% A    if( m_pNet )
    - I& h+ l/ D% v8 v! B0 d0 G. f+ h    {
    & y& |. C) m( x7 {5 l- l        // Find the player that was displayed the longest time ago, and display it.( G) H, ^7 h. \& T
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
    - Z1 D. F' t3 G        PlayerData* pOldestPlayerData = NULL;
    - K. \, r1 X! N8 `) H9 V        FLOAT fOldestTime = 0.0f;</P>! Z0 }  R# {) S
    <P>        m_PlayerDataListLock.Enter();</P>
    ' V$ d7 v( m0 L+ z7 t- M# i<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
    / G0 t# M/ b$ o& A/ u        while ( pPlayerData )6 n+ V5 I7 m5 b5 F
            {+ g% ~1 Z  H# j2 f
                if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )* S) B' {+ R2 D1 p  Q
                {
    : x) q$ t2 V1 T/ y. {/ W* w5 K                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;
    3 C* K9 C8 U, ?! ]$ Y2 f: T& T8 u  Y                pOldestPlayerData = pPlayerData;
    , Z% d; E# P, J; K& k4 J1 w            }</P>
    7 {3 S( F9 ]& X0 A# Z<P>            pPlayerData = pPlayerData-&gt;pNext;
    $ o, m' T% e5 `- Z) ?! [% X# t        }</P>
    0 x: m; E+ b3 T# x% G<P>        // Display the player with the oldest CI field, and update its CI field.) E( x. E0 ]  h! y, Q7 ^0 ?& }
            if( pOldestPlayerData )( R' V% w# h* ?/ }7 @
            {
    9 u8 j0 K6 _# ~, @, ^            ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
    ; W  m* O6 K. Z5 g            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
    ' F& ~- k% g, E- m# e            pOldestPlayerData-&gt;fLastCITime = fCurTime;
    3 P8 B9 S. Y) `; x. c5 d, B        }
    5 @" g9 S3 Y, W- V9 [+ h        else
    3 i* d9 }9 b! S+ l  O" G        {7 P4 N" f3 F! S# P& z/ X/ p2 W8 K
                ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    + i1 u+ m- b9 r7 J! z        }</P>
    2 g; {* m1 C" D+ W$ c+ O<P>        m_PlayerDataListLock.Leave();5 Y) I  n5 I( ~+ u
        }8 }1 `7 l+ E! q7 L2 A
    }</P>
    $ h3 T) n; c; N; E, S  L# B+ Q3 |) F4 U% J" g% c8 b! x1 ~
    <P>
    2 r6 D8 J' k" U! t//-----------------------------------------------------------------------------: @  D) o) L& T" F. X
    // Name:
    ) c& \' T# B# H$ F// Desc:   \  l; b, q. k3 l
    //-----------------------------------------------------------------------------
    4 T( @% y( ~% p$ Vvoid CMazeServer:rintStats()
    ) x# s1 _6 H/ Y0 u: x3 S! f{
    ; R, R7 W, i; ^9 x3 U; r    ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
    : n8 S! d0 d, W9 ]$ z' c, x" z                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );) t0 \" q+ x) P. r% X5 `
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
    : @" n9 z; A; d/ |4 N* f* s$ e                                    m_fAvgThreadTime, m_fMaxThreadTime );: ]; I7 C" Z- w3 `
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
    6 W9 w% D* b: A0 m4 _: y3 o    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );' M  ]" ?% M' Q  E
    }</P>3 J8 P" J; {- U

    + n/ O& i4 K6 ^! t2 m3 d<P>) f( M* u( W6 j! B+ Q& s
    //-----------------------------------------------------------------------------4 n9 V* m4 V8 S6 I' M
    // Name: , P( d  U5 Z& h2 G
    // Desc:
    ( u& V" e" i, Q  S, p" Z//-----------------------------------------------------------------------------; j& d1 i- a7 X
    void CMazeServer:isplayConnectionInfo( DWORD dwID )# \5 E: ]5 b7 z
    {6 i# R. |1 Z$ y% K2 U
        TCHAR strInfo[5000];
    . P) r) M5 [) X8 C, x. w    TCHAR* strEndOfLine;  f0 D& I9 N; f
        TCHAR* strStartOfLine;</P>2 e* }, Z7 Q" m9 f2 x
    <P>    // Query the IOutboudNet for info about the connection to this user
    2 ~. C0 W& H8 d6 I    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>
    & y! i5 m6 R$ z' ^+ S: u/ r<P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );
    2 y: @* d+ m' Y' Q+ R! y    ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>+ j) F9 e0 u* D2 g/ g
    <P>    // Display each line seperately6 t# v8 y* f+ C& Y1 k2 S8 K% E
        strStartOfLine = strInfo;3 e- ]8 l9 d2 S) X& d( E- c1 q1 u
        while( TRUE )1 ?# v& B7 n' g, E/ V( m7 X' }
        {3 x# U9 O* N& w1 ]$ n
            strEndOfLine = _tcschr( strStartOfLine, '\n' );
    4 D# |5 K! j5 j4 A% S! F+ e- z  `) l        if( strEndOfLine == NULL )
    ; |, d3 t" r0 P7 @. L4 U% |* b- o            break;</P>5 B, q/ |$ o( Z& w' B1 G: p
    <P>        *strEndOfLine = 0;* S+ k$ I2 T9 j0 N' M. `
            ConsolePrintf( SLINE_LOG, strStartOfLine );
    : B& v2 q2 Z/ v4 S# @- t  a        strStartOfLine = strEndOfLine + 1;2 {' ]- z& M5 q9 o4 q! t
        }
    0 D+ _6 i& {+ [$ ?1 n, u}</P>
    3 H4 f& O# Z( G% ], D! T( z  k' u' u
    <P>
    1 t9 A) T4 y0 a1 _  R( v//-----------------------------------------------------------------------------" k, V, Y2 ]0 V
    // Name: ' }( ]+ j9 o1 t3 c+ D9 C, h
    // Desc: 8 c" p+ d1 z- e; f5 G. V4 F) Q
    //-----------------------------------------------------------------------------
    4 S: T/ ~+ ?( G& pHRESULT CMazeServer::SendPacket( DWORD to, void* pData,
    + m0 |6 Q8 g, x& {# ~' c                                 DWORD size, BOOL reliable, DWORD dwTimeout )3 A' o5 S1 H) o# V; |) R; B
    {' f  l0 K8 B$ j+ O2 [
        // Chance of forcing any packet to be delivered reliably
    9 N: D1 F. r6 B' C& d; k3 Y/ j    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )1 v& }$ d1 ?: s: t. @: @- O( d
            reliable = TRUE;</P>! n! V) E  u# U# E. K0 f
    <P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    7 R% ~- _/ k, J8 q}</P>9 t$ P  t; e1 a1 d

    / [2 Q3 @( \. x6 e' X<P>
    # F. z# K7 e8 c  g: ?//-----------------------------------------------------------------------------. C9 J$ k# g0 e5 ^9 l; j% O3 a
    // Name:
    # Y/ h( c2 U" {, S// Desc: ! L+ G; g, a# d% P* M% p  b+ {
    //-----------------------------------------------------------------------------+ i: z) S) n1 B8 d! p" N4 \, m% h3 P* w
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )" H/ @& _) N" C; G. \' X
    {6 t! a/ B  g4 O3 K/ m
        // If we're up and running, then send this new information to all clients
    ! g4 H- ^* a* c    if( m_pNet )
    ) g. h- B6 J) ~; M7 W    {
    7 U* q( n& f) o0 x8 k        //Use the AllPlayers ID3 S% n& N$ l4 j# q/ q
            SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );
    ' @) W* y% m( p9 J    }
      Q7 ]$ `: R7 E}</P>& i1 y9 O2 V1 G
    7 W( P7 ?' G5 m
    <P>% k& s' }  C8 K) F+ V6 o
    //-----------------------------------------------------------------------------: k* d3 _9 ~) g$ z* T/ p/ ^
    // Name: , |/ r: L6 K# b: T5 T
    // Desc:
    # j6 c2 |$ ^' \0 w, I' X; s- k* W//-----------------------------------------------------------------------------
    # u5 t, K; ]: R+ |void CMazeServer::SetClientReliableRate( DWORD percent )
    2 H& n+ u; e9 h/ ?; e' m* D5 N. O{
    3 P1 H" r7 D/ [1 m! Q    // Update client config, and build packet containing that data
    , Q8 }3 J. D& w$ t* H( n/ u: {    m_ClientNetConfigLock.Enter();
    # y& j$ M% f4 ~    m_ClientNetConfig.ubReliableRate = BYTE(percent);5 a' m' {0 L" g1 a* H) T
        ServerConfigPacket packet( m_ClientNetConfig );' y. ^( I0 X7 h  a
        m_ClientNetConfigLock.Leave();</P>8 y. [' I) V8 u
    <P>    SendConfigPacketToAll( &amp;packet );
    ; S+ e3 J2 Z; n0 q8 ^1 z8 E}</P>4 |2 f' i6 x& d- _1 B) z* r

    0 [# j' p1 K/ n; O<P>" U7 G0 D" A  G0 K0 W3 m
    //-----------------------------------------------------------------------------$ O( T5 Y/ q* q( O8 o7 Q/ L
    // Name: 8 H! T$ g9 o$ l. K. C. v3 |) H
    // Desc: ' @5 v  |. K! a; Y- Q5 Y+ F  V
    //-----------------------------------------------------------------------------! p; s1 R4 M; ^
    void CMazeServer::SetClientUpdateRate( DWORD rate )
    - u& V  @8 Y- v3 @. E2 I{
    " s& |, A& h" C! w% Q- x0 L% W7 d    // Update client config, and build packet containing that data, Z0 L, g) y0 b6 A
        m_ClientNetConfigLock.Enter();1 ~! m+ ~; Z6 e) v
        m_ClientNetConfig.wUpdateRate = WORD(rate);5 E" O; r% c5 u3 N. {
        ServerConfigPacket  packet( m_ClientNetConfig );' A, q( H5 m  i2 z  e- o
        m_ClientNetConfigLock.Leave();</P>2 v. o7 a2 `" q
    <P>    SendConfigPacketToAll( &amp;packet );' t' ]) w" M! [" v! L
    }</P>
    6 O  O4 g0 K5 d
    ; }: W3 t3 E- W- j<P>
    ! i0 @' S5 Y. G4 S7 x//-----------------------------------------------------------------------------" F1 c- D+ z6 A3 \8 Z- g
    // Name: 2 }7 ^( O# `$ X) R
    // Desc:
    0 H  t( Q) \5 o3 r3 z//-----------------------------------------------------------------------------" U- K9 Y. [; I! r
    void CMazeServer::SetClientTimeout( DWORD timeout )* k" S( G$ s2 _: B( v0 j0 J- S
    {
      ~' t8 L( y% B' C5 P    // Update client config, and build packet containing that data
    & _3 M. I. g9 S% b6 v+ j    m_ClientNetConfigLock.Enter();
    6 y2 {7 R: F' H  M6 ?    m_ClientNetConfig.wTimeout = WORD(timeout);
    3 D8 f/ I7 E* [9 X: v# |    ServerConfigPacket  packet( m_ClientNetConfig );5 D! J/ j. l, I! v% ]2 L
        m_ClientNetConfigLock.Leave();</P>3 Y1 ~( o1 A& A7 g- q3 J+ [: s
    <P>    SendConfigPacketToAll( &amp;packet );
    " {* U& r7 n, q; j- V}</P>  Y- L7 l2 m2 g6 k, w6 D
    / f# r8 X# B6 O. ]
    <P>( u9 C* d5 B8 E# l! X5 Y0 C
    //-----------------------------------------------------------------------------
    & W& m, K- r! l( L" U// Name:
    / |2 D% u5 n) x( W4 N) [; ?+ l// Desc:
    8 a! E3 R6 r* N//-----------------------------------------------------------------------------1 I6 g3 u# j" x, C, D  T) ?
    void CMazeServer::SetClientPackSize( DWORD size )
    8 ]. d4 W  ]6 g4 r{
    & \1 \  }' A9 f8 I0 q8 ?    // Update client config, and build packet containing that data
    * d! y/ k% U- e2 T; A) ]) @4 _4 L7 c    m_ClientNetConfigLock.Enter();  Z% I$ ]5 e4 Y/ e$ X
       
    & `, [5 b' C/ d" |- D/ l: w    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.3 |' F, |' o0 z0 G
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   , B- \0 U! e: q/ z; O$ ?7 _! M
            m_ClientNetConfig.ubClientPackIndex = 0;</P>
    8 A$ U: O- K0 {9 W  z0 M<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);8 p3 C1 _) c- I0 ^+ p2 m& [* C
        ServerConfigPacket packet( m_ClientNetConfig );
    ) c* D; X6 ~8 D. @( P    m_ClientNetConfigLock.Leave();</P>
    5 E1 _8 }/ l& ^& m+ G* z<P>    SendConfigPacketToAll( &amp;packet );7 T, |) Z8 `& o+ u4 i5 ?
    }</P># B  L# y4 e5 v, }4 A
    0 d: Y; N$ b' _% d" [6 R, _
    <P>1 J  t+ K. i6 H9 s' k
    //-----------------------------------------------------------------------------
    ' q7 V* l+ v' L! h// Name:
    1 ]) A! Y& Z8 {4 T% S// Desc: 3 m+ b1 C- ~) ^" C% i+ H5 A
    //-----------------------------------------------------------------------------
    : u3 X6 {/ |/ D( k3 P1 v! Nvoid CMazeServer::SetServerPackSize( DWORD size )& a( j& [8 X* I/ r! O
    {! d& p6 C/ M3 H# Z# @; M
        // Update client config, and build packet containing that data
    / m3 N: F$ E8 b5 C& ^1 [    m_ClientNetConfigLock.Enter();) w8 w4 F' z# Y! f4 w- y. |7 I
        ( f# H( e8 j* d* U' Y( k) I' D5 ~
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.: [, {$ `5 t  A; b3 M
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   . d' Q0 Z3 j8 j* m2 m% Y. E
            m_ClientNetConfig.ubServerPackIndex = 0;</P>
    : w' T0 {# _* L9 n2 z. T8 z<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
    : B  ^, h: a  F$ a% x8 F0 D    ServerConfigPacket packet( m_ClientNetConfig );
    4 x  h/ i& _" @; b' {( G0 w    m_ClientNetConfigLock.Leave();</P>
    1 R& g' @. d, ?1 H+ y<P>    SendConfigPacketToAll( &amp;packet );: W; Q: V1 H2 m) i
    }</P>3 }: b/ i- [6 X
    <P>
    ! x4 I# L7 V6 N4 a+ X) p//-----------------------------------------------------------------------------% A+ m5 p& R: w+ a( O4 e
    // Name:
    ' f, K1 _- N- v" v// Desc:
    . ~0 V5 s* i* ?# [# F& |//-----------------------------------------------------------------------------/ X9 f; e% s/ p' {* t* ^
    void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )9 o+ |: f' p3 \9 [& r* g1 F! _5 V
    {, G6 @+ e; Q, S% ^
        // Update client config, and build packet containing that data) c* W0 x2 u: `4 X4 ^4 K
        m_ClientNetConfigLock.Enter();4 A% ], O& E8 N9 a6 x' z) D' n
        5 E$ ~* M! ?! S/ W# @5 ]
        m_ClientNetConfig.dwThreadWait = dwThreadWait;, \4 a3 C! b/ {- ]3 {
        ServerConfigPacket packet( m_ClientNetConfig );
    ; e1 W! L0 W! p4 P5 l& q' w    m_ClientNetConfigLock.Leave();</P>1 W7 g1 @& z# [/ S5 S
    <P>    SendConfigPacketToAll( &amp;packet );
    : q8 P$ ?, h# E7 m  e9 H}</P></DIV>
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2026-6-12 19:19 , Processed in 0.475801 second(s), 51 queries .

    回顶部