QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4167|回复: 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>
    $ U0 e' q6 y8 v5 W& K; h1 m- ^2 f<>// File: mazeserver.cpp+ j+ Y+ H) J" T7 Z3 u" H; ]0 H
    //5 f( ]- D5 w. i1 T6 W) j9 {  m- }& b6 }
    // Desc: see main.cpp6 K: A* z  G$ c0 z: E: h! F: G$ g
    //
    ' Q9 ~% i0 |# n" h// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.2 l- d) P3 J) }- `" O- y) _4 B
    //-----------------------------------------------------------------------------, V  k1 T7 _! _. @/ ^
    #define STRICT
    6 C' z- c& F+ ?% Z- n1 u) u#define D3D_OVERLOADS
    7 o9 r( q; c+ O' n5 J5 |+ S#include &lt;windows.h&gt;
    , n5 F2 [  y! i" B, z& ~5 t#include &lt;d3dx.h&gt;
    & p" W, p' S. u0 w, z#include &lt;stdio.h&gt;6 y$ i- E* A3 @5 y
    #include &lt;math.h&gt;
    ' `7 V) J  Y: u# Z3 k7 G#include &lt;mmsystem.h&gt;/ M5 n. r6 A/ W+ f) ~+ I
    #include &lt;dplay8.h&gt;
    ! ?1 K1 f6 [, q% e) W$ _) e#include &lt;dpaddr.h&gt;/ v* T. j' ~6 I% o( I  j
    #include &lt;dxerr8.h&gt;& t' C/ z8 ~( C) c* S) @4 N
    #include "DXUtil.h"& q0 b, N" I0 Y  _$ l
    #include "MazeServer.h"7 Y: K) W1 B. F5 d( T, g8 V  H9 ^
    #include "ackets.h"1 v3 i; N$ ^- o2 R" i
    #include "Maze.h"
    # Z4 r/ Q& `' E) o+ G6 @+ s#include &lt;malloc.h&gt;8 `2 v/ q! R' ^' f+ e) `8 V! z
    #include &lt;tchar.h&gt;</P>3 c. _1 Y( x' b1 _5 h! P

    1 c& V: d9 t/ l$ }5 e% m8 q! B! Z<>//------------------------------------------------------------------------------ u% \: g; H+ `& [5 R/ Q
    // Name: , b1 ?+ J9 T* O/ x) z# [
    // Desc:
    0 d( i6 G- P$ z7 a" p! ~//-----------------------------------------------------------------------------8 }7 C$ ~% Y. a- s5 [
    CMazeServer::CMazeServer()" H3 |" K( P  _) I6 q
    {
    ) ?' |0 p9 ^6 d! ~4 v9 J    m_dwPlayerCount         = 0;
    0 t- T# p1 \2 s, U5 l   
    6 S- h7 q3 N- I- L5 J, b: d( d    m_wActiveThreadCount   = 0;
    ( O  _" S. C, |    m_wMaxThreadCount      = 0;: [" V( }3 M4 c0 `
        m_fAvgThreadCount      = 0;
    0 F, A& p& E" K$ }! u    m_fAvgThreadTime       = 0;
    ) h, M4 i2 G2 Y3 a6 ~3 @    m_fMaxThreadTime       = 0;</P>& Q! g( m* J0 J" u
    <>    m_dwServerReliableRate  = 15;8 n: J2 x9 b5 E  H# `6 f( m: R2 C
        m_dwServerTimeout       = 150;
    1 m4 u2 ?( n- C  P    m_dwLogLevel            = 2;$ G9 D5 `  a- L6 H  L& |
        m_pMaze                 = NULL;</P>
    " g5 q% n5 |" A7 G: @  h4 t0 Z: ?; n; q6 Y<>    m_ClientNetConfig.ubReliableRate = 15;, u8 _; E! f8 t% X
        m_ClientNetConfig.wUpdateRate    = 150;
    ' M  x( w& x# b& P& j* e: n    m_ClientNetConfig.wTimeout       = 150;</P>
    3 z- H2 Y+ {/ B- D) d9 _+ I: d3 }<>    m_ClientNetConfig.dwThreadWait = 0;</P>
    8 G* t4 \( z, [0 v# O" I' N7 Q<>    m_ClientNetConfig.ubClientPackIndex = 0;' z- ^  S5 a2 W' t+ z. A
        m_ClientNetConfig.ubServerPackIndex = 0;9 `  W0 V* I6 F, Z; v3 e0 m+ `
        for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)+ D% n; }# i5 O% Z7 t* f
        {- P. ~: v; b: Q6 Z6 p' M
            m_ClientNetConfig.wClientPackSizeArray[x] = 0;
    ) ^" ], k8 m) t1 J. U! |        m_ClientNetConfig.wServerPackSizeArray[x] = 0;
    1 o+ G. u( {) k2 B    }
    9 U5 {* F9 I( z' o1 |2 J}</P>
    5 z6 T- h" {/ X0 k  B
    9 t: A6 i0 |( S<>
    9 q) g& h4 F# T  A+ v/ p6 R//-----------------------------------------------------------------------------
    ( Q$ x2 O1 U7 t0 ?, N9 Z// Name: ( o+ F8 P" G3 ]* e0 \& u' K6 y6 z4 a
    // Desc: ; m* s$ d0 u- m! m
    //-----------------------------------------------------------------------------
    0 X5 C3 Z* G9 pHRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )$ K6 ~# ]- e; B/ D
    {: K; m( w3 k) ]* h; ^* D
        m_bLocalLoopback = bLocalLoopback;
      {5 w  R- s  P; G0 i, j, S    m_pMaze = pMaze;# u7 u  ?. j! H4 X, B: c) ?
        if( m_pMaze == NULL )# T4 w! J- \7 L9 V
            return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
    9 [/ w5 [% W6 ^( U: t7 C<>    // Grab height and width of maze, Q: R1 G" ?. d$ W7 M. A
        m_dwWidth = m_pMaze-&gt;GetWidth();
    # d9 p$ J. z) ?) Y8 e    m_dwHeight = m_pMaze-&gt;GetHeight();</P>  q/ i0 U3 y: l2 E
    <>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    # t) t0 u/ U0 @& c. {    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
    2 `1 M% z; M: `0 s+ }' E# O<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.
    - d/ p( W8 u0 \: z) v; a. F: g1 D1 \, b    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )8 R. K* m/ r4 Q
            return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    3 u7 G# w& n0 T    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )5 J5 q- s/ g7 [: f: B0 a% T
            return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
    ; e+ P, g* i% q' ?' ~% J, q3 [<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;
    5 A9 o! b, f& N+ Z$ U    m_dwMazeXShift = 0;( k! V- e: I# i. p* C' W4 d& `* P
        while ( (scale &gt;&gt;= 1) )+ `! X7 }/ x5 @" u7 P# o( D/ Y
            m_dwMazeXShift++;</P>$ n) |/ a# E' v6 o* g
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;
    - z8 X6 U8 _" ], _4 m    m_dwMazeYShift = 0;
    . u  v' c7 C' a/ q/ l8 n& f9 ^% o! \: n    while ( (scale &gt;&gt;= 1) )7 V; Q: j# n/ `
            m_dwMazeYShift++;</P>) C5 O: g2 l' h6 \6 N" i
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    # i3 Y0 z2 b9 w2 S  o9 l        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )
    1 T$ Z! |# K; {5 n; t3 A        return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>7 T/ t* v; \* x
    <>    // Initialise the player list& R0 X& W% Q6 u3 M+ r
        ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );0 c% _1 f: y; l5 j8 U
        m_pFirstActivePlayerData = NULL;2 k& N( \/ x$ w# w' |5 l
        m_pFirstFreePlayerData = m_PlayerDatas;# B2 o' P1 L3 W+ o
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )
    3 R/ ^9 W* r$ d, b/ ^7 s7 f) I    {* S; T1 B) [0 {5 t6 @) q/ \: A
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];  s7 |& Q- ~+ [- t( `
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
    , t8 h1 Z, B( F) ^+ z    }</P>
    ( `) I$ E$ Y" f3 P/ i. A# w5 J% c<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
    $ c5 P" w5 e4 i# y) {3 R    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];
    2 v6 F9 `! [9 s" e    m_dwActivePlayerDataCount = 0;
    & C# `8 ~6 o# ^# {+ N    m_dwPlayerDataUniqueValue = 0;</P>
    % X3 Y/ y& h  d0 S  P1 H$ D) F<>    // Initialise the cells- L, C- B3 U5 f7 J. x
        ZeroMemory( m_Cells, sizeof(m_Cells) );2 O9 m  k/ _$ b9 q" y+ Q  @
        ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>8 Q' M$ M' Q+ C  Q) s
    <>    return S_OK;
    9 L6 X+ ~( N5 ~7 D* _% H; c}</P>
    $ w' g6 C: @+ e& z: D( p. r# Z$ r' k9 Z
    <>
    2 D, V6 R8 p, N# a& D* e# x//------------------------------------------------------------------------------ U# m% g5 s% Q: G( f8 L- m7 G
    // Name: % [& `* n# u6 Z& S3 w
    // Desc:
    7 O( c3 l' u+ C% x. _( r- J4 D//-----------------------------------------------------------------------------
    , L% s0 m/ D" ?$ g% jvoid CMazeServer::Shutdown()
    ; J  w. C. U( M8 \% j{3 `2 s! P/ I; g, c# \5 S7 I* l. Y
    }</P>
    7 o" b, X# B) Z/ ~& \
    4 d2 p% w8 m! R1 a+ x<>1 r' ~9 V# U) z7 U3 |2 o
    //-----------------------------------------------------------------------------
    + W% o/ E5 R4 z1 ^. p0 h// Name: ' i4 l& M6 e0 N5 N- x  I' V
    // Desc: : |* X! o7 C2 s" p; I* l
    //-----------------------------------------------------------------------------& K& V! O# m! I! I+ Y9 A% ~
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    ) |( M# O* X$ M5 Z# k/ u/ }9 Y{, [* E+ H+ `+ [: Q7 Y; {: y& @
        m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,# ]8 S" X/ I9 _- L1 i  }5 H; d
                              x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );9 U0 }7 _) w& l9 m; F7 Z- a/ j
    }</P>9 ^( P5 b. ?; A! y
    & s1 R" Y  @* x
    <>
    ' K4 w$ [6 z% _; W+ r# r- Y+ }8 `( G//-----------------------------------------------------------------------------  m9 Z# Y$ W1 P. w+ }
    // Name:
    / g8 ?4 x; p2 {- H( N  n// Desc: 1 K% }4 B& R4 x! u
    //-----------------------------------------------------------------------------6 K' x! _+ j- O; Q8 z2 i0 s6 J& {
    void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    * [( d4 w% H3 R' i6 n, V" d2 u{
    " R/ C3 [! p  f) x1 g9 S0 ~, W    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,* ~. D& c5 [" l5 H) R4 Y: I
                                x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );3 a6 D* x# F$ P8 |4 @$ L& F8 i" I
    }</P>' C- c0 [; M, C- K) f

    1 v9 ^7 q+ {8 [. U6 f, ]# h5 H<>1 M0 _) u* V& r" w% i6 X' X
    //-----------------------------------------------------------------------------9 a6 |1 `; ^! f
    // Name: $ e- {% Y, U: l7 `+ D* @8 @$ x6 h  ~
    // Desc: ( U3 z- I9 H& k
    //-----------------------------------------------------------------------------
    ; L% [0 \1 l! o( H* F4 Hvoid CMazeServer:ockCell( DWORD x, DWORD y )
    . i1 }4 y! e/ Q{2 q5 A7 ]% Z! ?/ a  E; N  v( @; y( D
        if( x == 0xffff )
    6 l5 V1 t7 m' r6 q: z( v        m_OffMapLock.Enter();
    - q$ _% f7 c5 X7 E    else
    ' E' H4 M5 L5 ~        m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);& F7 A9 B. f( M$ H
    }</P>, s0 s, e5 N6 o5 R6 H1 V

    0 t& p+ N6 @1 E- V: b* G<>- i0 E, Q' P) r  S5 `" I
    //-----------------------------------------------------------------------------, X- j) q9 o! g' {* ~) F. j. I! x! q
    // Name: 4 X( M; {0 m( F
    // Desc:
    0 A7 T5 E5 l2 d2 A  Y4 F//-----------------------------------------------------------------------------5 J6 s* |% D2 a, r+ f' {
    void CMazeServer::UnlockCell( DWORD x, DWORD y )+ W! f+ \0 L9 l+ Y8 b! d
    {" D6 V) D; k, {6 j* K5 j
        if( x == 0xffff )1 H8 n1 A/ k' g' p8 b$ P7 ]
            m_OffMapLock.Leave();$ @. C5 _% |+ _
        else1 P8 R/ d6 Y) W# E. H5 }( A
            m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);/ T2 H$ b# N' Z7 F' j6 V
    }</P>
    " W+ \  ^: D' z% E- G# C8 X( {) i% x* n  e9 w# Z3 W, e# V* ]$ P
    <>0 W! w+ Y9 p. g! Z; S
    //-----------------------------------------------------------------------------( }& v3 f4 [4 L8 L7 D/ Y( @
    // Name: - s" c( S5 k% [, w0 ^$ W8 t
    // Desc: ) G- c! r( N7 j8 k, \( j
    //-----------------------------------------------------------------------------) B9 s) I  r- w- ^# ]/ N& y" m8 ]( `
    void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    5 V. w8 s2 b1 k+ R{$ N6 r: g0 o0 n% m, I
        if( x1 == x2 &amp;&amp; y1 == y2 )5 G7 j/ M& A6 a( b& v
        {, _8 W; G" w2 i* Z6 I2 m! L
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )  ~: l6 ?! ]. U* _+ w  a) ~$ h
                LockCell( x1, y1 );* E0 }' R7 E4 S2 O: t9 \4 w
            else: M* A- E( m. S% n4 c. U3 Z* E
                m_OffMapLock.Enter();</P>* d* F* v4 c- t- C
    <>        return;6 b9 \5 q. s) R4 ?7 ]1 g, k" e
        }</P>- U3 u6 X# G' h. `  r0 I
    <>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    3 {) ^8 }! _" s5 Q    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    0 @# m0 [' r( E    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;' S8 z/ G# I! Y
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    + i; a- ^4 E9 `& B- C<>    if( x1 == 0xffff )- z' S# ?% V: y. e
        {8 B" n' N4 m) C+ o7 O+ R8 Y
            m_OffMapLock.Enter();
    ) J' k& w% ]) l9 l, K: z# ^        m_LockGrid.LockCell(x2shift,y2shift);
    " V6 I% H* v! y8 m& I; a    }/ z/ M8 Q, f$ n( [
        else if( x2 == 0xffff )
    # z4 R- P& x% Y3 O+ K0 ]7 T: _    {8 N' _- z4 @; N9 |& D
            m_OffMapLock.Enter();5 G; `& X. T: p  `" v; H
            m_LockGrid.LockCell(x1shift,y1shift);
    / c. p( y% H& o/ A    }
    ( X1 o' Y, r+ w7 q    else
    . j' c2 B& V# g9 d5 X/ _/ t8 Q6 Z    {
    4 y& E2 I5 T% B0 m, M$ U' g1 H. l        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);+ @# j; ]' z! b5 L; K
        }
    6 d7 \' a% d! i* ^. y1 H: |}</P>
    ; n$ r4 o5 |' s( G' m% {$ ]% o8 l9 d. ~* |8 k0 \/ A
    <># n; b: q  \" m8 P; E, Y
    //-----------------------------------------------------------------------------
    9 _& q, b) y% x" m4 g// Name: 9 }% A+ l, p" U$ B0 J* A+ v# `
    // Desc:
    # T, O2 e5 c7 a8 p* H//-----------------------------------------------------------------------------
    ) G! V7 k( ]) \+ ^0 N) fvoid CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    + }/ Q# E+ b) h, x{
    " j6 t' N- D  e* N' s    if( x1 == x2 &amp;&amp; y1 == y2 )
    ! S0 ?" A; A% a$ |5 J+ O    {
    + [# n1 n8 U9 Q  B        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )9 O7 ~( I' ~1 T( V! W. n) p  U1 Z
                UnlockCell( x1, y1 );; ^" w# p* O* K/ |: w: q5 j3 N: j6 ^
            else
    " B, `" ]9 Q! R* v            m_OffMapLock.Leave();</P>
    4 D! L3 P0 `2 Y7 X! M" i' E+ N<>        return;& f7 W/ i* G. q' |+ l. s
        }</P>
    - P+ b7 K) T9 G6 n4 K& \$ o% T1 x<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;: T3 B! f0 R! p# C1 p( ]* e
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    ; L% I4 r" d, _9 U- e    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;% {1 O: {3 U; d# ~
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>% D% p3 s" g2 G6 {4 P
    <P>    if( x1 == 0xffff )
    * W+ ^* m, K5 e4 f    {$ T7 ~) I9 j8 A( ~5 `
            m_LockGrid.UnlockCell(x2shift,y2shift);" a& L; m! A% B) `5 k
            m_OffMapLock.Leave();7 F$ `& ^3 R& A9 a
        }
    . ~8 o0 q: t# C- r    else if( x2 == 0xffff ). B/ \9 {! g& r* {$ x
        {" c: [9 P" }2 ]  b+ Y1 f
            m_LockGrid.UnlockCell(x1shift,y1shift);
    ( A; T  F& x/ Z+ S5 d        m_OffMapLock.Leave();
    8 M. S2 t  q- V3 Z* W- F# D9 T    }
    9 O, O* o$ b7 m( z3 j    else 9 K" b& D  O: k
        {
    ( j+ a" ]& o8 d/ e        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
    - F# H2 n$ Z# T" L    }- F5 b2 @) L; _0 E
    }</P>8 ]; O! \% A* m; x* \: \) z

    : Y# _9 B# U5 ]" K<P>
    % H8 i3 J; I( Z8 @* L2 F- w//-----------------------------------------------------------------------------/ a- ~) J. m% P# E) n( x" n
    // Name:
    ' d8 ?9 K4 ]! T// Desc: " ~8 o  y3 i1 P8 C
    //-----------------------------------------------------------------------------
    8 L! O8 g( B5 D* N6 dvoid CMazeServer::OnAddConnection( DWORD id )
    9 [/ A4 p0 B, z1 i5 l# W( e" R{
    ' t* s; K* P1 I: O, T    m_AddRemoveLock.Enter();</P>. ^3 P+ p( U! s
    <P>    // Increment our count of players
    6 s, |, [6 [4 h! ^    m_dwPlayerCount++;# P6 G* [4 _# N- O) v* ^
        if( m_dwLogLevel &gt; 0 )7 S2 E/ B' g* F
        {
    : r  O' N& I1 ~7 ]3 E2 N        ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
    " D& f0 b7 Y& i% ^" t3 M: o        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    1 l% @/ J' R9 G% G" v3 v0 o/ x    }</P>/ l9 q% n% y5 o. c% m. K
    <P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    ! Z$ S4 r" n$ z% l, N; B; h) g        m_dwPeakPlayerCount = m_dwPlayerCount;</P>, W6 B% ^& \0 B8 W
    <P>    // Create a player for this client! O* V+ y$ o0 ]
        PlayerData* pPlayerData = CreatePlayerData();
    1 Z# e) G7 l  D* n. |  M- i    if( pPlayerData == NULL )5 G( l5 Z5 j  z5 I# I' E
        {) T) M, W" y1 H! q5 L& ]: _
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
    * \5 j; Y/ @2 d* J1 K        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );
    + U, ^  Y) o6 J" H& v/ ~" d% s, d/ ?        m_AddRemoveLock.Leave();
    : \+ G) C! |1 z2 B        return;
    ; O! C% H( A# `  b& _9 y    }</P>5 h: D2 K4 ~8 k# y) l6 X
    <P>    // Store that pointer as local player data
    & Z3 Z! x1 y. M) Q" W# n    SetPlayerDataForID( id, pPlayerData );</P>
    ! ^' [2 ^( h: n  T7 o  n: }. m# }* L8 U  I1 m<P>    // Grab net config into to send to client1 p0 l' K& N, ^6 h2 ^5 f
        m_ClientNetConfigLock.Enter();
    5 k8 V$ g; o% ^% x- p5 l- W- j    ServerConfigPacket packet( m_ClientNetConfig );
    : Z5 G8 n/ X+ ~( f$ c8 }% G6 R7 r    m_ClientNetConfigLock.Leave();</P>
    / k$ u4 d- J" D<P>    // Send it1 ]& y& d* ]- ]  ]; e5 t6 t
        SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>
    " m5 `% N3 g, r5 h( a  \<P>    m_AddRemoveLock.Leave();
    - {$ v! E7 u; R' f1 ]9 z}</P>0 R* Y: K$ F' V% t  r0 k- E
    ' o8 [: O4 E% T6 k& r
    <P>; i: y. e8 S8 j6 s) b4 S1 D! {2 V# x
    //-----------------------------------------------------------------------------  T) R8 x& y7 n3 r
    // Name: 8 d1 P' v. n; n) j" j% l; p
    // Desc: ; w) \1 K3 [& _8 k
    //-----------------------------------------------------------------------------
    $ M0 M. l& D1 z8 ~& F. Bvoid CMazeServer::OnRemoveConnection( DWORD id )
    % |3 x" ^) M) \; D4 ^{  C+ D' F3 B, ]8 j( Q- ?$ \+ D" I
        m_AddRemoveLock.Enter();</P>
    ( Z2 n6 m1 R+ k<P>    // Decrement count of players
    6 y* O/ h" N7 @0 A* ?1 W# S    m_dwPlayerCount--;</P>
    8 N! o# q. y+ {9 m7 k<P>    if( m_dwLogLevel &gt; 0 )
    , p/ K' Y8 i. \( a    {
    6 a' D+ J0 Z# b, ~' K        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );( k& E7 k- J. i0 F  w: |6 \
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );& |4 g3 J' I( F9 k
        }</P>) \& g1 v9 ^; P; n
    <P>    // Find playerdata for this client1 h9 \) \! T  x. b& T- M6 y
        PlayerData* pPlayerData = GetPlayerDataForID( id );3 q9 e! l" e+ `9 K7 @
        if( pPlayerData != NULL )' y+ k- e5 Y/ w" K- n. ?2 f
        {7 ?& U  j+ {3 z9 c/ n! }- H& B' x
            // Destroy it/ N# H# O/ M& h& U$ o5 W
            RemovePlayerDataID( pPlayerData );8 _" _1 N/ y' N* g' t
            DestroyPlayerData( pPlayerData );
    ; N' M- q# }7 T    }</P>
    3 w/ ~4 y8 j/ W, H) i<P>    m_AddRemoveLock.Leave();$ a0 g$ z/ R; j  p3 L: N
    }</P>4 d7 \) }% M- U& N

    / t6 f2 w+ ]# e( j+ i2 Y5 O* Z<P>
    8 n6 m) S3 ^+ J* h2 u//-----------------------------------------------------------------------------
    " F- U4 J  w+ O# ]5 v// Name:   ^9 n) D1 E4 I& U( Z% v; P
    // Desc:
    & G1 u2 U! R: U$ ~  E) ?9 b8 _4 T//-----------------------------------------------------------------------------3 n8 F" j; d" m% _; T
    HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size ). l9 w6 _% P$ S0 V( ~# M1 _
    {
    7 }% u$ ?! [; u$ |6 [; F    BOOL fFoundSize = FALSE;</P>0 V4 j  F% ?  b0 |
    <P>    // Increment the number of thread we have in this process.
    ' K- n2 d* X/ m; q* T    m_csThreadCountLock.Enter();</P>
      ?0 I' H1 `) Y2 r" d7 K* }% L<P>    //Get the start time of when we entered the message handler.% \+ R0 w1 x6 {. i. Y
        FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>/ f9 b! n" x* m0 O
    <P>    m_wActiveThreadCount++;
    9 o  G+ Z2 w' Q+ Q8 w& e- V    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)
    & F8 X4 }- }' T! B        m_wMaxThreadCount = m_wActiveThreadCount;0 h& c  p5 P1 J7 M# s. w% y
        4 z$ f- u+ f% m; _$ k
        // Calculate and average.
    - {3 r. N  G$ b* t* U9 G' ~    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;- Q# j% p0 ^. T9 W/ D
        m_fAvgThreadCount += fdiff/32;4 I) D9 R; q- _% }
       
    3 [2 D/ d/ h  d% R* x9 N    m_csThreadCountLock.Leave();</P>9 j3 p7 I1 W" U1 G% u
    <P>
    " a: T# `  N: u4 K    ClientPacket* pClientPack = (ClientPacket*)pData;
    ! D& y+ l& j: ^% I: ~    switch( pClientPack-&gt;wType )
    & I+ d! p: x7 C& @* t" H7 t    {5 Y' v# e7 @0 R7 Z2 e; W" P3 l
            case PACKETTYPE_CLIENT_POS:& G$ q: m5 Y" r' O, T( N
                9 B/ I, x' B6 A' W- J
                // Check to see if the packet has a valid size. Including : F! r4 g8 b5 F, Q
                // the custom pack size., |( S& g/ s- Y& l8 H5 S$ }
                if( size &lt; sizeof(ClientPosPacket))& K$ L2 D8 ?: W( M6 p5 a* ~* {
                    fFoundSize = FALSE;
    5 B% z1 q; ~: j: T. [. j$ N9 x            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))
    4 o! z1 M3 F+ t1 p. S                fFoundSize = FALSE;
    ; {- a7 i" i: N2 B5 `            else
    6 |* r" r- I+ Q4 I7 y( b                fFoundSize = TRUE;</P>. }0 |- z6 U  t$ x, H3 v
    <P>            // If valid sized packet, handle the position., l' L2 ]9 }$ Q  n( C
                if(fFoundSize)9 ~4 n5 |8 b/ S- I4 N1 s
                    HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );, R3 x+ Y" b$ E- R! d  d) T
                else# T, |  l( r2 U
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>; N- V6 y1 ?# _& o) q, ^. {( w
    <P>            break;</P>( ]6 f  W6 y+ ~5 j. Y
    <P>        case PACKETTYPE_CLIENT_VERSION:) L$ r8 |! x7 p6 x9 N0 L! S% L
                if( size == sizeof(ClientVersionPacket) )1 e) k, m$ Q/ h. C, ^) q" y
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );" `- Z9 j1 e8 J: j- Y# S4 m
                else
    $ D) W2 G3 G$ k0 R6 x( s                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );3 ^& W9 s6 w, Y. E
                break;</P># K3 ]$ i* Q1 @1 W& X4 e* }2 G6 S
    <P>        case PACKETTYPE_SERVER_CONFIG:</P>
    * f" E) T! D1 D6 p/ }<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>) h! k1 M! @4 V& b: N7 o( g
    <P>            break;
    ! K) i5 C' O" S/ W4 |) P2 r        default:. B4 c- M5 |( ~, ?. c' t9 q/ J
                HandleUnknownPacket( dwFrom, pClientPack, size );
    " k5 r/ K+ Y- p/ U            break;6 @( N( @+ \2 I' s
        }</P>* s8 `- `0 b/ |# L! G+ A; H
    <P>    //If the user wants to hold the thread, Sleep for given amount of time.' Z, \  U5 q0 o* G7 L
        if ( m_dwServerThreadWait &gt; 0 )
    * V# r, ~, [8 R/ J: X. z& h1 C) i    {( {& M0 O, I) Q! I( r& c* ^: m6 N
            Sleep( m_dwServerThreadWait );
      W1 ]& t1 \' O+ r8 y- F8 j    }
    & A/ {, ^+ G$ t: F; ?    0 q) ^( M$ W3 i# ?
        // Retrieve thread data for this process.
    0 m' _8 z* h: ]# S; m$ i! W    m_csThreadCountLock.Enter();</P>
    7 r8 ]# i% s1 J: j<P>    m_wActiveThreadCount--;</P>$ X% F2 R4 o) v* c# D* m
    <P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;* ^' P/ V" S9 E, j# ^, `
        m_fAvgThreadTime += fDiffTime/32;</P>5 G- W  p: H: ^3 x# S7 s
    <P>    //Get the Max time in the thread.9 k/ O4 g+ T4 u8 g1 [, X/ f
        if ( fDiffTime &gt; m_fMaxThreadTime )
    + j# W" H0 a4 S/ D  b    {
    : s8 [# ]. B+ g/ i4 ]6 o- @9 J        m_fMaxThreadTime = fDiffTime;2 \' ]% S' m, K( p0 M6 J3 T
        }</P>( }' ]. @. j4 j2 Z1 G+ Y
    <P>    m_csThreadCountLock.Leave();</P>2 Q- n7 c/ \! }8 e! C
    <P>    return S_OK;% R0 s0 q2 C' d% p8 o& x) ~
    }</P>
    , _! d, @. u9 ^6 b. b  a0 q% x+ Z2 K! g; o1 u, p
    <P>//-----------------------------------------------------------------------------
    6 V2 l, T" H. t9 O2 W// Name: ; K1 V1 v% d/ w4 _
    // Desc: . p  A3 @: n/ j4 H8 e: D8 s" b/ g
    //-----------------------------------------------------------------------------
    . x6 O3 U2 r/ k- @BOOL CMazeServer::IsValidPackSize( DWORD dwSize ): X3 U# o: N$ J1 T7 B! N
    {! Q5 w  I& O8 ~4 k6 E4 r
        BOOL fFoundSize = FALSE;2 ]. q3 ]3 H* a9 I8 N! R
        BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;
    1 I' t1 t* t' m8 I2 e    ( g( Y% F3 B! ~% N. q( h& g8 ^, O
        // Check through the array of valid pack sizes.
    . _8 o* [3 d7 b4 r    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])3 Z* V" B" Q" F! T1 v
        {) L* l: H7 C" ~/ y5 ~! v
            for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)
    0 d0 T: e* Q, C6 X  f        {
    7 m( ^1 @/ c/ T% `: Y            if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    2 c5 ?/ l9 p% A+ A# P            {  q+ l' _' A- G2 ]
                    // Found valid size in the array.2 G; {6 n& h/ v+ \2 m
                    fFoundSize = TRUE;
    5 E9 c6 s* c" p5 b                break;
      G- B# Q! g) t3 a            }9 n6 m! P( `- Y' T( N
                if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
    ( x7 C' b; Z6 H        }. }7 A/ I/ H# D' o6 w6 N- e
        }2 G) C( N/ z- L: c* ~; p
        else
    ! y, q7 y7 o  f# o' h/ P6 A  q8 n    {
    * Z& V. m, ^9 u7 N) s; ]        fFoundSize = TRUE;
    0 X7 E2 m- z: s6 x4 E9 |8 Y9 r4 X    }</P>$ K5 a0 j0 _6 S, s+ ~
    <P>    return fFoundSize;( y8 Q5 q, t8 Q' Z' G: v/ B
    }</P>: y+ S4 D4 A$ }9 u+ v
    <P>
    " y. q* ^* e$ \! N  h" r: _& [$ _  d; i//-----------------------------------------------------------------------------
    $ [6 l& O& ?1 ~9 Y4 B// Name: 6 q' r% @- b( O" J+ E! @
    // Desc: % r  J( M! [9 N$ T+ Q& B6 |' F
    //-----------------------------------------------------------------------------' V4 `' V$ l. p3 @8 S
    void CMazeServer::OnSessionLost( DWORD dwReason )' U* P2 G; P* @. ]  O3 ^# j- F
    {$ X4 m6 j0 Y% J
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
    / s& D' b8 g" z& s: ^}</P>4 X8 Y8 A4 c5 {" C. o" |

      L# v1 r, u; a# ?4 i<P>
    % V; m! e9 U7 {9 a2 C2 Z0 o//-----------------------------------------------------------------------------0 K0 N, a3 T, p, U' }4 }
    // Name:
    1 s4 E+ _( p' Z3 |// Desc:
    ) }' r: A' _- D//-----------------------------------------------------------------------------
    * l# b; y+ X" Y# Q) Z! W% qPlayerData* CMazeServer::CreatePlayerData()2 I& z0 [9 B# O$ V
    {
    % H2 ]! c: Y0 U  N. `6 G7 ]( @    m_PlayerDataListLock.Enter();</P>  [+ }4 h. r6 Z7 w9 J* H% e
    <P>    // Grab first free player in the list, y" P+ Q/ U1 Y. F
        PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>: C6 \  y; N) A5 I
    <P>    if( pPlayerData ). \% c  _, S* R' j6 ^0 [3 z0 d( i
        {% m5 C" ~- j4 z8 e4 G
            LockPlayerData( pPlayerData );</P>
    9 r% _) n$ |7 t8 a" G# P& ~$ `<P>        // Got one, so remove it from the free list3 {; B( d: }# u+ P
            if( pPlayerData-&gt;pPrevious )
    % V: P, H2 R- W( \6 ]6 u1 }            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    7 i. k3 N  B. \$ p0 E! [5 f8 k* c        if( pPlayerData-&gt;pNext )( a  s8 g# J/ a8 C" F2 |3 j
                pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;5 R* B: I4 q# S$ I0 [2 |
            m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>- @, A+ z. s, b0 i. G
    <P>        // Add it to the active list- K! U- n6 c' e0 ~' P5 u
            if( m_pFirstActivePlayerData ); ~7 P/ a+ O( \
                m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
    4 h9 H' V! S9 A7 Y/ I        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;
    4 x& I) {! h! D- Z        pPlayerData-&gt;pPrevious = NULL;- o+ V, r& w7 O
            m_pFirstActivePlayerData = pPlayerData;</P>
    * Y: b2 m  G1 E# G<P>        // Update count of players' w  r9 L& B5 ^6 l/ s% B
            m_dwActivePlayerDataCount++;</P>2 N6 s* A3 \: Y5 t5 a8 T# l
    <P>        // Generate the ID for this player
    % q) Y7 G4 s) L5 k/ E: l$ r" c        m_dwPlayerDataUniqueValue++;- t5 q7 d) B0 k5 d& ^
            pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
      ~( O+ u4 H1 U0 O<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
    8 b/ a% L1 W7 y        pPlayerData-&gt;NetID = 0;1 L8 Q' C3 c- P+ l7 b
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>/ b! M6 x2 G- u8 m$ n! p$ y! d
    <P>        // Insert into the "off-map" cell
    3 y, H1 e1 h$ F! o- ?& k        pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;6 T2 h3 T/ _; A
            pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;
    $ N5 N2 I+ r( _( Q        m_OffMapLock.Enter();' x- D: k8 {  K9 D0 }- h
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;
    1 E& x* h' \3 c        m_OffMapCell.pFirstPlayerData = pPlayerData;, U% }' ^( D+ l/ w/ Q7 L
            m_OffMapLock.Leave();</P>
    * \, W0 Y8 ?6 T& b* r% H<P>        // Mark as active6 C0 M6 G* X6 ?$ ?% U" _  D
            pPlayerData-&gt;bActive = TRUE;</P>
    0 a, E* M9 |5 C( g* l: R1 _: \<P>        UnlockPlayerData( pPlayerData );6 t+ J4 y* g& p, x, h
        }</P>% x) g+ Q% l( D! C
    <P>    m_PlayerDataListLock.Leave();</P>
    3 y5 b( c/ I# K3 X7 d- |<P>    return pPlayerData;
    ; c# g1 {$ R3 m' x: r4 S8 h$ y}</P>0 a' e4 i9 }' [

    8 \/ @+ \0 M) j<P>1 E( s$ [5 A2 j* R
    //-----------------------------------------------------------------------------
    4 {2 H$ C, {* Q" ], P1 G// Name: 3 |- ]1 ^% K8 K7 n4 |5 b+ c/ J
    // Desc: 5 e! q, J) T- }6 j3 b% ]8 C8 }
    //-----------------------------------------------------------------------------
    , h0 X' _$ V0 \3 n; N2 {void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )
    . `- D( s/ z# r  F{
    + b. O/ W9 U3 X4 H- f$ k# N    m_PlayerDataListLock.Enter();, y) I8 Y: k! L4 o4 S2 f
        LockPlayerData( pPlayerData );</P>
    & F# _; O8 [7 G8 D5 H<P>    // Remove the player from its cell) ]* q, y* x2 d" N6 T5 j
        RemovePlayerDataFromCell( pPlayerData );</P>& a* y) g  Y$ y
    <P>    // Mark as inactive5 Y) i0 r6 A3 T6 q6 {; p$ h# u/ n. p
        pPlayerData-&gt;bActive = FALSE;</P>
    # k( c6 Q* d6 P4 [* o<P>    // Remove player from active list2 b+ T  W: ?" l% w3 E. N% y
        if( pPlayerData-&gt;pPrevious )8 d6 n0 K9 {0 \9 w, E
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    # E* C4 D5 K: j; V1 f    if( pPlayerData-&gt;pNext )
    3 \" M" [$ i# N) u        pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>: F8 A( J' B8 ^4 i
    <P>    if( m_pFirstActivePlayerData == pPlayerData )0 Q: g2 b. z% P. j) T0 s/ [8 e
            m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>
    ! s3 v. c; C6 G' N$ X) }<P>    // Add it to the free list; P# l' |$ ?  d4 F1 u
        if( m_pFirstFreePlayerData )" B8 B7 N9 F! n5 m% {
            m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;( O) p, y0 I/ b" R! e/ q+ g
        pPlayerData-&gt;pNext = m_pFirstFreePlayerData;
    * k/ a: o% o) q6 b* A7 K    pPlayerData-&gt;pPrevious = NULL;
    % G4 B" K  ]! g3 @% W9 M    m_pFirstFreePlayerData = pPlayerData;</P>
    + n1 n4 L" }0 N# E( @# b0 V<P>    // Update count of players* y" L8 O: }4 S
        m_dwActivePlayerDataCount--;</P>  }0 F) F! G- z( S! f& t+ ?
    <P>    UnlockPlayerData( pPlayerData );; `' K( n2 ^& U( D5 M4 ]. \, T
        m_PlayerDataListLock.Leave();- y& R/ l) Z- j' o9 m. a# m3 d7 I0 I1 @
    }</P>, v8 w; m9 t8 J0 K3 e( |
    ) S2 a7 U# e7 i. ?0 ~" U1 J
    <P>
    ( u; n8 T7 ~4 i8 y; ]* N' P% |, s//-----------------------------------------------------------------------------8 a" R& z$ t, Q
    // Name: % O" k6 \8 g# m
    // Desc:
    $ A. {0 r4 I# M' n1 e6 B( a//-----------------------------------------------------------------------------
    : x, W- k5 C7 Q+ j" Hvoid CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )
    1 F( p5 x( B8 E6 W9 N& _{
    2 W; A4 W/ |, ~$ ^    // Lock the player. f) }0 D9 J' H( q, ^
        LockPlayerData( pPlayerData );</P>, P( Z  M9 E, O, G) [5 o
    <P>    // Lock the cell the player is in
    / m; ^, o+ E4 \! M1 M    ServerCell* pCell;
    ' z: z. c3 A0 F0 Q    if( pPlayerData-&gt;wCellX == 0xffff ). p. i; z7 Z2 t) j* {1 R0 @
        {6 J; i% E4 b* A' K
            m_OffMapLock.Enter();
    * n. v& b7 ?# t7 X8 D2 }0 y) u        pCell = &amp;m_OffMapCell;
    , T! z! R0 f1 ]# d    }1 l9 H  _$ Y. a2 L; Y; T
        else
    5 s. D( B& w: H& P  @    {, a6 `" X  W$ i. l# Z! g  W6 O2 o& Y' }
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );( n; x6 _. r* B6 _. A* X
            pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
    * E1 H, t9 O" m: m    }</P>- Q. P8 W: w& N$ n
    <P>    // Remove it from the cell: L8 F; i. z2 a  Y5 Y. N
        PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    9 D$ r" ]1 X( A* ?* T    PlayerData* pPrev = NULL;
    ; C2 e( \2 z" W0 g8 V5 p. l    while ( pPt )
    ! @' L, i6 m% J! t' N    {
    / z$ F) U) e7 D& C. {, U        if( pPt == pPlayerData )5 S6 S- n: O2 y. U6 J
            {
    2 _/ ~1 q4 H9 U3 |6 @; Z: e0 l            if( pPrev )
    , T& F/ V3 I8 K2 E- V: K5 g! [                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    3 F$ x' Z! y8 z" g8 x8 P            else
    6 T8 P# M# R, O                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>3 V* g% M3 j5 D  w1 v: k2 r
    <P>            pPlayerData-&gt;pNextInCell = NULL;. J6 T# V* U5 p+ m' t* d
                break;
    + d6 H% `- U9 X        }0 E4 u6 x- J4 H- l5 f& N2 x. H% j
            pPrev = pPt;
    2 n3 G5 ^+ w6 \) a        pPt = pPt-&gt;pNextInCell;
    , c0 J% Z$ J% O- s( T+ l- |& x( m    }</P>; _4 `9 i9 h( p6 b
    <P>    // Unlock the cell& L. A5 P! N' d3 T1 v2 p" y
        if( pPlayerData-&gt;wCellX == 0xffff )
    * f7 c2 b& l3 f1 l+ E  z5 A0 v        m_OffMapLock.Leave();
    - v& w$ |5 P; ~: i, O' j    else, O) X- j& Q. S
            UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>( }4 j) ~7 E! U. p* ~: P
    <P>    // Unlock the player
    2 X+ W5 {* ]) |% |$ n. q    UnlockPlayerData( pPlayerData );
    ' z' a& A  b5 q! v# Z& B; c. j}</P>
    + i  e; J/ ]9 C7 A
    0 f( `/ Z3 r3 L) `<P>: F2 e$ [6 u4 \; P1 P& _# \
    //-----------------------------------------------------------------------------
    ' y! i9 m* h) _& }. M0 ~0 L// Name:
    & f" a" p- ^4 |' U3 M+ ?. J// Desc:
    & P- Q7 w( B1 s, ~( n//-----------------------------------------------------------------------------
    6 q, c# w* o- f$ M9 Lvoid CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
    7 y2 w- I% E8 [& K. D0 C2 d7 W{. D; Y4 Y: o% J* i3 r0 i; ^
        ServerCell* pCell = GetCell( pPlayerData );9 E# |2 f  d- `4 p9 n! \. Z
        PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
    3 Z4 S7 \- ~2 i7 C4 E& m  E5 V    PlayerData* pPrev = NULL;
    8 M4 O/ v7 ~$ r9 s& f    while ( pPt )
    % r8 B2 M8 W( r& Q. V    {8 Q$ K! ?9 @" {+ x
            if( pPt == pPlayerData )0 X8 z' K% M5 O* J' Z
            {
    * `& W% X' z8 Q- R            if( pPrev )
    * C* h. C9 P, _2 ^/ @/ Z                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;) Y9 I9 k  \' E8 z
                else
    : i# ~% I" \4 }1 [. C; {3 D6 n  `  p                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;
    0 I' l# m. D5 J& q2 Q( G4 B            pPlayerData-&gt;pNextInCell = NULL;
    5 _5 r: h7 g9 q! Y( B9 W            break;
    . O* h8 S* r7 t, G$ b6 [        }
    * j+ g" U. O/ ^        pPrev = pPt;
    # k2 X# n* L# \9 R3 S7 C$ e        pPt = pPt-&gt;pNextInCell;
    4 ^* I7 ~# ~+ R* B    }
    4 J! ^$ u& _' {8 U* z}</P>) [+ \5 S& n9 u2 W. J
      G( G% q' N/ ?
    <P>- Y0 _$ B! t( V$ V
    //-----------------------------------------------------------------------------/ D& R+ y- [+ {- X0 ?
    // Name: 0 x! D$ D2 V/ J9 L* ?
    // Desc: 0 q! p4 P, @1 z$ \; J% ?
    //-----------------------------------------------------------------------------
    . c+ z8 t/ B- m$ H' a4 a- F' Zvoid CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )
    7 X  ^6 b1 p& H; r& s9 J1 E  X{
    4 |7 ^( G- P! p2 `/ x    ServerCell* pCell   = GetCell( pPlayerData );
    ! b  q" J1 h/ h6 H. K' Q$ o    pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;, J' a  U/ Z8 ], G
        pCell-&gt;pFirstPlayerData = pPlayerData;& C2 ?$ X: B' j5 d
    }</P>2 n( Q- t- h2 ?1 p0 b1 m

    0 g% C" a6 a" s! l<P>
    9 U6 o( t" L3 j9 W  O+ \6 Z( @//-----------------------------------------------------------------------------+ P7 [( Z% o& V
    // Name: * G# b3 b# }, g9 V4 N
    // Desc:
    1 b/ H/ W' z' z) v$ e//-----------------------------------------------------------------------------
      [6 `+ n! c% X; y$ X) {void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )) G) v3 [5 ]8 {* o7 Q
    {
    : i, ~& Q- x5 t- ^    // Grab player for this client and lock it
    / ^# o; V, X9 l7 [+ F! [    PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );
    ! u7 P$ ~' K, b' K    if( pFromPlayer == NULL )
    ; T) C! ?+ N6 G) D. l    {
    ( `1 ?" Z. H% E        if( m_dwLogLevel &gt; 1 )9 ]! b3 j* I9 b1 e
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );; `. T+ ~1 B- N: M, X8 j5 m
            return;/ _% r# H$ r& _+ i5 m; n
        }</P>
    5 Q' V4 K8 L4 D6 z<P>    LockPlayerData( pFromPlayer );</P>. P; @" ^! K9 l4 h- T  k$ i# V' o
    <P>    if( FALSE == pFromPlayer-&gt;bAllow )
    - V  Z& [# d( M* s* N1 \    {' @7 ?5 J5 P/ W! C: V6 m* X
            if( m_dwLogLevel &gt; 0 )
    9 p1 T7 P8 ^' h            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
    0 r4 V) k8 `1 m6 X5 B! X% X<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );. \! k5 V: c6 i9 }. _' y& N
            UnlockPlayerData( pFromPlayer );
    * {7 |5 }4 Q& T        return;% N! A5 W' N. Q% m8 `% s/ H
        }</P>! V$ [& K; @/ c! x6 p* [" P& f
    <P>    // Compute the cell the player should be in now8 Z" o2 x1 Y0 ~* x+ U, Z' h
        DWORD newcellx = int(pClientPosPack-&gt;fX);
    / |: k# X) ]  v. t$ r3 \  A    DWORD newcelly = int(pClientPosPack-&gt;fY);; T6 l- k! p1 O' n2 G( n
        DWORD oldcellx = pFromPlayer-&gt;wCellX;# M+ y* v- r0 O( A
        DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>7 t* ^3 A( b( H( ?' g- x
    <P>    // Have we moved cell?
    6 B& _0 ?, t0 C0 k( M    if( newcellx != oldcellx || newcelly != oldcelly )+ \" b3 }7 a8 k8 \! s, Y, [
        {( P5 f( L- O0 G- z
            // Yes, so lock the pair of cells in question3 u* n& f4 V  B/ n' k! y
            LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
    & |+ [# x5 y) x<P>        // Remove from old cell and add to new cell
    4 B- X' x# h: N# R. m7 P        UnsafeRemovePlayerDataFromCell( pFromPlayer );
    / Y" P" I+ A3 u3 l8 V        pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    0 x; }$ e( }# Y        UnsafeAddPlayerDataToCell( pFromPlayer );</P>& E2 c* V* Z/ H% M2 z- Q/ G( l8 s
    <P>        // Unlock cells) X% A+ N9 Y0 i. M
            UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );
    : `( ~8 z* q) y1 U: q! T: u; l    }</P>
    ! \9 b3 I( [6 O$ g0 }<P>    // Update player position* X5 x- Q) h$ i/ {5 e5 a4 r
        pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
    7 w5 S/ k. n+ Q' n; v$ p    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    - O! p. a9 @( F% ]3 k: D    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
    / g7 |+ g: Q5 _* t<P>    // Allocate space to build the reply packet, and fill in header
    $ R+ n5 ~3 y& q" k- Z7 d! ]: ~    DWORD dwAllocSize;. B3 k1 e  _3 ?
        ServerAckPacket* pSvrAckPack = NULL;</P>+ I+ o# q; U4 x( {& W
    <P>    // Begin by allocating a buffer sized according to% |% z) C; d; W/ e7 [3 o! A
        // the current number of nearby players + 4.  This will give $ R- \. R  a8 ], _- P/ v6 e
        // a little room for more players to come 'near' without resize/ r: S( ~( Z6 w( S, h1 @- }
        // the buffer.) l/ @- @) i. ]3 h$ T
        DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>
    6 Z; k' \; Z8 [% }6 i0 ]6 T<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);  R7 Y4 _( v, P4 f+ a. w4 {
        pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );+ }' W6 v+ ^( s8 _+ ?
        if( NULL == pSvrAckPack )
    : J) k$ o# z4 c8 B* B5 E    {
    ) W3 d! _; P! @0 O' Z- ~" T" U8 ]        // Out of mem.  Cleanup and return
    7 z" s/ X; w* s" W) H* B5 h& U* ]        UnlockPlayerData( pFromPlayer );
    4 {3 b5 ^* a. e- w' i        return;       ) y2 d! y$ k# E  j
        }9 d4 {7 @6 p# a. |# l' V$ {: y
        ZeroMemory( pSvrAckPack, dwAllocSize );</P>! h# }$ r7 P* c& [# M7 j# D$ ?% M
    <P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);4 ?  z) e0 C* M; `5 S+ L6 o' s* o/ l
        pSvrAckPack-&gt;wPlayerStatePacketCount = 0;
    & O9 \( J% W1 c* X7 S    PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>5 \# J# `/ X# F- w2 {
    <P>    // Compute range of cells we're going to scan for players to send
    ! l( k+ q" j+ C& x    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;8 ?* O% M+ m5 ?; B% R0 W$ ]
        DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
    1 s6 s+ I9 u$ J' f  {' v, P    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;; `) C! o8 _5 M# X" }8 b  Q& Q
        DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>$ _  g0 v2 t- \- `) m& [/ F1 o3 \/ `
    <P>    // Lock that range of cells4 {% \5 [0 f. c& M. @
        LockRange( minx, miny, maxx, maxy );</P>
    - Q( g$ S! F# \+ r* R1 l<P>    // Scan through the cells, tagging player data onto the end of
    + `! e' R2 [+ ~1 y- z    // our pSvrAckPacket until we run out of room
    % X3 J0 O8 j9 X& V0 Q4 F+ B    for( DWORD y = miny; y &lt;= maxy; y++ )0 a1 \9 k! S) {, g0 Z. o, C
        {
    ( E$ u2 @1 Q$ H        for( DWORD x = minx; x &lt;= maxx; x++ )
    $ M% `& x& J1 B: k; S        {' U. [; [9 u/ {* E3 {$ K
                PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;
    6 h- j* g: b! b6 P6 ~            while ( pCurPlayerData )7 {. A" U! T% H+ Y4 f8 D
                {) q2 M6 p% K+ j2 |- }
                    if( pCurPlayerData != pFromPlayer )4 Z, g/ \+ s3 I0 w/ \. Z% u
                    {
    3 h$ N" p- g% k                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )8 j. l2 O. B: i; n/ r
                        {
    0 B% E8 {5 k* I3 G5 o                        // Make sure pChunk is where we think it is; O) a( K$ ?/ _7 T* i: @
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>
    ! `5 Z4 J: U. S$ H/ }<P>                        // There are more than just 4 new nearby players, so resize the
    # O6 C$ J% }# c% H+ J+ P                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
    % x7 c0 G8 G: v! X5 C- @                        dwMaxPlayerStatePackets += 16;7 T: c) @/ {% h* M, o
                            dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    ; R" T* Q: ^; H) B  c, n                        ServerAckPacket* pNewSvrAckPack = NULL;0 X8 }$ S+ z+ Q, X+ n, l* F
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );( J6 h6 _& u3 m; \
                            if( NULL == pNewSvrAckPack )
    ( ]1 i$ k4 ]& o: B                        {; w/ c* x1 w" V( Q
                                // Out of mem.  Cleanup and return
    8 \9 ^" K4 l1 R6 d& }2 X                            free( pSvrAckPack );7 m% k6 o* g) E! V8 K
                                UnlockRange( minx, miny, maxx, maxy );1 y9 h2 a1 t: q/ j
                                UnlockPlayerData( pFromPlayer );
    $ C5 L1 ]. A& G                            return;      
    % Z* v( {$ S/ |  a                        }</P>. n2 u6 P  M2 S4 a' b+ X1 L) ^
    <P>                        pSvrAckPack = pNewSvrAckPack;) Q+ n/ L; l: }! m) r+ U: _
                            pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
    $ P# f5 P! k! e0 h. m2 g<P>                        // Make sure pChunk is still where its supposed to be
    - o* x+ f& w2 i7 A5 L/ w* x+ R# L9 S                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );7 i& M* h/ r. E8 z
                        }</P>. g9 Z% R+ `/ o, \8 C  y
    <P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;) N/ c+ W9 T! c' q
                        pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;2 O/ v( q6 Q# \6 z
                        pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;7 p+ F2 x9 d+ }, t
                        pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;# D2 W3 S9 t7 U3 ]. S& F' L
                        pChunk++;
    % B! Y- Z  R% I" s) ]! c                    pSvrAckPack-&gt;wPlayerStatePacketCount++;2 b( a: [& Z7 h* m) U7 u
                    }! d% H; M8 S- E9 t4 c" p! W
                    pCurPlayerData = pCurPlayerData-&gt;pNextInCell;. ]" g& {9 I8 M- i1 d  D: V
                }
    ) a8 t- L4 ~0 Z; J3 B* f        }
    4 y; @% g% l+ Z4 F6 ^    }</P>, v- l! q: k: ]0 X
    <P>    // Update the dwNumNearbyPlayers for this player9 F. d3 x* |6 f" i
        pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>
    . I; w9 v3 I% B' [<P>    // Unlock range of cells$ C, Z, M2 k/ X" `4 u! a
        UnlockRange( minx, miny, maxx, maxy );</P>' a9 r; F+ s3 c: X" @6 [
    <P>    if( m_dwLogLevel &gt; 2 ), h1 L# P1 b; _+ ~/ J; ^; |
        {
    . m/ P9 v+ e* y7 b3 E        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    7 T: Q. M. a! u% j    }, i% K7 t0 G7 w+ H4 V! O  Q
        else if( m_dwLogLevel == 2 )* k5 {; r" B' ^: `/ k
        {
    . D/ T7 @2 p" `! R5 x        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    . \/ ]' j- U7 H1 K        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )+ S4 I  }( _1 C: e) n; g
            {
    ' ~( S) G% h$ ~+ ~& x6 s$ I            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    5 |  A+ }2 P5 a" J8 B0 X            pFromPlayer-&gt;fLastDisplayTime = fTime;
    - Q4 H- b! Q6 Y) c( u& h        }
    ) |% u- ]: b, i, L8 v% c    }</P>
    % B! `1 K# v/ R4 O! z6 b<P>    // Unlock the playerdata
    * p; w* {$ `, G5 s    UnlockPlayerData( pFromPlayer );</P>* R5 @  L: H6 }. C3 V# v$ @
    <P>    // Send acknowledgement back to client, including list of nearby players
    " M. \. o4 ?! n3 k8 N' }    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));9 O; |  W- D& _4 L

    / M9 ~: ~$ V2 Y$ f4 Y* F; f: m    // Pack the buffer with dummy data.
    2 m3 o  Z6 Y) J1 F, x6 k3 y: ^, ^3 E    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)( j: S5 W4 v* ~' O+ S$ b
        {
    + V+ Y$ }: z! z' O/ w        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];7 l2 J# A$ h# N! o
            VOID*   pTempBuffer = 0;</P>
    : w7 m3 p9 c. A3 V/ H! b<P>        pTempBuffer = malloc(dwBufferSize);- u" b. Q8 S6 S7 m5 B* o# L
            if( NULL == pTempBuffer )
    8 |' K' p% X+ A6 q, x        {4 Y! t9 X* l( K
                //Out of memory
    , O( y, E5 M& U8 v1 Y1 W            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
    . A4 _0 Z: G0 l  z) j  E            free( pSvrAckPack );
    * Q3 o4 C6 \$ H' |7 o- n. c  o            return;2 e$ X% z$ S2 L5 h( c
            }</P>
    7 N$ t$ e3 R' U( b<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');1 X8 l: D) _2 R1 H
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>
    - j& F& X2 f  S0 [4 N6 K8 a5 O% k<P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );
      W1 ^1 u7 P3 r* X* M2 Y    ) C/ B! U$ ~; _$ r$ |
            free(pTempBuffer);! H7 w' M- i( L& a- q7 Y& g/ _
        }   
    # S" y8 V, K3 U) i8 x    else
    : F1 R6 Q& Z- r9 I- V6 p    {
    : Q, h, V$ a$ p4 P. {5 u9 A/ {0 ^        SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );' H7 I) r/ X  j) o
        }</P>4 ?8 c' Z! m# O$ e+ ?7 h( k3 Q- ^
    <P>    free( pSvrAckPack );</P>, v& t; I- q" `1 ?0 W* j1 a6 O- L
    <P>}</P>
    % M& N% {: D& Q2 _$ ~' `9 K0 S7 m/ H3 d$ b! D/ s% H* k5 t
    <P>
    . p, t( i: ~8 v- [//-----------------------------------------------------------------------------
    4 t3 {4 Z+ [# B$ n" Q) {2 k: j// Name:
    * e+ @- F. K& l4 K3 ?) G// Desc:
    + v8 l9 O2 D; [% O5 U//-----------------------------------------------------------------------------1 V6 W2 ~! |8 F* t
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
    . m1 O( H% w' _- b" @$ A{
    0 T' J( q( b" @. o, B; U    // Grab playerdata for this client and lock it
    ) E! x. e" h2 y    PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );, I0 a0 r% t' }3 b1 ], [- G8 |/ Z
        if( pPlayerData == NULL )
    ( n1 x' |* s/ n$ Q. P8 ?        return;8 t! o1 k" x7 u5 U
        LockPlayerData( pPlayerData );</P>
    : k& I) ]0 v% w7 F) U  I% ^  i4 ]<P>    // Record the version number
    % g& s0 T, z5 @, T    pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
    3 _/ F- t2 o' u. o$ m  l<P>    if( m_bLocalLoopback )& _" z$ i7 {  a
            pPlayerData-&gt;bAllow = TRUE;' w" {- T, k$ p" d; A' J9 \2 @
        else# n) a/ j5 M  r/ I
            pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>
    ; a. J( S3 r8 h, t8 B<P>    if( m_dwLogLevel &gt; 0 )9 I0 |7 d* L7 H8 ^1 x
            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>
    & B0 r& d6 M6 q, P  E+ c7 `  D/ j' Q<P>    if( FALSE == pPlayerData-&gt;bAllow )
    9 I1 E) Y6 R1 h) f2 B: b2 W) G5 f    {
    ( f5 ~9 D& \6 v        if( m_dwLogLevel &gt; 0 )- @! ]$ T& K- U9 ?
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>
    9 S' V0 ?5 q9 L8 g# V% D. D<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );+ B; L+ W, E9 A2 z9 j! c; A- e
            UnlockPlayerData( pPlayerData );
    9 A! g/ [2 S- M( i5 j        return;- J% P" U% R) `/ ?, ^
        }</P>
    & l1 @  I$ {+ k5 c  d+ [<P>    // Unlock the playerdata
    * I7 Y+ a6 x$ t. S% W. y7 w4 o1 ^    UnlockPlayerData( pPlayerData );</P>. G: g! C: a. a- `2 Y# _
    <P>    // Send acknowledgement to client that the client was either accepted or rejected
    5 z: M  ?+ x) W7 ?' {; K: q5 g    ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );
    2 @: w' y* ~( S; q    SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
    + @  F, m7 S* e9 w}</P>
    ) c  y+ `( _3 N& i8 ?: k
    ) Y) u% y* |7 ]8 Q" e7 y, ]7 W<P>: N# H, Z! ]7 M0 Q" \
    //-----------------------------------------------------------------------------$ @& h# B, @1 @& u  }3 m; n
    // Name:
    : m3 ]& b5 c- U) R1 e* E// Desc: 0 P1 U2 [: z& Y4 X
    //-----------------------------------------------------------------------------
    & w5 M: A4 L7 u6 T: BBOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
    3 t: l8 n2 B+ x3 w{
    & C2 w3 P- h6 i: G: t    switch( dwClientVersion )1 X1 q; f! b. E$ S* H; n
        {- {9 ]) `: N& D# e
            case 107: // only v107 is supported
    ( l' B2 ?7 c: P; I- j, A( b7 T            return TRUE;9 |1 D# R! d" X7 e" e; J9 O0 x
            default:
    ( L9 x/ `9 n6 x+ `; s6 h6 k            return FALSE;
    , ^+ J8 _! v" y3 O    }
    - R; Y6 |& z# C2 k2 }5 }}</P>
      ]+ q$ J5 ^/ i  f7 ~) d
    6 i' E; F7 i+ r2 W<P>
    , ?! a4 o1 u: S  H6 s) v//-----------------------------------------------------------------------------0 i3 X1 m0 e0 ~4 \
    // Name:
    . o+ N& t6 Y) H// Desc: 4 U& f7 q2 i7 o$ T
    //-----------------------------------------------------------------------------% w, i5 _$ h- m6 }
    void CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
    4 t1 B4 N% E/ f, k( m( B0 }{
    $ \5 W! _# O5 ]) _6 i, ~& e' m) b, y    if( m_dwLogLevel &gt; 1 )
    ( M  G8 z* J; ^+ g        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>
    6 ^/ Y2 i6 I$ s/ b/ A<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );0 ^- w* C" L4 z* m+ h; T( e
    }</P>
    $ E3 A8 A* `- u, g0 N
    , S2 V1 W6 O! a3 W<P>
    . V! k3 r+ p2 b) e% V( P3 g/ C//-----------------------------------------------------------------------------' r' T# m. i# V& g
    // Name:
    / H, ^8 B; t2 w+ y- ]. g// Desc:
    * r# W  p/ \$ u9 r7 D% i0 K+ [//-----------------------------------------------------------------------------* Q, S$ e0 w4 ]
    DWORD   CMazeServer::IDHash( DWORD id ): F+ {8 {8 W8 y3 `7 N
    {
      ?" c: }. x9 ]    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);7 }- k6 }' k6 v9 V9 N- a- Y
        return hash;' ]* A% b% p5 W3 s& O3 W0 b
    }</P>) W: O4 }" V4 @5 ^. s7 b& t
    0 f7 L% e5 a  V# s1 i* L
    <P>
    + `, h1 e2 g2 C8 T+ Q//-----------------------------------------------------------------------------& S4 ?; k( i0 H( h2 c
    // Name: ! D6 b8 H+ r0 ^  r+ l( N( r( P) N
    // Desc: & p$ @# o( p+ q9 D2 ^
    //-----------------------------------------------------------------------------' f% ^8 N" [2 w  c) z% o) T, o
    void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
    * {5 n7 t8 p' v: M; Z: e+ n7 k{  e. V' L  Y9 S* S7 o! o3 _
        // Hash the ID to a bucket number
    $ b& s. W  r- Y7 V( U" ~2 l    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
    . G7 d  D# L" _2 E4 _5 ^<P>    // Lock that hash bucket
    . u1 Y7 p9 X$ O5 a    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    4 Z- S- K. \: A% f+ R' M2 \    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>2 Y, J( |' r( V! K, K
    <P>    // Loop though players in bucket until we find the right one
    & t8 J: ^- `0 W6 ?% N1 x2 g. q8 g    PlayerData* pPt = m_pstIDHashBucket[bucket];
    , Q! n! l# \5 \    PlayerData* pPrev = NULL;& h; O$ O& V, R. X
        while( pPt )
    0 K6 F# F  o6 \/ }1 f    {
    ( T" y9 a: C; K' V        if( pPt == pPlayerData )# g  W1 D# V: L$ i8 y! X
                break;
    " Z2 V8 M: W# o8 u        pPrev = pPt;
    " A4 ~. O5 B' ~3 k        pPt = pPt-&gt;pNextInIDHashBucket;9 y& y9 M  Q  O* v
        }</P>9 s2 S) R, e6 L( R/ P( _
    <P>    if( pPt )
    ) K# @& ~( _$ {4 G( i$ b. }    {
    , f' u* n: U' G* m  ^1 x3 u        if( pPrev )- L+ w' E% Z. I$ y1 G; V! C, i
                pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;2 D$ v  \* I8 r1 E, ?
            else" U9 A: k* M" x. p4 z% V
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
    ; S) X8 _7 h. D1 |7 |        pPt-&gt;pNextInIDHashBucket = NULL;
    9 Q$ E8 u4 U+ s    }</P>
    5 ^' X2 A  G' M% K; i# w- W* u/ J, g<P>    // Unlock the hash bucket/ u/ q4 E7 s6 Z
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    9 u7 t; D2 d& D9 z. `2 J; |9 Y}</P>. s. X5 d! E6 A
    2 w3 Q2 Y5 e4 D0 V8 k
    <P>0 K5 U9 o- ~' r) m& f8 [
    //------------------------------------------------------------------------------ Q8 g' J( _/ s" n0 b7 `% ]  ]
    // Name: ! L) k7 n5 y" X+ q5 C
    // Desc:
    7 ]" _7 u  z) _0 q//-----------------------------------------------------------------------------
    & j; l" b0 \2 rvoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )8 e& s. t- V) P& T, N9 V* X2 F
    {
    ! E3 D& R2 S) a/ @* F% B    // Make sure this player isn't added twice to the m_pstIDHashBucket[]1 _0 q6 d9 F2 b2 A3 o% t
        // otherwise there will be a circular reference
    ( o+ x6 p3 c$ ~1 `    PlayerData* pSearch = GetPlayerDataForID( id );
    - u( v" p4 C3 `3 h- C/ j' m$ k    if( pSearch != NULL )
    / q, z( U9 `( p, D3 T        return;</P>
    2 `8 A  L1 s0 c, A<P>    // Hash the ID to a bucket number5 I4 V: o" X+ S% V: Q& d
        DWORD   bucket = IDHash( id );</P>
    2 P( B* M$ r3 Q' x0 j1 h& ^. d<P>    // Lock that hash bucket
    ) l* v( t4 [. I6 H0 {    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    2 |0 [( c  _& n: u5 Q6 ~    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>7 [# B+ j5 C% y
    <P>    // Add player onto hash bucket chain
    3 D# h% `: j# |1 j' L    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];: m' o1 ?; K7 R% y2 _% M: o
        m_pstIDHashBucket[bucket] = pPlayerData;</P>. w. }8 F  T* |, B* V# I  t6 ]9 x
    <P>    // Store net id in player+ k6 q4 N* n& [3 n9 S' d
        pPlayerData-&gt;NetID = id;</P>
    $ _' n2 r7 P  W9 }! I5 y) k<P>    // Unlock the hash bucket
    9 F# K0 u7 I% ~8 W+ D, o7 S/ `    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();3 Y& ]( M5 P$ ]) M- _* e1 Q
    }</P>
    . s$ @5 f; ~  n, |: y3 U
    # i) h4 o' b0 K( l; H0 b# F2 \) s0 R/ S<P>. l$ V* o7 m' W) x" d/ k
    //-----------------------------------------------------------------------------
      Z7 `9 Z" V# g+ W" [  W, r5 t) {// Name:
    % l4 I# T, Q( e; d. b/ J// Desc:
    ( H& c+ \& S8 l1 s" A! U: g( Y% T8 p- [//-----------------------------------------------------------------------------
    : j/ w2 C. e  Q+ Z# B9 K3 ZPlayerData* CMazeServer::GetPlayerDataForID( DWORD id )
    / V8 Q3 g. T, j6 F. S) Y) b% b{
    9 B% ~# Y/ X+ {9 U. p    // Hash the ID to a bucket number" T2 `5 C  w% i1 ?$ w% d* I
        DWORD   bucket = IDHash( id );</P>
    ( w4 \2 t0 @: T, b<P>    // Lock that hash bucket$ s7 n, m, z2 o/ \6 [6 n, Y
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;! W  M) q( g% t
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>. P3 Q8 Z; M3 `4 U1 T) O
    <P>    // Loop though players in bucket until we find the right one
    ; B' n9 v, A) z7 f1 O5 _9 t  O    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];3 }4 G! @! ~" ~% s. h- G7 h
        while ( pPlayerData )
    3 f. y* p0 S# A" }, h3 s    {
    2 ?' I$ _: K/ o0 e2 C" t        if( pPlayerData-&gt;NetID == id )( r5 `* L' g# w5 ]( F. Q7 U
                break;% ~# a0 v! u1 \" F$ u
            pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    4 J% h/ S5 r" C8 g    }</P>
    1 i6 q! ^3 d9 ~" g: F; \$ k<P>    // Unlock the hash bucket; S$ h4 b7 j$ s& t* {8 X" Y0 Y7 P
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>2 @( L3 l/ e% `- }' j$ z
    <P>    // Return the player we found (will be NULL if we couldn't find it)! ~! d+ Y6 R& u( F; s6 r
        return pPlayerData;  v; W; y; |( w4 Q) e1 V( U
    }</P>
    & e9 @( W* L/ Y) b
    * E$ n+ A7 m% e7 Z- ?<P>
    4 C: e# H& ]# _//-----------------------------------------------------------------------------
    7 v8 ]/ i, ]$ T! p2 g& O& i// Name: 3 I$ k& K* C# J$ v
    // Desc: calls DisplayConnectionInfo for each connection in a round-robin manner* E, z$ C% }+ Q: s3 p2 H' L2 q
    //-----------------------------------------------------------------------------
    : l5 ~4 K# I& \9 ovoid CMazeServer:isplayNextConnectionInfo()/ I: d+ @7 F6 ^, a  r
    {/ F5 v/ F5 n4 H1 x
        if( m_pNet )- m/ _. B/ @' h* U- G4 b
        {
    + |2 k+ n) e* m6 n- R/ G7 t        // Find the player that was displayed the longest time ago, and display it.; `  I) V  q+ z4 {0 z9 d- C' w
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
    1 p5 l$ h; c, N  A3 k; q0 x        PlayerData* pOldestPlayerData = NULL;
    % m; U- y% O7 s* L        FLOAT fOldestTime = 0.0f;</P>
    1 W1 O& q0 q: P/ f  M+ X<P>        m_PlayerDataListLock.Enter();</P>; _' C* x4 i  z1 a
    <P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
    ! \( u* J! D+ l9 @" s- K% F$ H/ u1 _- R        while ( pPlayerData )
    3 g# Y5 f* p  {- P- p2 B0 Q3 M0 e6 _        {
    # e5 ^- s: S5 h            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
    % [# X; h4 u6 B            {
    ) U$ J* p/ q1 X) u" f* ~                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;' t( H) X* ~: B% [3 K9 V
                    pOldestPlayerData = pPlayerData;7 \$ Z) Z* [3 X& \
                }</P>
    3 L) U" h6 f1 j( |1 q& T1 Y<P>            pPlayerData = pPlayerData-&gt;pNext;3 H) ?" X3 w$ g" I1 X: Z$ O
            }</P>
    / A' F3 ~! K! |7 f: `  [: y<P>        // Display the player with the oldest CI field, and update its CI field." W  p4 c) l# @/ A3 f1 ]2 `
            if( pOldestPlayerData )
    8 e- Q$ r3 j+ Q0 I, }: D" h% g% n        {' @' X' F+ I- n# l9 v
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );$ M) e9 ~6 ?  w/ k! L( ~
                DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
    * `1 p/ j1 Q, e$ Y: s( `            pOldestPlayerData-&gt;fLastCITime = fCurTime;
    7 s# o0 t+ o9 p4 ]* w( |0 T4 D        }8 S( i. p+ Y6 l% o9 ^4 Y( o7 s( l
            else
    & ?! U4 |/ K+ ^( ^4 O        {% K* C1 D3 ?: Q5 s+ f, B( |
                ConsolePrintf( SLINE_LOG, TEXT("No players found") );
      N5 P* {6 H! \" h  V; S" x+ s2 U        }</P>( i5 I+ C& m0 V
    <P>        m_PlayerDataListLock.Leave();6 t( T4 p; N& M: K2 \/ R" Q% j
        }
    2 i$ A9 I' k% x" s, j8 |$ S6 J}</P>! r: D/ C7 j( o1 P; r4 w
    ' D7 ?0 z! H' X5 u/ n, o8 r; Z
    <P>
    & o# }# \0 T. R  M5 a//-----------------------------------------------------------------------------6 O( W# D9 `9 Q& s' X
    // Name: + Q; \( j* ^, f* }/ ^
    // Desc:
    $ A2 i% f6 g) d  C# m4 f//-----------------------------------------------------------------------------# I. ~% r: ^* N+ s
    void CMazeServer:rintStats()/ w9 c& N& A1 `2 v4 c4 U" n+ F8 o/ b
    {4 Y2 P$ P  ^3 n: w$ l  F
        ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
    1 g) b8 S# O9 a  |; ^* ^9 m; L8 w( R                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );6 X# y$ u7 B! A  ~+ ~8 w) d
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
    3 o4 A& V7 b- m/ e! E/ k* X                                    m_fAvgThreadTime, m_fMaxThreadTime );! _( g. @6 |9 d0 |3 D; v! x
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );  I* y8 m6 H0 Z6 n
        ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );
    0 J' d1 E/ H5 v" F: m3 |( ]}</P>
    6 A3 e7 e. s; P; B# `
    8 b" \# R. a7 {5 q- ~<P>
    " o$ f# d  b& [//-----------------------------------------------------------------------------7 ?6 u6 R- j6 u. b7 C
    // Name: " u% d: U8 ^; t
    // Desc:
    ( P0 q! F9 n1 q$ r# y, Y* S6 ^//-----------------------------------------------------------------------------$ o1 J% X! Q! G. z% c/ d
    void CMazeServer:isplayConnectionInfo( DWORD dwID )
    : \" }5 `4 b3 l6 r/ ?! I{$ l3 _+ R! j5 r
        TCHAR strInfo[5000];
    & \4 S, N2 F& O4 @0 S    TCHAR* strEndOfLine;
    ( W6 ?" u+ S/ {4 w    TCHAR* strStartOfLine;</P>
    3 Y& W8 Q+ ^0 L1 N' ?$ @' X<P>    // Query the IOutboudNet for info about the connection to this user. j  v! O  l0 A. M& f& S) Q: F
        m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>& q/ L8 P( e# e' k% F# A
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );3 ?3 f" P) e3 G7 g3 \
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    8 ?0 i, k' |* d# B  z  P6 a7 e6 ]! Z<P>    // Display each line seperately
    0 z. ?. }; A7 h    strStartOfLine = strInfo;8 j* {+ z/ Y2 w" z8 e+ }
        while( TRUE )# |! k( {1 q1 R
        {, k+ [1 c' V$ H9 v% |
            strEndOfLine = _tcschr( strStartOfLine, '\n' );
    " z" p: P% F4 d# ^$ Z& v+ S, E- K        if( strEndOfLine == NULL )  Q4 q9 S4 |; Q9 h: _
                break;</P>
    $ W; I7 T$ u( t<P>        *strEndOfLine = 0;/ b+ h: E( Y$ U
            ConsolePrintf( SLINE_LOG, strStartOfLine );
    4 t" C) o; _' g) V        strStartOfLine = strEndOfLine + 1;
    $ V- s5 Y; e/ {# g$ j1 m. _% E    }9 z' i6 ~: U! h! g
    }</P>
    7 ?+ u, _% {( P! p
    ' I2 j& ^) `2 g8 z) D/ [0 ]6 s* ]- f<P>! a, T8 F4 k* M; W  C
    //-----------------------------------------------------------------------------
    + v8 D# G7 c! {& ^6 f// Name:
    ; _* M* G( N- m! v4 ^& _7 O// Desc:
    3 U1 _9 a' @! m' [+ O  j' p+ ~//-----------------------------------------------------------------------------
    ) O4 f( I- P+ R9 E! rHRESULT CMazeServer::SendPacket( DWORD to, void* pData, # ~3 v+ ^) n  a
                                     DWORD size, BOOL reliable, DWORD dwTimeout )
    3 w8 {( ~, m6 |# O{( a, K$ {6 b% P; ]' C- r( r4 o8 U/ m
        // Chance of forcing any packet to be delivered reliably
    ! d+ |6 U; E5 `3 b: E7 E- A    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )- N: w/ `. o1 Z% `9 O$ d2 k
            reliable = TRUE;</P>
    3 g' A$ x2 V( I' Y( U: |* |; G2 N<P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );# f8 d# f; `" t4 Q2 Z) Y) I) [
    }</P>- _$ U- e6 J' @' w
    , S$ z. z( r8 T- Z% A- U
    <P>8 |( X* \0 z$ x0 F; y/ H
    //-----------------------------------------------------------------------------0 \  t8 d: a/ D( M3 w: ^0 F" c
    // Name: 6 s* t& E. c8 y+ U5 K
    // Desc:
    4 s9 R2 l6 B- ~" L4 g4 U2 n//-----------------------------------------------------------------------------0 |% V/ ^! E  V. [) P" M2 F
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )
    . V  k# U( c3 \9 ]. ~4 ?{
    7 h: T' k2 z) Z' s" t: y2 U    // If we're up and running, then send this new information to all clients
    9 j6 P  G5 H6 P. M4 w% ?    if( m_pNet )/ P2 s: n% `2 F0 d4 J
        {) e! A/ J  w% A
            //Use the AllPlayers ID3 V( J# b& E# T# @8 T, G
            SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );
    " `- n: y) Q& I* A& l/ I: S# \    }! K! k' L. v" {2 D- }  ]
    }</P>
    ) _) k( T4 r; W6 Y( J1 X. V. O# ]/ M7 ~! O
    <P>
    $ F! `3 E3 v. f; h1 P//-----------------------------------------------------------------------------
    + J; ~7 o. Y* m) R/ G! Z4 Z// Name:
    * V5 S, N* m# u& _2 O6 G// Desc:   ]: d) k# ]$ O0 \2 u
    //-----------------------------------------------------------------------------8 l1 d% C9 R8 ?' S, e
    void CMazeServer::SetClientReliableRate( DWORD percent )
    . u" h# I8 }2 a4 _, ?- g# I{
    ' s* I" e: @+ R) }+ |" F8 m    // Update client config, and build packet containing that data: A5 q9 ~& r$ L( M
        m_ClientNetConfigLock.Enter();( M) w2 R. l1 k0 r! u9 q4 L# @0 Y
        m_ClientNetConfig.ubReliableRate = BYTE(percent);. f: r+ X) m2 m( O9 `$ e; r$ N
        ServerConfigPacket packet( m_ClientNetConfig );! A/ v3 D% a# F* O( r7 B
        m_ClientNetConfigLock.Leave();</P>8 I( u$ K, O3 C4 I
    <P>    SendConfigPacketToAll( &amp;packet );3 U. f% v3 }+ |8 J, U' x
    }</P>- E% X0 S1 y3 j+ f$ Z) s) E% L
    4 u, S2 z2 m7 o: P: n) }# i
    <P>: B: ?3 t6 f# K0 `$ ?7 m1 w2 o
    //-----------------------------------------------------------------------------
    8 Z: N; N' }( X  a0 m& [0 y// Name:
    ! K" B6 d( i7 }; ?( K. v: r// Desc: 0 n5 N4 K* {: I
    //-----------------------------------------------------------------------------
    + S5 |! Y- E0 R$ J  x1 ]2 Dvoid CMazeServer::SetClientUpdateRate( DWORD rate )- Y0 M) a2 @0 K
    {  t/ D" H  U. o
        // Update client config, and build packet containing that data# l7 U$ S$ A. _, u1 i7 O$ B$ f" [
        m_ClientNetConfigLock.Enter();, `/ h$ r& V. k$ R1 }# q( q" Y, t7 X
        m_ClientNetConfig.wUpdateRate = WORD(rate);
    : o7 B0 Y: Z( N    ServerConfigPacket  packet( m_ClientNetConfig );/ w  u2 u, A# q8 B. Z! }
        m_ClientNetConfigLock.Leave();</P>
    ) ?  b$ l4 {! D9 e& V<P>    SendConfigPacketToAll( &amp;packet );
    2 ]/ R( E( L# E" J}</P>
    % d# s7 h. {" A. ?& Q' m
    , T. S  B0 N: }- ?5 R* U<P>/ O7 Q& o4 o) r7 h5 [' o5 j
    //-----------------------------------------------------------------------------
    + g4 l1 O8 v! ^  [6 V6 l// Name:
    " K, U, Q" z8 x/ }5 M. p// Desc:
      _" l+ _  Q, Z" ?//-----------------------------------------------------------------------------& ^; S. m  _; @6 c- ?% F* ?8 m
    void CMazeServer::SetClientTimeout( DWORD timeout )3 C$ F9 M; P- M1 r! A
    {
    , D8 u  ^# N  ^5 b) U    // Update client config, and build packet containing that data' M- v0 x- P2 S! R, K
        m_ClientNetConfigLock.Enter();
    ' S7 e3 z# Z( L    m_ClientNetConfig.wTimeout = WORD(timeout);; u0 I# i3 b& v6 I' l) x9 t
        ServerConfigPacket  packet( m_ClientNetConfig );
    ; ~/ g* b! h# |6 @* D. t5 t    m_ClientNetConfigLock.Leave();</P>$ L$ c# G# _' x1 q# A! ]" u
    <P>    SendConfigPacketToAll( &amp;packet );& j$ v2 \6 M" `2 x2 q3 |
    }</P>
    & D: f; O) N- K4 r; T5 a" _1 D* U  Y+ S! y0 J3 k
    <P>
    ( ?1 s5 I! p6 N. b  F$ n% ]//-----------------------------------------------------------------------------
    ! T0 Q3 C( d4 c' H  W5 ?9 p4 l// Name: + h! Z: ^! O$ n3 O2 c
    // Desc:
    4 E5 W/ M) v3 \* }5 z//-----------------------------------------------------------------------------( r! n1 T, z: |3 z0 Q% q* ^
    void CMazeServer::SetClientPackSize( DWORD size )
    8 k% i1 J) A( J{6 v3 x. ?# M  |) P$ y" Q1 k
        // Update client config, and build packet containing that data2 V, F: a+ u7 F3 l3 Q; i: H
        m_ClientNetConfigLock.Enter();
    % y0 W; A, S1 D7 C   
    , J8 C1 m0 T4 o  F    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array., h. o' r7 B- |( V1 |
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   
    1 \, T: S2 j5 ~1 y* g2 l( X        m_ClientNetConfig.ubClientPackIndex = 0;</P>! ^" q  o6 n* ?! [$ Y
    <P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);0 c& b7 i* w$ M# k
        ServerConfigPacket packet( m_ClientNetConfig );
    ' |' r9 T  f  g) u  s    m_ClientNetConfigLock.Leave();</P>+ z- v/ R. a; x% j* [! @: d% N
    <P>    SendConfigPacketToAll( &amp;packet );& ]8 T  `( Y3 d0 {$ c! J4 T, L
    }</P>
    - M6 s' I$ a1 C" a& k
    9 J2 n; S6 C. w- p7 C<P>! R; r6 n/ u7 d% R, f1 H& ]5 U
    //-----------------------------------------------------------------------------+ y+ I' j2 Y" ]. u* x* b( @+ r
    // Name: " r- U" ?9 M0 }7 M
    // Desc: $ Z" l( r% }9 [" w. M! X' I/ P, C! y  A
    //-----------------------------------------------------------------------------
    ' M) A  w. A, a( z, o# Lvoid CMazeServer::SetServerPackSize( DWORD size )
    " G) s7 ^% V! J* A+ S! O{
    2 h6 A$ v8 w+ j& b0 W: I5 [5 k5 v    // Update client config, and build packet containing that data+ }( h! j+ P; S: B& r# s8 i# K; V
        m_ClientNetConfigLock.Enter();
    ; A5 g9 e8 X% I" K' L0 g   
    6 j% f- }$ O* ?- g  c    m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array., \; D3 F1 m5 h3 C
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   
    ; O+ Y1 n6 C& s+ w4 C4 A        m_ClientNetConfig.ubServerPackIndex = 0;</P>
      I6 r# l) }+ F  q3 O<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
    0 z% ^/ g3 {( T) G8 L2 E3 M# d    ServerConfigPacket packet( m_ClientNetConfig );
    1 S1 L6 \: ~. ?% d& t7 [) j& i    m_ClientNetConfigLock.Leave();</P>0 g4 h: |+ c' D3 n
    <P>    SendConfigPacketToAll( &amp;packet );/ N, Q0 w+ g4 _. x, o7 Q3 b- v
    }</P>
    4 M$ c% ?3 q7 w  p. C( e, v<P>
    ! Z) d( ]8 P! y//-----------------------------------------------------------------------------
    / d# J8 p5 P0 `. B- J0 e9 r& v// Name: ! P9 |' m3 h# F  H& v
    // Desc:
    & e$ z9 \; P' C( j- H) w, ]( i6 h# x//-----------------------------------------------------------------------------' o! H# G" e( ?1 F# f' k
    void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )' _6 ~& I" K, [
    {9 v6 U; z  M0 P) ~) W# l4 P
        // Update client config, and build packet containing that data
    : T# R2 ^& @. Y4 {( a    m_ClientNetConfigLock.Enter();# N) k# b! ~: _
          k' A4 N8 s$ X2 B1 H! D" G
        m_ClientNetConfig.dwThreadWait = dwThreadWait;
    / Q2 F  v  u# N! N- `+ d    ServerConfigPacket packet( m_ClientNetConfig );
    0 R$ ?' y( S# ^* g0 j    m_ClientNetConfigLock.Leave();</P>) P" o6 e! m7 I$ R6 k) r
    <P>    SendConfigPacketToAll( &amp;packet );! ?! y6 J& r0 S
    }</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-14 11:30 , Processed in 0.437990 second(s), 50 queries .

    回顶部