QQ登录

只需要一步,快速开始

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

[分享]MazeServer源码示例

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

1万

主题

49

听众

2万

积分

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

    [LV.10]以坛为家III

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

    群组万里江山

    群组sas讨论小组

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

    群组C 语言讨论组

    群组Matlab讨论组

    跳转到指定楼层
    1#
    发表于 2005-1-31 11:52 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    <DIV class=HtmlCode>
    8 ]2 A+ s. t( m6 G8 r; V+ }<>// File: mazeserver.cpp
    * W5 S" G" e% a( x. W5 A//
    7 P5 D1 R# N) D2 j+ h! \1 F// Desc: see main.cpp: [# E" @1 N2 A4 h6 P  M0 U
    //
    " B. i; {3 e; z! E/ M, G// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.5 X3 `+ X* W5 n4 w/ B- x0 H
    //-----------------------------------------------------------------------------) E$ x( |# q9 F& G  h
    #define STRICT
    & M1 _* s  _! ]1 G+ w6 @4 U' ?#define D3D_OVERLOADS
    ; K! @' r' i- _6 k#include &lt;windows.h&gt;
    . ~- w  t! f4 e  [3 t0 F#include &lt;d3dx.h&gt;* F$ u/ H+ i) n" D2 I
    #include &lt;stdio.h&gt;0 c( E) q- v3 L
    #include &lt;math.h&gt;
    3 a0 G9 H# m" ]+ C1 C8 n3 `#include &lt;mmsystem.h&gt;
    6 G9 y. V  p- Y#include &lt;dplay8.h&gt;+ d9 k3 e% b$ I# r9 @& q' F/ }7 [
    #include &lt;dpaddr.h&gt;& G4 I: k1 |" F$ O0 j
    #include &lt;dxerr8.h&gt;
    * Z$ x/ A$ b2 g#include "DXUtil.h"
    9 s$ k; B& r' ~+ f#include "MazeServer.h"$ P. l% g* s6 ]# N& Q* S8 T
    #include "ackets.h"+ E2 w: W$ L" K" P1 r5 b5 ]
    #include "Maze.h"
    5 L4 v7 W7 v  h- L#include &lt;malloc.h&gt;5 t, i0 Y; A/ g! f5 \% ]
    #include &lt;tchar.h&gt;</P>6 R. h: H: b  [& A) \5 W
    8 h8 Z) k6 A( d, Y* d
    <>//-----------------------------------------------------------------------------
    ) l& j8 f2 g, \// Name: : C3 N- n1 N& ^4 _9 o
    // Desc:
    ! Z$ V9 @7 N" \* D% E//-----------------------------------------------------------------------------
    1 {: @( ]& t. U3 Y! m, y, YCMazeServer::CMazeServer()' X2 O9 }. v( E( o( J% m4 g3 T" ]# m
    {: b* d# [7 A% O0 Q" E6 d
        m_dwPlayerCount         = 0;: K1 U' W3 L  Q5 |6 L
       
    1 Z$ }7 \% H/ o7 z: }    m_wActiveThreadCount   = 0;" c* y/ ?! Q* y; I8 h+ ~
        m_wMaxThreadCount      = 0;
    $ _4 f7 _9 h9 J7 U    m_fAvgThreadCount      = 0;1 y$ S! B/ Y/ I% i' Q- l3 ]
        m_fAvgThreadTime       = 0;, S/ ^+ E  s& R/ @" {
        m_fMaxThreadTime       = 0;</P>6 S1 D* v$ s& P
    <>    m_dwServerReliableRate  = 15;* ?+ k: Z/ \% k/ `1 I9 K; j
        m_dwServerTimeout       = 150;
    : X- \6 h8 W+ |. _& P" s    m_dwLogLevel            = 2;
    6 H: ]& o9 `  `( \# u- J0 x    m_pMaze                 = NULL;</P>; Y" N) ~6 X, D7 w* u/ @8 @
    <>    m_ClientNetConfig.ubReliableRate = 15;  M7 D: @  M8 `/ K  n/ u
        m_ClientNetConfig.wUpdateRate    = 150;
    ) }# g5 {3 J& f% U" @- m    m_ClientNetConfig.wTimeout       = 150;</P>
    - n% i: g; \) b, g& u4 ]# R- Q<>    m_ClientNetConfig.dwThreadWait = 0;</P>
    3 ~" C1 m1 M  v- ^- x/ H<>    m_ClientNetConfig.ubClientPackIndex = 0;' H0 L6 ~& ^: q& i9 R8 ^
        m_ClientNetConfig.ubServerPackIndex = 0;7 I3 j" P3 x, B! C% P1 E
        for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)
      d. \) \/ M- |9 K, y3 p: B    {% `, k8 v- X+ }& ~7 [
            m_ClientNetConfig.wClientPackSizeArray[x] = 0;0 N6 Q' h5 Z1 e3 _/ x6 O% I/ ~/ }% y/ U
            m_ClientNetConfig.wServerPackSizeArray[x] = 0;6 e  ], @1 a4 P1 }
        }
    , \! h( a8 M' [# j: s}</P>
      M2 A4 i3 A7 M# F. c. k% C+ F' i5 Y* E: j! p  v
    <>
    : q3 s! c) b, V9 w# A0 G, ]//-----------------------------------------------------------------------------
      a1 ]1 P( ?) }// Name:
    * q7 F5 W3 u7 D- l// Desc:   k1 |7 h7 M0 m7 ]" b- R
    //-----------------------------------------------------------------------------1 P7 P3 _# N3 C1 X
    HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )8 e3 _  i0 g, p1 A( o; s& ?
    {
    : l6 X# f& d) ?1 d2 x( D    m_bLocalLoopback = bLocalLoopback;7 L- r/ ~8 w# t% _0 I# _# ^
        m_pMaze = pMaze;
    : B8 J7 {/ P# D8 W/ C4 v8 b    if( m_pMaze == NULL )2 }4 u, i2 w1 R  a( E
            return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P># C2 l" y% v! j; h1 v
    <>    // Grab height and width of maze- y1 g' R$ {! u9 M/ J
        m_dwWidth = m_pMaze-&gt;GetWidth();
    6 [; A; X2 W8 D0 n$ o. @/ R    m_dwHeight = m_pMaze-&gt;GetHeight();</P>" R4 T' n3 u- R' |( W$ j$ f
    <>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;& q+ ?% M, B8 M8 g+ X6 z- n
        m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>9 R% G/ r; c: }9 f! x
    <>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.
    : U( Q' g( Z6 e! I% ]    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    3 E$ o' W* Z& i" n/ j0 \' w* X) H3 h        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    6 H2 Y4 i! Q/ O' P5 e    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )
    5 h- P. B1 v" w, `        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>2 f* J* E$ L: G
    <>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;5 g3 C* h  p7 r! T" ~1 J
        m_dwMazeXShift = 0;8 h' Z8 m* o1 g' y( M2 D. i1 P5 w
        while ( (scale &gt;&gt;= 1) )
    # k4 ^  L. n: H6 t        m_dwMazeXShift++;</P>9 @. m6 Y3 u" F
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;
    - J. g) h( t8 ^* G: c; O    m_dwMazeYShift = 0;
      a+ ?/ O/ N# _8 V: c! J3 E2 R    while ( (scale &gt;&gt;= 1) ). a; r2 W. Z2 z& Z) k0 D
            m_dwMazeYShift++;</P>+ ?) C  K3 P0 j3 F
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    - z. C' r" l& n% H2 P4 ~        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )
    5 o7 C( ]$ C% Z# W6 e9 v: z2 ^3 u        return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>
    1 Y& }) F. V9 d( a: `<>    // Initialise the player list
    & J2 W+ p& s1 ^. J+ b  y# A1 z% Z    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );4 i. I5 U# X. H4 C3 N- ^) L
        m_pFirstActivePlayerData = NULL;6 i# `0 M% _+ V
        m_pFirstFreePlayerData = m_PlayerDatas;
    5 d" r0 ^9 L. k% }" [8 G4 {7 P1 l/ P    for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ ); u; a3 w* T- R, M. c6 u, o
        {0 e8 S" u1 u2 G. b! e0 [
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];
    - Z+ Z' N3 [9 H6 d        m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
    & ?& Y" d. W. b1 V3 J& C/ b6 ~; }6 R    }</P>, E% Z! y+ A, D4 U' F
    <>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];! b$ S8 y" q' O' i- ^; i. L
        m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];
    7 T# H8 b+ Z  q( F: R    m_dwActivePlayerDataCount = 0;
    5 U8 ?. v) ^' M# j    m_dwPlayerDataUniqueValue = 0;</P>& T  L1 G; ~/ q5 @& J( i
    <>    // Initialise the cells& i5 u! e- q  U
        ZeroMemory( m_Cells, sizeof(m_Cells) );& b  ^* @# b0 e! w& }5 U1 o* n
        ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>7 r" M( T0 v) @! m
    <>    return S_OK;
    # k; h( _! W: {* n% A}</P>$ p- O7 T% b! b( m+ ]& ~

    % j" l3 x, ]5 w' Z<>
    9 `( q: }" t/ ^+ k//-----------------------------------------------------------------------------6 ]- ^. @' }, c2 ^
    // Name:
    . I1 D6 D% x  T  u3 U  C// Desc:
    8 c5 @' L! D% X$ G7 j4 R//-----------------------------------------------------------------------------
    # t% P9 g$ [( A) q/ R. \8 n+ gvoid CMazeServer::Shutdown()
    ) K1 W& N& z- c) N8 f1 U{' M8 Q" @- S6 ?
    }</P>, Q% }( t2 s8 X' e2 h# b; U

    3 E7 f; |' ?- ~/ |<>
    , b- N; k9 G8 U; y' Q4 |5 Z//-----------------------------------------------------------------------------) O2 r9 G) W+ ~! T% S$ K
    // Name:
    1 _) Z, d; e1 |/ a6 Z# s8 @2 V7 a// Desc: ) e# W5 j* V6 O1 q2 v
    //-----------------------------------------------------------------------------
    ( ~! d8 d8 I- ^void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    , M* a2 {4 l; P7 a{* r' B. ^& g, E+ O2 }5 o; l
        m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,4 n6 h) |! W8 R" e1 ~* g! q8 s- f
                              x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    ; V2 m, p/ {! e3 X0 L}</P>
    2 j' F, u  N6 O+ k8 ^2 V% X! [  \7 W( Y1 H! ]
    <>
    & a: C& s1 w4 Q& o$ Z//-----------------------------------------------------------------------------
    ' O8 K8 {4 {/ W  |) R// Name:
    . i; z+ U* ^- S- N// Desc: % H8 N7 ^8 r  \. B0 F
    //-----------------------------------------------------------------------------
    : a( c8 |* [( C( mvoid CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )9 t; p! Y6 i! G
    {; I; B5 c; d0 B2 g6 j1 N
        m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,9 |7 v% G! q, ^7 @8 U
                                x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    . l6 g# C" \" Y  K5 Q) Q}</P>
    + H! H; g+ l  [+ A, W/ k% h
    & C; C  m2 [1 L: o! d<>
    6 @9 G: M+ C8 Y7 h0 s7 @2 D//-----------------------------------------------------------------------------6 d' b9 i2 F4 `
    // Name: 5 ~4 x1 n* v* K4 g0 S
    // Desc: $ ?$ Y+ R4 M' r
    //-----------------------------------------------------------------------------
    0 d" ?9 C9 z1 I3 M$ e1 Bvoid CMazeServer:ockCell( DWORD x, DWORD y )
    ) G& n+ _: I& L{' O$ _$ g4 ~$ R7 c4 `
        if( x == 0xffff )
    + u; T" r9 ^8 w        m_OffMapLock.Enter();
    & C3 F2 t7 Y, d9 r    else6 o2 T) h. H+ m6 d1 l& x. w, n1 l
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);9 }$ v- D1 D- A( Q
    }</P>% A( F; s6 j( j3 J$ E, }5 W
    ( @4 a- r, t6 m$ r4 j6 @
    <>5 [& V; I; c. A; [  F, c
    //-----------------------------------------------------------------------------6 {5 h: r& {0 i4 s
    // Name:
    # ]8 S: G8 p2 S) y// Desc: ! T$ e% s+ P) H
    //-----------------------------------------------------------------------------
    9 ~" ?' M$ a; D7 }6 j9 [! z  A; qvoid CMazeServer::UnlockCell( DWORD x, DWORD y )
    ) p- E( F7 W. a+ g/ h% x& l{
    ! c# E) R2 g5 a    if( x == 0xffff )* |( t) d& q" }( b' X
            m_OffMapLock.Leave();
    ; x- W# m1 v0 D5 [) e    else9 d* r$ d( {, y* Y  Z8 K9 F$ n
            m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);; k  o& ]  S. E1 q, \- r
    }</P>
    # J7 p* Y3 A, T% B4 E3 I2 V3 D& f5 l. z* ^$ h4 k
    <>
    0 R5 T+ W- t7 a3 M+ W//-----------------------------------------------------------------------------
    " f  {- l8 s' [( t/ D// Name:
    & x. H" _; s% A/ v+ u1 k// Desc: & Q, B0 X0 i6 U( \
    //-----------------------------------------------------------------------------* _9 ]; b( n$ ?
    void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    5 p& \. \/ [8 _1 Z( e{
    8 c* `% C( V/ M6 s6 S    if( x1 == x2 &amp;&amp; y1 == y2 ); {) a, Z: v4 p9 K  E* d2 A$ t2 u8 I
        {% d) [9 @) u" T; ~0 @9 e# p) [! f+ K
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    " `: \; Y6 ^/ {6 y. Q& J            LockCell( x1, y1 );- H9 y1 k8 A& \
            else/ K1 a! o/ B. J( d+ S# e. l! a
                m_OffMapLock.Enter();</P>
    . y/ u) v% S7 i$ L8 u( M4 f<>        return;% h- Z! X( v- y
        }</P>
    . I7 m) c3 j: `! g+ b0 \<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    1 q* ~: x- c- }9 w4 ^    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    ! T/ e$ ^! o1 J# K2 r( A6 u    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    ) Y) p" |, I' ?+ a! t9 v, I+ q    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>6 y  \7 B5 v8 }9 \3 ?' L: G
    <>    if( x1 == 0xffff )6 m/ h) U; Y; \# [9 N- H8 l
        {
    ) u. k& P6 s' @2 X8 @        m_OffMapLock.Enter();2 X, R) g& b% H
            m_LockGrid.LockCell(x2shift,y2shift);
    6 Z4 ^$ y; b* i! {# F    }3 X' O. z  q+ Z8 O  y
        else if( x2 == 0xffff )
    8 \4 E; H! s/ Q  ~5 k0 q7 f    {; |4 |. K8 W' u# j7 J8 A/ j% |1 {3 z
            m_OffMapLock.Enter();+ ?4 n0 l1 K; `3 S$ B6 n4 q
            m_LockGrid.LockCell(x1shift,y1shift);
    $ L# U* k5 x9 J" Q    }
    * S" @/ V4 A9 c* D2 g, r    else
    + k: J8 T8 Y- [; p    {5 e0 Q% z$ n2 c% {
            m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);( ^5 k# z- B: L+ o- ^
        }9 D& }) X- ~& ~. v/ S- B
    }</P>
    7 i1 P4 |) I3 w, }: j* O  v% w/ D6 S2 h# ~5 D8 i3 o' ^
    <>
    " U% i" o) v0 d- }//-----------------------------------------------------------------------------+ k( v* ^* F7 c
    // Name:
    8 `8 T8 Y# f: ~// Desc: 6 u0 M+ k: q& n, }* {2 @. E# w
    //-----------------------------------------------------------------------------
    * A/ t, b& I7 F* p. r; h' U5 rvoid CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    ' z/ E5 e0 `' M{& x" ?' I$ Y8 A2 ?2 t$ u; Z1 P
        if( x1 == x2 &amp;&amp; y1 == y2 )
    1 h5 M* k3 I) C  f/ u; C, V" ]    {
    9 v" x7 G; D9 D. A2 `9 o        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    " n; R: e5 w" z1 _: F) ]            UnlockCell( x1, y1 );: f3 }; W9 o/ ^3 n
            else  F( n$ }; z4 e/ k
                m_OffMapLock.Leave();</P>0 y$ V- [7 }, g0 A: ]0 O" V- D( L
    <>        return;
    7 O0 p  K& B- ~& _    }</P>
    7 w) m6 X: ]- B# I- o, H7 j<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    ! z  U6 D4 h, R0 A4 K    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    + o1 a* D9 m4 N6 x4 v) C$ s    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;) I6 n$ u: n* q$ L/ E+ H# X& A  {: b
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>& K% L$ d  f$ W  W; x
    <P>    if( x1 == 0xffff )1 j8 m% D0 b& Q/ e0 D1 O6 h/ E9 b
        {5 Q/ r! {2 E8 r9 n, k! l
            m_LockGrid.UnlockCell(x2shift,y2shift);
    ! w. U7 O3 u2 X+ `( r        m_OffMapLock.Leave();( g- ]; y6 X6 x: T- F" G. E
        }
    / d5 d9 G% _( @/ d- D7 Z    else if( x2 == 0xffff )
      y% V/ a/ O: e9 |" r, v* |    {
    5 n* K+ H  E7 d* I- p, w        m_LockGrid.UnlockCell(x1shift,y1shift);- Y, @9 t! H; B/ g/ Y
            m_OffMapLock.Leave();0 x+ u& m, G* a7 p& [% N3 U
        }# ~8 W" h  d1 U( H2 J7 H
        else
    7 l# F# ^" ~& V0 V    {& Q' g5 \5 f7 _+ H6 S! j& K# x
            m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);  L; y2 v, D' ]* g9 F0 G
        }- b! g3 U/ y) [
    }</P>
    $ l4 F& c; W' C' n2 L9 @% a0 I: G. G/ S7 L
    <P>
    9 |: x5 G0 q1 q3 W! a9 ~9 l//-----------------------------------------------------------------------------' M2 J3 X- w1 w! E
    // Name:
    $ W& L2 L) D" l9 g6 N// Desc:
    / J$ {8 p5 S0 n//-----------------------------------------------------------------------------% P- a3 s- U1 J& ]6 p8 r
    void CMazeServer::OnAddConnection( DWORD id )
      F1 [+ a' q, d: @3 T, n{
    ) b7 \0 z. e# `4 Q) W9 J    m_AddRemoveLock.Enter();</P>! P6 ?% U% i& x4 u+ ]: w6 r
    <P>    // Increment our count of players2 H# b8 R) U- i
        m_dwPlayerCount++;
    1 |& W& v! G0 H    if( m_dwLogLevel &gt; 0 )
    / S4 L! F+ ?5 e; @$ R' x% [    {1 C+ m  J6 L% Q
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );' x# O0 R- `! L8 N3 _8 c
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    0 j$ i. ^5 W/ s9 V  R    }</P># l" k% ]* B) n; \* @! B( O
    <P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    2 b( l/ F+ _, n( X! f" r        m_dwPeakPlayerCount = m_dwPlayerCount;</P>
    . C& y  z1 ^7 Z- ~<P>    // Create a player for this client; P$ {+ M1 F0 p3 p4 n2 A$ b
        PlayerData* pPlayerData = CreatePlayerData();7 B2 H& o7 _9 i9 I9 _0 L2 K  V9 w
        if( pPlayerData == NULL )$ u6 [- P* k1 f
        {
    " r, m- Y7 k8 E  F5 O        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
      Z8 G# A/ O+ c: H) e: e        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );
    $ x7 @5 s% }7 L        m_AddRemoveLock.Leave();
    . U" n" T% ~" I        return;, y8 s/ p' f& h! \4 g: p) i
        }</P>
    ' O+ h8 J. Q. |+ s<P>    // Store that pointer as local player data: o6 Y& E/ T* P* K) T/ |; t0 T
        SetPlayerDataForID( id, pPlayerData );</P>
    ; L7 g: ^( C5 q2 x2 z: s( }<P>    // Grab net config into to send to client* M) a+ d' W# i% D/ ^
        m_ClientNetConfigLock.Enter();
    8 F* c) H9 j6 I    ServerConfigPacket packet( m_ClientNetConfig );
    9 M5 u' y; c2 A5 M9 f    m_ClientNetConfigLock.Leave();</P>
    7 m- V, @5 `+ X6 a# Z# c<P>    // Send it" ^: ^. v4 m" I2 U5 o7 A
        SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>5 T2 `# z/ T' g
    <P>    m_AddRemoveLock.Leave();
    . B$ G$ r  T' q) Z}</P>  O7 A, |9 N) n" g! W! _/ w

    , P, p5 G. T4 S<P>
    9 x* ^9 }  M) }% D. q- p! G# k; {//-----------------------------------------------------------------------------
      k5 T' P7 Q; t( \/ p; S// Name:
    4 O3 |6 e4 \4 i6 O' @" D1 }// Desc: & d5 U. ^- H) a; H
    //-----------------------------------------------------------------------------
    $ b8 R5 V+ q: i; J% avoid CMazeServer::OnRemoveConnection( DWORD id )8 G( Z1 H$ W6 T
    {
    + [$ ]' z5 T1 [5 F3 |    m_AddRemoveLock.Enter();</P>
    0 g: ?% [+ W8 f7 ^& ]9 s<P>    // Decrement count of players. g, ]1 {6 q" E6 T
        m_dwPlayerCount--;</P>5 _: @+ b& h; X9 w! _+ E3 i
    <P>    if( m_dwLogLevel &gt; 0 )
    - V" O3 ^7 b# n& E2 q0 t    {
    : f, E- l; `% o/ m( S. a' n9 T2 l        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
    7 _* ]# o# p' S$ p; W, g( i0 G  a        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    & \8 a+ B+ v  S4 T/ w6 d! j5 V    }</P>! x7 l% r9 Y" n6 i5 E
    <P>    // Find playerdata for this client3 n6 M* h" x/ m# S2 G
        PlayerData* pPlayerData = GetPlayerDataForID( id );
    ! ^! C3 J0 Y$ R3 ~' g! Q( [    if( pPlayerData != NULL )
    " a. _7 L' ?  S& v    {
    ( T! ]* d; D: F4 a        // Destroy it: ^7 S9 y' A" y: K2 b
            RemovePlayerDataID( pPlayerData );! N1 q' }3 P! c' P
            DestroyPlayerData( pPlayerData );
    / \+ C! u% z7 k/ I    }</P>
    , Z# ~# q/ c# Q<P>    m_AddRemoveLock.Leave();: B8 E4 ~1 B6 L) U* [% s
    }</P>6 M" c$ m- i: M( {$ \8 J2 K5 d# ]% U
    ' \1 f- @, F3 K7 w
    <P>6 h8 m8 }: j" |3 W* l2 i! Z
    //-----------------------------------------------------------------------------
    ' v) @/ z# A+ s1 H3 `- A" F// Name:
    $ d2 C  h! i) L5 Y% Q// Desc:
    6 s9 i: y' O3 q- J. {+ L//-----------------------------------------------------------------------------
    3 ]7 v- o4 K# w1 X. ?3 V1 G; K/ nHRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )
    ! l  h. D; f6 u9 {" B{" _% l; d8 C0 I. f; k
        BOOL fFoundSize = FALSE;</P>
    * j9 I! d1 E9 T1 `<P>    // Increment the number of thread we have in this process.+ v5 Q& n# b  D* a, Z- J
        m_csThreadCountLock.Enter();</P>
    * |6 c8 `) L+ d. n<P>    //Get the start time of when we entered the message handler.
    $ M6 t- ?# \( q6 @; G+ r    FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>& b% [4 `$ [) p
    <P>    m_wActiveThreadCount++;
    : d% |/ A) K% [" K5 j- H- p( c    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)
    - }( o8 [) N7 h, P; t        m_wMaxThreadCount = m_wActiveThreadCount;0 V2 B, j6 v+ R7 c# X: D
        * D$ d5 _- ^( s$ P. W( Q
        // Calculate and average.1 Y" u7 l* s& Q) M% ~0 P  j
        FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
    0 J3 }. R, X- P) V" ]# s    m_fAvgThreadCount += fdiff/32;* g+ n. g1 \6 z5 Q6 z$ `# F
       
    ' \% C! T7 U+ r    m_csThreadCountLock.Leave();</P>
    / ]: y8 i* h) A; l; e: K<P>
    2 N9 r3 c0 M" ?0 ~7 c3 h    ClientPacket* pClientPack = (ClientPacket*)pData;
    0 v; T5 q7 z* W' f. ^& ?8 }    switch( pClientPack-&gt;wType )- n: J& [' S' O
        {
    * E+ r0 b' \8 V' R0 S1 K1 e4 L$ V0 m        case PACKETTYPE_CLIENT_POS:
    ) e( ~, z7 P" c            
    ; d4 e- J2 z' E7 q            // Check to see if the packet has a valid size. Including : R2 q$ u0 i  S& z4 `# K0 r$ f
                // the custom pack size.8 N% J+ B. N- y% s
                if( size &lt; sizeof(ClientPosPacket))
    * I# ?- g' _8 [5 g4 a                fFoundSize = FALSE;. q0 V4 O5 l2 K' W" L- }& Z7 |
                else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))% k) `, n. u( T, H
                    fFoundSize = FALSE;; X+ L: B4 @7 u% x; Z
                else7 e  N9 S+ J! y3 j, Y  o
                    fFoundSize = TRUE;</P>! m( o' s: \# u; Q& A% @! v/ _
    <P>            // If valid sized packet, handle the position.
    3 K  [, T, o2 ?0 L& `            if(fFoundSize)
    * I$ B$ \' u5 J0 Z5 B* A9 F$ ?. {                HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );3 ?0 ]( p5 E$ r/ o" r6 j
                else
    " V, h1 s: C1 T4 Q/ f$ ]                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>" R- Q8 u+ z0 e
    <P>            break;</P>
    ! @! T% q; e5 c8 A' L7 z<P>        case PACKETTYPE_CLIENT_VERSION:! H" w2 l" z. x. ?# E9 @
                if( size == sizeof(ClientVersionPacket) )
    4 w0 t( T, d% F, G/ {* }& x                HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );. n7 u5 y0 Z3 s( E( s
                else
    / b- R* b/ E- H1 B9 i                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );: z2 q- Z: B" `# l; k: _' W
                break;</P>
    + e2 x* T& `) {6 @# N9 q: u<P>        case PACKETTYPE_SERVER_CONFIG:</P>2 \. P. N, D, }: l5 A
    <P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>
    # Z, Y* B  \0 |, |" c6 }2 A. U3 v<P>            break;) F8 W- T8 C& ^- o0 W+ X
            default:
    . W" c, a4 P4 y4 d8 I" r/ P            HandleUnknownPacket( dwFrom, pClientPack, size );) i' I2 P3 {) T$ Z3 G& q
                break;
    % j) j9 `. M/ C0 q$ l9 J$ x7 }* {    }</P>
    5 u. [) i/ u  X* C<P>    //If the user wants to hold the thread, Sleep for given amount of time.! @5 E( D2 |$ l! J0 \
        if ( m_dwServerThreadWait &gt; 0 ), T: _( [1 u, C) ]; S' A  K
        {
    0 ?, ]$ N6 J. {2 H; f. N4 [        Sleep( m_dwServerThreadWait );
    5 i4 V' E! @1 o7 S3 O7 a7 y; c    }
    2 i  p4 R1 n- E4 ~7 z   
      T& f! A* x- W( K- j    // Retrieve thread data for this process.
    - }; k; H. U3 g0 {5 T$ i* r    m_csThreadCountLock.Enter();</P>9 a: C! b( R& d' s7 r2 S1 k
    <P>    m_wActiveThreadCount--;</P>% N& Z! ^4 r+ G* w
    <P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
    + S3 b0 \- r3 g    m_fAvgThreadTime += fDiffTime/32;</P>, J& z0 g8 k1 X# I% b
    <P>    //Get the Max time in the thread.& n; M$ X" n8 _8 L
        if ( fDiffTime &gt; m_fMaxThreadTime )2 U$ {4 ~, d8 J1 G9 t; y& J
        {# V9 s2 U' B6 q, I6 Q* O% Z
            m_fMaxThreadTime = fDiffTime;
    4 j, h% h) U1 j5 ~" q, [    }</P>
    6 u: E$ F) U4 {* J& b* q<P>    m_csThreadCountLock.Leave();</P>
    4 ^7 U/ z* V) X. X7 |<P>    return S_OK;0 y8 s7 ~/ q. x. C, M0 @
    }</P>
    * Y$ ~( A9 }: f: R/ o  u4 v
    , g1 t" k, r* c; j3 h: h<P>//-----------------------------------------------------------------------------
    3 I; d3 `9 T1 b1 g" Q0 ?1 A- |. \/ h// Name:
    ' Z. ?8 u; e- P" P1 V' b// Desc: . ^' |- E, `' m2 v% B/ R) ~, p' v
    //-----------------------------------------------------------------------------
    0 E  R1 P3 x5 B( E" @# RBOOL CMazeServer::IsValidPackSize( DWORD dwSize )
    ' A% L, Z4 J. s8 i( Q{
      M9 u2 z: K. ?  i    BOOL fFoundSize = FALSE;
    : ]2 l$ }% |6 a/ b0 l) z1 n    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;0 U- F2 G7 I( ~
       
    . x- s2 }1 S# u    // Check through the array of valid pack sizes.
    , d7 g  |7 D, C  X/ Q' {    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    ! @0 e, C6 M* o, `- j    {
    5 O' j  A7 Q+ T" _9 B% }        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)5 a7 G& ~) p+ @0 w' x/ X
            {$ w' }& E* N4 o& z
                if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])8 u" l* v! _7 i# R- E' g; A
                {* K- O; b7 M, O7 `: c
                    // Found valid size in the array.- \8 J9 g1 _. U& M* F% ?3 O% z  z
                    fFoundSize = TRUE;
    2 j9 \& F& K- w% e% o                break;2 p# _& n* q  W) `0 q
                }. b6 ?. n3 m& s9 P  L, W
                if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.) C$ _% |3 j6 v
            }/ T2 G( |6 e6 m4 ?
        }
    + r* m$ k" D/ b) u6 ~( A' J, T' L    else. O6 l2 [: t, `' K" m
        {! `. u4 r) T) B2 t
            fFoundSize = TRUE;
    ) R2 }5 h/ p: Y; x5 B9 L7 l  _; [    }</P>
    0 S) s* b4 F3 ^# w6 x# S7 w+ S<P>    return fFoundSize;5 Y% m6 k7 f7 w" N4 n
    }</P>
    8 x7 ]" a" [8 {/ L; A% U<P>
    & H5 Q. x" f4 }//-----------------------------------------------------------------------------4 l% _$ N9 ~7 v2 |" R- m
    // Name:
    4 d; X- g' z& o; v$ `* A// Desc: 2 l  I% L0 r4 H; n# I4 m
    //-----------------------------------------------------------------------------1 [' U4 f+ M  a& A3 ?, Q8 f2 ?
    void CMazeServer::OnSessionLost( DWORD dwReason )
    / F9 e  \0 t$ y  w( u8 M- p{  \6 h6 p( t1 J
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
    5 A* U- p" e. h- U( u) N- H}</P>! h! H8 P2 {5 L1 H
    0 n! H! z. t3 v
    <P>$ Q- {1 I9 c  l
    //-----------------------------------------------------------------------------. V- {1 i$ b3 \. O/ L0 O( ~# L) l
    // Name:
    ) [4 d+ i* R  D4 o// Desc: 7 C  x: d; v; x. Q* S
    //-----------------------------------------------------------------------------! L2 y, w' g+ U' I: K  r/ w1 U9 R
    PlayerData* CMazeServer::CreatePlayerData()1 d! b5 l9 `: Q. l2 r4 ?
    {- B, x' B. Q0 v) O; R9 b
        m_PlayerDataListLock.Enter();</P>
      ~9 [  L# F  E- m0 C<P>    // Grab first free player in the list
    # U% D. ]2 x9 X1 k8 I* C    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>
    7 \9 X6 m& M3 T+ y) J0 d3 O<P>    if( pPlayerData )
    . H/ ?) r/ G0 @' D8 c. d4 W    {
    & L1 z) n0 Z5 }! H1 X, |2 k0 b        LockPlayerData( pPlayerData );</P>$ t! c! t) J( |
    <P>        // Got one, so remove it from the free list
    8 @( D. G$ s; `7 i$ v5 M, _3 ?        if( pPlayerData-&gt;pPrevious )& O6 J& V1 K. [$ z5 G/ q  m6 Q! s
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;, i9 u* e# m% _3 ~2 t; \
            if( pPlayerData-&gt;pNext )) E, Y; C# V! R8 J2 b; [0 i) a
                pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
    $ W; j3 R4 x. U. c3 t/ N        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>8 n8 @/ `- j/ x0 r5 r* n/ ~" _4 L
    <P>        // Add it to the active list. `8 V0 @+ ^% q
            if( m_pFirstActivePlayerData )' f6 k: G( C/ A# n0 A2 e; ]- x% {
                m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;/ m3 t. m5 {2 V' ~7 \& w3 ~
            pPlayerData-&gt;pNext = m_pFirstActivePlayerData;+ ~* s- \' C5 I
            pPlayerData-&gt;pPrevious = NULL;
    , D! D3 L1 T6 ?& {        m_pFirstActivePlayerData = pPlayerData;</P>0 t% [4 Q, Z4 i$ f! V
    <P>        // Update count of players
    " }9 p3 W" I  h" W% r        m_dwActivePlayerDataCount++;</P>
    0 u& N" D5 K* r<P>        // Generate the ID for this player7 t7 t' E; S8 K9 A9 A1 C9 g8 A" f
            m_dwPlayerDataUniqueValue++;
    : [% K6 Q8 H: @! w5 B# `8 i' I        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
    4 x- U  Q: p8 C  |" w$ ?; r<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
    7 ~, Q4 s8 N. T8 k6 Z( l. p4 \        pPlayerData-&gt;NetID = 0;' {" h$ x0 E6 o( z: w' H
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>7 t2 i( z1 Z3 i6 `+ g5 \: \
    <P>        // Insert into the "off-map" cell* A7 ^5 \" N$ S
            pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;$ O  x$ a" v2 s, K4 [, E
            pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;
    7 d. H4 b+ _+ ?& a) C4 i/ E        m_OffMapLock.Enter();
    3 A: r& o/ K+ e+ f( i        pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;
    & O( F  K) c' g        m_OffMapCell.pFirstPlayerData = pPlayerData;% |0 m6 U' z- Y$ @4 t
            m_OffMapLock.Leave();</P>5 c# Q( p# S& ^9 i7 B6 ^- r( Y& @+ Z
    <P>        // Mark as active
    ' T7 O7 y' p7 T0 v% w; s1 k& U0 t        pPlayerData-&gt;bActive = TRUE;</P>9 U% ^4 `* z  U1 ~& x. \
    <P>        UnlockPlayerData( pPlayerData );
      L( J; Z* v$ v1 s2 L) r1 _$ q    }</P>
    * A; U3 Q* |7 A+ e) U<P>    m_PlayerDataListLock.Leave();</P>( a4 h/ K; [5 l- p* \! _
    <P>    return pPlayerData;( ]5 Z7 Q8 Q  I% U3 M$ K. s4 R4 G
    }</P># ~$ s5 @! W' c( Q1 A: _' x: T
    , f. \* K! q0 D- Q1 O( O5 f
    <P>
    : \6 q/ _: M/ X! i/ _# N$ q" K//-----------------------------------------------------------------------------* z4 N2 x7 H& A* v
    // Name:
    ! p7 {7 _% E; r2 l/ W2 `// Desc:
    7 B/ w* K( W+ U3 |//-----------------------------------------------------------------------------6 ~8 B) D1 N! n2 V2 h7 p
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData ); e, C$ H# z+ W. M/ i& s8 x
    {
    : y1 u: l' u; V* M6 C! y8 Y8 b" e    m_PlayerDataListLock.Enter();
    : J- L  L! [% M# w$ v; I    LockPlayerData( pPlayerData );</P>
    ' h+ H; _8 Z( G6 D; s0 o3 ]<P>    // Remove the player from its cell
    . V- h" b( M6 B7 l    RemovePlayerDataFromCell( pPlayerData );</P>
    ! q: h% ]: N6 J  `% i7 {2 f' f<P>    // Mark as inactive
    * P4 G0 N& Z, o* e/ |& o% I$ y# G8 e    pPlayerData-&gt;bActive = FALSE;</P>. @# b) Z4 v: A4 ]7 W" z3 ?" i
    <P>    // Remove player from active list
    ) w! G* J$ M" p8 E: x' w5 G    if( pPlayerData-&gt;pPrevious )0 R* y7 ]( l1 p0 J3 o
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;) R2 h3 |& i: k) K" ?. _/ W. ]
        if( pPlayerData-&gt;pNext )
    # S: W- J0 a' O8 Q1 r4 L! |: s* W        pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>1 e9 ]1 w0 n# K; O
    <P>    if( m_pFirstActivePlayerData == pPlayerData )
    # O8 _  }9 n+ {: E; B        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>
    5 B+ C8 o6 S0 c<P>    // Add it to the free list: s" ^! F/ z6 y" |" P3 D5 f
        if( m_pFirstFreePlayerData )
    + Y$ F5 g: i. T8 `5 s% N        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;( B2 d* v) }8 K' [# S( w8 h
        pPlayerData-&gt;pNext = m_pFirstFreePlayerData;
    ) Y  x5 a1 @# s% C$ d    pPlayerData-&gt;pPrevious = NULL;
    ) u+ |- K9 c: ]& d& }- k* x    m_pFirstFreePlayerData = pPlayerData;</P># k* d5 b/ r- i3 r
    <P>    // Update count of players$ ~" A2 j* i) c$ e
        m_dwActivePlayerDataCount--;</P>" D" N/ H( ^5 s8 o  s0 |
    <P>    UnlockPlayerData( pPlayerData );
    - |. U1 Q; i* D, F  O/ V6 X    m_PlayerDataListLock.Leave();4 H7 O0 c5 J6 J. a
    }</P>
    & E1 V, n7 s* A; z9 Q7 n9 N
    % o- b2 y+ n) K8 F+ i/ \- K6 M  a<P>
    ) q; S' F% o9 `+ Y. }//-----------------------------------------------------------------------------% N$ h. I, ~; Z. A1 t5 n0 ~. U( h
    // Name: 4 o' o& U' b# n2 J; P7 z
    // Desc:
    - E" I# n: W# `( |//-----------------------------------------------------------------------------" N( [9 t$ Q- ~+ h% q: p" e: y
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )) i5 |: u" C" S# M# t/ s* j, _+ p
    {
    $ ~) p3 ?0 n, P) l$ M    // Lock the player, b& Y  t: z4 E( R$ ~4 x7 A# y
        LockPlayerData( pPlayerData );</P>1 c" m' \) [5 q9 @# A1 C6 W
    <P>    // Lock the cell the player is in$ t0 p0 A. N0 i
        ServerCell* pCell;) u' n6 ^' b8 Z! x2 s" Q
        if( pPlayerData-&gt;wCellX == 0xffff )9 F% H! f, K8 [" e3 P" [2 g
        {
    + @6 C- i" k- w' w- ^& o* b        m_OffMapLock.Enter();& a( h& _* ^' I# {# V
            pCell = &amp;m_OffMapCell;
    7 L; B0 ^4 \+ U- q$ I    }
    2 o- }/ M$ s. G6 K    else
    7 k! I9 n7 V5 j0 J- `    {, x8 E" N' m% Z% g8 g
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );# U7 ~, @+ n4 B; h# ]& E
            pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];$ E! K2 Y) Y, y  x
        }</P>  u' a) H: x' ]( s% {+ F
    <P>    // Remove it from the cell
    4 C/ q1 x, x( i8 b+ g    PlayerData* pPt = pCell-&gt;pFirstPlayerData;: O: P' v9 Q+ s, u
        PlayerData* pPrev = NULL;1 K' y/ Q5 C% a6 M- A1 L
        while ( pPt )
    % c6 ?) D7 H+ f% i; ^9 r6 y    {, ^3 P! ]* c9 N: W9 m: C4 r
            if( pPt == pPlayerData )
    7 `7 F) ?+ o3 b. [, i) Z, b        {
    5 c2 H# W  m6 F6 ?& V            if( pPrev )
    8 y" b' v' F; a# s5 W- P; J                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    0 q" W" I5 u5 A3 Z4 t* Y9 u, A7 }            else) p) \! i1 m) @' X  C2 J! I7 ~; Q
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
    6 v! B" E) G+ C: I. L7 ~! j<P>            pPlayerData-&gt;pNextInCell = NULL;# L, x' h. z  }
                break;
    4 ~1 a' H9 v6 O- ~$ L& y2 m2 k        }
    ( j" L  C: T: F! G$ ]0 a1 X7 Q        pPrev = pPt;( q" i( m: l2 C! j6 s
            pPt = pPt-&gt;pNextInCell;  ]7 h, _, _1 u( C4 e8 Y; i
        }</P>
    2 Z2 A& V4 |" ]; O( S<P>    // Unlock the cell$ M. f" J8 |7 W2 I7 U& Z$ \* P
        if( pPlayerData-&gt;wCellX == 0xffff )" W. O& g- w, A/ m% _) Q! r8 I
            m_OffMapLock.Leave();
    0 |9 ~; F* k/ E* r2 m4 f    else
    2 A9 y0 h; o* k* \        UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>
    + M3 q8 B' J. ^3 ]. S+ i' v<P>    // Unlock the player2 }3 D' v! U5 B9 f2 F
        UnlockPlayerData( pPlayerData );: a. w- S' H9 [) _. E. A
    }</P>
    . r' Z1 s1 [& D4 X1 Y, o7 R" D: ]" f; f, l, V& i3 N* U
    <P>
    : A# |+ Y& l' W//-----------------------------------------------------------------------------
    , a7 W' m  m1 f- S+ }; F1 n// Name: ' ]; z+ u/ F. L- ^/ u2 v
    // Desc: , Y" N, E! W4 H
    //-----------------------------------------------------------------------------
    3 M5 p& M9 K8 Z) V( B8 g$ [void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
    6 m) Y0 T1 u& K6 D' H1 G{  y( _8 r8 }0 E, }! m1 X; D3 f
        ServerCell* pCell = GetCell( pPlayerData );
    ; `$ \9 n( i4 a5 o$ u- I) N/ q    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;7 S; x( s; W0 K- h3 R- u) ~5 v" B
        PlayerData* pPrev = NULL;8 I7 O* \! U% L4 c# i' R
        while ( pPt )
    " e- J1 l5 ?5 m8 Y( @# W    {
    / A' {) \: {0 B! V        if( pPt == pPlayerData )
    / f1 P8 d9 t  Q- B        {
    * P- K' G1 n1 |, Y            if( pPrev )
    5 g$ f0 F  X# b# u; f( O                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;) }6 H4 C8 D9 B* C# b6 i  T
                else
    ' k8 S, p3 F. r4 O8 l! @                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;
    0 w& b0 P- U& Y9 U            pPlayerData-&gt;pNextInCell = NULL;+ N2 r; ]" O8 [4 h7 o6 D# a
                break;
    8 F' f0 ]6 N" E$ ?% k- Y! u3 ?' L) u        }6 Y* ^' ~( c6 Z5 Z# @. G! o6 G
            pPrev = pPt;  C( g9 g5 d1 B5 i' `/ n! z$ c
            pPt = pPt-&gt;pNextInCell;6 b6 K2 C, ^2 N$ ?. Z- Y7 E) _
        }$ h% h4 B* B& C
    }</P>7 O2 C: C6 U# ~+ U1 k
    8 A$ C0 p- D5 @. i" J* k0 O
    <P>- u, F9 \+ Q- n2 m- p1 z
    //-----------------------------------------------------------------------------
    7 A, [# L3 S2 l4 W  F// Name:
    6 C" r/ @& E" x  _$ t// Desc: # G0 L* N# J  f- I. N, U3 M
    //-----------------------------------------------------------------------------
    : n  r4 _$ F5 z- Mvoid CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )" w7 V# U+ V* m3 s1 m* t- ?5 o
    {  I2 U. q  D* h- b# g* a# l) |
        ServerCell* pCell   = GetCell( pPlayerData );
    ) K# R/ ]/ i! `: f7 n! E% C    pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;
    + y( {4 \* e& I* n5 d" ]7 C6 E/ c0 v  s5 U    pCell-&gt;pFirstPlayerData = pPlayerData;
    2 Y. T8 Z; R) `  {# w) ~}</P>: v& Z1 k( M4 I; v/ z

    6 y. \% H7 P& S% F+ p0 [8 m<P>3 c1 }: G" A8 U
    //-----------------------------------------------------------------------------* w9 B0 Y& C( B8 k$ B* _5 i, \
    // Name:
    2 S- b, M+ C& Q9 @" g5 s' M// Desc:
    ; B9 Q6 h4 m' H/ Y! x( F9 |//-----------------------------------------------------------------------------
    4 w, ?, @( `( w& avoid CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack ): |1 s' Z  e% ]. @" X1 e
    {
    - s( F4 d( u& I    // Grab player for this client and lock it- O* F# h) S9 R1 H
        PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );8 o% ^+ a# g0 J* ~! f" v* `6 m
        if( pFromPlayer == NULL )
    * T/ ?/ s! n" J2 m( n( h    {
      _$ y3 |9 Q* k3 U3 a        if( m_dwLogLevel &gt; 1 )
    ' M) @7 }% m9 u( O( Z: d            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );7 m0 I4 S& Y8 U) l) E* P
            return;  Q& n  M& Q+ Y
        }</P>5 D+ k% y1 p5 {. X$ d
    <P>    LockPlayerData( pFromPlayer );</P>
    5 L/ S& g* \6 |- ~3 s<P>    if( FALSE == pFromPlayer-&gt;bAllow )' k8 V. A1 V5 v/ k( F* Z# w! ]
        {
    # S) x6 q/ g1 p3 P% V2 o        if( m_dwLogLevel &gt; 0 )8 K  Q) F* c! y" a
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>0 ?  C, Z* Z, ], `) [8 z; z
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );, q6 ^; X# q- m+ O2 v
            UnlockPlayerData( pFromPlayer );% Y# N4 ~% k0 w" c2 v
            return;7 W* y, `4 t6 C* D; Q
        }</P>
    2 T2 z9 w: H8 s* P3 H* e<P>    // Compute the cell the player should be in now8 i5 v6 x' G9 b- g" B+ L8 M# a9 F0 n- _
        DWORD newcellx = int(pClientPosPack-&gt;fX);6 K3 c& z# z+ Y7 T6 d; v
        DWORD newcelly = int(pClientPosPack-&gt;fY);
    7 w# R( K2 M+ `  K' {, t8 I" `    DWORD oldcellx = pFromPlayer-&gt;wCellX;* T- `8 Z# s) q3 R* `/ G
        DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>
    $ l9 U" Y- X; r7 c- a, e( |<P>    // Have we moved cell?
    5 I0 Z4 X% s5 y5 f    if( newcellx != oldcellx || newcelly != oldcelly )1 f1 v  _9 P  o0 V8 x0 G
        {$ _( y& i$ b) v
            // Yes, so lock the pair of cells in question
    ! V/ v" Q- j  e: t# g        LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
    2 B7 L1 d. g0 E# z$ z! O$ N' j" o% X<P>        // Remove from old cell and add to new cell- X# S# ^- s& {
            UnsafeRemovePlayerDataFromCell( pFromPlayer );* W- ]3 i' |- P: q
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    ) f2 D6 T  }1 {( L; Y        UnsafeAddPlayerDataToCell( pFromPlayer );</P>" R2 |9 l5 ~  a& o' M8 s8 ~7 A
    <P>        // Unlock cells
    1 D( c" H' f0 J5 t        UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );
    7 S6 G2 i# S6 C4 ^) {1 S6 C# ~* X/ d; a    }</P>
    ( c* X4 v6 f# z7 u5 P<P>    // Update player position
      e0 I, J  l0 D    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
    , `+ `- z# y- _( j$ ]# K$ a    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    ) L( p6 r! m/ v$ Q: Y4 {    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
    : U, k9 u3 Z3 I# p1 K<P>    // Allocate space to build the reply packet, and fill in header
    5 f3 Y/ r  Q; x8 p    DWORD dwAllocSize;7 t) d+ a' `! g* p& ]5 |
        ServerAckPacket* pSvrAckPack = NULL;</P>
    ; g6 Q/ s+ C6 z8 [' m0 {<P>    // Begin by allocating a buffer sized according to) g: S- w8 O$ Y3 Q! }5 h
        // the current number of nearby players + 4.  This will give
    % ?& P7 q0 r0 A- J& X' S& d    // a little room for more players to come 'near' without resize
    " e9 {  U4 y! m+ ~8 G    // the buffer.& {  f$ X, D0 F4 n- f
        DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>
    / w5 K' X. R+ f$ Z  R<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);4 A: J# j$ {$ O! L
        pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );% }5 C: ^' _% p6 s; Z, v6 y. x8 a
        if( NULL == pSvrAckPack )5 m5 o' }# F2 t8 v# R0 A* e# i
        {1 \" x' E; H) y0 }+ l
            // Out of mem.  Cleanup and return5 g- q8 l0 G" g. e6 w3 Z( v- n
            UnlockPlayerData( pFromPlayer );' M0 n1 t% A1 b( Q
            return;       ( l, S4 v3 @; E7 o& D# H" j, H
        }( h2 \* Z1 L! W
        ZeroMemory( pSvrAckPack, dwAllocSize );</P>
    ( ^2 ~/ ^9 t3 Q) x' H<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);, Q7 g5 M9 M' {  b# K0 ?
        pSvrAckPack-&gt;wPlayerStatePacketCount = 0;# [" J1 h! F  X9 |, n) I+ h  t
        PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>0 E9 h" e4 b+ W+ |0 G
    <P>    // Compute range of cells we're going to scan for players to send' b- B" `# J- K/ Y4 ^% c  U' x) B
        DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;
    8 x0 Q# D( |1 [( b! Z- c    DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;) u! p& G/ l8 ^1 O5 B/ K
        DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;
    6 q' `0 f) ?' r. h+ r3 V# O, S    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>; l! c0 c; y! p( ?
    <P>    // Lock that range of cells
    3 {$ [! g; R/ F" ^4 }) K    LockRange( minx, miny, maxx, maxy );</P>7 |& N" |. p* K/ y
    <P>    // Scan through the cells, tagging player data onto the end of
    0 v+ i( F5 o$ y/ H+ l: I    // our pSvrAckPacket until we run out of room
    7 @4 H, P& W) e) c, @& }2 [    for( DWORD y = miny; y &lt;= maxy; y++ )
    9 m3 b" J, I. d5 X( a    {0 K! z1 u* P* f$ I
            for( DWORD x = minx; x &lt;= maxx; x++ )
    0 W5 ?2 _$ n  g+ V        {* P3 V1 F" S5 x' l# i
                PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;
    % h- H* R# c4 H; O, ~            while ( pCurPlayerData ). T2 d. B" j; S2 H/ g1 ~8 ?9 S
                {
    6 D/ @6 @+ v# r; t                if( pCurPlayerData != pFromPlayer )1 F# Y* O2 ~( ~" i" W, t0 `
                    {* Q/ r9 j0 r  f+ K* b/ x
                        if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )- q, h# y7 M6 d/ m# J# T
                        {8 S. v8 _/ s2 e
                            // Make sure pChunk is where we think it is
    0 y) k4 a0 Z. n% [& H0 X                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>
    8 j1 L' x% y7 y% k6 o* S, t<P>                        // There are more than just 4 new nearby players, so resize the # b. D, c9 Z0 Z- f0 K- \: h) @: u
                            // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.) o: q4 g2 z/ @& h" i
                            dwMaxPlayerStatePackets += 16;3 W( E3 e* \: ]
                            dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    ' g4 g, y7 t8 s: \; R* s% j                        ServerAckPacket* pNewSvrAckPack = NULL;. q% L. x4 c- p! R
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );  C$ n, Z/ h: h( a: j) V
                            if( NULL == pNewSvrAckPack )! X: [' Q0 W, G! E
                            {9 u, B) K+ O( S6 q4 I" f
                                // Out of mem.  Cleanup and return
    6 f5 m8 C: `3 U: X* l# {                            free( pSvrAckPack );; r0 M0 @. d1 q) ]7 q3 y
                                UnlockRange( minx, miny, maxx, maxy );2 q' O* P2 X3 X+ M
                                UnlockPlayerData( pFromPlayer );
    * k3 F; Y6 F7 l5 z  N% F0 g* e4 B                            return;      
    ) ^5 ^5 V) O- F& P! ]: Y                        }</P>% ^* [) F7 b* S  {. t! I9 W1 U
    <P>                        pSvrAckPack = pNewSvrAckPack;6 X2 \; t0 T0 S+ d
                            pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
    / t8 j. X3 p( f9 D  E# M<P>                        // Make sure pChunk is still where its supposed to be
    ) I. F, s7 F1 h" O! \( s                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );1 \  H7 g1 Y$ b$ u& j
                        }</P>
    4 f6 z' |' G+ A  J# r<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;# v( a' D8 @/ A& O$ q: X
                        pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;* O' [. V! W2 g' O- G/ [
                        pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;
    3 f! s# B* L  |! V7 `                    pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;; |. d' R# U5 P- g; v4 G
                        pChunk++;" d6 l* b' Z- M
                        pSvrAckPack-&gt;wPlayerStatePacketCount++;
    ) X  {8 S/ X: g8 k                }3 ], ]/ W) C2 b
                    pCurPlayerData = pCurPlayerData-&gt;pNextInCell;6 f6 r1 E5 w( i/ P$ D
                }# U+ k4 M( B. T  L
            }
    4 n- ~4 w% J7 H2 ]    }</P>
    - \1 \) ]* K$ `; `. q- O<P>    // Update the dwNumNearbyPlayers for this player( x3 s$ I$ t5 j8 B/ q! F/ d
        pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>, W9 R1 j% z/ [/ l7 j. }9 ]: h
    <P>    // Unlock range of cells! N* V: m9 g# S; q
        UnlockRange( minx, miny, maxx, maxy );</P>. {1 S" ~7 C! T, B% M* H8 u
    <P>    if( m_dwLogLevel &gt; 2 )
    3 H1 [* b* s  T( ~/ {$ P% S    {: w* e* A( n  F' o  R
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    + L7 \' ]2 D9 U3 ?' s+ E    }
    9 |* O3 A% O3 Y2 h9 h    else if( m_dwLogLevel == 2 )
    ; p: r9 ]+ V0 `; n    {
    5 p$ ?# d- ?$ P3 E+ c/ z/ o        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );) B4 t7 w( `& u  X% R
            if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )0 T% |1 k1 i4 p
            {% z& i( a, F3 O5 [% j3 q
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    1 U  W' [8 ~- x' X            pFromPlayer-&gt;fLastDisplayTime = fTime;
      h. V* P) Q6 y- U3 n        }! }. G" n' l' y6 F' d( W$ t2 z
        }</P>/ P; u8 q! U' u+ f7 l; K+ b
    <P>    // Unlock the playerdata
      p9 ~- \$ d) _& V) d0 N    UnlockPlayerData( pFromPlayer );</P>
    2 Q3 b$ ^( L2 k* M! X<P>    // Send acknowledgement back to client, including list of nearby players
    - N0 W+ Q* t3 M- u/ \    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));/ s6 }1 o6 K* d7 z& X% R+ ]% O
    + d# ?, Z9 v) k2 o
        // Pack the buffer with dummy data.
    : s  I6 P8 ^1 [5 K: J    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)" r- n2 p2 A/ [# d! |$ J& A7 k( R
        {
    6 E, a) [& H& b" V+ R( P, C        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];! y8 \" K9 }+ S6 W  `  A  B
            VOID*   pTempBuffer = 0;</P>+ O: ^! ^$ h- w% l/ K
    <P>        pTempBuffer = malloc(dwBufferSize);0 N7 z5 ?% G# `8 F6 ~
            if( NULL == pTempBuffer )
    ! N: V# n! \0 L- B        {, c4 x, F! h; L! [7 V7 x
                //Out of memory# m" |- B1 J* Q* y4 [  j+ T5 s  w2 K
                DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
    ; E9 |% ^3 v! T            free( pSvrAckPack );
    ' I4 E5 k1 j" _) p$ c            return;
    5 {) G( h2 q, k+ q+ v        }</P>0 X+ E+ c4 \  i- e5 x$ I
    <P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');+ U, l# X# R8 o/ |; q
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>
    & m$ G3 p5 N7 R7 I<P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );
    % X3 v. ]% q4 G$ k" C, [5 i    / Z: i" S/ ^' p" q8 g1 N! s
            free(pTempBuffer);
    * Y; r, D1 R3 K. B& p( \    }   7 ~7 d* e" i  Z1 f; V& D; f
        else% w! G6 X7 t9 a4 @5 g- b
        {( {# e6 N6 g: @7 B! w& w
            SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );6 q7 v" N3 `2 k. a6 a
        }</P>
    0 W& Z) I3 d: o2 `. A0 o<P>    free( pSvrAckPack );</P>! E* K' S  B% f& p/ v: `
    <P>}</P>
    5 X# A. o; u1 k3 G3 x2 ?$ S" x+ U' m- \
    <P>
    9 l: M1 `& S! A( h; R( M& p//------------------------------------------------------------------------------ `# x$ Y0 ~3 Z
    // Name: ( I* P5 V: v2 q+ }3 ?; p  ^
    // Desc: : _6 |: [+ Q' E) u; U4 k, Z
    //-----------------------------------------------------------------------------, E& _% }4 a6 a
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack ). n' z2 f3 o4 ]( R/ q8 S
    {2 N) ?4 e# g  L! h3 e6 q
        // Grab playerdata for this client and lock it
    % H4 }# W5 t% m% O5 d% \4 E    PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
    3 _  u$ g% C3 O    if( pPlayerData == NULL )
    ' q+ f& g( F. `* E; x7 v        return;
    9 J9 M! K! H% I& i- v    LockPlayerData( pPlayerData );</P>8 @' L4 a, u$ [( D
    <P>    // Record the version number
    - J" W! q0 b1 V1 l! w* M- J2 c    pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>, M: ]  u: [8 I; q6 T
    <P>    if( m_bLocalLoopback )
    . d0 u. s! [6 I& {5 L/ z4 K, t        pPlayerData-&gt;bAllow = TRUE;2 }5 @1 a3 x% S- p, c  ^
        else
    ! f  x* x  D$ T4 X/ g" ]        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>
    9 ]0 H: V; Y: T4 G1 X% t4 e7 r<P>    if( m_dwLogLevel &gt; 0 )
    % ]( J6 K9 y: T+ M0 Z        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>
    . L" d: z# r% O1 `<P>    if( FALSE == pPlayerData-&gt;bAllow )
    0 r( d9 {4 M* N/ h1 V    {; [& R/ u* x: Y2 N
            if( m_dwLogLevel &gt; 0 )! Y' R1 j4 r# I
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>
    ' v1 n# G3 }2 [" F<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    ( s+ }6 f1 m% N        UnlockPlayerData( pPlayerData );$ Q. s" h  Z" w; u+ i
            return;  _* ^# }4 a6 g; |
        }</P>6 A) g4 O( n  s+ ]
    <P>    // Unlock the playerdata
    4 @. B& n- N  D1 a/ ^    UnlockPlayerData( pPlayerData );</P>  ]' l4 i# F6 @3 j! D2 R; d
    <P>    // Send acknowledgement to client that the client was either accepted or rejected
    + P9 Z  f9 H4 O+ N" s9 l7 t    ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );/ p) s# Q0 n& @
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
    $ {9 \, I4 c' B9 D$ d# v}</P>( G! v0 x9 i$ {9 M
    ! A1 I+ }+ A6 ?/ U0 p) I
    <P>& _+ g' ^8 u9 e( `& L
    //-----------------------------------------------------------------------------
    - C4 D: r7 Z- @6 }// Name: 1 i# v; F  j% Y8 Q" K- n2 K
    // Desc: 3 ?, s$ d9 d2 P, _
    //-----------------------------------------------------------------------------+ X) n/ t4 ^. `7 R: v
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )# N- O7 S' B. u4 n1 y, m+ [/ f
    {+ ^3 d* s, k" P9 O4 r+ V3 J
        switch( dwClientVersion )
    3 Z* N6 h1 J  o    {
    / x, o1 |: z2 e+ f5 @7 e" l        case 107: // only v107 is supported; H3 `' b: N- f8 G
                return TRUE;3 J% h& i, W; a$ ]
            default:$ [2 m6 `4 ~8 g1 j
                return FALSE;
    ! N* A: z- t9 `2 j( P    }
    # n; u8 ?. i# O7 y, ]3 A5 \}</P>
    7 U8 T; g; O7 O' U  ]: R5 B
    / A/ M% \1 z1 G) W1 L1 q9 _<P>
    ( g0 a$ F4 r$ T/ F! {9 @; k* `//-----------------------------------------------------------------------------1 r* d) B0 d' C% z# e
    // Name:
    0 o( Y5 Q* X% D7 n( s7 P. ^* }// Desc:
    " P/ w' A& X) X! V( C8 {1 i//-----------------------------------------------------------------------------1 J8 f! z5 D: ~) B) H( J# m0 a/ D
    void CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
    8 P' ^% x" W& y& e& a' s: c{
    ( d* V) x) V3 l3 ~* |    if( m_dwLogLevel &gt; 1 )% J$ P& |% U; K% n
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>
    ) h" Z2 u0 A4 o! x6 S<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );- l8 @. D; C. Y( `7 `* u
    }</P>* W* ]* U' U: {5 i6 ~( Y; b; D

    * x: @  X; ~2 G: }% j- p  T<P>! g) A4 p! I; `$ i, D% P, f
    //-----------------------------------------------------------------------------
    , ~5 u6 L1 y# ~* Y% U! \// Name: " R' c& f; k  A/ {/ u/ i
    // Desc: & L- X# a7 Q- x$ m5 f' _& k  `+ Z
    //-----------------------------------------------------------------------------
    * S  G% j2 ?$ D1 T: |2 uDWORD   CMazeServer::IDHash( DWORD id )
    ' ~5 k8 i8 f/ p' k  g" e  D  X{
    ) S! b6 W9 d" K; v) J6 ?% z    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);
    - I" H: F$ n0 u% d4 h' ]    return hash;- T" g& L: b) C1 I' X5 T5 m5 A
    }</P>
    ( Y/ x! w: O1 x, N0 U0 A  ?4 Q0 I" \) l+ d( y
    <P>" O" t( t" s& F7 t+ x
    //-----------------------------------------------------------------------------
    + j3 k" [5 F" A3 c& D// Name:
    + Q# ~+ F! ?4 g% n% |- o; W! W// Desc:
    1 y. v, L3 Z1 F! U; }5 U//-----------------------------------------------------------------------------* A$ b$ \) o4 @% |5 b+ M  e5 G5 ?
    void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
    9 g' [- ^; m; a5 G{
    ( b: _; K5 [9 p* V    // Hash the ID to a bucket number$ j: T) R* ^0 v0 p" b
        DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
    ) H  }9 E! W6 q" D) }<P>    // Lock that hash bucket; x0 V" u; s+ z4 b2 G/ a
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;- X- O( ?; ^) l: [
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>0 ^8 c% }' K: L7 t' u  M! b9 w$ j
    <P>    // Loop though players in bucket until we find the right one9 j7 v+ I. L5 B* `' x: w
        PlayerData* pPt = m_pstIDHashBucket[bucket];* j* S% A8 m- w9 Y, P% _' V0 d8 O
        PlayerData* pPrev = NULL;
    ; |* ?. Y4 d1 m+ l% J- H    while( pPt )
    : S4 a! Q9 a: c. _) ~9 ?    {
    % ^3 O) U9 e% b  `% c% M        if( pPt == pPlayerData ): U7 P, ~/ B0 r4 ?6 ~3 x
                break;7 F0 ^+ j" u1 V8 ^3 r7 ^% C
            pPrev = pPt;
    * W8 U  B% k2 f2 H        pPt = pPt-&gt;pNextInIDHashBucket;: H0 x/ F3 J  g! ?
        }</P>8 R& O7 K0 `. O8 w1 A# z
    <P>    if( pPt )1 _4 Q+ m5 m4 U% _! V8 Z6 {
        {+ f9 o) S) O( \0 @: F
            if( pPrev )
    " j: y* f$ w! E$ R% p! c/ b            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;
    + C$ f* }2 h! T3 B  T0 [- A        else6 G! h( i* y; R
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
      ]% w0 s; S/ T# O) L2 {" \/ z        pPt-&gt;pNextInIDHashBucket = NULL;1 {! ~# i8 m. I, Z( x1 i( H6 b
        }</P>
    7 T' `* b( M. p: J; \6 F<P>    // Unlock the hash bucket
    5 K) f; G* `6 t: ~( M0 f    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();, d" \& O( h& `! ]
    }</P>
    ' ~1 M, O+ Y) S5 m
    $ y6 P; C0 `  _1 q$ u  b<P>& ?( o7 ?9 ^* M( a, R
    //-----------------------------------------------------------------------------
    $ b% {; m, Q) p( p- y% \! f9 z' K// Name: 0 P; [( O# n5 J" @  E/ o& i
    // Desc: " A; J1 `# S! E* b; O5 ~* ]
    //-----------------------------------------------------------------------------
    $ u0 M5 O: N" {8 l! Lvoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )+ |* K4 g" m9 a" v
    {
    + R# Z. T/ C8 h* h* a! K    // Make sure this player isn't added twice to the m_pstIDHashBucket[]/ u* O7 [3 A; a+ \
        // otherwise there will be a circular reference1 w3 r* v! y' B4 O
        PlayerData* pSearch = GetPlayerDataForID( id );) U$ X# }+ [6 k9 N! g
        if( pSearch != NULL )
    2 B5 u4 U4 x! i% G0 w1 F        return;</P>
    * I7 A# s0 b0 d) q4 c. A<P>    // Hash the ID to a bucket number  f7 `! H  J$ T" I; U
        DWORD   bucket = IDHash( id );</P>. m1 b; _" H1 k$ A$ L9 R
    <P>    // Lock that hash bucket  a4 ~1 k; A2 u( S
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;% o/ w0 [8 k9 \$ Y, [) K" A" i  |7 m
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    & V; M; b/ S) F  O- l0 f( z<P>    // Add player onto hash bucket chain
    ' f6 Z4 b+ @- h    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];- `; l- h1 h% S+ T+ m8 b: X
        m_pstIDHashBucket[bucket] = pPlayerData;</P>
    2 z5 |4 T) X' o7 `% K5 B<P>    // Store net id in player
    7 ?; R; b1 d  ~) ~    pPlayerData-&gt;NetID = id;</P>" V, W# o8 ^; r6 ?/ Y4 P8 e
    <P>    // Unlock the hash bucket4 Y7 T2 [: o1 f8 a( v  w
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    . S" c9 \. z+ x5 ?0 |}</P>
    7 \4 `$ n  Q; U1 N- z
    ' U; u: q2 M/ l4 ^! u<P>* L2 Z; h( z# ?4 {9 ]
    //-----------------------------------------------------------------------------
    , w$ f7 a& _, f, F// Name: ( U. l9 q( y; {  C; D! X
    // Desc: . O$ q9 J" @$ {1 g
    //-----------------------------------------------------------------------------
    + O: W" K4 Q( A% J2 }- O: @PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )+ H7 G- [5 @% A" T; J  W
    {8 u* }8 y& C% c8 w. |  l  V0 q
        // Hash the ID to a bucket number# t  K6 }; ^" K+ K3 s  `
        DWORD   bucket = IDHash( id );</P>
    & B6 X0 z8 @1 o. O  N9 D, ?<P>    // Lock that hash bucket/ Y: u) o: G$ c+ [+ T8 F2 V
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    / x) ^9 A$ o% n6 L% n9 q; c    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>" ?+ v+ q1 E3 d8 I* D5 @
    <P>    // Loop though players in bucket until we find the right one  r2 u) t' f4 ~( W- g7 L9 W
        PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
      s; f3 z  D( X    while ( pPlayerData )
    ! o1 M7 r" k0 G& S- f9 d7 q    {
    ) `$ r+ g9 Y8 T        if( pPlayerData-&gt;NetID == id )
    % X0 Y3 @* R% r  L) ]+ Y! Q0 i            break;$ U. U( Q! ^! c% c
            pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;/ ]: @5 J) [& F3 o
        }</P>
    3 n& e: U# Q- X: i/ g<P>    // Unlock the hash bucket
    3 `; N: A% d2 d4 Q# m: z    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>
    : A$ k! A: T2 j6 F  s: q, b8 g" L# @<P>    // Return the player we found (will be NULL if we couldn't find it)$ t0 [2 \, {& l6 P1 K; g5 \# z' \" B
        return pPlayerData;
    5 [2 B6 q% U2 y# w1 J  \}</P>- a1 X( t  {# O
    % h+ X9 V: ~$ R1 [6 ^+ i. v
    <P>
    " L0 B; ^, v# W" \3 d0 H! S" Y% |  q  N//-----------------------------------------------------------------------------
    $ L) t" r2 o* a// Name: 8 R. V+ L% B& t5 H
    // Desc: calls DisplayConnectionInfo for each connection in a round-robin manner7 S$ L* {" s* m7 h: \" _: ?* h
    //-----------------------------------------------------------------------------8 p- u/ C2 e% s4 @
    void CMazeServer:isplayNextConnectionInfo()
    4 Q, _/ T" N7 S( M$ Q, y{! ~; ]# E$ z) |5 E
        if( m_pNet )' q: d; n( X: V8 q, o
        {0 L% V6 U& e  d" b
            // Find the player that was displayed the longest time ago, and display it.
    - R+ k- h0 X1 |8 ~        FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
    + v4 {4 i+ r, h+ c# J8 H* r        PlayerData* pOldestPlayerData = NULL;' H4 r6 V0 ~. v1 w9 {$ o6 q* ?) y0 O
            FLOAT fOldestTime = 0.0f;</P>
    , \3 [" Y9 Y( m/ C% w  d5 x<P>        m_PlayerDataListLock.Enter();</P>! R( t/ y( M0 @) h
    <P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
    3 n, H+ ^$ e- a1 C* l. c5 D        while ( pPlayerData ); K+ Y  {' r4 g) t  B
            {2 |) \! r+ U4 n( T% N
                if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
    5 y) j9 c2 w* u# S4 I            {
    8 |4 |) p3 V2 c& v, k4 S                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;6 n. G: t/ u! N- B
                    pOldestPlayerData = pPlayerData;
    : b& ~$ ]! p' j0 v+ {: S8 Z            }</P>
    8 e. G. X1 N+ j; p: O3 X8 O<P>            pPlayerData = pPlayerData-&gt;pNext;
    0 z" v' {, Y% f" Q# z( n- x        }</P>$ B, p$ D( i7 t0 A7 e  f
    <P>        // Display the player with the oldest CI field, and update its CI field.- c0 c0 |' S- F3 i* P  p, `
            if( pOldestPlayerData )! T8 M; o% _9 }! F
            {
    / }1 o0 n) f- X7 S            ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );+ c0 o; t! n% K& k
                DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );6 D; J3 J, B8 k
                pOldestPlayerData-&gt;fLastCITime = fCurTime;
    " D6 ?7 Z0 b% W8 \; [) X5 {( s        }
    ' G9 T+ s+ |2 T* `        else
    $ \$ y6 `6 O( R) M, ]9 ^* K        {: `  H# I5 Y$ T) Y
                ConsolePrintf( SLINE_LOG, TEXT("No players found") );8 I% C+ Q" @( Z+ S8 P6 M
            }</P>
    " n' {9 B2 [. [" g<P>        m_PlayerDataListLock.Leave();
    ! s  R( i6 }2 p9 N- @6 u' k    }$ A3 r  [0 \" P0 X  h# O3 p* S
    }</P>" V& j% }! u- r

    % h5 t4 v# h% }% F/ h0 k6 {<P>
    9 }; `/ ]8 F5 d3 O//-----------------------------------------------------------------------------( v3 J/ s9 Y6 x
    // Name: 5 y6 F- z# u( P8 ^  w
    // Desc: 5 N' m! x  E$ C9 @1 Y
    //-----------------------------------------------------------------------------
    : L6 O# B1 [, ^void CMazeServer:rintStats()- D1 m4 T/ G: u/ w! x( p
    {8 l. a) e; `- C  T5 D6 U  U8 l
        ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
    : M* P# s8 e& ~! \; b7 z9 E0 v' x                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );/ w9 ~' R. R2 |4 ^; y
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),, q0 Y8 R; ^! f0 ~9 r/ }, Y
                                        m_fAvgThreadTime, m_fMaxThreadTime );
    & a1 `! M' V+ p& L    ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );$ K2 s! l# f- y
        ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );
    - x6 F/ i/ w* w9 ]. i}</P>( I" L2 r6 C* E1 b
    ' G- P! f4 x5 ?& [$ b) u, `
    <P>
    3 ~; B6 L/ f" O3 `: f//-----------------------------------------------------------------------------
    6 ?8 i( M1 j, P* B: E/ w" ^// Name: 2 L% R) L- k" T8 k% `# u; m  I
    // Desc: ; O9 j/ d  B; Y7 a+ g" s5 f
    //-----------------------------------------------------------------------------( p; t0 a% T# ?. V$ a8 R/ q
    void CMazeServer:isplayConnectionInfo( DWORD dwID )
    3 U  ^% _: y& \{( I) I' M2 K, e  r/ {* L
        TCHAR strInfo[5000];  N5 J, r, {5 D1 q8 Q
        TCHAR* strEndOfLine;
    6 T# P3 G, a9 M* @    TCHAR* strStartOfLine;</P>
    # v: q; h% R" ?  L8 H<P>    // Query the IOutboudNet for info about the connection to this user
    & l3 _% Z" L2 |3 Q+ ?    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>
    ' P5 D' m; O0 g8 v; R1 g<P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );
    9 d/ P4 k- |- o7 U; ]7 [( l    ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    2 w) H3 Y7 {( ~  ?3 y' {' [<P>    // Display each line seperately
    ! w' z: }" z! g0 ?. S4 e7 Z( E$ i: U    strStartOfLine = strInfo;
    # i! e5 S$ T, J    while( TRUE )
    & g: @' f- R, ]  r  L6 ^    {. F; h" c. k0 w( l5 [5 y! Y
            strEndOfLine = _tcschr( strStartOfLine, '\n' );
    ' ?* T2 z6 X1 Y1 v2 u! f$ t% p8 V        if( strEndOfLine == NULL )4 ~* r5 s( y  E8 c7 e+ p6 C$ a
                break;</P>
    / }3 ~0 ~' H  z, n<P>        *strEndOfLine = 0;: n8 w$ A: L3 p! Y& d2 [4 s0 I* m
            ConsolePrintf( SLINE_LOG, strStartOfLine );7 y5 G2 d7 X6 {1 y, {8 s2 h
            strStartOfLine = strEndOfLine + 1;
    : k" e1 x* B. r: a- o3 o    }* B, x1 G3 [' [, c. v- N
    }</P>
    2 S- N' t: b; i1 F
    2 P4 u1 b1 O% |- F' @  z<P>
    1 h+ F6 }+ Z$ @5 d1 L//-----------------------------------------------------------------------------
      q, x9 \+ L2 J// Name: ! E+ v( F) }. i% c4 ~
    // Desc:
    $ d# d( C8 }/ {) s//-----------------------------------------------------------------------------
    8 G8 I: m8 @% X0 d( I/ RHRESULT CMazeServer::SendPacket( DWORD to, void* pData, 6 s, Q. H1 Q. f+ y
                                     DWORD size, BOOL reliable, DWORD dwTimeout )
    3 {' u: i0 w* q2 H9 m' g{
    ! U" n/ V- w% `    // Chance of forcing any packet to be delivered reliably) H/ K" C* F1 f
        if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )
    $ [0 p0 H% ^# T        reliable = TRUE;</P>% S* J' i4 K0 n, l
    <P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );9 z$ H( Q) p9 t: m# ~$ l
    }</P>/ D9 ]* X  {; u5 O/ c6 i) _
    8 Y$ h  L, o# I
    <P>$ k+ ^5 o$ k$ z/ _! p3 w
    //-----------------------------------------------------------------------------
    3 \/ ?; U- K4 g- O6 p' w5 Q- g// Name:
    ! u. @" _% ~8 ?1 M' b7 U// Desc:
      c) w! ]+ @$ `. V! r//-----------------------------------------------------------------------------
    " `. W- h; o$ z8 w' c9 Nvoid CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )+ E2 B7 w: @" Z
    {
    0 J2 V, k- W/ {' L    // If we're up and running, then send this new information to all clients1 |. w( X( I: K+ f1 {, {5 _
        if( m_pNet )
    7 P& G+ r  G" O- m. n$ H    {
    ) a9 W6 ?4 ]( f4 d6 M        //Use the AllPlayers ID/ `* D( ^6 f% J0 [7 p
            SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );
    : _/ Z* W" N# F; i    }
    6 h8 J1 C+ j6 r6 L+ ~6 K# W}</P>' o: B# {2 p' P& T

    , i$ C2 |& Q0 Z. s<P>
    8 K' t6 d' O; j. y3 D2 V/ }//-----------------------------------------------------------------------------
      G  {7 l5 W4 \% I- n// Name: 9 E9 d0 T3 k; E0 \& H. b- J0 G6 L# F
    // Desc:
    ; W+ i! `/ H9 {//-----------------------------------------------------------------------------0 `# g& H' T5 ~4 H' Q% g
    void CMazeServer::SetClientReliableRate( DWORD percent )0 C; l" K1 H$ N8 t
    {
    ; t) P, o2 f7 J7 r  I0 ^# o* `    // Update client config, and build packet containing that data
    8 i' k* F# V- d    m_ClientNetConfigLock.Enter();
    ; Y. n! h2 Z  @/ W2 w& n4 v- l    m_ClientNetConfig.ubReliableRate = BYTE(percent);
    % y( L! \1 J; g  g& w    ServerConfigPacket packet( m_ClientNetConfig );% B6 w7 }: k2 {4 y5 X
        m_ClientNetConfigLock.Leave();</P>- g1 W+ B7 X  n7 j
    <P>    SendConfigPacketToAll( &amp;packet );8 d; t5 ?, ~, ?7 r$ y- ?
    }</P>
    . z$ G% x9 o- V- ?( H) e1 n8 i4 T, ~9 e9 {; j  i
    <P>/ _: |* Y& Y6 u) t# P5 e6 y
    //-----------------------------------------------------------------------------
    " O) x& U- y* @8 i// Name: ( v$ b: U  E* a) B3 o0 i# d
    // Desc:
    ( S# g9 @6 d4 I- {. P//-----------------------------------------------------------------------------
    9 q* `+ I2 h: Q4 m( [' C7 ?void CMazeServer::SetClientUpdateRate( DWORD rate )
    8 j8 K: d3 E% `5 |2 M/ j{
    " d: t, O5 H( E& L    // Update client config, and build packet containing that data; l( u1 D0 e- s& j; x. |4 _
        m_ClientNetConfigLock.Enter();# y0 Y6 F: t! O! \: J9 U- V
        m_ClientNetConfig.wUpdateRate = WORD(rate);: B% \8 N+ T9 B& n9 r
        ServerConfigPacket  packet( m_ClientNetConfig );+ `; J! l; P+ u) e
        m_ClientNetConfigLock.Leave();</P>
    , B* `7 x- W' p" R8 i* J/ M* k<P>    SendConfigPacketToAll( &amp;packet );
    * q' @! L, E% U% K7 M  L, Q8 w}</P>
    2 u: M2 F7 z! f3 C0 X! B
    8 b2 D  Y# L, @+ a& f' i<P>
    8 i- D, Z0 \. ^9 q5 _//-----------------------------------------------------------------------------
    9 z+ b! X$ }8 w; H// Name: . z! G  R5 G# ]2 Y+ @0 `4 V
    // Desc:
    ' B7 A4 s) _$ k) X* t//-----------------------------------------------------------------------------
    ' o' l7 i, J, M1 Lvoid CMazeServer::SetClientTimeout( DWORD timeout ), x# \+ @/ O6 c& K
    {
    / Q* m) d9 {& g3 ~( |7 F* l& G3 J    // Update client config, and build packet containing that data
    8 V* _+ ^# r$ C1 l' ^6 p/ n    m_ClientNetConfigLock.Enter();
    - w( H( N; ^6 F; Y8 o) J5 \" `    m_ClientNetConfig.wTimeout = WORD(timeout);
    / r( {8 R1 ]) M- i% f6 ^& ^$ z    ServerConfigPacket  packet( m_ClientNetConfig );
    ' j* y0 S: J7 {' o; A) }0 E2 k3 [$ q    m_ClientNetConfigLock.Leave();</P>* d7 f' u% D- m
    <P>    SendConfigPacketToAll( &amp;packet );
    4 i# q/ [3 R9 [6 U; [) P- e0 S+ D4 A2 K}</P>3 q7 ^! q8 v0 M& r9 I8 t/ Q

    7 x, M" f2 u6 e<P>
      b+ |  p( M) g$ ~! M//-----------------------------------------------------------------------------
    6 c8 j3 h8 D3 b; L) N+ m// Name: # l1 j7 T6 d: B& z' S3 A" r
    // Desc:
    : [* R1 Z6 s/ i% {- X. t! L, M" `//-----------------------------------------------------------------------------; n: S. N0 M  x$ M' s2 D, x8 K, s, ^
    void CMazeServer::SetClientPackSize( DWORD size )$ i' U' g9 {  t& R& {8 Y
    {! w8 h. R" O" Y1 j$ M4 m$ B2 X
        // Update client config, and build packet containing that data4 W. O( [  x* H* t$ B
        m_ClientNetConfigLock.Enter();+ b+ h$ V# a2 V
       
    " f9 f/ w) m5 X3 Y$ G7 J    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.
    ; {  r$ @2 ]' p9 q, R; N    if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   
    1 C3 o* n: O( g, z9 v        m_ClientNetConfig.ubClientPackIndex = 0;</P>
    ) R# J7 O4 }' q( |4 y<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);4 J( {% b, i8 T8 b1 s( d; s$ J
        ServerConfigPacket packet( m_ClientNetConfig );
      i4 ]6 d, q, H- D* T8 x- r' z    m_ClientNetConfigLock.Leave();</P>2 j9 j4 B8 M& R' b4 O; n6 w
    <P>    SendConfigPacketToAll( &amp;packet );
    . y$ z% X0 `2 h+ p# p0 U}</P>' n$ b& }/ w# v8 e1 o8 D
    6 f' o. H' S% `% q
    <P>( c) J7 e2 ^8 a6 w' Z
    //-----------------------------------------------------------------------------( K+ B5 w( E! _' H$ x
    // Name:
    5 }6 s9 T0 B3 y2 e" ^2 e+ O// Desc: 0 x) f, [" F1 O
    //-----------------------------------------------------------------------------
    4 D5 h5 B5 W) }( h; X; Qvoid CMazeServer::SetServerPackSize( DWORD size )/ b8 g2 l" j1 j2 B
    {
    6 W7 U1 [* s* x4 u    // Update client config, and build packet containing that data
    1 [$ F* ^5 t" Y( ?" z    m_ClientNetConfigLock.Enter();
    # @* Z  j* `) Z/ K    % T2 f% ?: w) F& a, c2 K+ `
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.
      w& ]) a9 E+ H! o, u; \& [# e7 f    if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   + o$ m" J" ^9 U" }2 ?
            m_ClientNetConfig.ubServerPackIndex = 0;</P>
    - v9 J# l& c" s9 I5 H, E' }<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);; D0 [0 h6 b6 P5 R9 b/ s5 l4 @
        ServerConfigPacket packet( m_ClientNetConfig );/ V" ]: u; R2 O' b
        m_ClientNetConfigLock.Leave();</P>
    9 X# H; u$ q5 z9 m<P>    SendConfigPacketToAll( &amp;packet );" l  W8 b$ O8 H' o9 n* _
    }</P>
    ( k: i6 g) N& _! }! H<P>
    8 S  Z5 L! U+ {$ R8 X//-----------------------------------------------------------------------------0 n# Z' G1 S/ w$ k& j6 G( w5 b/ a
    // Name: - w) y& x6 E$ _% e9 o4 I
    // Desc: 1 W0 A/ Y' b! I3 a
    //-----------------------------------------------------------------------------
    9 g( y; R3 P2 Zvoid CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
    * p1 X8 k7 H1 U9 w9 ^: m5 b3 Y{& o- Y% J3 h: r1 ]2 `0 K
        // Update client config, and build packet containing that data
    0 G# v. K7 c, M" Y! Y# C& e# U: |    m_ClientNetConfigLock.Enter();5 H7 m7 b% k$ f8 m& j' K
       
    ! h+ D' g4 ?* d& i    m_ClientNetConfig.dwThreadWait = dwThreadWait;
    " W$ H6 O% z: Z1 `3 J    ServerConfigPacket packet( m_ClientNetConfig );
    : M# H% {. d) Z1 B) Z/ W    m_ClientNetConfigLock.Leave();</P>
    # ]' Q( r- f% x<P>    SendConfigPacketToAll( &amp;packet );3 V: [% {7 }0 A. n; @8 g& Y+ g0 H( m
    }</P></DIV>
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2026-4-10 18:50 , Processed in 0.416093 second(s), 50 queries .

    回顶部