QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4241|回复: 0
打印 上一主题 下一主题

[分享]MazeServer源码示例

[复制链接]
字体大小: 正常 放大
ilikenba 实名认证       

1万

主题

49

听众

2万

积分

  • TA的每日心情
    奋斗
    2024-6-23 05:14
  • 签到天数: 1043 天

    [LV.10]以坛为家III

    社区QQ达人 新人进步奖 优秀斑竹奖 发帖功臣

    群组: 万里江山

    群组: sas讨论小组

    群组: 长盛证券理财有限公司

    群组: C 语言讨论组

    群组: Matlab讨论组

    跳转到指定楼层
    1#
    发表于 2005-1-31 11:52 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    <DIV class=HtmlCode>
    6 }. D5 g: V0 _: h0 I4 X2 o<>// File: mazeserver.cpp5 ]0 R3 G9 @9 S* i
    //
    / s: r4 }$ u% m// Desc: see main.cpp; W& n3 e3 ?1 W- m5 \- \) Y1 F
    //( e* j8 C, h9 |$ T
    // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
    ' {8 f2 l5 d2 m  b3 I5 W0 A//-----------------------------------------------------------------------------
    % G- A) E8 U0 m#define STRICT$ T! R4 ?4 z( O  R
    #define D3D_OVERLOADS& J/ D- S  `- w* Q! x( n
    #include &lt;windows.h&gt;: `3 I! o/ l, G6 t1 i. {$ s* ~6 h
    #include &lt;d3dx.h&gt;% _6 ?* @" o6 m4 G
    #include &lt;stdio.h&gt;/ D1 \4 E6 P/ y# `' F  G/ s
    #include &lt;math.h&gt;
    8 |1 R( \6 C# ]" [( ~#include &lt;mmsystem.h&gt;
    ) Q5 ~( g; w- O0 h4 R#include &lt;dplay8.h&gt;
    / f4 Y2 ]- V% x" f#include &lt;dpaddr.h&gt;  E4 C$ A( j- K) @% J1 v
    #include &lt;dxerr8.h&gt;
    1 b* j3 \# }9 j# W+ S1 g#include "DXUtil.h"5 S( N% X* ]1 v* @9 X
    #include "MazeServer.h". x0 O# N  y6 B# m# Q0 t
    #include "ackets.h"
    ' X  I$ T' b3 H6 s+ H5 |( `$ `0 b% ]6 M#include "Maze.h"
    % d( q+ |' O) t6 h#include &lt;malloc.h&gt;6 f, T+ P, [1 w/ a# e# I4 Y
    #include &lt;tchar.h&gt;</P>; s: S2 I' S& K8 G
    9 A, n2 H4 N8 [% s5 @2 l
    <>//-----------------------------------------------------------------------------4 \& u9 O  h  k+ f5 N
    // Name: 4 @$ i0 t" D3 I
    // Desc: ' O2 Z! t- s0 J3 `1 K0 o
    //-----------------------------------------------------------------------------1 ~. {/ q5 u5 s0 k
    CMazeServer::CMazeServer()' V7 u- |/ O% |9 \: g1 V5 p
    {3 u" t( d  k1 i0 U" g7 ^; C: j
        m_dwPlayerCount         = 0;. i$ {1 Y, Y9 p+ @% Q* t
       
    7 S: V7 C6 c0 I' I2 v    m_wActiveThreadCount   = 0;
    5 i6 t# D" P8 d. [    m_wMaxThreadCount      = 0;
    % n- e" Q0 v8 H    m_fAvgThreadCount      = 0;
    1 K, E2 s; V' }    m_fAvgThreadTime       = 0;
    ! n( J3 Z. s$ Q& Z: E    m_fMaxThreadTime       = 0;</P>* f# G5 i7 ~/ a
    <>    m_dwServerReliableRate  = 15;
    1 \+ \0 S: v; z, |; U  ~# d    m_dwServerTimeout       = 150;) }) x7 a0 W9 ]9 }, Q& s0 ]8 K8 G
        m_dwLogLevel            = 2;% m, r: o0 h! v% A! Q, D; `0 X
        m_pMaze                 = NULL;</P>
    1 A3 R( R; \2 M/ y4 e0 |% _<>    m_ClientNetConfig.ubReliableRate = 15;
      y) a' j. [0 X+ l" }% x; `    m_ClientNetConfig.wUpdateRate    = 150;
    0 [& F( h, ^; ?( T& I7 p" l    m_ClientNetConfig.wTimeout       = 150;</P>+ k5 `( e1 d& d9 J+ `0 E. p
    <>    m_ClientNetConfig.dwThreadWait = 0;</P>
    % E% n! n7 U  Q7 d4 P<>    m_ClientNetConfig.ubClientPackIndex = 0;
    1 R* W* y9 u1 F* y    m_ClientNetConfig.ubServerPackIndex = 0;. N) `, ^' N7 P1 I7 i$ o7 c& l7 `# h
        for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++); T& a' m/ ]; s' M
        {
    . ]# c, t, T/ O  F9 m( @, C        m_ClientNetConfig.wClientPackSizeArray[x] = 0;
    . l7 T9 N- d5 P( u  M        m_ClientNetConfig.wServerPackSizeArray[x] = 0;* R! }. W( }+ d6 O
        }+ @% B: o' Q; p" H
    }</P>
    / B2 m: F6 n) l# W
    1 F! X* x  b$ w% J1 B<>$ Z/ B  j0 h% e1 A
    //-----------------------------------------------------------------------------. s  |+ z) Z& M: k5 R7 A
    // Name:
      j2 Y  N. n8 }4 i* X4 W; J+ ?, v; Q7 S// Desc:
    * u! `( f/ i& }//-----------------------------------------------------------------------------% {- F0 v& _/ J# |( P
    HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze ): C4 C" l* T" v" h% o# {) ?
    {7 K: l& ?; L8 b4 \( F
        m_bLocalLoopback = bLocalLoopback;% W/ x0 |$ }) t  B8 z4 A, H; S9 O
        m_pMaze = pMaze;' Z+ C/ L' Q& t% m
        if( m_pMaze == NULL )# n& P& o% L' e1 \6 A8 o5 B  q
            return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>6 p* i5 x& R" V# _7 H1 `8 N) m
    <>    // Grab height and width of maze
    2 {3 T7 ]3 l2 G. E  [6 f5 d    m_dwWidth = m_pMaze-&gt;GetWidth();
    - @0 S+ |& A" q    m_dwHeight = m_pMaze-&gt;GetHeight();</P>& h4 {8 m9 L0 q' W9 E
    <>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;5 @+ P! i9 p2 j: r0 d
        m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
    4 q& k+ C, ]' N; B6 v<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.
    & Z4 p6 Y# W( O( k' D- }) z    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    % G( u3 U. h, R5 r. y$ }        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    . x) N6 F  L$ M    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )
    7 D8 C+ i0 P! e' P; y+ x4 \4 f        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
    $ V' y- I* X# M3 b: Q( F% R, \<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;8 [% P* k# g" {" e
        m_dwMazeXShift = 0;
    - D( o. H# p6 l+ I    while ( (scale &gt;&gt;= 1) )* J1 |7 Q8 o, K$ l6 b& [, ~, r* k
            m_dwMazeXShift++;</P>; K( Z& g/ |# D) h8 h
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;
    2 o7 P7 i2 r& |& D4 z- b    m_dwMazeYShift = 0;% L" f9 b# {) L: B) K& f
        while ( (scale &gt;&gt;= 1) )" ]. I, L3 O8 h" S. f: c
            m_dwMazeYShift++;</P>
    7 u4 E5 T  a1 G4 }<>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||( U" @7 r  t, ]# D+ I
            ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )! x- ^9 C$ _3 ?7 X" ^4 E" N
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>- t% H, w0 y3 g, ?. Q* S
    <>    // Initialise the player list4 n9 v8 U9 y, l' {3 x1 I
        ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );( {) n9 b4 I+ W4 P/ |! l( b4 J
        m_pFirstActivePlayerData = NULL;
    8 n5 J, c$ m! k7 }3 X    m_pFirstFreePlayerData = m_PlayerDatas;
    - S& V' w. e; p# q! H( I* k    for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )
    4 z  L( l+ B" ^7 c, j$ o    {
    ' R; c! y2 A) ]  U. f3 b        m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];8 b1 M+ X4 d1 p! L$ F7 u1 N5 C
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];4 P) V# K( [9 o. b
        }</P>" Q' |0 a; E! ]! A' o" B  j# w( B
    <>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
    3 V( v7 F& w7 ~) E) m6 X& B) x    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];
    * x7 E* f/ a- T, O/ @    m_dwActivePlayerDataCount = 0;; b% K. u! s- j- d7 c! Q
        m_dwPlayerDataUniqueValue = 0;</P>
    1 G+ p5 i. B( }) {5 H8 ~<>    // Initialise the cells& D6 z* R3 i$ u9 j3 y% T
        ZeroMemory( m_Cells, sizeof(m_Cells) );
    ' f1 F2 r5 k: }9 F8 ^    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>
    0 F, C$ q! `! Q8 T" P3 T4 x  a<>    return S_OK;8 y; ^0 D$ W1 p9 Z3 N. N% g' O
    }</P>
    ; m+ J) ?2 L! q5 Q0 I2 X5 i- t) @1 j' M! j+ }, \" k
    <># ^/ C  M4 B9 n! S2 L/ M- \1 N% j
    //-----------------------------------------------------------------------------# p" W. P9 k: n2 v
    // Name:
    . S: b! u3 p; E# ?// Desc:
    9 i9 n; ~1 G( W9 X1 O; H//-----------------------------------------------------------------------------% p2 e' m8 }& `" J2 J
    void CMazeServer::Shutdown()2 w8 N; U# e7 p
    {
    ( {4 `0 W1 \# c2 J9 M, e/ N}</P>. j, }* ~. K" t2 s) Y4 T! J1 s& @2 M

    0 T- [. H: W2 P6 |7 P<>
    * C! X3 s( S0 M4 M//-----------------------------------------------------------------------------& ?* x/ D' W/ h- E) O# o
    // Name:
    * N- p# G/ y, v! J( M0 R1 t// Desc: ! ^4 I0 P) Y; q9 l* F- @5 u$ j
    //-----------------------------------------------------------------------------
    , d" ^+ w( K6 m' k7 U) N3 Z- w# tvoid CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    6 H9 L3 G7 M1 A. E8 \/ b{  F4 f' g& L2 t$ G' X  w. F
        m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    ! n& h3 y8 c1 ]6 D                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );7 K4 a; i0 A  R* `
    }</P>+ i  o& J2 M# {5 B
    ' n) m& L* L$ s, Z1 l
    <>
    9 F* H) `/ o& }//-----------------------------------------------------------------------------* k& ^- \8 L" Y! d8 N  ?
    // Name: 0 z% c8 ?7 A( A1 K
    // Desc: ( f6 Y! x0 Q! m3 _* u& `
    //-----------------------------------------------------------------------------1 s% V& d5 E: E
    void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    ( s. Q7 n! S, t# u2 F5 e" c" ^{
    4 o9 {( V$ J% f/ c: e) t    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,5 N! S0 b; Q8 Z8 U& N' A
                                x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );/ x* H; c& G' T
    }</P>' I$ F4 S8 P  Q( |8 F3 p! T
    ; i- x" }2 D  P7 l
    <>
    2 _/ D& j$ `, t4 n8 \! L//-----------------------------------------------------------------------------
    % j6 g) R6 s! t' d: }// Name:
    / l+ `# }+ Y. [4 J1 H. U' O// Desc: , Y( w& ?8 w( A# G6 [7 E
    //-----------------------------------------------------------------------------. a! p7 V+ O/ i/ U) S4 P) R
    void CMazeServer:ockCell( DWORD x, DWORD y )0 A. @+ S% e( r# s% B0 X
    {
    9 ^. t" X4 l: _; I( |- r! @9 @    if( x == 0xffff )5 ?  e' K% I, Z  r) I. `, k
            m_OffMapLock.Enter();) m- T0 @7 E" I2 x- h& e
        else- h2 E) L0 }: a" l
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    % R$ D; [6 f# `7 G4 B5 Y, o3 s: W}</P>
    6 `" J! Q# X2 t# `/ r; `" A  e: P/ I2 v: J( `# T% K
    <>( H* z% w7 i4 V( O. z
    //-----------------------------------------------------------------------------0 _) n2 _5 X  B. Z2 V8 l) C8 e" Y
    // Name:
    0 H: {. o0 _& G0 k% p% B' |// Desc: % _" T5 M- Y' q; H* p" u
    //-----------------------------------------------------------------------------8 d; w) h9 |3 I/ u$ S2 n- k
    void CMazeServer::UnlockCell( DWORD x, DWORD y )0 O/ F' x. n" H, W% p) A: Q
    {
    + X0 \5 q- J' Q1 i. j3 M    if( x == 0xffff )# k: C# P+ D8 ~1 K9 B
            m_OffMapLock.Leave();- k9 z% R- }. G% f- {2 e* X. T8 W
        else5 @* S. O  g; g8 `- M
            m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);# N0 J8 t* z9 J4 I5 D
    }</P>
    7 e1 Y! [) {  s1 X! H
    . W1 `6 \  q2 V, `<>3 U0 a$ j1 m5 w8 c$ {
    //-----------------------------------------------------------------------------
      N5 b& Q3 ]  I// Name:
    ) I4 c: Y3 O' i( i7 R// Desc: % u5 W/ Z0 b& C2 p
    //-----------------------------------------------------------------------------
    , P, m# t3 k/ j" m% evoid CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 ), y- h  u( z# [& q: Y2 h/ l
    {
    # k* q& ^/ l! v) I- n' p    if( x1 == x2 &amp;&amp; y1 == y2 ). X2 H3 n7 c; K, I$ Z
        {: _# H% g- ^# R3 [+ S! G* x  \- s8 ]
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    8 x% m  l& @: N& v' \2 e1 @/ M            LockCell( x1, y1 );' ?4 c. D! n; [! v& y6 P
            else# n( c3 g  b7 _. t$ l
                m_OffMapLock.Enter();</P>1 }4 u1 x; N$ a, _" n6 F+ q
    <>        return;
    8 l- S5 n5 @* r9 S    }</P>
    ! a! ]3 F; M+ ~6 M4 x; L<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;& P4 j% n+ ?- X6 z( [) z5 |4 d
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;* o/ Y7 r$ z) \3 J& M) A' c/ z5 z
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    7 S5 W# v! I" L+ L2 s/ O    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    : Z5 ^9 l; N( [) D8 V1 U3 H/ a) u<>    if( x1 == 0xffff )
    ! N0 |( K1 O5 s8 v; q9 B- _% X2 a0 G. ]    {
    5 Q1 p; y' E7 Y9 Q: m        m_OffMapLock.Enter();) G; K- a" Y! A/ D( K  b
            m_LockGrid.LockCell(x2shift,y2shift);6 j+ @+ U# i3 ?( w! O
        }9 c) ~( M0 d: \, i. ?
        else if( x2 == 0xffff )
    ) h0 h7 C6 N" F$ n) g" e    {9 N) d! ~4 O0 g
            m_OffMapLock.Enter();1 a# R; R* _% ?  |, t- W
            m_LockGrid.LockCell(x1shift,y1shift);% e% i( J5 t1 O! Y+ L" E. v
        }
    ' O  {  ]5 ?8 s) L. b    else
    0 {) q, e) W% J$ a2 W    {; A3 v5 L4 d' u- @  E* a4 P
            m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);; M3 T% U+ p: ~& M! q. k& S
        }
    0 K' P) @. p: \) F' G}</P>( z7 z! [8 C7 o( w+ g) I

    : N5 K( w2 z( H) t<>
    / H' W9 K3 }. h8 u//-----------------------------------------------------------------------------
    ' q* J+ v8 _7 V! [! |2 Y! U// Name: 9 g/ O3 U0 V2 |( v# d7 C& p
    // Desc: 5 ]) E/ F' ~) `" t$ n7 `4 v3 k% c  V1 o
    //-----------------------------------------------------------------------------) o1 v6 M# k: E/ W+ ~. s. d
    void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )# E" p' V5 K: {5 K; |
    {+ w5 X" d3 w0 {2 Y4 t$ T9 N" x2 ?
        if( x1 == x2 &amp;&amp; y1 == y2 )
    / [  X$ x- ?4 \2 a; A2 a. m    {
    % b2 _1 ], G  g( O2 Y: r$ K4 D        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )9 g+ a' l: \' _* d' j
                UnlockCell( x1, y1 );% f* x' m7 b& d+ z. O2 h1 ^# F
            else/ B* q8 s3 o/ e/ Z( f3 A! P$ {2 }
                m_OffMapLock.Leave();</P>
    " z1 z# O+ z9 J' h7 K" f. j! C<>        return;* S. ?0 V) H5 Z% ^1 |. d& N3 {
        }</P>/ s, A0 @1 M2 V0 W: I
    <P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;' H- `1 q: q2 N: s/ D) ?% s! e0 _
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    6 O! [4 f. C1 Z: F    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    7 Z" K$ a2 J5 J$ m    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    / R! x8 H4 z! I<P>    if( x1 == 0xffff )
    ' ~+ @6 b/ H( T0 y. V$ ]" U    {
    5 ?% R8 I1 H/ i        m_LockGrid.UnlockCell(x2shift,y2shift);
    ' g& y6 o. `- Z- P( {- b        m_OffMapLock.Leave();
    ' K2 o* O4 D& J: x. y    }. Z& h3 @7 n, V; v
        else if( x2 == 0xffff )
    " _0 Q+ |7 W# U5 e! G- Q: a. \    {: I8 L: g- p# \% w# D7 U" S
            m_LockGrid.UnlockCell(x1shift,y1shift);5 q0 C# D- K5 r1 b( K4 Y1 n
            m_OffMapLock.Leave();; H% W! o, _6 d+ p3 q" n: r! ~
        }5 [- b! t8 F8 g" u% H
        else
    2 i0 M* W! ~+ L' P+ y# b& n1 ]    {
    0 ?' t' p4 ^) e7 o6 Y% @) U  P        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);: Z) J* o4 A0 L7 @# t, w' G& ?
        }
    8 N& Y* K+ y/ }3 B% ^% `! i}</P>
    1 {5 l* |5 M) H- `
    6 C3 W3 j: T2 I5 w+ I; G7 d, \<P>
    % A8 @; Z3 L' v+ R7 U//-----------------------------------------------------------------------------( x1 @& ~1 I0 G
    // Name: ) X9 W9 W* K9 w2 h' z
    // Desc: ) b$ y$ P+ j( Z! g. d$ W/ \8 y
    //-----------------------------------------------------------------------------
    & N2 Y/ ?5 J; I$ ^7 Bvoid CMazeServer::OnAddConnection( DWORD id )8 Z1 P! j$ I! E" F2 C
    {4 G2 Q! J. ~: e( a4 K$ w
        m_AddRemoveLock.Enter();</P>+ V, c1 K+ H9 Y% F
    <P>    // Increment our count of players0 \5 b. [  ]6 V) Q) W6 ^8 R
        m_dwPlayerCount++;6 c- f' [% ]9 i9 w0 v8 q
        if( m_dwLogLevel &gt; 0 )+ F" ?# t9 G% I% x. I
        {
    5 ^4 r& R" S8 L! N/ q2 ]        ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );/ T8 V1 d$ k* b1 c
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    7 T7 K0 g1 h* |; H$ e: X    }</P>8 J9 @1 L$ o( r% S6 E
    <P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    % v* m5 t+ S# a- x' {        m_dwPeakPlayerCount = m_dwPlayerCount;</P>! v/ j6 a. a2 J% q
    <P>    // Create a player for this client+ G8 a; W: _! N+ ]" g* J
        PlayerData* pPlayerData = CreatePlayerData();
    4 u) [) S' c' B    if( pPlayerData == NULL )' b9 p* S3 k/ Z1 \% D
        {4 U$ T* M5 j1 v" N+ q- g" ~2 z
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
    ( r: m. t. v$ K. x# m  P7 a9 T        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );6 u6 k$ }2 X2 F/ M6 i. n  m7 v
            m_AddRemoveLock.Leave();
    8 A* W3 t+ w( S1 ^        return;+ A0 R. `, v6 M; w( |
        }</P>% m3 v6 ?) g1 U
    <P>    // Store that pointer as local player data# U1 p* F# H$ m' L; j  t& G
        SetPlayerDataForID( id, pPlayerData );</P>
    2 \5 a& C! E0 w0 e1 z  U& i<P>    // Grab net config into to send to client
    9 u' _) _# F+ v$ B9 ^6 Z/ ?    m_ClientNetConfigLock.Enter();
    ( M" |# r& k3 |    ServerConfigPacket packet( m_ClientNetConfig );
    4 l% v5 [- L& s+ V5 @3 F0 H: t2 b* c2 U; h    m_ClientNetConfigLock.Leave();</P>
    4 m3 [( T+ u- u* b<P>    // Send it
      n* Q; A- ?1 U2 g7 V    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>0 _! ~2 h4 }+ g2 F4 r
    <P>    m_AddRemoveLock.Leave();& S0 F, \0 Z% {  @% R. m
    }</P>! h4 x: ?* |% F7 A- f
    . r4 u/ P; k$ j0 e" Y
    <P>
    ) s! r9 Q5 p# V9 V9 d0 g3 t1 G//-----------------------------------------------------------------------------3 V% V. X- q! Q" Y$ f
    // Name: 5 v* \. m: f2 o  Z
    // Desc:
    0 K* p$ B8 ^* O5 i6 D//-----------------------------------------------------------------------------* w* @+ f$ C' s! _+ E: g8 l
    void CMazeServer::OnRemoveConnection( DWORD id )
    0 e0 A! y7 l0 o- V; p{2 u' \2 N# F3 @- {# S# F. G* V4 v
        m_AddRemoveLock.Enter();</P>9 y( R5 Y  m; h( Q+ G
    <P>    // Decrement count of players/ \, C% H$ P, q+ w7 j; l% S
        m_dwPlayerCount--;</P>/ X% m$ G  I  s, r7 ?
    <P>    if( m_dwLogLevel &gt; 0 )
    4 |1 {) p" f' s0 R. @    {
    / Y: Y# O% |' c        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
    * F: c* l7 Q5 g- m, \4 b        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );9 _7 H0 O' q' _3 N
        }</P>
    : m& }$ b& V/ }0 l6 N- o<P>    // Find playerdata for this client
    7 x& F+ v6 X  z+ O+ u    PlayerData* pPlayerData = GetPlayerDataForID( id );
    - M6 L" H7 N7 b) _; k    if( pPlayerData != NULL )
    : a7 k7 ]' ^: ]9 I    {
    6 O* D- M$ I) u( X/ Y5 V        // Destroy it
    * t! J: a9 E9 O        RemovePlayerDataID( pPlayerData );
    : P: ^6 J7 a, L, ~) I( P        DestroyPlayerData( pPlayerData );. Q8 B/ {" X; C9 a7 `! |
        }</P>: i! W$ z4 f3 J1 r  x
    <P>    m_AddRemoveLock.Leave();+ S/ D" x9 s) R; ~# f
    }</P>7 \  E0 K. v! e

    5 ?: b3 o8 k0 X! Y1 Q3 N<P>' h% L9 }' H, a' P
    //-----------------------------------------------------------------------------
    9 E: S! c0 p( R& M// Name: ' K3 B. ^$ x, R: z- N: l9 I
    // Desc:
    5 o% ~" }, |, R' z& r//-----------------------------------------------------------------------------$ g3 z* L- h$ K% s  p3 f$ S
    HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )
    4 f9 s4 i6 }( D. g& a  N{
    $ x* D$ ?  E- @1 _% r: ]    BOOL fFoundSize = FALSE;</P>
    ! G% ~! Q! t) T* B<P>    // Increment the number of thread we have in this process.
    ; T& j" O' M+ S: Z0 c    m_csThreadCountLock.Enter();</P>
    ' J& i8 s# M- K<P>    //Get the start time of when we entered the message handler., }  T. E& s, {
        FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
    # V2 _) m/ Y. p' ~% P<P>    m_wActiveThreadCount++;
    . e; Q) f1 C$ {4 u    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)! U: p, U+ c* y
            m_wMaxThreadCount = m_wActiveThreadCount;! Y+ {. B6 b, Z4 G, c3 E
        ) r( f' V( o0 u- |' J
        // Calculate and average.
    * S2 s$ Y1 e( a. m9 r' f    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
    1 |) s* O1 G2 W    m_fAvgThreadCount += fdiff/32;
    ' v4 E( w8 n& k# ~" V    0 ]+ [- F( w% v0 ?3 i
        m_csThreadCountLock.Leave();</P>4 Y3 [7 H. j% n* Z0 X% r
    <P>
    9 }9 U& Q: O* F: W+ u    ClientPacket* pClientPack = (ClientPacket*)pData;+ c6 o3 G6 [9 Q) {. q# J
        switch( pClientPack-&gt;wType )2 f5 K! M3 r5 s5 l1 [
        {
    1 n; H  E0 Y9 V( ^1 {- l# G) i        case PACKETTYPE_CLIENT_POS:
    % b) ^) E+ m4 a# H% P0 |            / h- J2 |+ {6 S+ u# s/ T
                // Check to see if the packet has a valid size. Including
    ( L+ ^, a8 f5 j            // the custom pack size.$ z' B9 i( p7 v! t$ y- s
                if( size &lt; sizeof(ClientPosPacket))! K& s% F/ _: U
                    fFoundSize = FALSE;2 w( [% W. ~" `
                else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))
    2 H' H9 D8 f: y3 r) I/ p                fFoundSize = FALSE;4 ~& U' b  p5 ]+ q
                else
    8 h' P- F* g+ `6 o! F                fFoundSize = TRUE;</P>
    0 S' j5 w( @) V! O, t<P>            // If valid sized packet, handle the position.
    # y) b$ N2 f  b            if(fFoundSize). Q; h$ J! `* D* X
                    HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );
    , W1 U3 h; c) V8 _4 `, q2 b            else, w0 P2 l' C- F/ ~* ?: a
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>. w8 m/ b7 [$ Q8 q* a$ H
    <P>            break;</P>
    / t6 Q- i, w; h3 _: ?/ m" K<P>        case PACKETTYPE_CLIENT_VERSION:- }; g) J% ?. F+ |# r
                if( size == sizeof(ClientVersionPacket) )
    * ^2 r; l1 s, g' @( H% w                HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );3 m$ Q1 A! D8 X* j
                else- k' d" A, Q4 b8 C2 A: ~, E& a
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );0 d) _6 N& T, n' T( y/ ^  L
                break;</P># [, L9 p# L8 y  S
    <P>        case PACKETTYPE_SERVER_CONFIG:</P>
    7 f  K  k' A3 N) d) H<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>
    # ~, S* h4 O2 K. t<P>            break;. J8 [; d% F# p. q3 F5 O/ e
            default:6 v/ n! ?: c- s, ~, Q7 k! H+ c7 |$ Y
                HandleUnknownPacket( dwFrom, pClientPack, size );: ~: t7 C3 g3 e. d1 F) t8 u% ~4 y
                break;
    6 M% F* x4 n5 |) e' G    }</P>
    / E+ v/ _* k: Z' o* `5 J! i<P>    //If the user wants to hold the thread, Sleep for given amount of time.6 }' Z( s; x2 |) K7 x  b
        if ( m_dwServerThreadWait &gt; 0 )9 D6 \6 U! Z0 u- ~
        {
    1 u: @& R+ D7 Q        Sleep( m_dwServerThreadWait );* d- [0 F" r0 p; E/ V
        }
    , a2 E# m7 j: X3 Q8 T  @( x" ^, W3 D    - P  W; T! q0 b
        // Retrieve thread data for this process.8 c, X7 B0 g/ y# G5 f% P
        m_csThreadCountLock.Enter();</P>3 h1 t2 c7 p5 F3 [6 S
    <P>    m_wActiveThreadCount--;</P>
    + E7 q4 L2 O( z( O# s<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;5 [3 q2 n: k+ H6 k. D3 D
        m_fAvgThreadTime += fDiffTime/32;</P>
    ' Y+ l0 P6 M) [4 |2 q+ e* b7 `: C<P>    //Get the Max time in the thread.6 H) ?( V# s" O. l# k
        if ( fDiffTime &gt; m_fMaxThreadTime )
    $ t- l$ w# N5 Y* l8 [    {
    . i% N" y+ F/ u! c        m_fMaxThreadTime = fDiffTime;" F% ~7 O5 w5 t! h3 j2 V
        }</P>' E: }. ^- m* C; ]
    <P>    m_csThreadCountLock.Leave();</P># C5 P/ h* @/ t# o
    <P>    return S_OK;0 |5 i) w( T9 y8 V5 R: S* G
    }</P>3 q% b, e% X4 @: A

    - |0 G) K9 T# L) w" R! B5 ]0 ~<P>//-----------------------------------------------------------------------------8 H" D2 ^6 f  {) M
    // Name:
    ' @8 b; T7 P- j8 d+ }! P+ P// Desc: + j; B2 w' F) U) j
    //-----------------------------------------------------------------------------
    & j9 \5 L8 s1 g7 h3 FBOOL CMazeServer::IsValidPackSize( DWORD dwSize )
    , |! |; \" h+ ]' P{
    ; M4 T3 o+ q' Q& |; l. m    BOOL fFoundSize = FALSE;
    * o: Z) {" M' _+ k  k    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;
    ) ^/ o( ~$ G, T7 I    9 M0 V0 u' L& G1 Q0 K3 G( j, x
        // Check through the array of valid pack sizes.6 y* d# p% y. I0 j+ h' X- D1 ]
        if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    & [+ z, z7 p5 f+ V$ G$ A    {
    , n7 Y' v, A) ~        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)8 x% E7 x7 ~) o9 D
            {
    , o1 d# U7 y8 ]- n, K/ }            if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])- Z% D5 P9 i/ n& O
                {
    6 ]/ V1 K4 O4 D/ B: l) Z5 T                // Found valid size in the array.
    , \) v. T  {) K$ y                fFoundSize = TRUE;
    8 B  I5 R  e1 Z% _: H& L7 y. d                break;
    * N! U0 H" Q, Z! x  ^            }# `6 Z9 J; ?) F2 @3 D( h
                if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
    ' R6 p9 V3 y9 R+ o! h        }, `9 r# d, F& j3 Z% Q/ u3 |0 O9 A- E
        }& a; E, O% T) M! u
        else: t  K* |6 N7 P$ Q
        {
    " ^9 e1 h0 I- v, J8 U! W& O# P        fFoundSize = TRUE;5 _  D0 {$ Q4 X2 U5 A2 r5 y
        }</P>! A/ c! b& O" l
    <P>    return fFoundSize;
    1 `: y$ u4 U/ P: i% b}</P>
    ' M7 |6 L) O1 d" e5 y- A' U<P>2 W% k% ]; q+ ]: U4 f
    //-----------------------------------------------------------------------------0 o9 L2 }0 g! c! E3 j; a
    // Name:
    ) j5 @& r0 l' n// Desc:
    ' O/ ^' |% L! F$ z4 {//-----------------------------------------------------------------------------
    / c' E" l1 _1 g: Y. F5 X  Jvoid CMazeServer::OnSessionLost( DWORD dwReason )
    . Q; o  P3 d+ h0 W6 c{! W( w) R  ~" @! i: g6 k" i
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
    , V9 {: n# j+ f; m6 d: j3 v! s}</P>4 w  a- M4 V8 e0 I- N
    ( W% }8 t4 g' V& D. C) g- |
    <P>
    : u# ]7 [) H) d3 u7 ^//-----------------------------------------------------------------------------. t3 Z  \! I# V2 @- W3 n, X
    // Name:
    5 j; j6 T9 l3 R- `// Desc:
    ! H8 w2 C- k7 X- `7 t1 W//-----------------------------------------------------------------------------4 v8 c" `* r* P! L1 K
    PlayerData* CMazeServer::CreatePlayerData()
    ) v6 v3 q7 C9 `; V0 A$ Q{
    ( a* E/ n0 j5 a0 M9 T6 G( h% f8 e    m_PlayerDataListLock.Enter();</P>
    4 L; r7 d% \4 S6 N- l! o3 _<P>    // Grab first free player in the list0 P1 \& F! o/ p2 V: F0 j
        PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>1 M. E$ E8 h5 |; f8 s
    <P>    if( pPlayerData )
    & ?6 R3 ?" ~3 k( ]" N    {" N  v- {4 C; Z# \& S/ Q
            LockPlayerData( pPlayerData );</P>
    0 b* ~5 L+ H0 m+ ^/ `3 x0 ^+ I<P>        // Got one, so remove it from the free list' g" a& G7 \4 W6 E# o
            if( pPlayerData-&gt;pPrevious )
    6 Y/ ^2 o; y0 v8 j* u            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    2 ~$ x: V2 `' z) s3 I3 d        if( pPlayerData-&gt;pNext )
    4 }2 B. ~1 z1 T  k9 s6 Y            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
    : |6 Q: n* D* X" Z3 {2 X        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>& ~; G9 @6 f9 d5 K
    <P>        // Add it to the active list* R: V) g' r! G4 c% c( J
            if( m_pFirstActivePlayerData )8 }6 @$ B# {  f8 _3 Q4 ?
                m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;1 m( b' K6 f9 r, i& s: ^7 `
            pPlayerData-&gt;pNext = m_pFirstActivePlayerData;- y( }! w6 G# j& x6 z
            pPlayerData-&gt;pPrevious = NULL;! _2 x* T( P  c* g7 K/ p
            m_pFirstActivePlayerData = pPlayerData;</P>
    6 F4 L9 @. E- ~1 W0 r/ C# w<P>        // Update count of players
      b7 H$ }/ K% w" s# v8 R        m_dwActivePlayerDataCount++;</P>  M. K6 |2 d( {2 u2 I8 A
    <P>        // Generate the ID for this player2 n/ [. _5 X+ R: i- {, ~
            m_dwPlayerDataUniqueValue++;
    + S1 l! O0 j. c" v; k        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>3 v! s" F- j5 v# D& [- l
    <P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
    6 ~$ z, h+ F- ]3 Y        pPlayerData-&gt;NetID = 0;
    ; j1 H0 T6 M' }0 m        pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>6 T2 p3 G& A, G$ r9 h
    <P>        // Insert into the "off-map" cell5 f; h# B, D7 i$ m. L; |& f& [
            pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;
    8 e6 o# N  C0 u        pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;
    6 M$ O- `* w0 R) s/ \+ \* x0 t        m_OffMapLock.Enter();6 M( R7 l$ B' P. W0 o. \( }4 y
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;
    - |  u7 U. h- K% f4 d* q# h        m_OffMapCell.pFirstPlayerData = pPlayerData;
    % X) ]  R/ J) ~0 M: L9 ~6 g6 Q        m_OffMapLock.Leave();</P>; z6 d8 s$ W: d9 g. h( H
    <P>        // Mark as active
    ! t' l& |" T9 v: S        pPlayerData-&gt;bActive = TRUE;</P>. H7 E5 X5 F4 w  K4 {
    <P>        UnlockPlayerData( pPlayerData );
    6 s& r$ V( ?. w$ q% |" s: x) K5 n    }</P>) p" u, g$ a8 X9 o$ H* p/ |# y
    <P>    m_PlayerDataListLock.Leave();</P>: v- R8 Q8 r* j4 e1 j4 K
    <P>    return pPlayerData;
    * _' m1 [+ N1 k" |. |( |}</P>
    5 o2 S3 l& N2 F2 ^. `1 \. b+ z! @
    <P>  U; a' d4 B3 J0 j' d
    //-----------------------------------------------------------------------------& U7 Z- C7 x7 K, Y0 Y- o: N4 w
    // Name:
    # C/ s7 f) K& ~// Desc:
      l) e) u8 E2 Q5 b9 V; t4 A: s//-----------------------------------------------------------------------------
    ' l$ |4 E! I$ Z0 }. w4 B' Rvoid CMazeServer:estroyPlayerData( PlayerData* pPlayerData )
    1 k+ h, ^/ S& I. @% q6 ]0 |{
    ( v8 p, f: B+ ?0 Y- ~, x2 z    m_PlayerDataListLock.Enter();
    4 G8 Q4 D$ I1 C- K$ A, R) s    LockPlayerData( pPlayerData );</P>
    ( v# ~1 k. F; v1 \2 _( l* c<P>    // Remove the player from its cell
    . l+ h; K; ?( r  G& o    RemovePlayerDataFromCell( pPlayerData );</P># y; m1 |+ y3 A. z8 M: y( j* f
    <P>    // Mark as inactive
    1 Y$ ?2 Y) N1 }9 I1 d    pPlayerData-&gt;bActive = FALSE;</P>
    $ |6 T2 P6 Y" q, r% X2 f9 _! J3 {. P<P>    // Remove player from active list
    ' H1 {4 A# f' o8 P1 S4 {    if( pPlayerData-&gt;pPrevious ). D2 ^! n+ O& }  p( I8 T" G" U3 d
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;: H. {$ O; n5 F  h& j
        if( pPlayerData-&gt;pNext )
    4 q/ M7 B4 A+ j' s, i8 S& E! D        pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P># t* z6 M4 B9 z# H! \3 l9 I
    <P>    if( m_pFirstActivePlayerData == pPlayerData )
    $ i) t, y/ [; s$ C2 f  v  o        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>
    ; m) {; `8 w1 z  X+ B3 ~( u<P>    // Add it to the free list& y9 F8 X4 K8 L. ~" }0 c6 l
        if( m_pFirstFreePlayerData )
    : A  q( ~6 A0 O. ?# x1 |3 y  H! }        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;0 r7 R+ d( E: ]$ N
        pPlayerData-&gt;pNext = m_pFirstFreePlayerData;* e. t' Z1 P1 z/ W& d8 T/ A
        pPlayerData-&gt;pPrevious = NULL;
    4 L4 v, G+ M9 P6 B3 F    m_pFirstFreePlayerData = pPlayerData;</P>
    / E0 C' o+ A' h<P>    // Update count of players
    5 d) q+ ]8 E5 D" K: J# y* v    m_dwActivePlayerDataCount--;</P>
    ; s. a' n2 L$ P: }  I/ C<P>    UnlockPlayerData( pPlayerData );$ R# t$ s" Z$ V. `9 v; o5 B
        m_PlayerDataListLock.Leave();/ g) Q9 K' v/ x# k$ @8 V
    }</P>
    ; n( J1 p" T( f3 H: e: j& Y9 p$ i) _  R. y3 x6 g
    <P>3 i! V+ F& u1 {6 k6 p( t4 l
    //-----------------------------------------------------------------------------, p6 R7 ]7 l, N0 M; [, @
    // Name:
    # j/ ]+ P; j& w# s" F/ |  G// Desc: 9 e: _, C! A9 e1 v: C
    //-----------------------------------------------------------------------------: D, m: n& v' y
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )
      c; I, e- h1 R4 l( o5 p5 ~4 [{7 e8 G, J5 h8 h* J6 |
        // Lock the player/ p3 c) Z1 z1 o( r
        LockPlayerData( pPlayerData );</P>
    . K+ J1 G. w# k7 F<P>    // Lock the cell the player is in+ C* q' j0 p, E
        ServerCell* pCell;
    " O( L+ m! x* ~8 n4 p+ W    if( pPlayerData-&gt;wCellX == 0xffff )0 r. e2 V+ U3 b
        {" x" O$ T( s- y6 ^
            m_OffMapLock.Enter();, v3 A9 t& n# ~/ p4 f
            pCell = &amp;m_OffMapCell;
    $ V6 A5 |/ N4 R) I' C    }
    " F% ~; J9 h+ A7 U- l, \# @    else
    6 y0 ~( X4 b* i- Y; ?) r    {
    7 U/ j. }* j" F        LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );
    1 V) |9 G2 z, n7 W: G5 F        pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
    1 B% ^  D& m: V; E$ c    }</P>: M+ t: o9 q% X5 Q6 ~, N6 A
    <P>    // Remove it from the cell7 t. \# p( C! y3 ^
        PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    3 s& T. H, E  A8 r    PlayerData* pPrev = NULL;3 M* s4 g% Z1 S
        while ( pPt )  \" z, V3 G2 F6 u) H2 i4 O  K
        {
    ) S" d& A; d7 V        if( pPt == pPlayerData )! m+ j8 G- i3 n' d8 H
            {
    " r3 a4 n4 p5 L, \- b- x0 C: U            if( pPrev )" a" z5 W2 Y' T# A& ]6 O
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    1 L' g5 c, P" u6 e( M            else
    - E3 v+ w6 b$ D0 [8 j8 f& x                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
    ' `/ J/ l) H6 k& W6 q; E7 Y2 W<P>            pPlayerData-&gt;pNextInCell = NULL;- k( _3 [, y" O7 P/ w1 L
                break;
    " a3 D% R- V3 Z: u8 F        }7 Q" S" {7 O, p$ H3 @( ]
            pPrev = pPt;$ n* w! P) p/ \# C# }' |
            pPt = pPt-&gt;pNextInCell;  P7 z" z' Q" l5 p8 t
        }</P>1 ?  [8 z1 o0 _% V. [
    <P>    // Unlock the cell
    3 E0 b1 ]. u; [/ N8 g* W    if( pPlayerData-&gt;wCellX == 0xffff )! {3 q$ D' e6 w3 n& r( g! y
            m_OffMapLock.Leave();: s# U+ z4 A$ E# k& `/ `* d
        else3 C4 _- l1 u  r9 V/ c- e
            UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>  j" D. I* m( U# w: ]
    <P>    // Unlock the player  T9 B4 \2 e, H2 W
        UnlockPlayerData( pPlayerData );
    ( Y. b' Z% I2 ], ~$ c# o$ H7 L}</P>5 `% v' w9 i# ~+ d' v% Y; p  `
    ' }6 x" y7 a2 U) k
    <P>
    3 x2 a' B2 ^' c; m6 Q5 y9 W- f//-----------------------------------------------------------------------------
    9 p! N& b9 f" s- r8 Y" T// Name:
    % e: h8 N8 u" u* H, E. Z" O! j// Desc: 5 U/ a, s3 V3 M4 y, S9 {
    //-----------------------------------------------------------------------------
    ! f" W/ Q* S) X6 \; K! wvoid CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
    # }: D) m8 c, q) @  O0 b( S{
    8 m$ X% N/ I0 O3 v, l# d  J    ServerCell* pCell = GetCell( pPlayerData );
    + F, D7 k5 P8 M% ^    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
    7 S3 a  D1 ?; J    PlayerData* pPrev = NULL;9 A2 q& m0 m7 Y* G
        while ( pPt )
    2 x0 ?: t, P3 }    {
    3 h$ Q& e9 A3 l9 A# [/ @8 r        if( pPt == pPlayerData ); h1 g+ w( }1 Q1 T
            {5 x5 H* r/ d. O: u( Y
                if( pPrev )
    - ]* j4 Q- V8 U$ |4 j& A+ d3 f2 `. i                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;+ B& H! s1 P3 ]# X1 B# Y
                else2 {: O# f0 e$ p0 K0 i, L( Z
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;
    % n- s  B8 [4 f" Z6 l, }  C            pPlayerData-&gt;pNextInCell = NULL;) [+ A9 n2 A* R: ?
                break;% `& T- x* S; q
            }8 R; E7 x5 m& M  Y" f  o3 I3 n
            pPrev = pPt;
    " [! @/ A6 i  u# o  X' y        pPt = pPt-&gt;pNextInCell;
    6 V4 r# g; I9 `2 R    }
    7 R" F4 a; ]4 ~3 e5 p( q}</P>' t1 m- o9 d, i

    - o8 T. g# q4 {& l$ _<P>
    $ s/ a4 F: b4 G//-----------------------------------------------------------------------------1 M! I4 ?6 _+ C1 e3 A
    // Name: * p! r' ~5 }! R% d8 ?3 X7 u
    // Desc:
    " ~  }/ Z) V# `//-----------------------------------------------------------------------------
    7 ~; U- x$ T3 L! c$ ?$ bvoid CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )  g/ C- r+ ~) }
    {0 b. k- A2 d# j, n
        ServerCell* pCell   = GetCell( pPlayerData );
    ( q- G* [7 O7 W    pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;! M' ~4 Z) ^- I. `6 Q$ J7 `2 }
        pCell-&gt;pFirstPlayerData = pPlayerData;6 g# }5 P4 c: ?3 h6 @4 b, z
    }</P>
    0 }" W' i& y" z) K9 f. `
    * O$ `+ Y/ |7 v; C<P>/ y% e& v7 p) S& M- b
    //-----------------------------------------------------------------------------
    9 n; d, }8 g5 z* |! y  d- \// Name: ) l9 F; L* ]# v7 g$ E
    // Desc:
    3 Z& }+ I) Z7 c4 q" `! J//-----------------------------------------------------------------------------
    / U/ l5 [" @& s/ s' w$ N& Uvoid CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )5 ~3 X& S9 i5 L, x; N
    {6 [6 z: ^5 a  J1 O# D5 G7 `& w. y
        // Grab player for this client and lock it
    7 ~6 q# z7 [, z6 f) z    PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );
      U% I4 s' e: J$ S2 T+ _1 D    if( pFromPlayer == NULL )6 D/ g0 K0 a# H* E- Q6 y9 ^0 k
        {4 k, E* _3 \0 @: P# |* q# e
            if( m_dwLogLevel &gt; 1 )7 \: f7 x- E/ R* |7 F7 B9 T
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );" p$ }/ H3 K3 k! ^# e8 b: G& M6 s
            return;  j2 A6 Z0 k4 N( f5 m
        }</P>
    . l" |, x  {" J) h; u2 K% R<P>    LockPlayerData( pFromPlayer );</P>
    8 Y  {( i1 G# G1 l+ _<P>    if( FALSE == pFromPlayer-&gt;bAllow )
    ! r9 m$ F$ t0 \. Z: m    {( ?( X2 ]$ b3 I2 n
            if( m_dwLogLevel &gt; 0 )9 g+ }/ f$ h6 R2 x& Q2 E0 l2 ?
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
    3 y) J5 k0 e" e$ x" a<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );& Y" P+ v+ B' d- n2 z
            UnlockPlayerData( pFromPlayer );
    5 d1 M; T3 D( z2 V' O        return;0 @# v: F' j: s5 O
        }</P>
    9 `3 V) |( q2 M2 S0 {$ i' J<P>    // Compute the cell the player should be in now2 L' f/ ^1 F0 i3 e+ _# A% X3 T
        DWORD newcellx = int(pClientPosPack-&gt;fX);9 ~; ?) t, A7 _
        DWORD newcelly = int(pClientPosPack-&gt;fY);8 w1 P/ u0 j& P" C9 E
        DWORD oldcellx = pFromPlayer-&gt;wCellX;0 Z  t" f& e4 K$ f) {# S0 y
        DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>
    * }# J- r& g2 Z1 O<P>    // Have we moved cell?
    " j  X5 a9 W) T7 ^. T    if( newcellx != oldcellx || newcelly != oldcelly )
    ) _" i9 k  S. X  G: W( I6 K: `    {
    ; g- P  }& l, u: R        // Yes, so lock the pair of cells in question7 R7 b; H; a' _% D. ]1 f
            LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>5 y5 a/ \( ~9 R$ R
    <P>        // Remove from old cell and add to new cell' `5 ^/ i5 ~/ V6 G& `
            UnsafeRemovePlayerDataFromCell( pFromPlayer );) k# p# H' J/ ~3 G; u
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    " m9 W% ~* `$ X6 b$ S5 q        UnsafeAddPlayerDataToCell( pFromPlayer );</P>5 T4 ?) C0 c/ K- Y2 a9 [
    <P>        // Unlock cells# _* D# q5 Y! Y. q  d9 Y0 x- ~& u2 W
            UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );
    ) l" o. X2 V1 `0 l4 N) W    }</P>
    / r0 q1 X. Y/ |! w+ R<P>    // Update player position; x9 z" b0 `6 {* K1 K$ E
        pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;  U( V" U5 J% t3 E. ~/ z& a
        pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;* h: m1 D% F# j$ t. P& M9 {+ R# e* ^
        pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
    0 V. }/ h1 i# N<P>    // Allocate space to build the reply packet, and fill in header 3 l. m1 Z- }" t' ^
        DWORD dwAllocSize;
    . w7 i0 b+ N  `5 [1 @    ServerAckPacket* pSvrAckPack = NULL;</P>
    ! t8 _) o* C: v" ]6 c<P>    // Begin by allocating a buffer sized according to
    6 R: R$ R4 l; E5 H1 |1 a' {& r. [    // the current number of nearby players + 4.  This will give
    % P( w& L) J$ Z, g% @8 H    // a little room for more players to come 'near' without resize" \4 }, T/ b/ A! Z' F
        // the buffer.
    8 Z- }# g3 c& G1 @    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>3 N, E1 u) v! i, Z% Q  l1 S
    <P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    . [4 f5 e" o3 x: @4 \9 [    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    1 [& h6 ?' p$ L1 F+ a1 w    if( NULL == pSvrAckPack )
      W+ @6 A/ s. c- P$ M/ o! i) H    {2 t; R% t4 \* \2 a
            // Out of mem.  Cleanup and return5 }! @" r" U/ S% J# Q, d" Q; T
            UnlockPlayerData( pFromPlayer );4 O, S: t& q9 @6 H; M8 R$ R
            return;       # _; l7 u) i% ^% p; p3 f
        }
    & T- ~# [$ d# |  I; J% f$ ]    ZeroMemory( pSvrAckPack, dwAllocSize );</P># T1 D* T0 Q' ]# T) \( N: y
    <P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);
    % a+ B( ~5 {. y- T& {+ c$ X    pSvrAckPack-&gt;wPlayerStatePacketCount = 0;! V& B7 x  f( G1 Y8 D7 g, a
        PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>
    3 p! W2 Q: O* B  r6 K7 K. h) @<P>    // Compute range of cells we're going to scan for players to send8 J' w# O2 X# p% J
        DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;
    + G! b6 p/ }  M! G8 Y* p, z    DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;2 l$ b: ^6 @1 n( e6 g4 m
        DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;
    : m" i4 {$ i2 Q2 o& k* E' Z    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>
    , j1 O% H4 ]. O8 ?" s! ^<P>    // Lock that range of cells
    / f0 k5 O$ n- ^* N2 U( {' t    LockRange( minx, miny, maxx, maxy );</P>
    $ d- _) X6 H1 k$ E& u& v<P>    // Scan through the cells, tagging player data onto the end of( o) K! x  o, m; l
        // our pSvrAckPacket until we run out of room" X8 l! `! m* u$ H) W9 `* A( b
        for( DWORD y = miny; y &lt;= maxy; y++ )' w' `2 m! O; e: O
        {1 u" W- Q0 O  O$ V
            for( DWORD x = minx; x &lt;= maxx; x++ )
    ! r; L: x% D* ^  z) R. E8 r* U        {6 |. S) t' W( Q$ ]) x* _8 w8 l/ M
                PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;
    6 _* G& i7 ^, L6 ?( B: S; S: B/ d            while ( pCurPlayerData )- n6 j" v9 l$ Q' y% o2 |
                {' v  p$ ~5 l, _4 X
                    if( pCurPlayerData != pFromPlayer )8 b6 _/ n4 y9 l
                    {! _. e3 q* B; A0 w' s
                        if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )- p/ X! O& J% v* @( q/ P
                        {
    # G- }: z3 j% {+ _1 d- ~                        // Make sure pChunk is where we think it is
      `; u" k0 l6 Y8 a                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>4 I9 q. x9 s0 H0 D; R& j
    <P>                        // There are more than just 4 new nearby players, so resize the
    7 Q( e  E0 R$ w                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
    % ^: G6 u2 N; Q. a! D$ ]                        dwMaxPlayerStatePackets += 16;
    9 b* S$ H) X6 T% l! p! ^0 f                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    . T+ R% I% N. h6 m( X                        ServerAckPacket* pNewSvrAckPack = NULL;
    " m) Q+ ^8 ^2 Q( H* _% _% z                        pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    # x9 j+ w7 J4 `" P# }                        if( NULL == pNewSvrAckPack )% @% B8 U8 U. k+ x1 T( s* H
                            {
    ; p! R, V1 @* h: O% u+ E                            // Out of mem.  Cleanup and return  W* h& f) [! D$ T3 ]
                                free( pSvrAckPack );
    ) Z, ~6 m& N5 j1 I0 m                            UnlockRange( minx, miny, maxx, maxy );
    8 r! h- h3 ~5 \! p+ k& N                            UnlockPlayerData( pFromPlayer );
    - g7 I, k0 W3 A9 o  A8 M0 v                            return;      
    2 w# ]  n4 k" H% L                        }</P>) c+ I' {0 P" s' j" A' U/ y$ j
    <P>                        pSvrAckPack = pNewSvrAckPack;% `7 [4 N2 D' u3 I/ ~
                            pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
    9 _7 Z  W/ V) E$ w9 }  Z<P>                        // Make sure pChunk is still where its supposed to be$ x" y2 ]* D8 [) {7 m
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );
    , @6 J% e" r( t: ]! p                    }</P>
    4 f. A) X- o2 L) F0 p<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;
    1 L1 M; B5 J/ d0 e: d' K& ^; @                    pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
    1 o! k6 ^& ^5 @) I+ w                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;
    & A% y% K# R$ V                    pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;$ Q! N  ~3 g  I6 K
                        pChunk++;/ k- Q9 I7 t! M( \# R5 K* K/ u
                        pSvrAckPack-&gt;wPlayerStatePacketCount++;
    & x5 k8 D+ {# ^! v$ o( ~                }9 L# ?6 B- v! t1 r. R$ C! x
                    pCurPlayerData = pCurPlayerData-&gt;pNextInCell;
    ) a/ v+ P/ n7 Z6 c0 Y& @            }( ^* `8 s/ H4 m9 r6 {6 q
            }# i( [  k/ P! [4 m
        }</P>. v2 \1 w3 o, R5 y' ?
    <P>    // Update the dwNumNearbyPlayers for this player$ M* O4 e% E0 C. [7 Y! t' H/ X+ i
        pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>
    ! r/ t+ g& Y% J! a5 \* O<P>    // Unlock range of cells
    ; M6 B- b* r7 f" |+ ~" _7 b0 @. p    UnlockRange( minx, miny, maxx, maxy );</P>+ y! k9 k! n0 k& v& y" o# K
    <P>    if( m_dwLogLevel &gt; 2 )
    . I; A3 q4 i# B. K- `$ E  t  U    {( b# C7 R' U. r8 y
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    5 ?! I7 j) ^# {# q    }
    6 s& r* z' k& E3 q) T    else if( m_dwLogLevel == 2 ): I% s# _& @* v4 O/ a9 i
        {
    , O: c2 t6 J- e  `9 W1 h* G& f        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    5 l/ ~1 w) I3 I/ H5 Z        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )
    2 f" T, l! v* A: Q  g, @8 I        {
    % B' `- J1 L& @/ x2 q5 P6 t. O            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );9 M  F- m2 x5 I- @
                pFromPlayer-&gt;fLastDisplayTime = fTime;
    ; j# E) a7 K& k0 H/ A        }
    # A$ m. _# L2 h* a& }$ e2 }    }</P>
    ( B6 z  J& w2 Q, \7 F& i# Q3 ~+ @; [8 U<P>    // Unlock the playerdata3 l3 `' D1 U2 h9 Q% s) J
        UnlockPlayerData( pFromPlayer );</P>
    % u9 Y- l# j5 i' `, Q<P>    // Send acknowledgement back to client, including list of nearby players $ W' t6 D( O2 U, Z! x" d* y& L
        DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));
    : c. B/ a) [2 `+ x9 E+ T4 e( l : Y3 N! H" c  V
        // Pack the buffer with dummy data., G7 l' L0 x& [- Q. p
        if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)
    " C% O. L/ E, i    {
    ) u/ p% x7 p3 k% o4 P) v, a7 Z        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];
    ( S5 J) _+ [4 V! _* D        VOID*   pTempBuffer = 0;</P>
    9 Z% Q% v5 |1 X) }; ~0 @9 }% l' G% O<P>        pTempBuffer = malloc(dwBufferSize);
    2 Z) J# o+ `* S% F+ Z8 |        if( NULL == pTempBuffer )
    : M7 @8 i: z9 |$ w/ }& Z! L        {4 R8 D1 C9 N' }$ N) E3 S7 Y' C8 y+ K
                //Out of memory
    ; v8 `% O3 r! C7 N            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );; l  P) n1 S  W* I6 y9 b
                free( pSvrAckPack );
    7 N1 x1 H; _7 x            return;
    9 _0 t7 D; f& g        }</P>+ X7 e; s3 l* e4 y1 }8 b
    <P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');9 D9 W6 ^, D, d' o
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>
    * K7 g9 p- j$ A* ~3 _( O<P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );
    $ V; D8 A+ }- |; K: }    * }/ j% N% U+ _3 D! }) A+ N
            free(pTempBuffer);' q! ^1 J  l: r2 ]
        }   
    , Q+ H+ m+ k2 ^7 `5 e    else" t: ^& T, x' Y% S- O
        {- ^4 P4 J. {" U+ V2 J
            SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );2 b, O- J2 W4 Q1 w
        }</P>
    + x1 O6 f8 |# a<P>    free( pSvrAckPack );</P>: |# p2 a1 H5 |
    <P>}</P>6 p! e, D, D8 ^% H/ h
    , Q0 m2 B8 K. Y+ x: S
    <P>! B$ g6 A' a$ D: {+ T) g$ \
    //-----------------------------------------------------------------------------
    & l" A# _3 J+ s) p% E% ?// Name:
    # t- \# T" E, K+ B5 B// Desc:
    * I/ J; I7 \- A4 l: @* p//-----------------------------------------------------------------------------. i" ~" v7 c/ L! p
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
    9 j& L$ g: {; N0 S" T{; x5 N; ^! x2 N
        // Grab playerdata for this client and lock it
    9 s; @& P$ Y& b: Y' `, }    PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
    6 R9 g; e9 `0 a  u, c1 Y. B% V    if( pPlayerData == NULL ). l2 ]: B- I9 c) U4 A7 u8 m  L
            return;
    2 q+ ]( c0 b! D3 P8 G/ \    LockPlayerData( pPlayerData );</P>
    & g# M- ~" n( C  k) {. a% n<P>    // Record the version number 8 a; a! M* T3 y( [( o2 W
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
    # {0 w4 W) o1 d3 {1 v* x/ t& x<P>    if( m_bLocalLoopback )' d9 E( `0 e. f& C0 z
            pPlayerData-&gt;bAllow = TRUE;
    / I, M/ A( U/ A$ H) u    else
    , v% [7 H9 c7 S/ M        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>
    8 B2 g6 K$ I2 L* x+ ?' j9 W<P>    if( m_dwLogLevel &gt; 0 )
    2 U! K* }/ N$ p! |$ X4 I' }, e$ |        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>
    , m2 [. v& h7 [6 K7 W<P>    if( FALSE == pPlayerData-&gt;bAllow )1 ], H" c" M* h$ x+ A' \
        {3 R# x: ^" ~% f1 ~" i4 y2 E
            if( m_dwLogLevel &gt; 0 ). h( l# P; s0 t
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>/ t. z' {- e' g3 m
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    , f9 L' U2 U/ b; v" p1 z' e. r        UnlockPlayerData( pPlayerData );; p; Q+ b9 b; v
            return;
    " X8 n8 c' ^- N2 p$ ?    }</P># ]) [* c, W7 X  j$ k" t+ D( ], j
    <P>    // Unlock the playerdata) H1 @9 T6 Q: ?& H- b
        UnlockPlayerData( pPlayerData );</P>, _2 v# M( ^: \
    <P>    // Send acknowledgement to client that the client was either accepted or rejected. b! E$ j/ q' G; T6 f% ]# q& d2 c
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );# _0 y: J2 |, C7 C& q
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
    ) a6 o8 B" W: s7 I$ }1 D}</P>1 u! G6 D# b0 r4 m' z2 N9 E6 X

    6 a! `8 s9 K9 C0 I6 @6 q<P>
    5 {% x7 l' |' V0 ]3 q//-----------------------------------------------------------------------------2 L/ H* y2 V+ U+ ?) b! ]6 M$ P
    // Name: . ]) g' ?5 [7 _2 L! \  X
    // Desc: 0 E5 j  c) ]; w: \" B
    //-----------------------------------------------------------------------------1 c! B( ]2 w+ O. X! k/ N7 ^' U* K% g
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion ): o; r8 C" a& Z( i% I( j
    {& d  j) {, A1 ^1 E( L* a
        switch( dwClientVersion )
    8 S( p: B5 j5 I7 j    {
    ' J* ~' L. c" W' \        case 107: // only v107 is supported
    2 E5 Y. u; X( q" U, t' z# D" z8 r3 j            return TRUE;1 [5 m" M! c+ Z" I9 `, g) B
            default:: z7 f% [* T3 j& ~# Z+ Y8 z" M- A, g
                return FALSE;! S5 y% K/ P0 T, Y0 ^! O
        }
    3 g7 d# z& e1 P}</P>5 b) J; f) P) l

    : u4 A1 Y- V3 N) z<P>( a$ X8 z% l% ]+ s4 c# W0 Y
    //-----------------------------------------------------------------------------
    5 }* G& \: L" \) u// Name:
    9 V) P7 z; K; p9 H) Z% ^( j// Desc: + b! Z  S4 Y2 O0 ]  n8 W& e4 A: P
    //-----------------------------------------------------------------------------
    ' W9 A( r' z* N# {5 T* y1 dvoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
    - ^, K  |$ ^2 Z3 \4 v! r{- p% [+ m+ x6 O4 `; \4 |2 p
        if( m_dwLogLevel &gt; 1 )# _; v) X* Z! ?) [& @
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>
    # M% a( m: I0 s& b<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );6 G& A# Y6 a: [. |
    }</P>
    , ^$ F5 g4 Z- a
    & G: b3 ^0 Y7 {7 V2 ?: d: h$ w- c<P>
    - J  e3 L7 @1 }* A6 O4 r//-----------------------------------------------------------------------------
    9 T( X# j2 q7 ~" M: _' l& `// Name:
    ! }9 Y1 W0 {  @  a// Desc: ' r4 d5 m# z( t# g
    //-----------------------------------------------------------------------------$ i" p+ N# b8 g, t4 V1 n! f% q
    DWORD   CMazeServer::IDHash( DWORD id )- X; y* c6 C- m7 c+ [
    {
    & K& \  [  J1 g8 d: o    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);( f8 ]; w$ e1 n5 H+ _
        return hash;
    4 n9 L% E' O5 t  x}</P>
    * ?0 x) _" |1 W' H" O* G6 i- u2 q
    <P>: \- `% m6 E6 [2 n& |" T2 }
    //-----------------------------------------------------------------------------
      r# u/ D+ H3 l1 Y) p// Name: 1 Q" l6 v! T& p- |" W) L# U5 B. E
    // Desc: 3 E6 u: n9 J! Z! H; o7 v
    //-----------------------------------------------------------------------------
    $ z5 w( B: |1 U- R* S* u" q1 Avoid CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
    ) Y' p2 I  _- e* E2 X+ W{
    . }) F# U& t6 l1 B    // Hash the ID to a bucket number
    ' f2 v9 k4 X. H1 ~& i: a    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>. ?1 z7 w8 [4 F0 I
    <P>    // Lock that hash bucket
    + C. j9 V+ a+ J1 V    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;7 {' C8 j0 _8 z7 _" f% B, a6 U
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    $ E8 y% G4 s6 C; m1 f" a<P>    // Loop though players in bucket until we find the right one, T7 J/ `2 I! Z9 Q) u- i+ A- j; }
        PlayerData* pPt = m_pstIDHashBucket[bucket];* D1 P1 |% ^+ y7 F
        PlayerData* pPrev = NULL;
    ' ~7 G% f- {9 @    while( pPt )3 R' L& m2 K4 {& ?
        {
    ' p0 n, W" W9 C  N+ K# E1 r        if( pPt == pPlayerData )3 N5 H( o5 G6 Z) f
                break;
    + H: R" V/ K0 u0 o, Y& ]        pPrev = pPt;! @/ I/ v9 q, y! _5 l; M4 \2 p" p8 H
            pPt = pPt-&gt;pNextInIDHashBucket;4 b! W0 j$ h3 Q4 M
        }</P>
    6 v8 W6 _) p9 s<P>    if( pPt )
    * P0 ^$ g. L+ k6 h/ d% ~    {& c5 y) H8 k7 ~* b/ q
            if( pPrev )' }8 H( u0 D! U( y0 P
                pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;
    / B- N7 _: P1 x' x) O6 [% s        else! E$ k) w# C4 {6 x8 w
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
    . k* n% {, W& m0 l        pPt-&gt;pNextInIDHashBucket = NULL;
    + S2 \6 b4 s! k8 W    }</P>* Z) g3 C* T2 R* U- d3 c
    <P>    // Unlock the hash bucket5 j0 V0 r8 b& Z# w
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    6 n  K9 Q& [3 F- h& C0 F}</P>- H# k5 }' l5 I& D

    ' [2 q# \8 f4 r* V6 h) P9 k<P>) m+ n' @9 Q; y! q( [
    //-----------------------------------------------------------------------------& a, r/ E9 ]3 t" z+ P8 N
    // Name: * T/ g* X. c" y- ^' w$ b
    // Desc: 9 T; }4 ^9 P2 b% e) {
    //-----------------------------------------------------------------------------
    9 R$ X1 m6 V3 N7 u$ S/ {" qvoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
    $ ]: R7 }+ u2 q& d" |{1 ^6 N; r  x# Y: }
        // Make sure this player isn't added twice to the m_pstIDHashBucket[]
    - @* m! @$ E1 e" t; X    // otherwise there will be a circular reference
    9 ?5 V) K9 w1 @& o    PlayerData* pSearch = GetPlayerDataForID( id );
    8 g1 H5 Q: f7 r* R% \4 w3 M    if( pSearch != NULL )
    7 l- V- h2 T) _! M        return;</P>, _2 v' X# x' ]- Y" J3 l1 w
    <P>    // Hash the ID to a bucket number
    - n0 g/ Y3 c0 b    DWORD   bucket = IDHash( id );</P>% j8 g- o1 P8 ?9 S
    <P>    // Lock that hash bucket) y4 w/ A' O# ^5 e9 s& M
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;* g! M2 @: M. T
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>+ F: k. [8 Y2 a1 y+ ~; w+ V
    <P>    // Add player onto hash bucket chain
    & T- ?& ~2 g: P$ E2 x    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];
    7 x5 A- K0 E; d; [  I/ y4 ~    m_pstIDHashBucket[bucket] = pPlayerData;</P>% O8 q" i1 e" y) \7 \. y
    <P>    // Store net id in player
    . [2 g& j6 R3 R$ p. H    pPlayerData-&gt;NetID = id;</P>0 \: l8 N' U0 k7 S% ^
    <P>    // Unlock the hash bucket4 R' P. Q8 z2 P; f/ u$ I- q
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    ) z/ u* |/ h  ~+ F% B$ g, p}</P>0 j, ?  }0 l7 u, G6 n. ?
    " \  }9 f' r- L
    <P>
    & \* t& A! N6 i" r* @- D( h//-----------------------------------------------------------------------------
    7 h( y$ r/ D; V9 [' H// Name:
      ]5 L4 S$ F" R2 S8 J/ }// Desc: 3 ~4 S$ C1 x1 B1 V
    //-----------------------------------------------------------------------------
    / \( t# B6 w/ Q/ g/ k) a; W5 ^# u5 vPlayerData* CMazeServer::GetPlayerDataForID( DWORD id )1 B+ T; s  M: C2 W
    {! H# b3 w5 J' X! i/ o) [) X% {0 r6 Z
        // Hash the ID to a bucket number+ N  f, \6 I) P8 W5 H9 @
        DWORD   bucket = IDHash( id );</P>
    ( D4 K. K* j7 P; j9 b<P>    // Lock that hash bucket) v2 E  n2 a, W, E# w$ ]
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;3 p9 o3 P: w" s
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
      o  l3 M. X! U& p5 H<P>    // Loop though players in bucket until we find the right one
    2 g, P/ _/ _& C- C5 i$ C  B    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];, T5 l; E' m4 Q1 r5 `0 B
        while ( pPlayerData )3 {9 Z3 Q% U% h. a# e
        {
    2 d$ M/ C( `+ C% i        if( pPlayerData-&gt;NetID == id )6 x5 U8 @: c- R2 [, v
                break;
    / E% K/ ]  u7 H- L7 p3 Y        pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    $ w4 N( N" k( [2 ?" ^    }</P>* r' q- E3 e1 F
    <P>    // Unlock the hash bucket
      w( g: L% n& ]: ^6 k* W) U/ o    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>' O* @) g- m' X2 `, B
    <P>    // Return the player we found (will be NULL if we couldn't find it)8 P' r- o! K- P# D% m3 g2 B* x5 h: K
        return pPlayerData;7 M% c5 b: D" ^1 `4 H2 D
    }</P>
    $ O& B; X2 U3 H+ I7 B5 h/ V& u2 t! r# y) w
    <P>
    5 B5 A4 Q3 q. g. Y" @//-----------------------------------------------------------------------------  E7 n. }' j# \  @" Z
    // Name:
    6 n) M& Z  `3 B; F. Y: T// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner
    2 W/ _7 u7 l% ?; p3 Q. d. H- E//-----------------------------------------------------------------------------6 b+ ~% u. V) ]  D$ O, k
    void CMazeServer:isplayNextConnectionInfo()8 D6 W5 b1 k) J5 `  P/ n
    {! B# c( S5 T. O: m8 V
        if( m_pNet )( f, z1 u8 Y+ M# Z
        {+ t( B' @4 s: J3 y6 o6 z$ @
            // Find the player that was displayed the longest time ago, and display it.
    " H' j5 A/ _0 h2 o5 R; y: a8 ]        FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );( v" A4 Z8 X. x
            PlayerData* pOldestPlayerData = NULL;9 S! j; m; E7 G7 D; s" K
            FLOAT fOldestTime = 0.0f;</P>/ U- w/ }! l+ S; }6 @0 T
    <P>        m_PlayerDataListLock.Enter();</P>
    1 v3 J# ^; o& A0 b9 \<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
    ( V7 v1 I" U0 u; `        while ( pPlayerData )' a  b: {' Q) I9 O& x+ s6 p
            {
    6 N6 T2 I7 c) e1 \% ^& X$ V' K6 ?            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )& Y9 y. A, B0 p% l( k
                {+ l7 K0 s' |8 g/ u" p
                    fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;. C% a( V( Z% q7 f. j1 \$ q
                    pOldestPlayerData = pPlayerData;/ ~& X/ N  }) H% L" h# q
                }</P>2 v; b* s, j4 C% \* ~: Y: \
    <P>            pPlayerData = pPlayerData-&gt;pNext;
    ; @3 w: [. z7 I7 U! R% s        }</P>
    . }# O$ }$ h! E  N<P>        // Display the player with the oldest CI field, and update its CI field.
    5 ]" H) k' `0 _6 t' i4 N        if( pOldestPlayerData )
    6 O) l5 B% w3 t. H- j9 S  i        {, w) K- j3 k; j4 Q# F
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );) b9 e. ]! l; j/ [, z
                DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );* E; p# Z  ]1 S% N3 O4 g2 a: U$ Y: Q
                pOldestPlayerData-&gt;fLastCITime = fCurTime;
      R6 u" r) F$ Z        }9 y& \" U( Y) V& [3 I7 n
            else
    $ k1 z& W& o! n( x6 W        {- H9 p- Z/ }# K$ ^, N
                ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    - N! V1 \) x  s- _+ E        }</P>" d! C1 E& W5 W, e: H
    <P>        m_PlayerDataListLock.Leave();2 f( V  d4 ^4 E* K
        }
    * J& \8 N* P4 [5 [1 W}</P>: ^* ^. J5 E4 ]  ~) P- K8 W4 m
    " {$ w$ s3 Z- v/ m2 y! V
    <P>- l6 W- E3 H' R" m
    //-----------------------------------------------------------------------------
    9 v' z2 o5 Y4 i1 `// Name:
    1 F. D0 w* Y0 S3 L. p0 H8 P// Desc:
    : r- K$ `2 ]3 `$ k% }: ^4 B//-----------------------------------------------------------------------------
    7 w0 ^0 A& U5 p4 }8 Zvoid CMazeServer:rintStats(), A0 g. Z( m( h1 O1 b' Z# {8 A
    {
    9 p2 m! u6 U2 Z8 a    ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
    % [" K; m$ y; B; P, D/ n                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );  Q+ S; H8 r+ s6 D6 b* v: }+ |: G
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
    ! n1 ?$ Y/ K0 Y, S                                    m_fAvgThreadTime, m_fMaxThreadTime );8 N2 n" y8 b9 {: P
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
    4 I8 F% u! B# h2 E# o0 l6 g    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );3 D+ Q* Z3 C' o! ]2 c! k) [7 Y9 i
    }</P>( |$ q6 r2 x4 C, T/ X; t- @( f& F
    & G& l! H# y8 I# o& U; _, m9 w9 r
    <P>, I( m# Y3 p( s0 m2 g
    //-----------------------------------------------------------------------------1 C, b/ j4 ^5 {  J
    // Name: ; \0 a! Z9 b4 O. J0 g
    // Desc:
    2 J0 [0 j1 i1 K* d//-----------------------------------------------------------------------------
    1 K" |1 R) C: _, q# ^1 a# N$ qvoid CMazeServer:isplayConnectionInfo( DWORD dwID )
    3 W, ~- w& L2 K" s  o$ ?" a{* q  I& b# d0 H' ^% `
        TCHAR strInfo[5000];/ f  C8 Q$ [, Z! j% f# _( M
        TCHAR* strEndOfLine;
    $ D- L6 A* d% X: ]9 C  X$ I2 `    TCHAR* strStartOfLine;</P>
      _, l7 J5 b; s) L<P>    // Query the IOutboudNet for info about the connection to this user
      ?. f0 g4 V+ H    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>1 X' j. E( d* F
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );3 C8 f  N4 t, Y9 }  s
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>4 {1 y& R1 Z- [4 _. ]& X
    <P>    // Display each line seperately9 B0 R3 e: x. l) W6 D( K5 P
        strStartOfLine = strInfo;
    5 k" c3 n: M& A( G. L    while( TRUE )
    9 T+ F  Q/ a$ H5 x4 h: Y* U, N) Y- `    {
      Y  a8 s  O1 S7 S5 R" p        strEndOfLine = _tcschr( strStartOfLine, '\n' );- w/ o! J( @. D0 L( W: g
            if( strEndOfLine == NULL )# j4 c0 Z3 Y' Q& t
                break;</P>! ~2 w. z( `! p+ m* F* b/ m3 }
    <P>        *strEndOfLine = 0;
    $ c2 `. A" D# l9 X) }, ?$ B; m3 \2 P        ConsolePrintf( SLINE_LOG, strStartOfLine );+ ?" d; Y( q; U% v' H
            strStartOfLine = strEndOfLine + 1;( \7 x( y( [: @/ s7 X
        }' m' G, H: _( b* B# l
    }</P>
    $ |+ t* D- k' r: _
    5 W6 ]+ g4 Q( Y; I<P>
    9 e1 Z  Y9 m: `! x" k9 G2 V  {//-----------------------------------------------------------------------------
    0 P* k& d7 a& R// Name: % ~! I0 N0 H9 g+ Z; @
    // Desc: & |  U2 c0 M: S! f/ u7 ~7 H
    //-----------------------------------------------------------------------------+ R! g6 s2 |, ^$ j( F. W: g
    HRESULT CMazeServer::SendPacket( DWORD to, void* pData,
    ; E1 E- O( Y( g6 T3 F( z% n. n/ h                                 DWORD size, BOOL reliable, DWORD dwTimeout )
    + P0 [8 G$ H6 R; ]7 X{
    8 t' T4 G% j$ r* C+ A: G0 D    // Chance of forcing any packet to be delivered reliably" q7 K! Z3 F% f" }2 u' g- W: c
        if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )
    4 n- D4 c% J3 \# H- _        reliable = TRUE;</P>' T' y* C) o7 R. B4 c  w
    <P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    ! ]4 O9 E. Z! a: D1 \+ G5 K7 k- a6 s}</P>
    ! H. \" {) {' v0 Z  u9 _1 t( F/ G; s6 }4 z) L
    <P>% U' J8 f' g& q) b5 g$ n
    //-----------------------------------------------------------------------------
    " e( u8 J' H" w1 Q' P// Name: 8 ^" K. y; H" B4 O
    // Desc: 5 d# J/ G5 Y$ j# }# y
    //-----------------------------------------------------------------------------
    # ], t  e! f2 G+ ^% t3 l2 [8 Q2 T- xvoid CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )
    - ~- h. C7 ?- y! v  f9 v8 R, [{
      U- \, w( `- V2 Y7 B9 T7 E    // If we're up and running, then send this new information to all clients
    * r  `# u( @0 O2 O" w    if( m_pNet )
    9 x3 v) T  o- C1 f8 U- j- y" T    {
    - P1 Q  S6 r! _: T        //Use the AllPlayers ID& _: t& _2 E. k" Q6 g, t: m: W
            SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );* f* S& J, A* ~/ h& I( I
        }
    . B- M" U. n. h" \}</P>9 b8 [1 S# M6 K7 u' F

    " U. R9 Z$ x( M* Q& J<P>* }" |" S! ]% _& N) i4 z) A2 P
    //-----------------------------------------------------------------------------
    4 I! T; O3 ]' Z* t// Name: 9 [% H$ O. o- b# F' z7 S
    // Desc:
    ( P) p" u# ~! N  g( Q: o//-----------------------------------------------------------------------------
    " V, h  l0 v- Svoid CMazeServer::SetClientReliableRate( DWORD percent )& q- o+ R: }$ o9 ]3 u
    {
    4 y% M/ T% N/ h  V    // Update client config, and build packet containing that data
    * [, N$ X2 E5 Y! |% A' J  N2 l    m_ClientNetConfigLock.Enter();( x: }+ h5 W; {- g# @& \
        m_ClientNetConfig.ubReliableRate = BYTE(percent);
    9 `! Q+ Q; L& E' n6 O7 {6 ]7 c    ServerConfigPacket packet( m_ClientNetConfig );+ [# ~6 H5 O# p. |
        m_ClientNetConfigLock.Leave();</P>8 z3 e& K, q/ y7 e1 J
    <P>    SendConfigPacketToAll( &amp;packet );  m5 j% _* I" o+ [/ }, U* R3 S
    }</P>
    : g! F7 E6 N, F. I4 H
    + p% n9 z) v, d* r: z- `<P>
      @/ s: t' {  n$ J. g7 F% y& W4 B//-----------------------------------------------------------------------------
    # b3 K6 g# ]# R// Name: $ N% y. i5 N( k* n2 {
    // Desc:
    ) D6 L1 r6 ^& _- u* R0 A1 W8 T//-----------------------------------------------------------------------------
    . s) a% F1 Y  R( Jvoid CMazeServer::SetClientUpdateRate( DWORD rate )
    : m+ @9 p& T8 k6 A. y{% `, U4 X. ^" ?4 u
        // Update client config, and build packet containing that data7 J9 u. u0 j, w8 `8 J& @; o
        m_ClientNetConfigLock.Enter();
    8 c6 E6 ?' d" v& a    m_ClientNetConfig.wUpdateRate = WORD(rate);6 r3 a7 D; u. M" @7 c7 G
        ServerConfigPacket  packet( m_ClientNetConfig );
    6 O; I1 z! u- n5 T, R    m_ClientNetConfigLock.Leave();</P>% H7 b% X' [( o- x) a
    <P>    SendConfigPacketToAll( &amp;packet );
    + V; u2 a* w5 r: q3 w- o}</P>$ T7 c( a/ V! N% G

    8 l3 u% p$ o0 J# Y, a<P>
    , M; T* {6 I$ Q7 S: G8 V- z//-----------------------------------------------------------------------------  L9 |/ _8 M/ s4 f$ m
    // Name: ! p% v9 T8 X2 D6 r& M/ v! B8 Q: C0 M
    // Desc: 4 \! E# r1 j2 s+ }# o; O
    //-----------------------------------------------------------------------------
    . m2 @( |) G1 k; K& P5 N. qvoid CMazeServer::SetClientTimeout( DWORD timeout )7 C  f' d% D, C  D* I0 K
    {
    ! Y& p5 X. d* G" Q( i    // Update client config, and build packet containing that data$ y5 [6 r. V. N* ^4 _# a) B
        m_ClientNetConfigLock.Enter();
    * ^& v1 k( }8 f    m_ClientNetConfig.wTimeout = WORD(timeout);* g5 p8 W5 H( O( Z2 _
        ServerConfigPacket  packet( m_ClientNetConfig );
    % @& r6 x* [+ I$ d8 Q! ~( }    m_ClientNetConfigLock.Leave();</P>
    ) s! X4 b4 F9 G3 j' o) j4 A/ o<P>    SendConfigPacketToAll( &amp;packet );, U. H/ q; y8 d! c# J+ O! D: Z
    }</P>
    % m1 u: V: d7 u, D9 E9 p( T1 }) `4 W
    <P>
    " w( }: V4 b  y//-----------------------------------------------------------------------------
    ' b2 X1 k: z2 l// Name:
    7 c2 ]5 T' f$ E/ @3 B3 O// Desc:
    2 Z6 y% S: D- R! w: W//-----------------------------------------------------------------------------
    % s/ V( W6 M+ ~: {8 Q" n& H, kvoid CMazeServer::SetClientPackSize( DWORD size )
    . U, s% |+ v5 e+ a{1 P$ D' q, U8 c& }
        // Update client config, and build packet containing that data
    # f% U2 j. K# D+ ]) i( |( a* ^    m_ClientNetConfigLock.Enter();
    ' `7 G" @+ e$ ]5 g* \5 U: e    " M* D( Z) t' B$ I6 H% x
        m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.
    & J( t/ _  j8 h) Y: O  [    if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   8 ]. Q" B5 L- n$ v: e8 R  A
            m_ClientNetConfig.ubClientPackIndex = 0;</P>) @; g$ B6 @9 `! u& G  o3 c" r
    <P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);: w; g8 C/ F4 Z$ k4 P
        ServerConfigPacket packet( m_ClientNetConfig );
      ?8 b. @' E% I    m_ClientNetConfigLock.Leave();</P>
    ( n  v$ y4 e, q! {; O+ a<P>    SendConfigPacketToAll( &amp;packet );. |" ^- S: P% N
    }</P>
    6 _. I, G8 a: E! h  R6 F. @+ C7 d# a8 n
    <P>3 x6 g( i, y1 @: H9 e( j: X
    //-----------------------------------------------------------------------------9 d$ F2 W: c. G
    // Name:
    6 r( T6 V% B" w$ o+ K; d* N( R// Desc:
    / H0 c) w( N- v6 x# L//-----------------------------------------------------------------------------3 |& [* h0 E3 O, Q. M  f* _  P
    void CMazeServer::SetServerPackSize( DWORD size )8 W9 W! x4 d6 x+ N% |
    {
    3 f& q4 ]2 \$ P. C/ Y' N    // Update client config, and build packet containing that data
    6 ?* _8 d+ d* y3 [' y    m_ClientNetConfigLock.Enter();
    4 ^  f8 y5 W  {0 J* }$ G0 [   
    : d! ~8 o/ \- U  {0 K1 D  A    m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.
    $ I0 {# Q. z" S+ c$ E) x7 U    if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)     Q: g8 o4 ]: d/ u: ^) e
            m_ClientNetConfig.ubServerPackIndex = 0;</P>
    : `4 L: a2 F) c& l2 c<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);! g! f) E0 H: k' P7 J9 i
        ServerConfigPacket packet( m_ClientNetConfig );5 m2 n: K0 j( X" \7 u( r8 _
        m_ClientNetConfigLock.Leave();</P>
    1 |: H# x2 M7 J" z* w- h<P>    SendConfigPacketToAll( &amp;packet );1 a2 W" ?2 a( ?" J
    }</P>+ x9 D/ _' ^  p3 S% H& N* C/ e
    <P>9 ?% a. O' g- \! N1 @1 {% i# e' D' u
    //-----------------------------------------------------------------------------# `  g/ a: i6 `
    // Name:
    3 p& [6 d* y, ~% [// Desc: 0 q2 W) g# n# U7 j+ J6 O0 t( d
    //-----------------------------------------------------------------------------
    ! G: C3 o% O+ E% ivoid CMazeServer::SetClientThreadWait( DWORD dwThreadWait )  x/ O  x1 A5 o- p. b
    {
    2 a. w1 R1 ?4 d, L* e! I+ v    // Update client config, and build packet containing that data
    ' {4 ?# F, O# i% P9 U" x    m_ClientNetConfigLock.Enter();, T# d$ C4 q# e# ?& T5 d" {, s
        ' g7 M0 p( q/ W6 ^8 H* g/ E+ J
        m_ClientNetConfig.dwThreadWait = dwThreadWait;, N, r! J  p# Q, _4 i" P
        ServerConfigPacket packet( m_ClientNetConfig );
    7 U& q  p3 T: q4 T/ x    m_ClientNetConfigLock.Leave();</P>- l8 z' S$ d0 V, z
    <P>    SendConfigPacketToAll( &amp;packet );$ Q) ]+ l  ]; b4 ]/ Y& g+ a
    }</P></DIV>
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2026-10-8 05:36 , Processed in 0.464746 second(s), 51 queries .

    回顶部