QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4195|回复: 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>
    " O, C) l6 H* Q+ X<>// File: mazeserver.cpp* v" }. ~& O% w1 U
    //
    ( |# F% A/ V& t. Z+ \// Desc: see main.cpp
    : M6 O$ [' B; D/ i4 _( m& O: R//; D" G) D  N: `
    // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.% x. ^+ y1 O6 J8 [
    //------------------------------------------------------------------------------ ]$ v" g. Y) O. z0 v% G2 c$ F% c
    #define STRICT
    - c2 H' z  Z- D" M: e7 S, B#define D3D_OVERLOADS, d* `" K9 t: E% ~. @/ N( g' ?& O
    #include &lt;windows.h&gt;, R: t4 e) u7 ~$ N
    #include &lt;d3dx.h&gt;, k9 |3 p! U( v7 q# l
    #include &lt;stdio.h&gt;
    - s, e* V1 Q' q- P#include &lt;math.h&gt;+ s& R4 @4 W) V
    #include &lt;mmsystem.h&gt;) }9 n8 ]( G1 Y3 Z  W
    #include &lt;dplay8.h&gt;4 V# ]4 [. e8 k' s7 L4 ]8 a% Q
    #include &lt;dpaddr.h&gt;
    1 s6 E$ f: _% E% b5 c#include &lt;dxerr8.h&gt;8 g; v6 ~5 D# X) m' H% g
    #include "DXUtil.h"# X' P, k) W$ k* Q3 v# P
    #include "MazeServer.h"/ o% N( l2 ?2 `, x1 q
    #include "ackets.h"
    # x! d- G; d4 o1 z; ?  r0 F& {  Q#include "Maze.h"
    - B; y6 w  H% l; ]#include &lt;malloc.h&gt;! }9 a1 k* q4 f) n$ S: R- o
    #include &lt;tchar.h&gt;</P>5 r. l1 `  B3 U( a: d; l
    ! f: Y) v. ?& z
    <>//-----------------------------------------------------------------------------( S& x3 k8 ^& P' E2 E
    // Name: * x1 O  H$ v: B9 i1 d, v
    // Desc:
    ) Z7 s& E. ]/ X$ ^//-----------------------------------------------------------------------------$ N' B; m, v8 L, g
    CMazeServer::CMazeServer()7 M5 Y% c. G" s& S8 x) q# N8 e
    {( f* w( D7 A& G0 ~. @; L2 K4 s
        m_dwPlayerCount         = 0;
    $ D  C, Y0 f* {$ K    . K9 i1 X" p' I$ E( Q. C  c
        m_wActiveThreadCount   = 0;
    / X5 D  s+ [. M' ]" _8 ]6 _    m_wMaxThreadCount      = 0;
    + A4 d( Q! S. b* y% G    m_fAvgThreadCount      = 0;
    " Q& ~) r- i, W& c( F    m_fAvgThreadTime       = 0;
    ; k6 m; n4 q' Q! e    m_fMaxThreadTime       = 0;</P>* k% t  \( ?9 |" }' U; L" M
    <>    m_dwServerReliableRate  = 15;0 `' a/ F5 N' A, l6 L
        m_dwServerTimeout       = 150;
    ! U. ?$ \8 f  `& ~0 _4 I    m_dwLogLevel            = 2;
    9 F& n* f$ V0 Q    m_pMaze                 = NULL;</P>
    . @% t. Q# i  d5 X0 F<>    m_ClientNetConfig.ubReliableRate = 15;1 @7 V. S# I. s
        m_ClientNetConfig.wUpdateRate    = 150;0 \6 u7 L. r' e( ]) S8 ~
        m_ClientNetConfig.wTimeout       = 150;</P>
    4 U0 f, C: U! ]. g<>    m_ClientNetConfig.dwThreadWait = 0;</P>4 f$ k- H$ @7 E8 c% r
    <>    m_ClientNetConfig.ubClientPackIndex = 0;
    4 g; H; u0 m) G6 v3 k$ Y# m$ l5 O    m_ClientNetConfig.ubServerPackIndex = 0;- c8 c  ^0 ^" O( Y# d2 {
        for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)' ?# q% E( h# J; x
        {
    . a$ O& _2 b0 U6 I! C  C        m_ClientNetConfig.wClientPackSizeArray[x] = 0;
    6 U5 g) A4 L# M' p        m_ClientNetConfig.wServerPackSizeArray[x] = 0;9 d$ Q! y$ J% g& W. U7 E
        }/ L- w7 Q, X1 z- M
    }</P>% W- n* x2 p2 N$ K1 x! `. e
    0 k7 e+ ~' w, g8 x- u. y0 \
    <>4 {0 @8 T7 `/ q" A
    //-----------------------------------------------------------------------------6 Y% z5 _3 f% L
    // Name: 2 E$ m7 r. {% \/ d2 M* N
    // Desc: , @) u" a% n9 k- o$ }
    //-----------------------------------------------------------------------------
    8 c0 [" {3 G4 {3 ?; E- Z" AHRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )
    5 W/ o6 c( W5 A+ T! x) H/ e{) R8 h7 G1 Z4 ]/ f# ]
        m_bLocalLoopback = bLocalLoopback;
    " l- w- T  @+ S4 c4 Q5 J" D    m_pMaze = pMaze;$ I% U- t3 s) l: N$ v
        if( m_pMaze == NULL )0 M- d$ [( ~- ^7 K% y& s+ r8 j6 O
            return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>4 Y# }3 z0 X. U" h6 m
    <>    // Grab height and width of maze
    ! ?& B) g9 l) R0 d! _4 w6 ?    m_dwWidth = m_pMaze-&gt;GetWidth();, D( X* l2 Z: f
        m_dwHeight = m_pMaze-&gt;GetHeight();</P>5 {5 }, G. l$ H* u
    <>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;. O. b4 h+ x, `+ }3 y+ u5 ?
        m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>, l8 c& J4 O: Y* h  E' e! w
    <>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.
    . i; r0 ]. \/ a2 g" C    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    : e+ p( A6 U& ]8 A' R5 i& v        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );5 N3 Y+ i* Y3 P; Y' A4 j
        if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )
    ( N/ h1 |  g) b        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
    - m7 o, [. k/ f+ h<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;
    ; ]; P( q' z% |% S9 W    m_dwMazeXShift = 0;
    " z0 D7 S8 n; C    while ( (scale &gt;&gt;= 1) )( T/ }5 X3 O9 V* Z! q, x1 t
            m_dwMazeXShift++;</P>
    6 P8 F# `2 u- t4 O<>    scale = m_dwHeight / LOCK_GRID_SIZE;2 |6 C/ t" v2 A% _" q
        m_dwMazeYShift = 0;# Z7 ^7 }% d+ S8 D
        while ( (scale &gt;&gt;= 1) )- {5 s9 y7 L/ m7 |7 r) c
            m_dwMazeYShift++;</P>. p1 T/ R  k2 \, X
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    - }+ N2 J: S1 C        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) ), n5 C3 W3 p9 d& ^/ l( O& \1 C/ h% s
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>6 A+ z+ f% P" e; R/ s5 J$ X
    <>    // Initialise the player list
    % k/ F3 l+ @: }$ |2 T    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );, ?) k: A& V! M, e( t/ R0 U
        m_pFirstActivePlayerData = NULL;
    & e- b* d& ?6 n+ f1 \; Q/ p: f    m_pFirstFreePlayerData = m_PlayerDatas;6 T0 G4 ^# @7 b( e8 L' k5 s3 j$ ^
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )' p# o/ O8 }5 u2 t. x' S
        {& Q4 n# j. E/ T( r" r6 T
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];$ J% ^7 u( j9 O
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
    , i7 u' n. J: a' e  F8 B' o    }</P>
    % A  j, @6 ?4 ]$ `8 K  |# a<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
    ( X7 S0 K: `6 K/ A0 M, \4 Z    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];4 n! g9 N) x; g* c* H+ b( m( S1 F
        m_dwActivePlayerDataCount = 0;* x, x. Q' s. r& |( |
        m_dwPlayerDataUniqueValue = 0;</P>, R, G9 \/ y- k- `& Z
    <>    // Initialise the cells
    , r% C3 h9 p8 ?5 b    ZeroMemory( m_Cells, sizeof(m_Cells) );
    + `9 v7 o3 m) H( y- L    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>
    8 V. @% N7 M4 r<>    return S_OK;
    2 W0 U" D' e$ s; k" Y9 a' V: q}</P>4 D( H0 u. ]& |- Q' I/ Q

    9 H! f) c" q6 r<>; G- t  y: J/ b- ]
    //-----------------------------------------------------------------------------
    , m2 E2 Q# H0 b: ?// Name: - ]* ]0 e  u' K3 N
    // Desc:
    ' b$ l3 b% p4 Y( h+ L0 s% @0 e//-----------------------------------------------------------------------------9 @5 `$ ^& M% K0 y# Y7 |
    void CMazeServer::Shutdown()  d( h- e( C/ y& M" h& h4 j
    {
    , M: Y0 Q' Z7 N) B}</P>
    8 K9 ?2 {$ d! V& K0 R" U8 J6 S( D5 l- _" M! {& I5 f6 w0 V1 C2 U7 ]2 N
    <>
    ' L+ w+ T) b; Y- U//-----------------------------------------------------------------------------
    - c- W* @3 i+ D! Z// Name:
    : R3 }0 I% C! G: M, Y9 g9 C// Desc:
    # V+ K8 D3 f7 E. m" _//-----------------------------------------------------------------------------4 [: y" l0 a3 W- p# a) g
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    4 w4 N& X8 V+ V1 d* j. B{
    1 v- z# ^+ `+ ]/ v& v  r& [1 ]    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    & A, j! p" [$ V* a                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );' _& ^: b. l2 r) y$ u5 U' {# `  I3 o
    }</P>+ r( A% M3 [& D# T' V/ {* l

    : L" d( L3 Q/ O$ O. x<>
    6 g. ?/ r% D" o- S9 K7 m7 R. h//-----------------------------------------------------------------------------
    5 U, A  c7 S& ^// Name:
    7 I% `2 u& l9 i# z// Desc: 1 X1 T0 D6 A% g: G0 H( Z
    //-----------------------------------------------------------------------------! j' F1 Q4 z( ^6 a$ w0 S
    void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    + @( s0 s6 T- M* {1 z. }  I$ J{
    7 f! _( m& ]. f( ?    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    ) w0 @' @1 p' L% w/ z- _- J                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    + t7 R( w8 S; E( S}</P># {5 F9 L6 y3 x9 f( P1 f1 W

    ! H: X% i% Y( r& E; m' t<>3 c9 b( Z0 X8 Y/ X
    //-----------------------------------------------------------------------------6 t  ~4 J( m8 A
    // Name: - e# R0 F! J% x' t
    // Desc:
    8 B$ i% B6 A, Q+ e& j- Q' T//-----------------------------------------------------------------------------
    4 _1 H9 w1 K1 L6 ivoid CMazeServer:ockCell( DWORD x, DWORD y )
    1 z2 I2 L. }' O4 c) h( A4 g{
    $ f. R" s5 X+ E, x# r    if( x == 0xffff )& z' i( z* H' K  k* }4 l8 P! }
            m_OffMapLock.Enter();
    7 }& B. ]0 [* A    else
    2 w% e- |9 p0 X. V$ I4 o, ^+ S) _        m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    7 ?0 p' M$ D1 ~+ Y! \}</P>; O: }1 V2 y. i. N' y# a# v
    ) l/ t9 `6 e% z% w7 g: u+ P; s
    <>
    3 k/ t' |, t- o0 ^, @; @//-----------------------------------------------------------------------------% X; a4 b) A+ u9 Y3 b  S4 v
    // Name:
    / k/ x( I0 c$ x" k1 p# m0 d3 ]6 B// Desc: 3 U" F1 [) h1 E$ ^% y7 k$ Q4 Y7 V4 n- b! s
    //-----------------------------------------------------------------------------
    ( c: b5 S9 E1 t# M  Bvoid CMazeServer::UnlockCell( DWORD x, DWORD y )
    ; F+ j) S% M/ M  ~9 I{( ~6 G+ F4 l( P
        if( x == 0xffff )
    6 R2 p1 I$ m* o        m_OffMapLock.Leave();
    2 {7 S2 C. m3 ^* A  @2 O    else
    6 Y0 B) |3 J8 m0 m9 v8 V        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    . M( _+ M9 i8 L* T4 I' K5 n. T}</P>. s4 Z2 B; Q) Z/ u+ `" g9 _4 J. Q

    - {0 Z8 j: @( T3 j0 u7 @7 \  y0 k! E<>
    # j5 ^: ?2 m8 l8 @2 j( }" d. k; E//-----------------------------------------------------------------------------
    2 z! V9 R4 a0 }// Name:
    ! M8 u+ b) [$ W1 b9 b3 U; |// Desc: # z5 ^3 a' ]( M' e( d- I
    //-----------------------------------------------------------------------------3 C. s  D6 s5 Q0 T
    void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )- s' M. b  l) a( q: D
    {$ ?1 @! S" q7 N1 E9 o" v/ O
        if( x1 == x2 &amp;&amp; y1 == y2 ); n% Z7 d% I0 Y4 a9 W7 u9 ^5 h
        {
    " G; M+ _% c9 g' K- o7 q        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )+ E: {5 l" L# _! i4 _9 n" G
                LockCell( x1, y1 );
    3 c7 ], h4 @& _# e6 E5 v        else, y4 t  H* U- J
                m_OffMapLock.Enter();</P>- w! Q6 {! a1 h$ f
    <>        return;
      S9 l& m- Y' V" q5 C1 V6 D* K    }</P>
    9 p0 F5 N( e  u<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    ) i( {: _# a& U/ Z    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    , I' P. y" e. U  ~0 ?. u! }    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    ' q3 I+ h5 n& r    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    . E: D( @7 ^  o- O, b4 M<>    if( x1 == 0xffff )
    # P7 q0 w- @9 {# B- \* C6 M1 d, y- l    {" J1 G1 k; S) Z( i( @6 s+ T
            m_OffMapLock.Enter();
    0 H* c9 f; i3 e1 a8 ?4 X3 y# a! M        m_LockGrid.LockCell(x2shift,y2shift);
    , n# n6 H/ F3 j    }1 b3 h& h9 d4 k. K4 _) A. l7 E
        else if( x2 == 0xffff )6 i2 l5 Z2 u# I3 i
        {3 H8 k  r! o7 `
            m_OffMapLock.Enter();
    0 u, f( |/ T  V- J% Q$ r+ Z' e        m_LockGrid.LockCell(x1shift,y1shift);
    3 `9 m0 i) ?+ I8 c' t    }
    8 E, q  V4 L$ `" L. \1 n  B    else
    , p% ^$ P% k: P, X8 I& T    {& v% _: m& y% _! @2 t& D2 j; s0 ^
            m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);1 w: l2 [; h7 n) O
        }6 P2 x2 _( {! b+ M5 D  G. u0 }
    }</P>9 ?3 M  L; [/ g

    4 z" C5 z( Z. ^: U2 h<>* R( k2 ?# n4 c+ @
    //-----------------------------------------------------------------------------+ K  T, J1 ]5 N) q# u% u, z4 C
    // Name:
    6 X9 N& I* g1 q2 }// Desc:
    $ Y( K; b* N& Y//-----------------------------------------------------------------------------
    ' t- W; \2 F) `3 ]% Wvoid CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    + Z) N6 M# w( R! D1 Y{) u3 e4 B! G: n. C6 K4 T
        if( x1 == x2 &amp;&amp; y1 == y2 )
    + n7 a# b/ N, K, t    {: S  e2 r# {$ `
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )' y4 O# ^# J9 E. t. w
                UnlockCell( x1, y1 );+ |" a% r+ a0 i9 r8 h$ E5 B
            else- {4 P. Z7 `+ e5 p8 Q
                m_OffMapLock.Leave();</P>
    3 b4 F) s5 g' Y# }  h<>        return;
    : w8 D& X. F0 K: A- V5 l3 A# m    }</P>1 K; g7 R* X5 @9 X! h0 b, l
    <P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;9 f% q2 ^- |) K% E
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;$ |& A& y  }7 P7 W6 u4 I
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    * m+ S6 o" U' E    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>$ r+ ?3 ^! a% M
    <P>    if( x1 == 0xffff )
    3 y* U: U- o9 K! b* o% d- h+ e2 s3 G    {
    1 [# Z! r2 C# `: O        m_LockGrid.UnlockCell(x2shift,y2shift);
    $ P5 G9 v+ S8 c! [* b        m_OffMapLock.Leave();
    ) s; H5 t; w. V! x% @$ a2 t" C& d% {    }- U' z$ e) y4 m9 [
        else if( x2 == 0xffff )
    7 [& B8 c/ y# ?$ H3 ^' @    {
    ) B3 Q4 ^0 n6 _: T( i$ k% _        m_LockGrid.UnlockCell(x1shift,y1shift);
    + E- P! v& b/ r/ n. F        m_OffMapLock.Leave();# h" S2 M9 N/ s9 f# ~& c
        }. p; [( W. ]  v$ q8 d
        else / k4 S) o5 \+ l
        {
    6 E2 t2 Q1 s" Q2 ^+ I! c        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);% @) J9 Q% l* T
        }. C5 E' X$ M0 _
    }</P>! m, ^) H: a. d! c) r3 W: d& B- k( ?

    : y8 g1 y8 E  z1 O& h<P>1 H7 p0 [' \' u& x
    //-----------------------------------------------------------------------------6 n: v3 E- @- x! Z: h
    // Name: # y- y/ x, k3 V  T  p
    // Desc: 2 d8 |4 u2 d7 Q' ^0 W. A
    //-----------------------------------------------------------------------------8 P% c. C" D, V4 i6 k2 ?! j
    void CMazeServer::OnAddConnection( DWORD id ); d" D. i% i+ D) l0 l
    {
    2 _" {' x8 A! @% l5 W    m_AddRemoveLock.Enter();</P>
    # q6 V. X# e* m3 m" u' r<P>    // Increment our count of players
      i$ X, K& p5 l- T! p    m_dwPlayerCount++;( k- l3 w9 I+ x& Y. x! h+ z8 O
        if( m_dwLogLevel &gt; 0 )
    ; X" Z8 E3 b& q4 [+ c    {' c+ q! G- c( m: k& \$ Z
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
      l$ v( v3 E( j3 U2 U$ r# T, v        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );9 t* d, B+ t' M0 p3 h
        }</P>
    ( i, S6 `9 N0 G+ q<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )! V2 ?2 d% {& m% Z0 E. L
            m_dwPeakPlayerCount = m_dwPlayerCount;</P>7 F2 ?( ~0 k. v
    <P>    // Create a player for this client1 U) _, |$ t" S) ^9 g) U
        PlayerData* pPlayerData = CreatePlayerData();0 {, Q" Y% |- N- z* n" L+ ?
        if( pPlayerData == NULL )+ V$ I' [2 e* ^& b+ }: i
        {
    - S& K" c9 _7 K' U3 B( c        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );, [* i. t  Q6 h4 n( [& X. o
            DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );' N" x3 q! R+ B  w) x0 ~8 M
            m_AddRemoveLock.Leave();! e8 k  S4 r4 b
            return;. j; [2 V: C$ ]
        }</P>
      O( [. c' m' ~/ `$ N4 m7 q$ V" v<P>    // Store that pointer as local player data
    & ^: n$ w7 @+ s$ O2 [8 o  {& {; o    SetPlayerDataForID( id, pPlayerData );</P>1 a1 q2 C1 m$ r
    <P>    // Grab net config into to send to client
    " F2 W% D5 W# J9 o$ n    m_ClientNetConfigLock.Enter();
    # u+ E# Y6 D8 H! F& L" c. U. |2 s    ServerConfigPacket packet( m_ClientNetConfig );
    8 p" I7 _; {8 c; E# J    m_ClientNetConfigLock.Leave();</P>
    7 d* P- C$ v5 V0 ^<P>    // Send it
    2 v! s3 M8 L6 N, |! Q. E/ r& T% O0 t" T    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>, Z( \! v' y: k) S# z" p( \; `2 E: h& ^
    <P>    m_AddRemoveLock.Leave();6 s3 i# k. Y/ r/ L9 h* y# K
    }</P>
    + m1 l, [9 l& Y7 U
    2 O/ f& E% N5 d" t9 z, k  `<P>, P# M6 ]$ S$ a
    //-----------------------------------------------------------------------------3 d& ~6 A- ]- G8 d. W
    // Name: ( H. l8 w" ^8 |
    // Desc:
    4 Z( Y6 o5 i; t9 U# S; o+ s3 y//-----------------------------------------------------------------------------
    * L6 _0 w" N, j5 l- [! Kvoid CMazeServer::OnRemoveConnection( DWORD id )$ x! u4 f$ |% ]& V
    {; j4 J. ?" P* M* ]
        m_AddRemoveLock.Enter();</P>
    4 f% [: Z9 m& B- {! q9 R. h<P>    // Decrement count of players6 `1 d# w6 M) O
        m_dwPlayerCount--;</P>+ y( w6 J; V5 J
    <P>    if( m_dwLogLevel &gt; 0 )( v* j! w2 E4 @
        {" k4 H: S: O' e3 l8 \& N' E5 V" h
            ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
    7 ^4 b- Y8 H0 H& y2 C$ `        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    9 l+ K6 G. w7 S  ]    }</P>- j, v: B9 M+ |# q$ P2 d- e) E
    <P>    // Find playerdata for this client! d. L: p3 b: G$ N* `  d
        PlayerData* pPlayerData = GetPlayerDataForID( id );
    * B- Q6 C1 R7 P. U) Q( s    if( pPlayerData != NULL )5 o2 F. Z, t* m9 d9 e; ~
        {
    6 O9 I9 B7 {9 X8 Z* f        // Destroy it
    5 Q' i. h& s* }7 I1 V* X        RemovePlayerDataID( pPlayerData );
    % @9 k2 J; [) C9 u' s        DestroyPlayerData( pPlayerData );4 D; F: {4 }  ^4 ^
        }</P>. A8 d  N5 E4 |3 }' K
    <P>    m_AddRemoveLock.Leave();  M& a$ g- g. D! V- j
    }</P>
    - _4 d5 C& |% F' L7 `
    # L5 Q- d. c7 [5 B8 E2 H<P>
    ; l& D+ e  ^( r//-----------------------------------------------------------------------------1 c/ C* I& K3 z: [
    // Name: , u8 y! u. T6 b& _$ k
    // Desc:
    . R* u: z0 j# }& I/ Q//-----------------------------------------------------------------------------
    1 M% |4 N- x8 b' ]5 U: ]% E; |HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )
    ; z' w# J/ x& y6 b8 }{
    ( T6 E+ s+ _# S7 s5 ~  Q    BOOL fFoundSize = FALSE;</P>
    % o& l+ Q+ T1 K' s<P>    // Increment the number of thread we have in this process.5 u5 m" C) h% V% l$ M" V. ^8 ?
        m_csThreadCountLock.Enter();</P>- u* O; i7 J, p5 g' o7 @
    <P>    //Get the start time of when we entered the message handler.
    7 R) I) Z/ i$ I( a' A2 y8 t, j% [6 R5 i    FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
    8 S" S8 [6 `, N* m9 o/ P8 _& f! `7 u. I<P>    m_wActiveThreadCount++;
      s/ q$ ^% _. J9 c) h1 U. d    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)2 R: _* T0 e0 L4 b! }" a- m
            m_wMaxThreadCount = m_wActiveThreadCount;2 c& b( n5 I& k2 Z  U, e1 m2 F
       
    . r2 K7 A* y" O. l* p* N8 p* a" J    // Calculate and average.1 |3 R3 _& L2 Z7 o4 B- L% v
        FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
      z+ q8 n  q' t1 S: @- @    m_fAvgThreadCount += fdiff/32;
    6 m9 L' u; ?: k0 s( ?    " d, i( p' E5 e+ [% y
        m_csThreadCountLock.Leave();</P>
    7 R7 z# B, |; |$ W2 H: J. ]<P>
    # X7 b* \$ q5 K# `    ClientPacket* pClientPack = (ClientPacket*)pData;
    ' y+ Z( T' l+ a; |6 V, W    switch( pClientPack-&gt;wType )8 I, x- ^( l" ?9 e/ K9 K8 ^
        {
    . g" p/ l4 u8 r) d, K        case PACKETTYPE_CLIENT_POS:: d& T. T* m; G9 H0 u# \3 P, n
                
    , x( u, u. ^" f( K$ O            // Check to see if the packet has a valid size. Including 6 B" N( O" X+ T# G) R
                // the custom pack size.5 x- t% x1 t- @0 X8 d
                if( size &lt; sizeof(ClientPosPacket))
    4 c0 C! g, R! [! E$ W6 y                fFoundSize = FALSE;
    0 A# H- I6 m: k9 Y- X" z            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))
    % i( M( \0 T" k                fFoundSize = FALSE;) m$ r9 Y( O$ X' Y0 s+ |
                else
    7 [, r, w# b& q6 l) a7 R                fFoundSize = TRUE;</P>
    2 ~' o7 v7 q5 }, `  N- R<P>            // If valid sized packet, handle the position.6 @9 j; v: _0 m2 f; H3 P+ U
                if(fFoundSize)- F" E, `% D! n1 F5 \. Q  S
                    HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );
    7 x7 G( t4 F2 u: l4 t            else
    * N& w* Y0 D6 @  X; z! O2 {                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>3 k& E; |8 j. b; f4 \- q3 w
    <P>            break;</P>9 s5 r9 y+ _: i5 t: r- C
    <P>        case PACKETTYPE_CLIENT_VERSION:' _3 n, N: m( }9 j3 s8 A+ l
                if( size == sizeof(ClientVersionPacket) )
    " C) s/ A7 z1 l6 x5 h                HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );
    4 R5 s# B; m+ `4 u$ [            else  j) E/ ^$ H( z% @: {
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    % N+ {9 ^- M9 m            break;</P>
    ; \! u" P# |  L- W$ ?1 d( Z6 l<P>        case PACKETTYPE_SERVER_CONFIG:</P>5 Z8 I: ]1 n" ]0 v3 i, r
    <P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>: V, W8 G( f* b
    <P>            break;% v6 b, ^& B/ ]( @! ]4 q  B
            default:
    2 j0 u3 x3 f3 `& K7 A            HandleUnknownPacket( dwFrom, pClientPack, size );
    2 Y0 l  I" D/ X, t. D# i* F' S3 U            break;! Y; O% W9 q: k% V% N% k
        }</P>
    + p+ H4 d0 x( \  g0 `<P>    //If the user wants to hold the thread, Sleep for given amount of time./ d) ]/ j" G& U, P
        if ( m_dwServerThreadWait &gt; 0 )2 A/ Q5 P0 e- s: F$ }0 M
        {
    . r' F  z' j* e! u% O$ R- I        Sleep( m_dwServerThreadWait );$ N, R7 Q: x, z9 P
        }
    / }1 I2 H& K) a" E! o   
    , J7 v3 g+ L. D8 |    // Retrieve thread data for this process.& A5 u3 a( B' o. N/ `* M
        m_csThreadCountLock.Enter();</P>7 T0 S& M2 r& N$ r# B' c
    <P>    m_wActiveThreadCount--;</P>6 o2 H% a5 B) Z4 F! V0 D
    <P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
    & b4 u' @, z! t4 E6 v' p    m_fAvgThreadTime += fDiffTime/32;</P># t7 _" |" {: m* {
    <P>    //Get the Max time in the thread." q/ d9 T+ |5 V7 f  Q6 k
        if ( fDiffTime &gt; m_fMaxThreadTime )" ~, l$ L0 o# F% Y
        {* M# Y1 w; f7 j$ ^! V4 W2 P2 t
            m_fMaxThreadTime = fDiffTime;
    2 a: _3 ~" c6 W3 z4 y, v    }</P>
    5 T2 C5 ?3 `6 V# y<P>    m_csThreadCountLock.Leave();</P>: e! ]& X% s) _" {
    <P>    return S_OK;
    0 O3 \  {! j( r}</P>4 b: T6 U( U; _. a5 T$ T

    9 F( v3 v3 e4 \% Y<P>//-----------------------------------------------------------------------------
    5 S( @. P" r" A, s0 }// Name: 0 a$ W; @( h. ^8 j* d2 u
    // Desc: ; ?. D0 T3 M; B3 ~9 w
    //-----------------------------------------------------------------------------' [0 G. j& L# F8 n- J
    BOOL CMazeServer::IsValidPackSize( DWORD dwSize )# Q% w3 y, k3 G2 K- y8 W
    {1 r/ t4 A+ k/ h% w& C5 H. d
        BOOL fFoundSize = FALSE;0 L6 o3 d0 _1 T, L
        BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;
    1 L/ G, c. i9 ~* B. X( n$ u   
      A/ g! j- p+ S9 u  y. g    // Check through the array of valid pack sizes.& r  ]: ~. c, N$ z
        if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])8 Z) y: ?6 X* g. S$ t) b
        {3 R# e; Y0 o( m% P8 [3 d
            for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)
    ) J9 Q# R5 b1 s9 J8 x0 z        {
    / X8 w* {( n; A% t            if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    , y5 W# K1 b* L; I            {
    " N/ }3 m/ w9 a  f& b* S3 @                // Found valid size in the array.: w# H8 |. f3 F3 X" ?& j
                    fFoundSize = TRUE;. V3 E; ~' _3 A6 j1 D8 R7 X
                    break;  g8 L5 L! |: b6 V! Y9 _9 U
                }5 {/ n4 D  V% |, G$ u) D, p
                if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.1 c9 h2 D% I0 z7 P. T
            }
    1 ?$ P0 Z/ q! l' j# ^4 v    }5 V. n' o: P9 g5 F  ^
        else
    - X" @* g' M2 j% T  @: K" L% |    {' Y5 ~* H( G. s, E3 \& Y) x
            fFoundSize = TRUE;
    5 D9 v0 {- Z2 |0 R4 S8 D. Z0 g    }</P>0 i' c0 c( ^, i" k: C
    <P>    return fFoundSize;
    5 z# f/ t/ k% ^6 f2 B( T4 K+ s}</P>) S& S/ E, r: N" }2 A- f9 a' z8 G
    <P>
    ' x- N& Y9 Y( @/ W* C//-----------------------------------------------------------------------------4 b: }& L3 Q) W6 Q$ j
    // Name:
    % ~; f( _; I  o8 I( U// Desc: % u- V( ?# q) Z( Q
    //-----------------------------------------------------------------------------3 r0 J- C3 E  ?- d- \7 M* w
    void CMazeServer::OnSessionLost( DWORD dwReason )
    4 F/ d+ A: S: y! Q{' o8 _  f7 ?0 ?7 n# X( D- G7 s* P
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );! \& J  S( B1 e+ Y8 N/ F
    }</P>, s2 V! ^# J: V/ M

    5 Z# v% \4 i0 r, C" T' p& k<P>
    & {! e* Y. o9 Q: V//-----------------------------------------------------------------------------
    , d% \$ ]- b2 G& l/ C/ H// Name:
    7 q6 |, {; \- n4 Y// Desc: : ^8 U! O* e$ Y9 G
    //-----------------------------------------------------------------------------' k; q  f+ q# `" N; z1 X
    PlayerData* CMazeServer::CreatePlayerData()
    ; p- b' K2 q: b5 p$ w{; E1 r8 A5 h$ ^! Y; @, y2 F! \  ^
        m_PlayerDataListLock.Enter();</P>1 `2 S4 l, o5 E
    <P>    // Grab first free player in the list
    8 l$ r3 F* r, ^# T' p- o    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>5 c# s1 i; @: m9 P& `+ D* d
    <P>    if( pPlayerData )! G* V& M" `$ h) _  ~5 J2 I
        {
    * r3 K: u5 D2 d3 r) A/ |        LockPlayerData( pPlayerData );</P>5 Z3 G4 C+ i! j5 L" M- R5 L
    <P>        // Got one, so remove it from the free list. [; s1 R* V5 U/ o; A" [; t$ e
            if( pPlayerData-&gt;pPrevious ). T  U, J4 b4 S) g
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;  I* A: \/ v) G4 |1 k
            if( pPlayerData-&gt;pNext )' [; T% Z2 |$ g. m' O2 d# o9 o
                pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
    ' D) y3 Q/ i* s  ~, v        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>; D. b) J7 r3 E( c' H6 k  F& G
    <P>        // Add it to the active list
    $ I# X- m  b$ H1 ]        if( m_pFirstActivePlayerData )
    & R: v. V# X  A+ ^7 y1 H            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
    ) z: a' P. v' c9 k0 h        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;
    3 V( E7 {! E: [9 y5 g" F5 S' o        pPlayerData-&gt;pPrevious = NULL;  V' T9 O# _  _3 A% h
            m_pFirstActivePlayerData = pPlayerData;</P>, G$ T+ M) O$ w- Y
    <P>        // Update count of players* x2 Y9 C2 D- _9 U
            m_dwActivePlayerDataCount++;</P>
    ) H! s& J; U  y<P>        // Generate the ID for this player  O0 O( }. @& q! |2 k- A& S6 z
            m_dwPlayerDataUniqueValue++;
    1 y$ x$ M1 U# ^! @6 i* @        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
    4 q" s' f' E) ]  w8 r$ T<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
    6 }' e3 `7 Y" S4 Z+ A& C. `. [        pPlayerData-&gt;NetID = 0;
      x; w0 c* r; P2 x: M2 i        pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>
    . G7 i6 G9 |# b0 u. B<P>        // Insert into the "off-map" cell
    # F9 t6 _- I. }' ~+ ^0 w        pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;
    4 E1 z; A2 z4 \" h; S7 s$ A# ?$ n" I" _        pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;' q; s1 L0 p  w4 Q
            m_OffMapLock.Enter();3 H  f; D6 I( h/ `; }
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;  _2 I1 ?" Q4 D7 J
            m_OffMapCell.pFirstPlayerData = pPlayerData;
    5 W& \1 C* R7 p' ^/ L% J% p7 a        m_OffMapLock.Leave();</P>
    # C4 k; T# R+ M5 z+ V<P>        // Mark as active
    ; M9 n5 |- P: x: E        pPlayerData-&gt;bActive = TRUE;</P>
    6 F8 x: ^9 L# }/ i4 E9 s<P>        UnlockPlayerData( pPlayerData );
    1 o8 q2 i* C& `! X% Y: I    }</P>7 i* k; ]' @3 e+ A
    <P>    m_PlayerDataListLock.Leave();</P>1 ?( J8 l3 c) N9 h! Y! V* s
    <P>    return pPlayerData;
    , B# S/ p+ T6 }% }8 I7 I/ D}</P>* u4 Q$ n; W2 \) N; S
    ! N  D  D' W/ U9 x
    <P>. V7 T* a: _1 _; R  R
    //-----------------------------------------------------------------------------
      _! B7 u1 c4 K4 Z/ B6 z  @// Name:
    , O2 x" N# u0 r+ Y. P, q// Desc:
    : o$ ]# \. @, [' [" F# P: K//-----------------------------------------------------------------------------
    / h! F2 q0 U6 H1 }# {( q! ]& Dvoid CMazeServer:estroyPlayerData( PlayerData* pPlayerData )
    4 _2 I8 ?( g0 Y9 l  Z/ e{
    , ]6 }; J2 a/ g+ T5 R    m_PlayerDataListLock.Enter();, W! y% K( V. O+ H6 T5 a4 t
        LockPlayerData( pPlayerData );</P>$ g. [- z! L6 b" y$ D; g0 C
    <P>    // Remove the player from its cell
    " b7 i8 O  t; O- J* Y' J    RemovePlayerDataFromCell( pPlayerData );</P>! L7 ?  Z# m1 Z! J4 c( ^
    <P>    // Mark as inactive
    ; i% F, _2 g' N) {    pPlayerData-&gt;bActive = FALSE;</P>
    ; E  ?: O; w4 @8 \<P>    // Remove player from active list
    + U% j' E7 @% i! S& j* t    if( pPlayerData-&gt;pPrevious )- X7 b. |' n( M$ G9 Y- C) A
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;5 [3 ]' L+ V8 ?( F3 ]& R
        if( pPlayerData-&gt;pNext ), \0 Y1 S, S" p- v
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>
      T  i) M, W  O: L0 K<P>    if( m_pFirstActivePlayerData == pPlayerData )
    3 q4 t9 X8 [* Z, \" |        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>! _' @5 k# |4 x
    <P>    // Add it to the free list5 _% r8 q7 d* w
        if( m_pFirstFreePlayerData )
    " O7 P7 t+ V( C* M! P        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;3 S; O( p8 }; t; ]2 e4 n8 \
        pPlayerData-&gt;pNext = m_pFirstFreePlayerData;
    7 R. y1 U0 |  x    pPlayerData-&gt;pPrevious = NULL;
    " L4 a6 e' f6 B    m_pFirstFreePlayerData = pPlayerData;</P>4 v( y3 H- [$ R) y) Q
    <P>    // Update count of players& }  C$ w' w. \% p9 Y/ L
        m_dwActivePlayerDataCount--;</P>
    2 W, O. P& W/ g& I0 [<P>    UnlockPlayerData( pPlayerData );! J: G+ ?2 s. c. R( \: V$ u2 Y. G
        m_PlayerDataListLock.Leave();  l* I. M# ]) t) i$ A2 A2 `8 B
    }</P>
    + H1 v; b9 I# q7 T  x; o
    0 p$ {0 ], K* t! u2 }<P>
    & Z) q: \8 }9 \, p" x//-----------------------------------------------------------------------------
    * a  j* ]" f8 l$ f5 D; i// Name:
    2 Y* j, I$ V1 [// Desc:
    ; x) g% d6 I  T' ?; K* \1 u//-----------------------------------------------------------------------------6 f. p6 a5 a1 V7 @5 c* Z  {9 u" O
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )" h2 F3 T, e' H" R( y
    {
    2 E( |% a+ H" x* M" ^; M5 h/ `    // Lock the player
    $ S# W4 f. G3 `4 Q7 F6 ?4 d    LockPlayerData( pPlayerData );</P>" D. i( w+ l  \( e( Z4 e$ k6 {
    <P>    // Lock the cell the player is in! s3 S( O3 I& p& B5 k; Y. @- K# L
        ServerCell* pCell;2 U2 x1 i1 R  Q  j, K$ m4 `. o5 {
        if( pPlayerData-&gt;wCellX == 0xffff )
    : n2 b4 m/ p$ a4 g4 Q1 r( v    {
    0 E* G, M/ s$ F        m_OffMapLock.Enter();
    * K! t2 r$ r/ u; L        pCell = &amp;m_OffMapCell;
    ' G% l  {4 `/ S- _: u1 t3 _    }6 F! C. m& G% y/ U1 S6 A" A
        else
    ) N* k% ]# c) |0 ^/ I: C* }/ D    {; N; s0 `  L/ O; ]" V7 X& U
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );
    6 f$ G- J( E3 `" d. ?        pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];! g: T: p5 i* H4 y
        }</P>6 p0 ^! ~. _' |" R" ]
    <P>    // Remove it from the cell
    3 |/ [5 i  j) ^3 B8 Y6 u2 p: h    PlayerData* pPt = pCell-&gt;pFirstPlayerData;) M7 ~1 i6 Z; Y0 F  c1 |
        PlayerData* pPrev = NULL;7 m* q9 s- w9 ]2 E; ~
        while ( pPt )
    3 a! o$ D8 M% U) [3 c2 ?    {+ n; v% u1 s' f  [, p& t: \
            if( pPt == pPlayerData ); |& L& l9 ?5 z; i4 Z' P
            {
    8 j( Q/ z. \% P5 z  Q+ x4 y3 _+ {7 b            if( pPrev )
    & }$ \& |$ I  {, V, O, R6 ~% X/ q6 o                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    ' l& x; ^  h- G+ n' M; w* v  t8 W            else* f4 R, h; j5 Z
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>, d4 a8 `- C* a' ]
    <P>            pPlayerData-&gt;pNextInCell = NULL;6 x6 x" h; A7 S! q3 K$ C* z8 @
                break;
    ' ~' j, s' ^) h& ^        }
    / i3 ~! O! q5 _9 J! X- {0 ~4 l        pPrev = pPt;0 q# P9 E" C/ @8 C; {
            pPt = pPt-&gt;pNextInCell;* j' x5 Q$ y" X+ z
        }</P>
    ) c" t7 @, Y: {+ G% x7 u' z+ u<P>    // Unlock the cell
    ' N/ Z# O; X6 A9 ?" Z4 {+ w    if( pPlayerData-&gt;wCellX == 0xffff )
    : j' W$ c) W5 `6 h9 ?: Q, J        m_OffMapLock.Leave();
    7 Z- i' a9 z' c3 t) N4 E% Y" R    else. K/ c  B  J5 W1 V5 G3 T
            UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>
    8 m; M; p# f2 f# _( ?<P>    // Unlock the player
    6 D5 n8 l9 G7 S8 e( t    UnlockPlayerData( pPlayerData );* w' R% c' w# o* q2 H4 d
    }</P>
    ) z1 ^' l! K9 r, H/ r' w$ @- Y7 Q4 T9 s
    <P>
    & }: ]; ]4 R# Y//-----------------------------------------------------------------------------
    4 {# K3 J5 W% E6 j/ z// Name:
    4 f7 V7 N( Q: C// Desc: $ b; N. o0 y6 d# s4 f; X7 V
    //-----------------------------------------------------------------------------" `) e6 i. ~( b& y
    void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )* J8 h) @; q# i3 S
    {+ h' E( G: R* Y$ W
        ServerCell* pCell = GetCell( pPlayerData );
    - [  C% s* Q- I+ N8 }+ H- S    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
    8 b- y% R' K3 {+ a$ v' C0 ^: \9 m6 c    PlayerData* pPrev = NULL;
    0 k' E+ B8 O1 j1 r( p    while ( pPt )
    / ]( V' p) R& ]( K# ~+ V& }    {
    3 G% r- `% ^1 m- n# E# |2 S        if( pPt == pPlayerData )# n- j0 D6 y2 G4 s" ?% ]( |0 l. b
            {
    ! u1 ?  ~; W, q. t            if( pPrev )
    , J0 \# p7 S9 T2 H                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    % h6 T" o; h1 P8 {6 }            else
    % ?5 H$ Q% f) l- x                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;
    # z' L5 q. t  R: i            pPlayerData-&gt;pNextInCell = NULL;3 _* M6 Z, S  H
                break;
      ~1 @6 E; m9 ]( G! d        }- v, E* ?0 \6 i1 F4 T1 n0 C& Z
            pPrev = pPt;
    - Z% K) H% _0 c        pPt = pPt-&gt;pNextInCell;' C* h# W8 B: ?. [  l; T4 T, Y8 d
        }
    0 P' y% P0 K, J/ _}</P>
    1 N' U# j; ]0 e
    5 h7 h. @. i  v* S<P>
    6 P( s! ^+ m( q9 f9 T7 d5 `# D$ [: O//-----------------------------------------------------------------------------) T4 M- t7 Y- c" q& C5 x7 P
    // Name: / o" V2 W; _) S) O1 u" V
    // Desc: 6 s/ E/ |2 n) S
    //-----------------------------------------------------------------------------
    + P, N! W" M! u5 S# {void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )& U7 x" ~- Z( E, z
    {& }( f- V4 b# t0 o  b
        ServerCell* pCell   = GetCell( pPlayerData );
    ; ]  |8 `3 z2 D* Y    pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;9 ~# ]0 _2 _* Y& T+ {+ f
        pCell-&gt;pFirstPlayerData = pPlayerData;
      H( ]  P4 g2 U}</P>+ w( I; [+ b7 g2 t; P
    ! K! e9 G$ M/ u' A
    <P>4 c2 f1 p* o' B  S1 [
    //-----------------------------------------------------------------------------
    # j+ C6 W# B0 s6 `6 ^9 S8 Y// Name:
    0 B8 y& T5 u/ @& J// Desc: / G) A% b9 f8 y( o1 y+ P0 O# a# k
    //-----------------------------------------------------------------------------% i6 j% D; _$ E4 ^" N
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )) t2 V1 I9 c3 p! V' Q1 t
    {
    : f* o7 X7 x5 p: K& l3 Q    // Grab player for this client and lock it1 ]5 P0 [5 |0 A- y' C5 r
        PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );
    5 A/ m( D  U4 G0 ~7 T% G    if( pFromPlayer == NULL )6 {3 S3 Z+ Z5 F5 S5 t# ^; X" o
        {
    ; H, ]. E" p, Q6 O% i. z$ c        if( m_dwLogLevel &gt; 1 )
    2 Z0 Y5 P- t( f7 c1 l. i; u0 c            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );' X; }( H) P; A9 B% X
            return;
    ! q4 n) V: Q5 G/ N8 ?- s/ U- J    }</P>8 M2 Y1 W5 b/ l4 v) C& i
    <P>    LockPlayerData( pFromPlayer );</P>
      t' A4 Y% ]  ?6 G# P% U2 x- s<P>    if( FALSE == pFromPlayer-&gt;bAllow )
    0 T8 C# U" ?( K& L' K* U; v0 u" @    {: ?* ~- {, k" r6 ?0 [3 h- \
            if( m_dwLogLevel &gt; 0 )$ b  V  G) b. f
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>- ]7 \, m' }; v% W9 ]
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );  M: r" r+ o( v) Y. L5 z
            UnlockPlayerData( pFromPlayer );
    1 C  R5 Q( \6 H        return;" v2 Y+ L0 X4 a4 Z4 f
        }</P>: S3 a) j+ x# l0 r- [3 P2 c! A
    <P>    // Compute the cell the player should be in now& E; S5 v9 R: D; p1 c; f! t: c
        DWORD newcellx = int(pClientPosPack-&gt;fX);
    + a- C6 ~1 F$ m8 L8 X5 }$ x' N    DWORD newcelly = int(pClientPosPack-&gt;fY);0 `& t& P5 {1 {% ?# u% Z
        DWORD oldcellx = pFromPlayer-&gt;wCellX;
    ) m' t% e% {) V6 z    DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>; B8 Q. j1 j: W
    <P>    // Have we moved cell?
    3 J6 X+ |5 s+ B. Q9 @1 r0 {8 J8 B9 q: w    if( newcellx != oldcellx || newcelly != oldcelly )
    1 {8 c5 L, e$ f5 I: I    {; g+ B. c. g. M
            // Yes, so lock the pair of cells in question: B1 ]0 }0 {$ i: B5 J( B# `( y
            LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
    " g5 o8 ^5 ^/ A+ e/ y" C7 E; K<P>        // Remove from old cell and add to new cell, R/ ~2 k; `6 E
            UnsafeRemovePlayerDataFromCell( pFromPlayer );
    0 J' R7 q+ {; W        pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);# }& p0 \6 q" K
            UnsafeAddPlayerDataToCell( pFromPlayer );</P>; b# t8 Y- p$ r0 O# M
    <P>        // Unlock cells1 P6 d( k$ ?8 d4 g- P: j) U
            UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );/ g0 T( ]) H6 z% O7 T1 v  v7 {
        }</P>
    6 K( a2 y1 E9 ^3 R: Z" i* a<P>    // Update player position, ?& g( z$ j+ _
        pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;. n, Q2 ?- W3 s" U* O( C, F
        pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    * U1 {  R% t: R5 ^8 N7 _: Q    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
    7 k# c1 w. a# z& n9 ]<P>    // Allocate space to build the reply packet, and fill in header ; G+ V% K3 q$ K
        DWORD dwAllocSize;
    2 X4 Q, K, N) l+ x+ U) E    ServerAckPacket* pSvrAckPack = NULL;</P>
    % `0 V" w: ?! v! P  P<P>    // Begin by allocating a buffer sized according to1 u) d' J6 U6 H) v  f# q, V
        // the current number of nearby players + 4.  This will give 0 D" C/ S$ x& y
        // a little room for more players to come 'near' without resize( k3 c% E/ h- i. H7 y
        // the buffer." u! N* i3 W1 {/ a$ X1 ~* Y9 v
        DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>
    9 v- W% ?/ H! [, N; E- S<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    6 u$ y( Q- T# \* d/ ^    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );! S! F9 E2 P; W4 A
        if( NULL == pSvrAckPack )
    7 n% H2 Z( M! X9 l1 x    {
    : O6 @# B' @8 m! ]/ ]  N        // Out of mem.  Cleanup and return
    % o2 x; H8 K, F/ S6 H8 P1 b% z: m        UnlockPlayerData( pFromPlayer );2 S9 v. N$ \4 _4 W( n( g& H
            return;      
    / o/ S$ w1 L( [$ K  X+ a    }
    ; W: x9 x; Z7 k1 J    ZeroMemory( pSvrAckPack, dwAllocSize );</P>
    ( t; v6 c& V# R' q$ o<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);
    , G1 i6 T* v  N3 v: @& k9 i8 M1 `    pSvrAckPack-&gt;wPlayerStatePacketCount = 0;
    ( Z$ a7 j  A7 i* M2 D. @' o    PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>
    4 T  @1 d( C8 |9 m7 l<P>    // Compute range of cells we're going to scan for players to send" X1 f6 x; A: t# @
        DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;  _* y0 i3 e: g; [; p; X9 U
        DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
    ) c/ @; B! |. \    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;+ c$ V" ^% n% k1 K0 y
        DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>- W/ W, f4 X2 x2 i0 d# A
    <P>    // Lock that range of cells( ]5 {1 K& Z( u$ A, U6 Z
        LockRange( minx, miny, maxx, maxy );</P>" p, ~# l# C* T9 ]6 a; b: r0 p
    <P>    // Scan through the cells, tagging player data onto the end of' H7 K) M) R! [+ x' c7 X$ b5 i/ F
        // our pSvrAckPacket until we run out of room2 h0 ~* T3 F  h; t, @+ n9 h- s
        for( DWORD y = miny; y &lt;= maxy; y++ )
    * x2 ~1 v' C/ H    {5 @* n/ v* u  r7 h- ~' C
            for( DWORD x = minx; x &lt;= maxx; x++ )
    " G% W8 u* g# h5 w" p1 g        {
    $ S! \( \2 [6 [, n            PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;& j4 e; H+ D! s
                while ( pCurPlayerData )
    9 p3 L" W: Q. D. @. {6 y            {) f3 E+ i& p7 d# N) H
                    if( pCurPlayerData != pFromPlayer ). h  ^2 ~6 P0 Z, A& ?3 t* R0 d
                    {2 n; s, Q9 W% G- Y& Z
                        if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )
    - F; j5 V: y$ q$ L, N                    {
    : ^& F5 K4 }: L3 @                        // Make sure pChunk is where we think it is, g) [4 W4 ]% v3 y7 m
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>
    7 [5 K: R! v. c: f: Z: s. Y8 b; T<P>                        // There are more than just 4 new nearby players, so resize the 0 U. c# s( Y% @, F
                            // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
      B( j2 f; R* U7 `- J1 F                        dwMaxPlayerStatePackets += 16;; K5 ?! }! n8 `6 J" `% Z! h
                            dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);) R/ G+ `' W7 ?/ g# ^2 B1 o8 B
                            ServerAckPacket* pNewSvrAckPack = NULL;1 R+ p+ B# o/ g* ?' K
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    ( h! f6 ]  z# W& r                        if( NULL == pNewSvrAckPack )
      [1 E! a& e7 B$ h8 m/ a                        {
    6 O/ J( v" Z) v* i* V) B                            // Out of mem.  Cleanup and return
    : R. \& ]. B, \9 T8 n* x4 Y                            free( pSvrAckPack );
    & l3 G, W* j# I6 L* ?. X& M+ v                            UnlockRange( minx, miny, maxx, maxy );" @5 L1 B- K1 r3 V% R$ _4 T5 m
                                UnlockPlayerData( pFromPlayer );, k0 p; c7 i! s- M  m8 v8 D: k4 Q2 O
                                return;       + E' j1 d3 y; o: _3 V" g- G! V% B
                            }</P>/ V$ H- n6 Q) a6 b. X
    <P>                        pSvrAckPack = pNewSvrAckPack;
    : b( }1 g6 G# @9 R% _9 ~                        pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>8 t9 W7 a. I: z3 x9 o' |3 u$ y$ a
    <P>                        // Make sure pChunk is still where its supposed to be* P9 B; G! m  a/ e' x4 o! z! Z) [
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );; W4 K; ?2 N% e4 D
                        }</P># `) P8 W! ]$ S' y& P: `: ]
    <P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;
    & `% z5 c8 n- G                    pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;& B) T- n/ O! {3 s, ?
                        pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;: B' T" F/ ?6 v" d& y) c) K$ Z0 ~: |
                        pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;' w: N' g  e1 g+ K
                        pChunk++;% r, W1 {* O+ P( @% U1 j
                        pSvrAckPack-&gt;wPlayerStatePacketCount++;7 q) b, q( K4 {" @  B7 n
                    }' n/ p# P7 I3 t% C! i( M- y7 _3 ?- _
                    pCurPlayerData = pCurPlayerData-&gt;pNextInCell;
    $ m3 ~7 A1 x/ D9 i$ z6 S            }
    ' ]% c# S, S9 Q* D$ u0 ~2 ?        }
    ) W" o6 G2 z: y2 _    }</P>/ p, D: B1 m; D1 i& y& c( Z) |7 k
    <P>    // Update the dwNumNearbyPlayers for this player
      {. J; C0 N* H% S- I& V; @    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>
    $ T5 r  m  L9 s3 j6 m# p4 m, K<P>    // Unlock range of cells
    8 D7 U1 G. m3 a    UnlockRange( minx, miny, maxx, maxy );</P>9 `, r  j0 a2 X3 t) G; G
    <P>    if( m_dwLogLevel &gt; 2 )1 f* ~7 b3 H5 C' K9 @' ^
        {
    + |6 E5 e) e# r; T1 Z8 i        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );' @  e9 ?, T$ J. Q2 I  `3 k3 t! r$ ?
        }
    - M! b, X, ]& `6 _7 i- N$ z    else if( m_dwLogLevel == 2 )8 n0 T) |% x( x) h8 V" k  C) n0 f
        {
      }$ J) v6 Z( }9 z* `6 h7 h        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );& s' t& G+ Q! @5 q( T+ C
            if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f ); C: b/ }& i3 ]+ T
            {
    0 Y" U0 a+ Y+ [* @            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );+ I2 q7 _" r) z8 C) i$ N
                pFromPlayer-&gt;fLastDisplayTime = fTime;
    . }) I* c' D6 i+ ~1 C" F! |        }
    # ~% Q* \. I2 A$ w    }</P>
      B  [' [. C8 N) Z' V" G& |6 f  M7 @<P>    // Unlock the playerdata7 s4 v$ O) g6 o! p) a
        UnlockPlayerData( pFromPlayer );</P>
    ) o& V( Y  }. H. _" e+ ]! H<P>    // Send acknowledgement back to client, including list of nearby players
    - S+ G6 R* e- e$ ?    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));. Z, h, r- I4 \; q2 w; z0 Q) W

    7 `2 q' F9 D# n1 E) H1 [9 X    // Pack the buffer with dummy data.
    + s; N8 ?* Q+ H) ^4 A    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)" D$ L( @: Y% O. w: _4 F* H  w
        {+ @  i  \2 g- f% K4 b8 @( U
            DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];
    , \. g+ h% |5 n- M( }& x        VOID*   pTempBuffer = 0;</P>6 K$ s* [: f% R# R
    <P>        pTempBuffer = malloc(dwBufferSize);
    ! {4 h* A+ N+ o$ a4 u4 \        if( NULL == pTempBuffer )
    * {. l; g! j! s( Q) N% u        {' A5 o4 j, o3 v8 v) @& F
                //Out of memory* S/ w7 K6 U2 g- r$ U
                DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );% I/ [. p% l0 l4 N
                free( pSvrAckPack );: a9 i0 o' k# O4 Y, ?$ _; z, t$ I
                return;
    & c- L  l, m8 Z& E5 _3 K% e& ^        }</P>1 q  D+ m) D4 s) E9 L) Z$ \, L
    <P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');2 T9 `1 C0 G4 L# d! S& T5 Q
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>  D& i1 A1 T& H3 m7 Y, w
    <P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );
    7 _& o( h: ?) `+ h    9 D6 A8 j! t0 y# m7 ~  Y5 ]
            free(pTempBuffer);1 l* m* }) T* m# G$ g+ L
        }   / [8 N% J& W/ o4 a
        else3 v; f  X8 f7 Z+ _0 [
        {7 ]& p, q' o( s; m9 [
            SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );
    , J: P* T9 c" D1 b, m6 a    }</P>; X0 c' [8 U7 {; f
    <P>    free( pSvrAckPack );</P>/ e0 @, {! Z5 m. b
    <P>}</P>. y( I+ `2 K9 N: s' u% j9 D
    9 L$ ?1 k% I7 I3 \% C; u
    <P>
    ! ]# Y- ~* _5 U" h//-----------------------------------------------------------------------------9 u, g2 d' x- A, I$ `# j
    // Name: $ z) }# D/ b/ k. ]; G
    // Desc: & p) N% A# q1 P1 |
    //-----------------------------------------------------------------------------: q( t" ^' ^& h* m; m1 X
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
    1 |4 h4 W  O5 U7 N5 W. A{
    3 C# V( x) \# O) T    // Grab playerdata for this client and lock it2 e$ [+ h7 w0 r! w. \
        PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );9 O7 x+ I- U1 P9 \7 N- f3 [
        if( pPlayerData == NULL )) w) U2 N) o6 G+ K% S4 s8 \
            return;
    2 O; Z1 G6 _8 L1 E1 a$ T    LockPlayerData( pPlayerData );</P>; q+ t! U, a, E' D3 [. @+ d
    <P>    // Record the version number # T( F" O4 a: j, ~$ G  X; v
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>9 ^$ P3 D/ Z) V1 J' B
    <P>    if( m_bLocalLoopback )
    ' j  g( `6 j% I, P( I$ X  ~5 r6 x        pPlayerData-&gt;bAllow = TRUE;
    ) k8 i0 v  o/ }0 M    else
    ( f9 p! j: x% E( U        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>3 `( t5 x. K9 m/ ]
    <P>    if( m_dwLogLevel &gt; 0 )
    1 @) e4 \% E0 d0 j$ n3 W        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Client version=%d (%s)"), pPlayerData-&gt;NetID, pPlayerData-&gt;dwVersion, pPlayerData-&gt;bAllow ? TEXT("Accepted") : TEXT("Rejected") );</P>
    + a0 B3 R7 P8 Y! }, x& q0 E& X<P>    if( FALSE == pPlayerData-&gt;bAllow )
    * I8 ^  R  k0 J9 `    {
    0 D3 v/ i+ l7 }; Z# }) V( N/ }        if( m_dwLogLevel &gt; 0 )/ b; U! {! v4 j% j9 X' E
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>
    & g" Z; i6 v  l<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );: K1 b7 O0 Z, l3 t; B
            UnlockPlayerData( pPlayerData );% J* d/ ?+ N& O9 a# ^1 X* n' J! h
            return;
    * Z9 B+ z( s  I& k6 k) y5 F    }</P>2 W' }9 g8 U: z. Y
    <P>    // Unlock the playerdata5 w. F  u% @! A% f
        UnlockPlayerData( pPlayerData );</P>1 F$ Q. d; s7 a0 ]$ k
    <P>    // Send acknowledgement to client that the client was either accepted or rejected
    ) E( }% g& q1 \1 \! c    ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );: B; w. @9 t4 x8 o" r' b
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
    + R1 U4 z, e( p7 D7 P. |! R}</P>- t9 _% }( v$ u& d3 N2 P: Y- ]
    2 D  [9 i. c1 P& V
    <P>5 h& U2 J% m0 J$ A
    //-----------------------------------------------------------------------------' N# B$ q) u  W+ _- `
    // Name:
    ' i) V/ Y# ]! Z3 t, k- |9 s// Desc:
    , B# f0 w' v: r//-----------------------------------------------------------------------------1 T, U4 `$ q: j6 k
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )4 L$ J0 A; q5 f9 B
    {
    4 B* K+ ~* a, x+ e    switch( dwClientVersion )3 C0 a* ~. G% t2 F1 K
        {
    & G+ {; G& t- q        case 107: // only v107 is supported
    5 h* I/ C! [- }9 r3 ?7 A            return TRUE;" T+ _! S- b  D, n2 Q9 Z
            default:7 p6 {/ F( E: R; p) `, c
                return FALSE;9 h% u- f8 Z" J8 N: u  {, @7 _0 q
        }
    ) I( u3 c" e" S3 J5 m# R9 V# w}</P>. u: W6 h4 S" v

    : R7 n0 t  |( e8 N6 D5 u2 B. s( K& ^<P>
    ) Z4 T  H& x$ P- F2 m//-----------------------------------------------------------------------------
      s3 J6 A+ n9 [. d( E2 P// Name: 7 c, H# u" A4 s+ T8 W1 G
    // Desc:
    ' N" a; j- w% `" R. f; c//-----------------------------------------------------------------------------
      H+ O& X3 }2 _2 lvoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
    + y; u% J+ ]( d{
    - Q; ]6 q, _5 a: A& h: Q    if( m_dwLogLevel &gt; 1 )7 @' h9 S* Y; z, v% x. Z' _
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>. Z3 d" f3 U: \+ _! F& ]' s% }
    <P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    $ p) h  `+ ?3 E  B. y# E3 q}</P>
    : i6 a  ?. l" ~  s/ U6 H& ?% z" H( F! I% A9 v5 Y  F
    <P>
    , X- b& o, k0 ^8 o# x  ^7 u# j. d, M//-----------------------------------------------------------------------------
    7 R) W# f' x1 s) O) b: ~// Name:
    9 x& K8 `9 o: d# T/ `. V; z// Desc:
    5 y) k, N6 f4 O3 v- x+ k! _2 b//-----------------------------------------------------------------------------
    ' L8 J/ }& q, X. M9 WDWORD   CMazeServer::IDHash( DWORD id )
    5 Y" a0 B; y# E{
    5 V. P7 D3 n8 ~; G    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);
    4 f  r0 F3 r" e    return hash;
    # k& O; I) c2 v* W! [4 J# Y}</P>+ D- \6 L! \) r( e% a* K

    " J$ O  Q" k- j8 b7 m$ B<P>5 D/ c: C$ ~- |: i! H+ @
    //-----------------------------------------------------------------------------
    & o9 Q. [+ g# e// Name:
      L& U, J! ~) W% p2 L( w1 s// Desc:
    . m1 k/ O2 u" \* Y2 i( ]! i//-----------------------------------------------------------------------------' G# v7 ?8 m% _: l" y) k
    void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData ): o9 A2 \$ X; B1 K3 U$ t, S
    {+ J+ U: {8 r7 F# m) \5 h) M
        // Hash the ID to a bucket number' L$ A, X$ p: b! e  Q' U: b: ^
        DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>" R( z/ n: N/ z& f8 e
    <P>    // Lock that hash bucket
    , r0 `/ u5 C9 W: ~  W8 h    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    ' T! t: c4 w$ }/ _1 M    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P># f  G7 c( m& ^( B& s4 A" o
    <P>    // Loop though players in bucket until we find the right one" k  o  \9 i1 x% `- L- u  p+ x5 [% p
        PlayerData* pPt = m_pstIDHashBucket[bucket];* ?  L, ?3 W3 L& {% }
        PlayerData* pPrev = NULL;' q8 ?6 @4 B. ]0 C' B# j$ B9 f& F( H9 h
        while( pPt )/ ?2 c! r5 Z0 q8 }  D
        {
    1 c/ A2 s' a3 J8 y0 e, Q        if( pPt == pPlayerData )
    , @% }/ Z( L# p) Z            break;
    4 R6 S, P9 Y% h        pPrev = pPt;3 v% n+ T: X% _2 @: B7 i0 ]' k/ U( @
            pPt = pPt-&gt;pNextInIDHashBucket;$ z5 M" m! o2 }! w4 z: Y+ R
        }</P>
    9 P9 l* L0 J/ X3 u' N" ^8 ~<P>    if( pPt )# o) L7 _! x/ M1 }1 p# V
        {, d2 }+ {9 w# b! I: H4 k2 x
            if( pPrev )
    / h: L3 j( _; ~, U  N! f. ^            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;# Y& L1 s  c) Y0 ]
            else7 {& N2 T* d, ?5 u
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;, J! y" W# F) [) Q0 F4 ], K
            pPt-&gt;pNextInIDHashBucket = NULL;; L- H! d( ~3 S' R
        }</P># f( k/ V0 s% T7 }! _9 B9 b9 q
    <P>    // Unlock the hash bucket2 @' I8 A1 H4 a) c) g
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();5 J1 K' Y) r, B+ L& U0 b
    }</P>
    9 d# _& f9 s/ w3 i( |" g4 c- W( G
    <P>3 W, j- s4 B- C3 f, u$ B
    //-----------------------------------------------------------------------------: j1 p1 i7 C/ a9 O( o* |
    // Name:
    ; L/ y, W2 n8 O8 A% L, `+ W// Desc:
    $ r' D! w6 Q" D, }" m% H2 `//-----------------------------------------------------------------------------
    : k3 B5 t$ y# q7 Xvoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )& Z7 Q; {/ @  E. g' v4 G9 r! f9 O
    {7 A5 c% {8 y9 ]3 \$ D
        // Make sure this player isn't added twice to the m_pstIDHashBucket[]6 O7 o9 P7 c+ d, |
        // otherwise there will be a circular reference
    2 P) f+ D9 S, _/ ^1 A: P0 c, F    PlayerData* pSearch = GetPlayerDataForID( id );
    : r  H0 Z4 s# K; J# y. i$ n    if( pSearch != NULL )
    + r4 r3 z% m* c6 y        return;</P>: N& D& a. @1 ^" }, p
    <P>    // Hash the ID to a bucket number. x% U9 \+ e! ?2 P2 f0 O
        DWORD   bucket = IDHash( id );</P>
    + I  r7 \# j1 W" X. ^<P>    // Lock that hash bucket
    " L# r8 G6 H7 q    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    . [5 T( [. _5 q! g    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>7 @6 U: V$ ^; [& z; D
    <P>    // Add player onto hash bucket chain& P6 e3 e. ?; \
        pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];& j- u1 i5 B4 [
        m_pstIDHashBucket[bucket] = pPlayerData;</P>
    5 u6 p- w$ B/ Y) f& q) ]# n<P>    // Store net id in player
    ( p5 s7 E3 O9 ~: x& c. c- j6 ?' ~    pPlayerData-&gt;NetID = id;</P>
    7 \. s0 l( M8 v' ^. {<P>    // Unlock the hash bucket6 I) m: b" I9 |+ f: D. i
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    # n: @- p2 m" g  h9 F}</P>0 `1 Y9 t1 G! }' h* k6 R3 Q% [, g8 @
    ( X, |. m4 Q. p: }  K5 o( w
    <P>6 r9 }1 _- d" E# A) R. r1 a
    //-----------------------------------------------------------------------------
    - z" ?0 B" K  b; i3 u// Name: 0 t$ I( M; u, v8 W
    // Desc:
    8 x5 E" w( v* C  B7 Y, {//-----------------------------------------------------------------------------& I4 q$ [  Y( _' X" }
    PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )# b- X$ l, e1 [* g: `
    {
      R$ h5 e$ {1 R2 s    // Hash the ID to a bucket number
    + R, n8 z1 g* Z4 T    DWORD   bucket = IDHash( id );</P>2 Z9 ~' r$ s! W3 O+ }6 Z: m/ C
    <P>    // Lock that hash bucket1 I1 d; i& v, |$ {
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    0 V; g8 _1 L  V    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>- H7 a0 w! r3 S3 e9 Q
    <P>    // Loop though players in bucket until we find the right one
    $ X6 @5 W* L  `* H* x    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    * M) q# C( X% G- J    while ( pPlayerData )
    . x" Y* \' J4 U* v, N$ y5 X) A    {7 p0 m. d" I$ U+ z: j
            if( pPlayerData-&gt;NetID == id )* z, r9 D/ m# I, c( W
                break;
    / x% t  k; P6 ~3 c* Y+ b        pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;6 r$ G7 A3 _+ p. i1 H* B) X
        }</P>1 B6 ]+ k# q3 f
    <P>    // Unlock the hash bucket
    0 B2 y9 ~. k$ j7 t    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>
    4 ~- z% |. l6 j+ ?* h( \- K<P>    // Return the player we found (will be NULL if we couldn't find it)  b  _% n" U: R$ Z; Q3 W& X
        return pPlayerData;- V* P+ f4 M) N! X) N/ P
    }</P>
    $ h2 f' H- d2 T  m% Z% \$ |# c
      Z1 b2 V% ]3 o1 n. G) Z<P>
    2 _2 F; |! B' b4 r' _% I//-----------------------------------------------------------------------------
    2 n3 S  ]0 w4 G# g! s" Z# \// Name:
    " \; n9 T0 H9 H// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner
      V7 E" n' E" e6 K6 k//-----------------------------------------------------------------------------
    9 S( O# g7 E: p  s" O. |void CMazeServer:isplayNextConnectionInfo()
    $ o& Q' {+ X; G" X{( b" z# C$ ~6 @+ D' Q
        if( m_pNet )+ U; q, O& w! ]) w( s8 e
        {
    1 A; F7 v! l1 ~9 O        // Find the player that was displayed the longest time ago, and display it.
    0 w5 W7 ~! k  M, ]/ @1 ^5 ~9 w5 w        FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
    6 |: I6 Q" [" o/ C9 ?        PlayerData* pOldestPlayerData = NULL;
    ! ~8 G: ~! C) p0 d6 g4 P" l5 e        FLOAT fOldestTime = 0.0f;</P>$ h" O2 C3 `2 S5 w3 a) B5 ^
    <P>        m_PlayerDataListLock.Enter();</P>$ ]/ f7 A' I, J1 w
    <P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
    4 I6 E6 L+ |  b9 X        while ( pPlayerData )
    " h+ b' I, E( Y) L        {* z4 H( W$ D) D$ F0 h. O
                if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
    # _. D( B( {, h1 e) Y            {1 o  q; K0 ~: t  M& z
                    fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;
    7 [' Q# P, M/ O. z& `; |8 {. b8 ?+ J' P  H                pOldestPlayerData = pPlayerData;
    , G- F3 @2 x* M/ V4 U) ]( e) R            }</P>
    5 a! Q4 K7 l9 N<P>            pPlayerData = pPlayerData-&gt;pNext;
    ' C5 Z, H0 r2 \4 G; k" J& o8 Q* W- i        }</P>  Q. q) r" O+ q7 @
    <P>        // Display the player with the oldest CI field, and update its CI field.
    3 [: P8 t7 ^" F* I6 R        if( pOldestPlayerData )$ `) L& \: y/ l3 G. y) X
            {, z  N! ?6 l8 K" |9 N/ O. o
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );) z7 c0 f6 j: U* S6 g7 T
                DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );: e7 O/ E# I4 O
                pOldestPlayerData-&gt;fLastCITime = fCurTime;7 A# V$ ]/ n) M% f" M
            }
    : l0 M. n6 u# |, ~        else5 M7 m4 X' j( V5 n) N
            {
      |, E8 K. I) R, N2 ^            ConsolePrintf( SLINE_LOG, TEXT("No players found") );. Z, ?% o) z" k& k3 J. v
            }</P>, A0 r& f8 ^( b' K+ B1 ?
    <P>        m_PlayerDataListLock.Leave();
    ; X: B( w6 t- t" I2 a. ^    }- C% O7 [$ W6 g7 [& T  u3 D2 z( |
    }</P>
    9 N9 }2 T; ]. L" q* j; f/ d( l8 \; [0 v3 N1 d2 G3 f0 a
    <P>
    ' E) s' u7 m* N9 A" G' W% T//-----------------------------------------------------------------------------  d" k* ], ]# T* g
    // Name:
    - x) P& m& I; M5 M% m9 p2 F// Desc:
    7 `* Y* `, D/ L' z  |+ c. E//-----------------------------------------------------------------------------, N0 w. G) _) S2 v* I/ }
    void CMazeServer:rintStats()  ]. S& F* o( j+ o
    {% j9 d; b, x0 p# r4 k, Y
        ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
    ( k/ ?" o6 q) {# F& D                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );* g4 U1 F% ?" a- y) W
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
    8 J/ }& K$ R( J. `                                    m_fAvgThreadTime, m_fMaxThreadTime );, X: f7 t9 g. ^4 R2 f  k
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
    / f) I) [+ ?8 L7 O# d2 T    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );5 o) H3 ]" b# I% X
    }</P>6 U1 f" I$ W: J; Q
    2 p  U- i$ k, F8 a. S
    <P>+ J* q9 V8 a/ M
    //-----------------------------------------------------------------------------, o$ U, W! c3 g& c
    // Name:
    7 |8 w1 j: l: Y// Desc: 0 p* Q! T5 v" \( y; Z; _
    //-----------------------------------------------------------------------------( h/ ^+ C2 N0 Z1 s& O
    void CMazeServer:isplayConnectionInfo( DWORD dwID )0 b& h" o6 ?5 Z2 K
    {" o& ?9 _9 ]; K% H( r* |6 N* J" P
        TCHAR strInfo[5000];
    ; G) t+ I* G/ M    TCHAR* strEndOfLine;3 \/ k7 v5 [1 u/ k$ b% D
        TCHAR* strStartOfLine;</P>
    7 e5 ~3 v3 t! G, \<P>    // Query the IOutboudNet for info about the connection to this user8 k7 x4 l. x$ E
        m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>
    1 f+ }* r. I  X' f4 A2 R9 S<P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );. g( i' G* ~1 [2 E
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
      m7 u! X( N+ |+ `" ^' {<P>    // Display each line seperately7 h' N! R) L! S: K
        strStartOfLine = strInfo;
    3 A  g- y; l$ {0 |' W8 d; Z) N# G    while( TRUE )) O0 {3 m% _9 E. n# n6 I6 G  p- G
        {
    ; G# |  v2 T0 E& a/ R1 U        strEndOfLine = _tcschr( strStartOfLine, '\n' );9 v7 V% y% `  G: _$ G5 J0 K
            if( strEndOfLine == NULL )( c' I9 {. C2 v' x
                break;</P># W! o; C* m' p. ~. b! F; p
    <P>        *strEndOfLine = 0;7 W, X7 v+ f* ]* B; v+ I) Q5 z
            ConsolePrintf( SLINE_LOG, strStartOfLine );
    ! g  A' T* p* }% o5 [' Z/ S        strStartOfLine = strEndOfLine + 1;
    % {, c  A1 k0 C    }; }" L' [& o- m. m0 W1 P/ n
    }</P>' \$ i( h8 T) H; X+ X# V
    3 t. M* }$ _% c* d
    <P>/ ?& p! l* R" R% P& e
    //-----------------------------------------------------------------------------
    7 |+ Y) K/ l5 B// Name:
    6 H% D, [- R* b, ?  O! M; {( ~// Desc:
    5 I  K! [5 B: T% J//-----------------------------------------------------------------------------
    ) n. P. m, G* i" ]# k5 T: w4 `3 ZHRESULT CMazeServer::SendPacket( DWORD to, void* pData, 7 Z" z5 y. e: Y2 V
                                     DWORD size, BOOL reliable, DWORD dwTimeout )
    - E% h% z& l& L/ x0 d: y+ K{4 h+ z. y+ g/ }) ]1 k# K8 [
        // Chance of forcing any packet to be delivered reliably( Q, A+ G) U0 E
        if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )9 z9 z# i( [- u: `( z
            reliable = TRUE;</P>: J8 @  C/ _* G% A3 R  ^) R
    <P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );* K- b8 C  R( Z0 d* Q, b% t- K8 v" }
    }</P>
    # K2 N, N: s8 K- w) _# `
    7 x5 Q5 B$ F+ d# h7 c<P>
    8 W1 k. G+ S$ k//-----------------------------------------------------------------------------) P; ?" \8 _, l9 O6 D, ^
    // Name:
    5 Y% A1 [& s8 m# i) P// Desc: 5 t/ ?0 z0 v- \# T, p& O
    //-----------------------------------------------------------------------------
    $ z% g+ T8 U3 i, M6 e8 E4 w4 V; V" wvoid CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )
    2 F$ s; n# ?; \. ]( F2 V& W{
    ! x( [: y! t0 c8 @9 z* k, i    // If we're up and running, then send this new information to all clients+ ~$ Y( |/ _- I
        if( m_pNet )
    5 s2 u+ S+ H6 |( |' L, Z9 O* C    {1 ~% s" |* L7 R5 y" ]  M
            //Use the AllPlayers ID1 B4 ]3 a' f0 ^! V6 Q! M% ]7 O
            SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );' Z( N- R3 s% j
        }
    ' K  [' m) }# w' [; ]}</P>* ]4 O* D3 X2 Q; N2 F9 j( b( _
    4 O: a$ s( R$ @1 x
    <P>4 F% G7 h' W7 j8 d
    //-----------------------------------------------------------------------------
    " x1 z4 T# f. |. [+ Y+ d. D7 I$ }& r// Name: ) }; y( G! ]% S  O
    // Desc:
    % Q' {& ~6 a" c# W  n( t//------------------------------------------------------------------------------ ~4 b  b; M; g% D; V
    void CMazeServer::SetClientReliableRate( DWORD percent )
    6 T. @: ?/ t$ x" u1 R# k8 W{, e' V# x5 e4 d1 i* k/ C
        // Update client config, and build packet containing that data
    $ w( y2 w. s! r1 G    m_ClientNetConfigLock.Enter();9 S% Z$ R) O4 V# X. f8 I/ }" a5 Q+ D
        m_ClientNetConfig.ubReliableRate = BYTE(percent);
    5 }3 V4 z7 o& B0 ?    ServerConfigPacket packet( m_ClientNetConfig );: V# j# c( d: m2 s8 D
        m_ClientNetConfigLock.Leave();</P>
    ) w6 }1 P$ D) L4 ~( z6 j  p<P>    SendConfigPacketToAll( &amp;packet );
    # I$ P( r3 Y0 g6 m* R' k. J: Y}</P>- x% V* T9 m& L' v: \
    & H5 c6 _! {0 R2 j3 W
    <P>: k) z9 G. x5 L
    //-----------------------------------------------------------------------------
    : ^3 ^5 K; L: X/ D2 P. ?  m// Name: 4 m( [( P$ [4 G1 t) ^& @
    // Desc:
    9 J; }8 d4 p. A0 u% Q8 M% l//-----------------------------------------------------------------------------
    - L( h4 m9 g6 Wvoid CMazeServer::SetClientUpdateRate( DWORD rate )! S5 G1 x2 ^0 N6 n- z
    {! s" j$ x2 s1 P, l) |
        // Update client config, and build packet containing that data/ ], w. J# j& T8 U
        m_ClientNetConfigLock.Enter();
    ( ^- H& g% {& {$ Y    m_ClientNetConfig.wUpdateRate = WORD(rate);
    & O9 U8 z! m% W1 _7 O    ServerConfigPacket  packet( m_ClientNetConfig );1 A+ ]) [! F8 ]  t8 W
        m_ClientNetConfigLock.Leave();</P>
    ; a" C9 U# M4 [+ p5 O, Q9 n<P>    SendConfigPacketToAll( &amp;packet );
      Y2 c9 T+ q% H! p. J4 l0 _}</P>$ g/ y% |; q' |# x% H
    # M6 [4 g9 X+ ~7 `3 M
    <P>+ H. O8 d/ i, u
    //-----------------------------------------------------------------------------
    # r! [: M3 m3 g: T// Name: 7 R/ h& ?, N$ L/ m; C$ S
    // Desc: * [- [$ a- q, g& v
    //-----------------------------------------------------------------------------+ N& l; u9 l2 s: w4 k, ^7 o
    void CMazeServer::SetClientTimeout( DWORD timeout )* C" Z) L6 c/ B* r1 \
    {
    7 W8 m' F3 w+ }    // Update client config, and build packet containing that data5 t# P' X6 K- ~0 A1 h0 `; `
        m_ClientNetConfigLock.Enter();
    6 V/ X6 Z/ O3 \4 L4 D. w7 L/ t    m_ClientNetConfig.wTimeout = WORD(timeout);% S/ N9 [; u/ z5 r  |& u% d# x
        ServerConfigPacket  packet( m_ClientNetConfig );
    # V' o/ B6 J7 R3 F( e/ W    m_ClientNetConfigLock.Leave();</P>
    8 Q. H4 u2 b' a# s+ {$ `<P>    SendConfigPacketToAll( &amp;packet );" v. q# V* L( I- m1 j2 U
    }</P>
    - V1 g/ k) {. u0 n# G, ]5 c0 W" ?% E8 Y" y; T
    <P>- O; l3 L. F8 N' Y. t; r+ I7 c
    //-----------------------------------------------------------------------------8 C$ b2 _8 e# W
    // Name:
    4 f( U) D/ N6 [% l& y/ s// Desc: . @6 l9 [/ h4 [- Y# S/ {8 p$ P) ]
    //-----------------------------------------------------------------------------
    ' k7 `0 r- J! [' R) E9 |# {8 Dvoid CMazeServer::SetClientPackSize( DWORD size )' |6 f: t9 k# K0 _' F
    {0 m6 i- w) d/ b( J/ H2 x9 @
        // Update client config, and build packet containing that data6 u  [3 w3 u! Q+ m, q# ~$ B
        m_ClientNetConfigLock.Enter();9 M7 e- q/ M+ Y* S9 T
        8 A: D8 k5 R3 a. C9 a5 D1 D
        m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.; e3 [. ]2 P- A5 T1 j. g
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   7 L- n* X9 r6 Z: I
            m_ClientNetConfig.ubClientPackIndex = 0;</P>0 O" L5 q8 o' a: J. _
    <P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);
    * m6 D: y  M. w1 T    ServerConfigPacket packet( m_ClientNetConfig );- H( Y0 i! T5 ^' }7 F1 h
        m_ClientNetConfigLock.Leave();</P>5 u# E& S9 P- b. O5 A
    <P>    SendConfigPacketToAll( &amp;packet );
    ) X0 o6 }3 s- O+ \& A+ E}</P>
    " B6 r  `+ d- |/ I* }
    ( @+ X# ~8 Z8 g<P>7 w, }0 F  n* Z9 w
    //-----------------------------------------------------------------------------4 `( n, @+ b* N9 V( u7 w: ^. h
    // Name:
    ( Q0 r- t, r8 H3 L- _/ G// Desc:
    ( d8 D" ~- u+ G$ |3 r) q! ?' l1 h//-----------------------------------------------------------------------------
    6 w1 n2 x% c) x9 B/ K" rvoid CMazeServer::SetServerPackSize( DWORD size )! J  [) P; X- W: R( b6 C2 n
    {
    2 G+ _! F: W! h. T6 s. w) f    // Update client config, and build packet containing that data# a8 P3 q: b4 g* B) C' m; e2 r/ Y
        m_ClientNetConfigLock.Enter();7 H' R; ]. @& ?- j
        7 T5 h. }2 v& H7 |: V
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.( |. p' |  T0 M
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   
    , y; X5 I( D$ g        m_ClientNetConfig.ubServerPackIndex = 0;</P>
    , d: w: Q; ], P; y: C<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);- [4 t! P: k5 f) l/ c9 |
        ServerConfigPacket packet( m_ClientNetConfig );
    # ?: b" d5 K3 E  c% \5 A8 }    m_ClientNetConfigLock.Leave();</P>5 X2 A$ S( U2 ?; }/ Q. X; D
    <P>    SendConfigPacketToAll( &amp;packet );
    5 ^/ w1 Q* E$ q}</P>
    4 @! ]; A& B* n' z2 Q<P>
    " o* z' y+ u  R" }4 R//-----------------------------------------------------------------------------
    / q% ]/ A) n# L6 U! H" M- p// Name: : }5 _/ k5 P7 D. Z1 e. w
    // Desc: # [  C7 j7 l, W6 F
    //-----------------------------------------------------------------------------
    : o6 P+ t: ~8 d% x! |/ o* [: ivoid CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
    / Y: }* V5 r( x. Z/ p' a{
    7 j# x4 w- j8 v    // Update client config, and build packet containing that data
    0 J7 R2 g3 v9 T    m_ClientNetConfigLock.Enter();
    2 z! J- Q2 {  q9 r, g& g: W" J   
    0 B% S2 S; P$ D9 ~. f/ N    m_ClientNetConfig.dwThreadWait = dwThreadWait;8 l) z  I+ R# F3 T! v" j( `
        ServerConfigPacket packet( m_ClientNetConfig );4 i, @" ?0 ~, m! Y" u; ^/ B) N
        m_ClientNetConfigLock.Leave();</P>
    , ?) b% n: `. y, h# P<P>    SendConfigPacketToAll( &amp;packet );
    # x1 F  B# M8 u* S$ g" W9 z}</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-8-9 01:38 , Processed in 0.594920 second(s), 51 queries .

    回顶部