QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4161|回复: 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>
    : a' P' M5 g$ t( t  I<>// File: mazeserver.cpp
    2 n0 R" p6 q) \9 I* a1 j" @//' ~( a% W( K  {, `# s& X. P
    // Desc: see main.cpp
    8 F7 I( B* `, k& c: R" t; \, a//
    7 S8 w1 k. @" A6 X' s1 c// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.3 O" i1 ]8 k; y* L% ]( Y9 ?" Y
    //-----------------------------------------------------------------------------
    . b. I  Y  a6 F8 i" p#define STRICT
    , c8 |5 ~! c! e5 z#define D3D_OVERLOADS6 R" M4 q, M9 Q- j: K
    #include &lt;windows.h&gt;
    & x% X2 u- j5 j; R$ V. L; S#include &lt;d3dx.h&gt;
    7 b, Y7 N# d3 G, \' \#include &lt;stdio.h&gt;
    ! N2 g) D7 u( d/ x& u8 }% }7 W: j#include &lt;math.h&gt;0 u) I( Y4 `( O! a
    #include &lt;mmsystem.h&gt;3 k* F9 n% b# w5 \2 C3 k. R
    #include &lt;dplay8.h&gt;
    ) i- u8 q+ b+ h) S2 C#include &lt;dpaddr.h&gt;# m$ w" g* k/ n, `
    #include &lt;dxerr8.h&gt;
    1 [; n$ d7 l5 p1 i" l4 H9 j( b3 @#include "DXUtil.h"  p! q+ c# c$ ^$ B1 F- L
    #include "MazeServer.h"0 @# _8 w" m" W1 ]7 ?: p; u) J
    #include "ackets.h"
    7 [% L% h, F" N( y#include "Maze.h"
    ) r' |' ]9 e" H# `& n* L% P#include &lt;malloc.h&gt;
    ; @- X8 Y4 q+ }3 @9 H: Y4 X$ o$ X, |#include &lt;tchar.h&gt;</P>
    ! G/ J: d( m6 m
    0 F1 _. m# n' ~+ z<>//-----------------------------------------------------------------------------
    2 l$ v( C3 u" N. ~( S// Name:
    ) U" Q- N! I+ ]* A// Desc:
      f. q% y  O7 [//-----------------------------------------------------------------------------5 F0 m7 L8 `5 ^* x5 `7 Z/ p
    CMazeServer::CMazeServer()8 l. n; r/ v$ Y, ?( s
    {
    3 w7 w: W, k. ^6 D3 a# }    m_dwPlayerCount         = 0;4 ?6 m1 t1 o0 ^4 W& b" _( O8 c
        6 x+ A- p5 A+ q. b
        m_wActiveThreadCount   = 0;" }$ F! g% U( t9 X( i# Y
        m_wMaxThreadCount      = 0;( G/ D7 Y$ H# b
        m_fAvgThreadCount      = 0;: S0 E6 e) q7 X# E
        m_fAvgThreadTime       = 0;
    ' g' G+ |: l$ j  O    m_fMaxThreadTime       = 0;</P>& p. |3 k, w3 r2 w- @. S
    <>    m_dwServerReliableRate  = 15;
    + {0 n2 _8 c0 D* M6 Z( S( V# V    m_dwServerTimeout       = 150;+ l- E) l4 Z8 ^- q! I
        m_dwLogLevel            = 2;
    - w0 e. |- l/ g2 j) e    m_pMaze                 = NULL;</P>
    9 p6 ?! H) u( A<>    m_ClientNetConfig.ubReliableRate = 15;' `0 \* [; Y( I; w
        m_ClientNetConfig.wUpdateRate    = 150;# z! S& u. Q9 m# h
        m_ClientNetConfig.wTimeout       = 150;</P>/ A4 [9 U. g4 n/ D. T
    <>    m_ClientNetConfig.dwThreadWait = 0;</P>, z9 w3 j% }- Y, V9 S) x, Q0 V8 B) k
    <>    m_ClientNetConfig.ubClientPackIndex = 0;- M* \, M2 f+ a4 x
        m_ClientNetConfig.ubServerPackIndex = 0;/ T( s6 l0 e3 ?  W+ s- A0 y
        for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)9 H, r2 a4 H. I3 I% ~
        {/ C% Y( F/ L& s* a! V* w
            m_ClientNetConfig.wClientPackSizeArray[x] = 0;
    5 ]4 N# e: U4 {* O$ @        m_ClientNetConfig.wServerPackSizeArray[x] = 0;: o  }3 r2 i4 R( }) _' K
        }
    4 y4 X7 p2 y' ?6 _3 w}</P>
    : D  L# T. Q$ |- _2 K
    & B/ R( s& d1 @& \<>
    * z2 e- H1 e/ M0 c0 h% y; w3 Y//-----------------------------------------------------------------------------
    ! \/ n3 g8 f3 \8 U// Name: $ p* k* M( U: t; i1 S% Y( W
    // Desc: . X- C' M9 `( D" q7 y
    //-----------------------------------------------------------------------------. Q' o/ v# i/ K6 T( G
    HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )# N* w# ?- \6 d
    {
    8 M' g# n# W3 _0 z- j' e    m_bLocalLoopback = bLocalLoopback;
    & F; A  K& M/ E! G    m_pMaze = pMaze;
    1 \# F, d; Z" h$ {! w9 K    if( m_pMaze == NULL )+ s% w% y8 E7 `7 h! r
            return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
    + C+ U5 }0 p# n  F" |9 M9 m3 o<>    // Grab height and width of maze( ?: u  T1 r; p7 l
        m_dwWidth = m_pMaze-&gt;GetWidth();9 K# Z% `9 g  y2 j
        m_dwHeight = m_pMaze-&gt;GetHeight();</P>8 J4 P1 e; _$ l3 t
    <>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    2 |) j, j" e0 S. {) ^    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
    3 K0 G. _, ]' l7 f" z' _+ y<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.
    % C$ v5 _9 Z( i) h$ f* M: i% I    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )9 b6 Y0 C2 s+ z6 p! w
            return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );% Q! |0 s. ~: v, d! _8 t) x/ B
        if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )
    % x$ y, b' H( z% M        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
    & Z( P, Y- P& D& q4 h) Q<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;# n. \* O+ Q4 [% G% ]
        m_dwMazeXShift = 0;# {# ~2 c" H4 O
        while ( (scale &gt;&gt;= 1) )
    / T, L3 n/ @' F0 c        m_dwMazeXShift++;</P>& E2 Q8 U4 F4 |4 m/ S; P9 k! [
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;5 j1 h/ U* c: ]
        m_dwMazeYShift = 0;) W0 P" m2 S* ~# ~6 J. C3 f
        while ( (scale &gt;&gt;= 1) )
    $ D: ~! ]6 W3 J- o1 B: N0 O  Q        m_dwMazeYShift++;</P>
    3 f2 s0 B* g, w<>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||( l1 _8 G/ a4 ^* c
            ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )7 H9 e: ]2 ?! {6 D: k0 `9 ?+ O
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>5 H/ G% X. t( m3 J+ Y; [
    <>    // Initialise the player list5 Q7 H( I% q% L; z9 G0 ~( Y: `
        ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );8 ~" ~% H( ]; k9 ?2 p
        m_pFirstActivePlayerData = NULL;& j. [% ^. O& Z0 s- `$ B
        m_pFirstFreePlayerData = m_PlayerDatas;
    ! L0 ]! Q/ v' T0 O/ `$ i: j    for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )
    $ {7 l  S& j2 K% W# t    {  c% m) f4 X8 F" O; C8 `
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];$ ?  Y) e1 t) M9 f7 L
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];+ x3 P( S* Z4 q! j0 y
        }</P>
    7 Y$ I" a- m: I6 W<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];, w  p+ F: Q- [; V. G
        m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];$ g$ S0 H# ~" d4 i
        m_dwActivePlayerDataCount = 0;
    3 }) _/ Y& S" U" s  o* K) t/ q    m_dwPlayerDataUniqueValue = 0;</P>& v4 {0 U/ B# s; {
    <>    // Initialise the cells9 i1 ?  K! {! P" Z/ o" a
        ZeroMemory( m_Cells, sizeof(m_Cells) );
    / T3 F& _8 z5 Z/ a) J+ `8 D. u, ]6 ~    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>8 N3 L2 u9 T! w. S2 J
    <>    return S_OK;5 Q: i; ~( {, i; K' z
    }</P>
    ( e8 l5 l4 q- a. J
    ) w0 O- J% k0 T, `9 ?* X0 v( J( T<>
    . i7 p6 s; {% y$ h- h0 {//-----------------------------------------------------------------------------
    0 W" E8 H. W4 ~$ d: {// Name:
    ( D1 y% r2 {! N// Desc:
    ! Y. J9 k& }% l. H/ C- I//-----------------------------------------------------------------------------
    , g) n* c7 ~* T" J! d+ o: ^void CMazeServer::Shutdown()( A: _- W3 p6 I
    {
    + z$ g, x  X# S7 I" ]+ V}</P>1 z3 ?; g# @& e( L& G# \' S
      L4 ~, p' j; n* Q. h3 \, u
    <>8 C# J8 ], {: `. ?  e
    //-----------------------------------------------------------------------------( U9 n1 n6 ^' @* E9 U3 A. A, n
    // Name:
    ) e0 p1 n0 z' H2 @// Desc:
    - P  n' K. C/ ?4 P$ A. l9 S//-----------------------------------------------------------------------------! T8 X9 T7 j. ]* g( m$ `
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    ! L2 {1 J: s, }( g{
    " w6 J+ {# A" t4 t- N( S& q    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,3 V. Y6 I2 e: ?# p
                              x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );7 h& j1 U9 |7 \9 `
    }</P>
    7 c9 ^/ B: l8 q7 v8 C4 K9 Y3 M% ]/ t5 p  O8 n
    <>
      E: c/ O6 }0 z& F* t3 Z0 N/ p4 c1 s4 x//-----------------------------------------------------------------------------' Q: y( `& K; L2 x6 }7 F0 A
    // Name: . g" g' ]) N1 ]* I0 a6 J
    // Desc:
    4 f5 c, J3 s: O7 m- E* B2 R//-----------------------------------------------------------------------------/ u4 d  a/ e) z! q: ]# x( O$ Y" O/ n
    void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )! S) `6 b2 `9 I% N% H1 F3 G4 e
    {
    : p7 k5 i  a: n- ]    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    6 q4 p5 Z7 u/ U$ @5 M                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    9 J* s) \# R$ P}</P>
    / z9 |* Z% q( g  Z: y2 R& C- {; @' n  ]" Y$ W2 I$ r
    <>
    8 _) i0 E. S" |' `//-----------------------------------------------------------------------------2 I* B4 ~% t) ?- q1 ?
    // Name: ' T3 l% [6 D9 _/ X& g
    // Desc: # R4 [. I- p4 j, e. M
    //-----------------------------------------------------------------------------, T* [6 p, B) y1 R' Y3 l
    void CMazeServer:ockCell( DWORD x, DWORD y )+ G% \- g; u0 d; F  X- l6 Z, I
    {4 y. k- P/ o! {
        if( x == 0xffff )7 H, N; W& m3 s( w" `
            m_OffMapLock.Enter();
    8 o) g% x, F5 {2 a" D, O    else* Z( [+ b% S: W$ ]* ?# i; r
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);9 X- Q' Y- [$ o2 S2 k' C8 p
    }</P>2 v9 R) D$ c# l

    ! d, v8 u" x2 H" C4 X<>
    ) ]' q: ^. g5 E# N; A( t//-----------------------------------------------------------------------------5 p& d/ }( U1 I
    // Name:
    , T1 d: p8 p- _# ]// Desc:
    6 ^9 F2 o* n8 H( I9 R//-----------------------------------------------------------------------------
    & ^$ W, I3 J/ R3 wvoid CMazeServer::UnlockCell( DWORD x, DWORD y )
    5 ~9 X0 s* `8 X: ^5 [{# J" V+ Q/ y3 |
        if( x == 0xffff )1 G+ @  y6 A! W" X" a6 |
            m_OffMapLock.Leave();
    $ \" a$ v% s/ F+ J# H# V8 b" y6 T4 l    else
    $ D7 e% w: t4 J) c! H        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);, h: T0 B/ s7 |- l$ V9 O
    }</P>
    , d* c- W& ~; v1 ]+ S' A1 J* w& H. o2 g" ^0 L% {. A
    <>4 H; Q5 Z6 C& J  A0 L
    //------------------------------------------------------------------------------ U  |' s& t4 z5 u
    // Name: " G* b7 j* m: u* \4 u$ t& m2 o
    // Desc:
    ' n/ p. }) R: j" b0 i, s9 b4 d6 X( o//-----------------------------------------------------------------------------1 Q& C3 H9 \" Z) Z8 n
    void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    ! c! c: A' ^% O7 w8 ~6 c* l7 n: O# D: [5 R{
    + C& Y2 e1 e) ^. W+ `( Q8 e    if( x1 == x2 &amp;&amp; y1 == y2 )
    ! F2 K; Q" e8 N1 c    {
    6 n, X0 ^6 r' x: r9 O& O# D2 s; O        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )1 n# j* W: f/ b& Q4 x
                LockCell( x1, y1 );7 Y2 x$ m- X  q" J6 R8 N! e
            else- w" }* p# i- Q3 R" }
                m_OffMapLock.Enter();</P>, @8 F1 \9 c& p* I/ K
    <>        return;6 e! S  b. l! A
        }</P>
    ; S! a! \! E9 U/ Z<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;! p4 i3 d" ?+ ?6 }  o& T
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;; a7 L+ @) y" v! D
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    * }" S# U& J" @+ C" n    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>1 l) x* x' M. {* h
    <>    if( x1 == 0xffff )/ A! L2 ~1 U2 Q1 L2 h
        {2 t- g& }; S) B& T# `  d$ d  q2 w1 k# V
            m_OffMapLock.Enter();+ E0 B7 f/ Y8 b4 V* O3 l2 U: h8 K
            m_LockGrid.LockCell(x2shift,y2shift);& B3 N) V3 L8 }  O2 ]9 m0 D
        }8 ]* u6 M1 D2 w6 h2 H$ }
        else if( x2 == 0xffff )( q$ B; V$ h. |  ^0 |( L3 S4 R6 G4 T4 L
        {( G) D1 {% R. P+ P2 L2 }5 B' n
            m_OffMapLock.Enter();% m2 ?2 n: R0 k9 x
            m_LockGrid.LockCell(x1shift,y1shift);: l) S  o7 ?  s
        }, y6 E; W& R( N3 c, ^
        else
    + J! p9 g8 V" J3 o8 b1 _    {) {+ j7 O) m* ^+ M" E& h
            m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);3 M  V3 k" V$ V1 c3 M6 q
        }
    ! x) @1 J: Q2 X7 D}</P>2 w% c3 k6 l9 W; J6 u; H
    " O4 t0 |. f5 J
    <>: @. r+ n8 c; k
    //-----------------------------------------------------------------------------
    ) l0 k4 @( z) l7 P0 J8 H$ W/ ?# T// Name:
      W- {) F1 M% B, |# y6 o' f// Desc: ; r- a8 L1 f1 G1 _
    //-----------------------------------------------------------------------------; n0 U5 V6 k# h& W, d$ h9 o2 }: N
    void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    / h: G& R, K( b; t# q{' S1 ~+ v# G( f. i1 @# b* Q7 D) G0 D  J
        if( x1 == x2 &amp;&amp; y1 == y2 ): @, M- f, i" D6 l. P' X
        {0 ^* Q& T; l' B2 q
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )7 o' P$ N; h7 m) l
                UnlockCell( x1, y1 );
    9 V0 e6 z, O4 {# h! ~        else, z! ?4 x, r% S- m
                m_OffMapLock.Leave();</P>
    # n! \; c* M- [. K9 i<>        return;
    . W, J' n. O: u8 U5 ?) C    }</P>0 X1 J9 S  Z) j& V  F+ p9 s
    <P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;, N- {, \0 l8 X7 _5 J, P
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;5 Y# p" m% ]' a; A7 f+ V" [
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;1 D! x! q  N, ?2 z; Z
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>) {5 J1 W  p1 P; o  Q
    <P>    if( x1 == 0xffff ), l. z! s2 A- A
        {
    2 ~6 C4 H6 P. B; t        m_LockGrid.UnlockCell(x2shift,y2shift);. T9 g: P! |- _, u: U
            m_OffMapLock.Leave();3 @" L& m( Z3 I( d( J; o
        }
    ( r' y5 b! ?& _- w' E6 b9 I% q# b: e    else if( x2 == 0xffff )+ Y' a( g7 p. o9 J$ \
        {$ r: U( [) V4 d3 p- j. K, T  _# b
            m_LockGrid.UnlockCell(x1shift,y1shift);
    ' D: X9 C$ a! o6 C, M        m_OffMapLock.Leave();
    : U$ y3 [5 k: r    }5 r8 j! q4 v0 _: J
        else ) I* Q8 A1 h3 E6 L
        {$ C, F. Q5 `. B- t
            m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);" `4 H1 m9 r! s$ z. w# l! t: q
        }
    , ^# f/ E/ v! P, x- h}</P>
    1 n+ @" O! v7 U: M2 c. r% G6 [- T6 A# V; F
    <P>
    1 q# Y2 {  r: B) H8 W+ j6 D//-----------------------------------------------------------------------------7 `6 B/ \( c" Y
    // Name:
    8 S, e+ d! S% K& w+ b// Desc: * T2 v  s- u5 @( x! y6 l
    //-----------------------------------------------------------------------------
    , U% C" U  t5 Cvoid CMazeServer::OnAddConnection( DWORD id )
    4 V$ z( a7 W, U  b: W* _{
      T) w9 y1 E5 x( X    m_AddRemoveLock.Enter();</P>
    0 {# x, J& O: H& w9 S9 Z2 O: h  S0 C<P>    // Increment our count of players
    , l* m0 o* H" f    m_dwPlayerCount++;5 Q1 ^' a" w- J+ n; j3 e
        if( m_dwLogLevel &gt; 0 )" l2 T. V3 L% {$ |5 _, o7 o
        {/ L+ O! C8 H( a- Z2 u2 t) ]9 G& ?& J
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
    ' W9 F+ d/ U, e& d1 Z+ S        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    $ d" m& S4 r8 K  m1 }" w7 _    }</P>
    3 Q2 G6 G, G$ t1 S  X7 F# |<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )+ t  v. w( @! \% [/ g
            m_dwPeakPlayerCount = m_dwPlayerCount;</P>
    ' H9 T5 A+ M) y; n, B$ b8 _<P>    // Create a player for this client. f7 J4 U4 W6 T9 Y+ L4 I5 H$ \% v! V
        PlayerData* pPlayerData = CreatePlayerData();
    ( h4 X; b+ k) j; ]$ B5 q8 Z    if( pPlayerData == NULL ). j: A( b* `2 u) t$ J1 O
        {
    7 ?( M+ F0 z0 ^7 i        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
    ) n3 h4 b2 ~8 B" J8 }        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );
    ' b- \2 E, c* e, ?8 C3 O; E        m_AddRemoveLock.Leave();8 _+ I+ K  B' S. |7 Q& z1 U3 X
            return;2 j7 i& e; m; T& M4 L
        }</P>
    1 C6 R' c5 b+ V) y<P>    // Store that pointer as local player data2 [! s% O0 O9 i
        SetPlayerDataForID( id, pPlayerData );</P># n: h9 E6 R' Z1 y& w; D9 `
    <P>    // Grab net config into to send to client6 ]2 {  [' z1 Q. c. T: u" b! F4 k
        m_ClientNetConfigLock.Enter();
    2 }( z2 k/ k: ^  [# W6 v    ServerConfigPacket packet( m_ClientNetConfig );; L3 o8 {; T; C+ H/ S+ F& u
        m_ClientNetConfigLock.Leave();</P>6 i! k3 P7 x2 J+ m: e
    <P>    // Send it
    7 |0 A' T6 V3 \/ O% P: C' m$ s    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>
    $ u$ q: e/ `5 ]( H, ^, l<P>    m_AddRemoveLock.Leave();4 T8 [+ @1 l8 z
    }</P>. I: u; J5 f5 z) K0 r
    2 w8 l( l4 D5 v$ Z
    <P>
    0 O/ _# ~5 |3 }/ ]9 X# ]//-----------------------------------------------------------------------------& \) F& d; Q$ y6 N6 d: N! L  O
    // Name:
    3 L7 W$ c# s7 \. L! \4 n// Desc:
    - f. R5 W) B# G2 j! ?//------------------------------------------------------------------------------ p" X3 L* E2 g; G& V
    void CMazeServer::OnRemoveConnection( DWORD id )
    % W: x& `/ f' o5 w7 {# r. q{% Y" w  z6 G* G7 J- E) @
        m_AddRemoveLock.Enter();</P>
    0 W" s+ r' d3 B9 r2 k2 Y<P>    // Decrement count of players+ i: T% L- _% B( E: O
        m_dwPlayerCount--;</P>
    8 |4 |- w+ A# F7 O7 A, _+ z" v$ w<P>    if( m_dwLogLevel &gt; 0 )9 h; H. m' O, Z. I7 l/ H, R
        {5 v- h! Z4 O) D" M+ F) P
            ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
    - W! P5 x: A' Y' b        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    ; M# n6 ^! E* _4 g" O    }</P>. ~' F% R: m2 Y% O8 r  G# T( r+ O
    <P>    // Find playerdata for this client
    : n. E& A/ O/ l7 j" H; s. H    PlayerData* pPlayerData = GetPlayerDataForID( id );* ~' P( f# k' A$ d% B
        if( pPlayerData != NULL )5 i1 I' \$ a, |2 `5 ^1 f2 b; v7 ~# s
        {' j* E% {  d( g" U6 x
            // Destroy it* E1 p1 e: a  n# D, N' ^
            RemovePlayerDataID( pPlayerData );9 ^( ?0 ]0 l3 w1 r6 g' ?/ W  n
            DestroyPlayerData( pPlayerData );
    2 D5 {2 c$ {; S& W5 t6 O    }</P>
    / w" \5 M7 c9 F) S+ n# B$ P( k<P>    m_AddRemoveLock.Leave();" b4 c7 v, r3 Y
    }</P>. G. N1 ?( T2 E# b/ r4 Y$ D7 x
    . ?7 |/ w% g- D& i
    <P>" e1 A, Q% x4 ~) q. a8 C
    //-----------------------------------------------------------------------------/ K* k* ~. g& l* K6 E* q" X4 e0 U, @
    // Name:   p  _! }2 L# }( R; Z; o
    // Desc:   N+ m3 w, g/ B
    //-----------------------------------------------------------------------------
    3 j  P5 a2 x) f) V; tHRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )- t, }1 e3 \0 i
    {
    # E7 {% [! v1 @9 [' X9 t1 X$ [4 L    BOOL fFoundSize = FALSE;</P>
    + Q* W3 U4 `5 d4 o1 n<P>    // Increment the number of thread we have in this process.
    $ g  N( _9 H( ~  k: F2 {    m_csThreadCountLock.Enter();</P>; U4 R: r$ T6 H+ e6 C9 O$ Z
    <P>    //Get the start time of when we entered the message handler.
    ( r6 Y0 ~$ X# f! h* M    FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
    6 m) ?6 [5 J! v$ s' i<P>    m_wActiveThreadCount++;$ M: y+ c4 H1 h- M) c
        if(m_wActiveThreadCount &gt; m_wMaxThreadCount)" Q! }3 z- ~6 e0 n/ y5 {6 `) {
            m_wMaxThreadCount = m_wActiveThreadCount;
    6 C& g$ B/ S" p. p/ U    0 T/ C' F  A$ O
        // Calculate and average.# M$ a# `3 D0 m3 a' F
        FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;% h: B, w$ z# b5 h+ v, @) f/ }' x
        m_fAvgThreadCount += fdiff/32;
    - Q% E5 A4 u2 X9 n    , |* W" X: e0 i/ O! j
        m_csThreadCountLock.Leave();</P>( D* d# L& w4 p8 `! t
    <P>8 L" `1 B; h, x$ k1 u
        ClientPacket* pClientPack = (ClientPacket*)pData;9 c; q' J+ y* h8 E7 W) b1 i2 m* U
        switch( pClientPack-&gt;wType )
    . g  L3 K8 {+ Q# j    {
    5 c5 N) `$ r& @) A2 ~6 }        case PACKETTYPE_CLIENT_POS:
    8 w4 J% u8 j) S: k8 H0 c            0 n7 x% H0 m8 q* F5 B6 ~* g
                // Check to see if the packet has a valid size. Including 0 o6 F/ c& V& f+ x) V  e$ B
                // the custom pack size.- R& X! a" B6 y0 Y6 b
                if( size &lt; sizeof(ClientPosPacket)): V: n# H$ v; y9 r; j7 Z4 |
                    fFoundSize = FALSE;
    4 D1 w6 _* C" H: b9 K! m            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))
    9 ]; v' w6 u9 R% ?8 Y" c9 R                fFoundSize = FALSE;) y. _% N1 `: O! J1 H
                else
    & A4 Z0 c* ^$ W+ {# i+ |3 ~! o1 T. b                fFoundSize = TRUE;</P>$ u1 n; L) ]( ]' U+ x3 p8 p
    <P>            // If valid sized packet, handle the position.
    4 y; Q: G0 k" {            if(fFoundSize)+ F% `* g0 {- c3 X+ `9 o1 s1 F1 [
                    HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );; M3 E4 K" w* p6 G; y3 W% ^
                else
    9 X$ d) ^% ~5 O* Z                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>4 E4 a% ?# c" E7 W
    <P>            break;</P># ~4 }/ E2 q0 m8 J
    <P>        case PACKETTYPE_CLIENT_VERSION:
    8 n4 E/ o5 S5 |7 o9 E            if( size == sizeof(ClientVersionPacket) )' c, [, g9 v' S2 a8 A
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );
    * @. y7 l3 N5 a' E: H4 U+ o3 f5 ~            else/ _, b, Q4 w! b1 _- ?& v( R
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );8 C; C: p( t$ p+ ~* \
                break;</P>' \, v# H6 A2 c3 M
    <P>        case PACKETTYPE_SERVER_CONFIG:</P>
    2 S/ P) M  }# \<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>
    ) K/ b6 v$ `! h  C7 J5 R<P>            break;+ x" s8 u! l, A# |. h' v0 ]
            default:
    5 a; {, [# ]/ E0 D            HandleUnknownPacket( dwFrom, pClientPack, size );
    1 e( ~+ Y5 K* S5 w) a+ }. D) i7 \            break;7 i% x& a, v. B- [- \
        }</P>
    # P+ s4 ?- R  c$ [<P>    //If the user wants to hold the thread, Sleep for given amount of time.
    . F. e+ G0 ]/ v' j    if ( m_dwServerThreadWait &gt; 0 )
    ' N4 T5 q7 w8 a4 a* O5 }3 D    {4 a. N) I9 W+ c) J# {) f" ~/ y
            Sleep( m_dwServerThreadWait );
    ! W' Z( O" P" u    }' P& D: s" _8 `* G# a( J$ N
       
    % h0 |) |0 y- C$ Z9 T0 k    // Retrieve thread data for this process.4 D. z+ K. y5 I) ^; A: w$ _5 ^
        m_csThreadCountLock.Enter();</P>
    & X. D, e" H* X$ L5 G+ g4 y3 @2 }, b<P>    m_wActiveThreadCount--;</P>0 F( e: `! q9 v1 H$ L
    <P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
    : p) ?" p4 }: W! p    m_fAvgThreadTime += fDiffTime/32;</P>6 A6 ?, @( w. L+ E" M% z
    <P>    //Get the Max time in the thread.# V: \4 B! r9 t% `. I! K
        if ( fDiffTime &gt; m_fMaxThreadTime )1 `8 P' c3 [& h4 I
        {
    % q0 T3 Q% `' k5 e        m_fMaxThreadTime = fDiffTime;2 D. e( H8 G5 S) a
        }</P>
    6 V- B4 }  l3 g: u<P>    m_csThreadCountLock.Leave();</P>
    8 V9 ]5 _8 t# H7 y<P>    return S_OK;
    4 o" C- X$ P7 K, z}</P>3 C* ?+ J2 {! ~$ E  T7 j5 T7 d. T
    & _9 }  }& x  a0 h) e; g/ I
    <P>//-----------------------------------------------------------------------------, ]/ L" o- \. e0 L' a7 P
    // Name: * B. ^/ g5 g) B1 W1 |" R# c2 k
    // Desc: 8 K% n: {: |& v. H+ ]! ?
    //-----------------------------------------------------------------------------' d- ^5 @' _0 C; r. @! e' X+ b
    BOOL CMazeServer::IsValidPackSize( DWORD dwSize )
    4 c. m% M1 W5 \+ T1 C* P3 e5 Z{6 v( u, G/ t: a; a( b3 E: Y
        BOOL fFoundSize = FALSE;8 \2 E3 k% B$ W# G# U% Q6 `3 o
        BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;" _+ z6 U, e3 R
        : V- \, c, M/ `3 ^  L, ^
        // Check through the array of valid pack sizes.
    7 d. p3 B$ J; Q, f/ E9 @9 d    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])- ^- }# m* e$ z/ `
        {
    # @% ^& B- X9 h* v; J/ m) y8 v, M4 w        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)7 e: a& D& z- s" N
            {
    ' J" J7 ]2 D7 P% M            if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    6 G7 L. P2 L$ [# k% H            {3 @$ t( z! A7 E4 C
                    // Found valid size in the array.
    0 n$ y" H9 S- s/ X  E+ W                fFoundSize = TRUE;/ q+ _- y' H" j& {" W, ]. y* s* G
                    break;
    & i  y8 q" P: B2 s. H$ N+ O            }
    . q: W+ P9 e& g0 L) v            if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array./ `# H9 R' W+ O* d
            }+ X# L+ q3 s& }9 W6 J) t
        }
    ) c( L0 o3 {4 x3 j5 C    else
      P, b" |6 K- q4 d    {" ~/ H# l7 w! U
            fFoundSize = TRUE;* y# K, Q& O9 I- E- A* \' M
        }</P>$ g& w* [6 _6 |
    <P>    return fFoundSize;% l$ {- j$ d* s) |/ K# C
    }</P>
    $ T) W9 T  j. f, O  T0 N. S/ D<P>( b0 O, y2 N& M- q* ?* w6 ?
    //-----------------------------------------------------------------------------2 z& B# D! X- Q, e; f) E% g
    // Name:   f. a. h9 {2 t
    // Desc:
    ' @' Q* x6 r7 J0 Y7 G//-----------------------------------------------------------------------------  ]5 A1 }7 X. N# Q# Y7 \
    void CMazeServer::OnSessionLost( DWORD dwReason )* d* \& x  i9 B. o& L9 K( p3 N
    {' K6 G' h4 j- s
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
    # Y3 r9 L3 T9 c9 X$ Z* x! m' O}</P>
    - c5 L: [8 p/ V2 {, ~: ]% D4 b+ G/ }% V- W0 c
    <P>
    2 a0 H5 K$ s3 }& s; ]/ w; ~% [//-----------------------------------------------------------------------------4 {" o2 Q* `% a" `0 F1 e
    // Name:
    9 x8 w! Z2 U2 D6 ^( E8 m7 l// Desc:
    & p# R5 c& g; P6 H1 ?0 ]# F//-----------------------------------------------------------------------------2 r. B  z! x! a$ r2 q  Z1 j$ b
    PlayerData* CMazeServer::CreatePlayerData()2 U% F& B+ K  ^: S
    {
    9 q1 i/ h1 r" X) l! `8 V+ S+ _1 Z% m    m_PlayerDataListLock.Enter();</P>% [/ Q1 d  A. i8 X+ r+ H
    <P>    // Grab first free player in the list
    & x1 T- T( a! t9 w; ~) c1 U    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>; }1 j# h& j# s  y9 N
    <P>    if( pPlayerData )
    . Y: P* O6 A8 k: b& v    {
    3 o* r) J* e2 Q& O4 L  c9 _) [" e6 f        LockPlayerData( pPlayerData );</P>
    & n- }* e+ n& G% @<P>        // Got one, so remove it from the free list" e, D; s8 d4 E, u
            if( pPlayerData-&gt;pPrevious )8 P. x  Z; V2 b
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    % r! \: |7 }8 q# U$ c1 C8 {# e        if( pPlayerData-&gt;pNext )
    ! x! R5 ?& G5 n% ^7 a9 e            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
    ) V$ Q0 I3 n1 n% I$ z$ `( ]# i        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>
    3 M1 Y- B5 E/ X9 r7 @<P>        // Add it to the active list4 A; s4 \8 S' ]7 c$ h2 P/ s) H
            if( m_pFirstActivePlayerData )
    5 O5 \. g6 t: \* g            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
    ) C% [$ e! l) t+ K5 |5 y        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;, E* g+ I: h9 e8 `% `0 P& m1 ]
            pPlayerData-&gt;pPrevious = NULL;3 g. K3 c9 V7 D% [- Q6 b+ z* R# r& r
            m_pFirstActivePlayerData = pPlayerData;</P>) a* W4 ]2 E0 j$ N8 a# ?
    <P>        // Update count of players
    7 _% }% h& x6 H* \6 p        m_dwActivePlayerDataCount++;</P>6 U$ m" H& _2 l5 t' X8 c
    <P>        // Generate the ID for this player
    ' ?% L$ P1 _) {* [. w, |        m_dwPlayerDataUniqueValue++;
    5 y+ c/ s: ]- `; K. ]        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>( b9 z- q- U5 U) n! @9 Y( F
    <P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;0 \( S( K, V0 p2 R" z# Q$ ^
            pPlayerData-&gt;NetID = 0;+ r$ v( a4 r: D1 F
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>0 L# M* B) R1 h/ `% ]$ ]! i8 W. M6 e
    <P>        // Insert into the "off-map" cell
    " D' S1 f8 Y/ O4 P- D5 `( J        pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;9 `5 Y1 H: i/ J( }! a& G- G1 I# B
            pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;
    * Z$ U  ~' u8 [) v, n        m_OffMapLock.Enter();# q" @- g% w! f& m3 E% ?+ |
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;( i: X$ ^6 t2 R$ q# K1 ^
            m_OffMapCell.pFirstPlayerData = pPlayerData;
    4 k( o, @: p$ ]* O        m_OffMapLock.Leave();</P>
    1 `" U; W- d8 [<P>        // Mark as active) w0 h$ D. C1 h
            pPlayerData-&gt;bActive = TRUE;</P>
    ) R5 _2 I+ \( I! B2 |<P>        UnlockPlayerData( pPlayerData );
    + M& _8 e, b0 D0 e    }</P>3 u# @, v, G( k
    <P>    m_PlayerDataListLock.Leave();</P>7 w9 x9 r) |6 ^
    <P>    return pPlayerData;
    " D7 Y, `$ L: O3 S}</P>* m3 E6 Y0 a3 p$ x

    ( o7 B4 d4 }; y: _8 t$ C" O<P>
    , Q( B3 s9 z7 r0 I# H9 v//-----------------------------------------------------------------------------
    6 d& F4 A% r  c& i- K- J! b' T3 k; r// Name:
    4 K+ v  {/ I, Z0 u// Desc:
    8 h" `  d5 Z: H& K+ \2 ^7 N; Z# s//-----------------------------------------------------------------------------0 P  M, _" h8 F: s1 o" h
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )
    5 j# L+ D8 ?5 [: ~{4 _5 h+ y5 N- r9 _1 `
        m_PlayerDataListLock.Enter();: l/ Q" [, a: `+ U/ P
        LockPlayerData( pPlayerData );</P>
    9 u: D6 S) J9 ]) ~5 P5 v<P>    // Remove the player from its cell
    " ?  h3 Z5 {: S$ R    RemovePlayerDataFromCell( pPlayerData );</P>4 z+ ~$ l5 }. o) P/ `; R
    <P>    // Mark as inactive7 g+ c* ^9 d# @# i. ^& L; Z% e# e
        pPlayerData-&gt;bActive = FALSE;</P>
    8 T$ G% Z' G. `- y) X<P>    // Remove player from active list% W) |& f8 Q) L  f7 b+ m
        if( pPlayerData-&gt;pPrevious )
    ; v' ^2 O5 [5 K, x0 x# v        pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    ; X2 [" m8 x, m8 h    if( pPlayerData-&gt;pNext )
    " s; q1 H0 n% O, x+ q        pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>0 r7 p8 S8 `* Z$ U
    <P>    if( m_pFirstActivePlayerData == pPlayerData )
    % {3 ^4 g1 O$ R4 F        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>
    7 _: z: H$ D+ i/ W: k( O<P>    // Add it to the free list1 J; `' G8 u0 k( z$ y" v
        if( m_pFirstFreePlayerData )
    ; y  |1 B! w; J9 t' A        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;8 d' {* w8 J- [; a7 n
        pPlayerData-&gt;pNext = m_pFirstFreePlayerData;( \8 q5 k( ]+ n1 t* E  W  Z
        pPlayerData-&gt;pPrevious = NULL;8 M9 J/ A6 F4 p2 m4 q0 y/ S: G/ r* Q$ K
        m_pFirstFreePlayerData = pPlayerData;</P>
    . T6 F6 r2 \, V<P>    // Update count of players
    6 A: O& L; X6 P: [, y/ R3 [    m_dwActivePlayerDataCount--;</P>
    8 P+ Z& Z$ g- v9 d( L' @<P>    UnlockPlayerData( pPlayerData );! g$ `5 v, y% [! u4 O+ d
        m_PlayerDataListLock.Leave();# I8 Q9 {- c! g) @2 u% K" ]5 K$ }
    }</P>0 T: n3 G6 X7 E2 o# t
    ( @3 c# a* k  D2 \/ R' F
    <P>
    : s1 s1 d, J$ V' M: R//-----------------------------------------------------------------------------! o. L6 h6 a! ^2 X
    // Name:
    : X: Y9 @1 \* A; l% q, p! r! S* {: R// Desc:
    3 S7 n$ i+ V0 k' g6 b  ?5 f//-----------------------------------------------------------------------------
    : T& z( M9 G  L: s  ivoid CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )) v% g8 H, V% T; W: e& R. r6 x
    {
    0 J( L9 `+ ^& `7 A! N1 H9 }% A1 n    // Lock the player; B( Q/ }: t# }) P
        LockPlayerData( pPlayerData );</P>( O$ F, Z- G; z! N. {( m/ X* v
    <P>    // Lock the cell the player is in. D/ n( `# g( C3 g2 ]. O: z
        ServerCell* pCell;
    0 k9 \2 G, K* d' b, v    if( pPlayerData-&gt;wCellX == 0xffff )/ k7 J- c0 @4 }2 J
        {
    # b, k0 s% R  |' k, B) i        m_OffMapLock.Enter();
    1 f3 N/ U& G( q7 t# p        pCell = &amp;m_OffMapCell;& N- ]- L9 w5 S7 s% v1 b$ j
        }' y' D  a* ^" o. N! }' o/ X; g( M2 f
        else( C& ^0 E7 u+ h9 e
        {
    & N3 R! ?( N/ m8 C' o' g        LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );0 Q2 d, p% l" ]9 y" v6 j
            pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
    3 z) T3 ~  h) ~9 q/ k- c    }</P>7 D  z- w/ B: x' K. f0 T
    <P>    // Remove it from the cell. e' \: n5 p7 y; s* Z% C  u
        PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    , A% t! E5 Y) S) c" V    PlayerData* pPrev = NULL;
    1 l  [# n( s. n* w/ X" n    while ( pPt )
    3 L9 A* T3 S6 r0 `2 d3 m! F    {9 @' l! ]; Q- _/ ]
            if( pPt == pPlayerData )4 m, h; Q% i, B4 o/ E" f. ]+ t, J$ U6 h
            {
      E! \/ S: i- R8 d0 m1 Q            if( pPrev )# k2 r  J+ Q+ i' `+ q
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;/ L" i* x" _6 l( p) o, U
                else
    . b4 J4 [+ n) M# @7 }) j                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
    % E' {3 X/ A; d9 |2 M<P>            pPlayerData-&gt;pNextInCell = NULL;9 [9 X* @+ T0 n* w6 g7 L
                break;) Z1 L1 N& Z0 `) ~5 h
            }
    5 w3 e# _. D4 W4 W" w: {6 Y; p        pPrev = pPt;6 k8 D, @8 ^4 D6 j" r
            pPt = pPt-&gt;pNextInCell;
    ! W% z. ~! V/ v/ ~; B' y. ^    }</P>: _1 }/ e$ y0 p9 `: |: M5 n0 E/ K
    <P>    // Unlock the cell2 p% L5 [0 j; X; c
        if( pPlayerData-&gt;wCellX == 0xffff )
    8 S# T6 k2 O: ?" E) N8 f+ f        m_OffMapLock.Leave();
    3 {/ K$ e0 O' P. L3 Y+ J    else
    ( l6 W9 g4 `. X3 U8 w5 C. G        UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>
    . F9 ^) T( [( l! Q<P>    // Unlock the player
    ; B" ^; [6 O' I: m( T% }1 ~    UnlockPlayerData( pPlayerData );9 @& Y0 j0 [& d7 U$ A
    }</P>+ B9 z0 }% u, h/ z" f! V7 I+ H. f

    8 q3 t6 _+ `8 z! u% [<P>
    7 O$ c0 R, ^: V9 L9 v) _//-----------------------------------------------------------------------------
    $ a( c( w' K4 H' M& D. C) B// Name: ; V! l' n( W+ X7 A) z
    // Desc: . b2 k, j' w' j  K% E! v
    //-----------------------------------------------------------------------------
    2 c  G/ G- X% b- ~! Dvoid CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
    * r5 Q$ R! }* y/ H3 O1 v" r7 s{
    2 Z0 g; B  F! S% W    ServerCell* pCell = GetCell( pPlayerData );# E# L) z# g' J" O8 M; \, F
        PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
    0 N4 W( F+ Z/ ]. x8 X4 c9 ]& }    PlayerData* pPrev = NULL;- R4 r$ R0 o8 H% d, T9 N( U5 ?8 L% h
        while ( pPt )- {% V- y$ e( }( z
        {+ R- t: N9 p# Z2 V
            if( pPt == pPlayerData )2 V8 y! x/ F* y3 B1 |
            {
    # A! c: o- O4 A+ b: x            if( pPrev )
    1 e8 M0 b$ o* q/ y) j& {: V8 F                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    1 j  K3 g8 u* X" w/ d4 y$ d4 ^3 Y            else
    # Q& a3 k6 \5 X2 ]0 V6 d  C" N                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;8 [+ ^6 e" Z; d4 B" T7 r) [) K3 W, m
                pPlayerData-&gt;pNextInCell = NULL;9 u& ^/ _; h* F( q  J
                break;) X) [5 n+ S, G  n
            }
      e( g- F0 ~5 o        pPrev = pPt;: m. n5 ?! B+ K0 n7 J* e) m7 d
            pPt = pPt-&gt;pNextInCell;# e, h8 F' i4 Y1 m4 b
        }# q& D; R/ T( ?5 Y% L( D$ [, T
    }</P>
    % ^, g( S5 u! Y4 Q% i& g3 k# c* ^
    8 v8 r5 R; ~7 G. M1 H<P>9 l" P8 B% a1 [4 N
    //-----------------------------------------------------------------------------
    4 U! j% z' j& n0 G+ z// Name:
      C/ b: f; P- @& C// Desc: 0 F+ I4 S/ ~: q4 C7 k$ C% v+ j/ u7 \
    //-----------------------------------------------------------------------------
    3 c8 V4 J7 n. [  {  fvoid CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )
    " p$ P( g1 k( M* g% u{
    $ M8 V$ c, w: L6 e- H    ServerCell* pCell   = GetCell( pPlayerData );4 P! k$ b  p, k9 i  Y
        pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;
    9 D3 v0 ~* o2 \; B5 J    pCell-&gt;pFirstPlayerData = pPlayerData;
    + {# ]/ F& ]" j4 h}</P>
    " a2 h6 \$ \* S+ t" w6 K* x6 w1 @5 V; V1 m2 z( x3 O5 i
    <P>
    ( O  \$ E9 N8 O5 p$ R. h//-----------------------------------------------------------------------------8 i1 K8 l- @+ S( p# l
    // Name:
    0 B2 R$ g) d% D// Desc: ' c; J; D2 t9 i0 q
    //-----------------------------------------------------------------------------4 B: i) H1 |( u8 H7 h. x3 C
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )& s5 M; k8 ]# g, E
    {
    8 f# A$ h( ?& n4 l( Q/ h0 a; P    // Grab player for this client and lock it! L1 f& U6 `2 E# |7 }  M& H
        PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );5 C% Y! G/ h1 i% u; t; S1 e
        if( pFromPlayer == NULL )
    4 N4 N* s" U+ ^# j    {
    % g3 [# ~1 D# E3 y$ U# r3 g        if( m_dwLogLevel &gt; 1 )
    # a* k4 q! z: e0 u3 j            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );
    2 Y+ U, b6 n( e+ ]        return;# G5 Z; n5 P6 M  {( p4 }, y
        }</P>
    % |7 m5 V: x/ K# }7 t<P>    LockPlayerData( pFromPlayer );</P>& @! [0 {: q! j( m
    <P>    if( FALSE == pFromPlayer-&gt;bAllow )
    ) j4 W, Q: B, |    {4 e5 j9 N4 i, \) j6 w& o
            if( m_dwLogLevel &gt; 0 )
    3 M$ _( z* }% B6 q0 I. R. U7 B            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
    7 u& T5 r7 P) x% }3 N<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );* ]  d. o! j, ^; |6 c5 {, |2 U3 Q2 f% u
            UnlockPlayerData( pFromPlayer );  R8 p6 a6 R+ O9 R
            return;
    ' k* b/ V: u* [9 B$ e+ N    }</P>4 T0 z, L7 o; X0 b& e7 T
    <P>    // Compute the cell the player should be in now
    ' o" @+ C- U; N    DWORD newcellx = int(pClientPosPack-&gt;fX);
      G* g* b, \8 R% s    DWORD newcelly = int(pClientPosPack-&gt;fY);
    & |  D; Z- N& D    DWORD oldcellx = pFromPlayer-&gt;wCellX;
    * S8 t+ v2 B2 @& D  G5 V    DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>
    7 @0 ^, ~" X6 i1 T2 K/ o8 j<P>    // Have we moved cell?, J' ^9 U1 X& h( b1 w1 E
        if( newcellx != oldcellx || newcelly != oldcelly )! L! f" u7 p8 ~+ b9 G! V+ j# M( t
        {; j) ^+ W2 l- l$ b
            // Yes, so lock the pair of cells in question! R) `1 {& p% S' D& }5 w
            LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
    - m4 L1 S( h) C<P>        // Remove from old cell and add to new cell
    . p* c6 ~8 b0 _        UnsafeRemovePlayerDataFromCell( pFromPlayer );
    2 h% H6 n- r# v  Y& t: r$ ?3 H2 d        pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);3 B+ f. ^+ k- J+ \- f  e
            UnsafeAddPlayerDataToCell( pFromPlayer );</P>  o$ v! q! l* F( r# Z+ Y7 y& s
    <P>        // Unlock cells
    9 ?6 q/ W2 e9 X1 e& ~& d* t        UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );
    6 ]( L( [. V, t/ s- J    }</P>* M( J, K/ j9 P5 \
    <P>    // Update player position
    ( g1 Q* O$ K7 W    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;2 Z0 ~6 I; n0 p
        pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    " w  d6 S  b0 `; U/ ?4 A+ V0 z; ]    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
    % v6 a3 k: ?7 Z: }<P>    // Allocate space to build the reply packet, and fill in header 3 d- r- Z$ I. V& X: \. Q
        DWORD dwAllocSize;
    6 i& @, c0 u* I; \    ServerAckPacket* pSvrAckPack = NULL;</P>
    ' z  ^# r9 B3 Q<P>    // Begin by allocating a buffer sized according to/ s( l' M3 X" o3 ]. {# Q
        // the current number of nearby players + 4.  This will give
    4 B( ~1 E* t* q% _, \; w, N# t- _+ h    // a little room for more players to come 'near' without resize
    % J- o$ x2 l# u    // the buffer.! q) Y- B0 i: S/ ?' k& q) q% U/ `
        DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>
    7 q8 t- O; [, `( p8 m<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);( K+ \, O+ B; K8 M0 W: |
        pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    / K8 a( {' i0 Q3 z0 S! R    if( NULL == pSvrAckPack ); K( z$ X/ O* M7 {) Z( t" i! ?
        {
    # I- ^/ H$ b* d: c        // Out of mem.  Cleanup and return
    3 m9 U$ O: Y1 i. {2 ?        UnlockPlayerData( pFromPlayer );
    $ H: @5 Y- k) j+ n' ]: A7 q        return;      
    " V3 D  V) T: A7 t6 [/ x( p    }6 |" m& G8 ?/ d# Z# {! O
        ZeroMemory( pSvrAckPack, dwAllocSize );</P>! w. Z9 I  Y8 B
    <P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);0 ]9 P! T9 {" d" q% u1 T+ \
        pSvrAckPack-&gt;wPlayerStatePacketCount = 0;2 ^% x7 U. V2 f5 |
        PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>7 ]" c1 ~. R9 [: |) q0 F
    <P>    // Compute range of cells we're going to scan for players to send
    & P& C- k" A2 w    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;
    : @# |% P* s+ a4 r8 y    DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
    6 a7 ?) G* f! j    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;
    ! x% u% e8 N% n$ l% B' O' r9 `% ~3 U    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>4 Z) T- a1 i3 P/ ]) i! C1 ]0 @
    <P>    // Lock that range of cells
    1 F$ W7 n+ `3 |$ @+ _3 q; K! r8 d    LockRange( minx, miny, maxx, maxy );</P>* F. y; H5 i- V% H" f
    <P>    // Scan through the cells, tagging player data onto the end of) A) w3 z( g  Y& Z/ P( f: ]
        // our pSvrAckPacket until we run out of room
    0 l) J' D7 U: A    for( DWORD y = miny; y &lt;= maxy; y++ )
    : O$ F# x1 `9 G* Z    {2 i* Z; ^, ~# r5 Y+ d* N0 }
            for( DWORD x = minx; x &lt;= maxx; x++ )
    ) O$ L, n; r# D# d        {$ Q6 i% m1 ^6 ^( s5 Q9 m$ {9 s- J9 i
                PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;: \. H. Q( q7 x7 K& L
                while ( pCurPlayerData )
    ' G& t* Y) ~* f) |            {
    1 Q+ \5 @/ }. F! \  c" {! s& l                if( pCurPlayerData != pFromPlayer )2 }  O6 x' ^9 G% D
                    {) l2 E# r' y* d# L8 z% W5 g
                        if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )+ I6 t( \5 s( s, @# @) A' B
                        {! A# h% j8 c; J( t- K! c
                            // Make sure pChunk is where we think it is
    ) \& f+ o2 M/ s. W& a2 [9 S% e                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>! s1 a; }: V: J
    <P>                        // There are more than just 4 new nearby players, so resize the : x9 c4 `) X% B4 ]
                            // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.* P1 R$ c4 N; u7 i8 r+ C/ O; I
                            dwMaxPlayerStatePackets += 16;
    " E: U# d: k9 V, C9 g4 F% p                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    & s' C. w3 y7 f( S6 v. e! d8 z                        ServerAckPacket* pNewSvrAckPack = NULL;
    ; p0 F& h$ r; ]' s" n$ o/ u$ A                        pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    0 \2 t4 s5 D0 t% f' H                        if( NULL == pNewSvrAckPack )
    8 E) F' {. h3 O, W4 h5 k5 `7 c1 T                        {) ^- p9 K$ F  ^/ q
                                // Out of mem.  Cleanup and return
    ) A% [, s# _2 J# @6 u0 D, e                            free( pSvrAckPack );
    $ A+ t" f6 }/ H                            UnlockRange( minx, miny, maxx, maxy );7 E1 Q' I8 ^4 X) |& T: w
                                UnlockPlayerData( pFromPlayer );2 h9 ~5 W; s6 i
                                return;       : \3 t' ]. r5 _$ N
                            }</P>* y" c7 g9 f2 X& E) v5 I3 w+ y, E* M, E
    <P>                        pSvrAckPack = pNewSvrAckPack;- ~/ T. Z% s0 N
                            pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>) I$ ~) x. ^- \: g
    <P>                        // Make sure pChunk is still where its supposed to be0 n5 D  h/ {7 X8 J
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );
      X, Y; }* j/ T, q- u. I                    }</P>+ d* u: t( ~1 i
    <P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;4 T, E0 }' |7 r! p
                        pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
    ) j, e' T- N, l6 i( G" u                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;; ^! [8 c; ]7 Y: c. x
                        pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;
    ) t# J' d: U$ i* X. f# c7 j                    pChunk++;6 |6 r. @- @, J1 Y/ L+ N- P4 i3 x
                        pSvrAckPack-&gt;wPlayerStatePacketCount++;
    $ e# ]8 n5 C$ M- m) ]                }% M% d- _- j1 P; u; t
                    pCurPlayerData = pCurPlayerData-&gt;pNextInCell;5 U0 H7 M  P, D% a, @2 O) Q9 [$ ?
                }
    - L8 B2 Q  {# o2 U- g. K        }
    + M& `) i  j% z9 x. v, X# }    }</P>
    ) S$ C/ d8 Z* t. b6 R8 m" O<P>    // Update the dwNumNearbyPlayers for this player& z3 w9 J# ^5 s: u* Q5 e2 a
        pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>6 `, x. }, V4 }4 Q
    <P>    // Unlock range of cells1 Z  l. Z; \1 ]+ N
        UnlockRange( minx, miny, maxx, maxy );</P>
    # m% a9 r9 S/ @) b7 J1 @( T<P>    if( m_dwLogLevel &gt; 2 )7 _' k: t. J6 m' y7 Y. C5 ^
        {! ?* M* u) a+ x: D; _. h# @0 m
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    $ f1 J4 B9 H0 `" |3 r% Q    }
    & Y9 j: ?0 q- ^1 s6 d: e& t    else if( m_dwLogLevel == 2 )) l# Z: z) Y8 w) g, @# s+ [; Z7 Y0 e
        {
    : G1 q6 {# q9 q2 Q  J5 [1 G( l        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    5 s: D8 A4 P* D* B) i- B9 {        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )
    $ L( o2 ]0 H" |- f5 ?        {. A3 R; f, a& v' {
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    5 ]" l$ [/ h1 e1 s+ _2 O            pFromPlayer-&gt;fLastDisplayTime = fTime;1 E( v" d. u' ~" r: B0 y$ p
            }; y  a: d/ B! _
        }</P>0 n3 e2 q! z5 }7 b
    <P>    // Unlock the playerdata
      X+ l# Q0 Z5 i2 g    UnlockPlayerData( pFromPlayer );</P>
    5 l* I/ Y8 Y) J* X+ z$ |, D<P>    // Send acknowledgement back to client, including list of nearby players
    9 W" |( _1 Z* M7 a    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));
    . R( I4 V3 C8 I, c6 D 8 B% c, [' }$ z! M$ o  o) T  ?
        // Pack the buffer with dummy data.* b) e4 g$ Z1 ]( }$ g
        if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)5 s. J: G3 X3 w
        {0 u$ p* Z1 Q! _$ d( x! ~9 d2 q
            DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];
    # E6 @- {# D. w4 }5 ~& C        VOID*   pTempBuffer = 0;</P>4 D6 n; i# |0 v2 Y3 T' @- d  c1 j
    <P>        pTempBuffer = malloc(dwBufferSize);
    $ v2 {( X4 x( E, H3 J, L  a! G        if( NULL == pTempBuffer ). [/ G8 j& e$ Y/ p7 }( s
            {+ l, d2 D* }) p% q# ?2 o; O
                //Out of memory3 Q3 }  J% a$ A! G
                DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );3 P4 |4 \% v2 K$ K6 a9 W8 o) Y
                free( pSvrAckPack );7 b4 u/ ^+ a& \5 p3 v
                return;9 x$ P' i. L0 p6 k
            }</P>; e5 O9 c* h' ~" P
    <P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');( J/ b0 o3 E. B: n6 e1 Q: i3 H- @
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>
    4 @+ W2 F+ Q8 S; g% q  e" |<P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );. a; W' M. t; M' |' I) V- p
        $ ]7 Q$ P" d% q; h7 Z
            free(pTempBuffer);
    * y' v3 o; X: ^    }   $ B& |. H0 d$ n1 v2 c2 n
        else
    & x" k" i" S, W0 [. w    {
    / O3 i0 }2 A( W9 o/ C; P4 m2 v5 t* P5 n        SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );
    1 A4 u7 {2 w: b9 z6 Q    }</P># U5 w7 S( E: D: H- e+ n9 h
    <P>    free( pSvrAckPack );</P>6 `! Y1 [( r, J, o3 ^' A
    <P>}</P>& R7 E: R4 \0 N3 [9 }1 G

    : Y# q- U; ~5 T0 p( F<P>
    ; q0 n7 {! M0 S  T$ F0 u//-----------------------------------------------------------------------------+ Z: r1 ]0 x% v: D3 G" S, o' R2 C, `
    // Name: " ^/ Q/ o" e: _0 A, j& ~9 m  @
    // Desc: / F3 p, V# n6 z
    //-----------------------------------------------------------------------------: Z! z7 {* ]6 _( J5 Q' ]9 m
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
    - n0 {7 s) H0 T) q. l{
    # Y8 A8 L- n3 n: y    // Grab playerdata for this client and lock it0 C6 c, P& @1 L* k6 O
        PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
    4 d5 A/ j& d: n    if( pPlayerData == NULL )# y* w. P* S: [" D, z, Z
            return;1 n: e, r% Y; Y/ Q; b6 m- ~
        LockPlayerData( pPlayerData );</P>. ]9 g+ z# y$ U, S; s4 v! ?
    <P>    // Record the version number ) s* S. O% d: s6 t
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>4 A% m2 [) V4 H5 u+ ^1 P
    <P>    if( m_bLocalLoopback )
    7 W% }! `5 W; f+ |: u        pPlayerData-&gt;bAllow = TRUE;
    3 m, ?3 T4 F; h  e- g    else8 L/ x) ^5 C) i( q9 i4 P: i
            pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>' K% Y: q3 U5 B9 m6 I9 |
    <P>    if( m_dwLogLevel &gt; 0 )
    7 g* n- F! D7 O( G$ f: E7 }        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! v/ u$ o' c* B8 s<P>    if( FALSE == pPlayerData-&gt;bAllow )+ y' J% V2 g9 f# Q
        {
    9 |( i& Y' i- v3 T$ C1 `7 [1 {        if( m_dwLogLevel &gt; 0 )% |$ Q% Z+ G+ t$ U: M
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>* }' ]  \/ w' a9 S2 T" |# V: H
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    * r  @, ^7 g5 ], w' c        UnlockPlayerData( pPlayerData );
    : F6 {" T) |% v* e        return;& F) u% S$ `# K! p
        }</P>/ b; B! a& {; Y" T; |( e
    <P>    // Unlock the playerdata$ }! q, E7 D* ~' b8 z" W, z
        UnlockPlayerData( pPlayerData );</P>
    - e& {7 ?5 ^: [7 N8 z<P>    // Send acknowledgement to client that the client was either accepted or rejected5 ^) z) z: S* u  F8 t- z' E/ Y2 Q9 A
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );# k% Q, s% F1 D+ N3 d6 r
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
    1 h5 [# `9 R3 g; r: Z! @}</P>. n- h  v+ y' U6 r  \. [
    * h9 P/ }$ s  {' d  ]+ }
    <P>6 U* \$ k! _; V# z: h
    //-----------------------------------------------------------------------------
      Y5 P- |9 Z- S// Name: : j. A0 C* w) n5 z0 W/ j
    // Desc:
    6 \. ^6 J3 n% b& C8 T4 e$ y//-----------------------------------------------------------------------------# `" Z8 a- X2 z
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
    . p) q2 H* r# }{
    + u  r2 Y- g) f1 N    switch( dwClientVersion )  R" g9 w) k4 v- V% |
        {# q+ N; X0 t: ?& w/ F
            case 107: // only v107 is supported
    ' R0 k" ?: ^5 m& l* s6 U4 |3 L            return TRUE;
    7 }! Z4 Q: j$ y' i/ O6 R        default:
    & A8 F( G$ s) f' t            return FALSE;( `# A& R! Z( L! P, v( K4 W
        }5 W! i" b5 R  Y5 m. o
    }</P>
    + Z& W, o- g* P9 F
    & C; U+ J0 W+ O* K; E. T<P>  z0 u4 ^- E& E" Q) K: [
    //-----------------------------------------------------------------------------
    ) `! ]7 m% s8 s// Name: % O4 Z. J- ?1 y
    // Desc:
    & ~4 ?8 R' J4 c! h+ l% H4 ?" r//-----------------------------------------------------------------------------
    5 j7 A5 x$ S( K' f1 Kvoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
    & g& z- M" a, \6 Z/ [( [{  a6 x7 [9 F# ]/ O4 j
        if( m_dwLogLevel &gt; 1 )/ J2 j2 T* }# ]! c. C" g" ^7 s
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>( k  C1 T9 N6 A/ r. }
    <P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );' O8 b1 z( s  G& @$ D* n1 o9 O
    }</P>
    1 b* T% X; s% Q. D
    + q6 ^8 y, G3 L& Q3 W<P>7 m7 K% t3 w; t2 l# b
    //-----------------------------------------------------------------------------$ Y) l: D0 ^7 C) v$ Y  _9 y$ @
    // Name: 6 k2 T  N6 u2 i7 o" D, G+ _" @( \
    // Desc:
    / J$ F/ b/ R: m6 m//-----------------------------------------------------------------------------
    # \: b" [9 @" l5 k) k% p( [DWORD   CMazeServer::IDHash( DWORD id )/ Q- c2 ?. |: c! j+ A' N+ Y
    {; R( W# w# i1 f* [$ f$ h
        DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);& x& ~) r- N" m, [9 @
        return hash;% R3 C$ o5 n4 k  l* D; Q3 l6 O
    }</P>
    $ S1 h. Y4 V0 x: @
    ' I8 N$ f7 C6 Y$ M5 c! q$ i<P>
    / A$ J8 O' U+ H7 {' c8 w  ^//-----------------------------------------------------------------------------! u0 }- G: i# t; }7 d2 U
    // Name: 1 Z; D' V% w2 [5 h
    // Desc: $ A# d& z9 x0 b( Z! h2 R
    //-----------------------------------------------------------------------------8 N! R# N. I: u# P$ f
    void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
    # U* |8 T& O; Y0 q* c, R5 b) B{# P3 K  a. b6 S" L) I" q
        // Hash the ID to a bucket number
    7 v  o- b" Z* Y/ w0 G    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
    ; l1 c0 C' _, J: ?8 t<P>    // Lock that hash bucket. a( @6 M; c  s5 K$ j+ K
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    , |+ ?' E. R7 V! \* v+ w4 J, c    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>3 j7 X0 C0 q7 g0 Q2 C
    <P>    // Loop though players in bucket until we find the right one
    8 x' O/ U" D+ z' T4 Q3 E    PlayerData* pPt = m_pstIDHashBucket[bucket];
    + z* y! Z  A3 M6 U9 b) X    PlayerData* pPrev = NULL;
    + u  ~+ y- `* k4 a9 l1 r" K    while( pPt )
    3 ~- H# e( Q- N3 d* |/ c) B' W    {8 b$ u% L- c% O7 [: m$ x' O  o
            if( pPt == pPlayerData ), N7 d; j6 x- A' Y! A# x
                break;; y2 R6 ~6 O8 _% p# j
            pPrev = pPt;5 ?- F7 [6 x; ]4 i6 ]5 N
            pPt = pPt-&gt;pNextInIDHashBucket;
    2 M( W+ A5 _1 c9 Z& `    }</P>. g6 T% ^% t- d$ n. g9 M
    <P>    if( pPt )( L! l0 ?1 D: \% m: r, _5 \$ R: j
        {
    2 I7 X$ Q% j' W7 @        if( pPrev )
    # B& r" o$ k0 [' U% s9 O  }0 z            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;
    7 u; C! E6 K3 u5 y! y7 f        else
    * u; g; a0 m' ]5 c& G. D. ~  t            m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
    ! B  W0 t' d3 D; m3 z8 ^, w8 G        pPt-&gt;pNextInIDHashBucket = NULL;: _. U4 f4 j& y. P
        }</P>: g0 z& \3 P* j6 F- ?# G" I& a3 Y
    <P>    // Unlock the hash bucket
    # t. W; V( G6 G5 `; k    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();% E! u& |& ~0 F. L* ~9 H
    }</P>
    5 ~1 m9 d  B: J8 ~7 c& ]' e# H; [4 u0 t; E, `) u
    <P>+ v4 n8 D! h3 t) U# O
    //-----------------------------------------------------------------------------# e( R9 k0 v( p
    // Name: 9 K7 B' b. l$ A1 M
    // Desc:
    + W4 x3 @2 G) P* J0 D//-----------------------------------------------------------------------------* n$ D; e! l7 i, _0 N) V/ A
    void CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )( M4 o. u3 \# v0 {# `* h* B% H3 R% x
    {
    9 Y5 A, M; R# D& e, r4 ~$ i    // Make sure this player isn't added twice to the m_pstIDHashBucket[]: c) o( ^7 P, t' A0 q5 P2 e
        // otherwise there will be a circular reference
    4 {$ i) J+ F' b: [# [    PlayerData* pSearch = GetPlayerDataForID( id );
    3 f' D! ]! n1 a7 t8 j    if( pSearch != NULL )
    5 Q. \; ?: P7 k. |0 R        return;</P>
    ! b6 G4 U9 c3 k<P>    // Hash the ID to a bucket number
    ( C9 k) s: G2 U1 q4 b& @    DWORD   bucket = IDHash( id );</P>. R5 g8 q: G$ S, u) X
    <P>    // Lock that hash bucket- p* {1 v3 {! c) q( O- \
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    + Q+ y5 [+ Y, d. i6 P    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>) ~. a; Q, w) P2 D( P# l& h3 B
    <P>    // Add player onto hash bucket chain, `9 B4 [3 R9 B
        pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];! `5 Y, ?0 i( P
        m_pstIDHashBucket[bucket] = pPlayerData;</P>
    , U2 f& ~1 z, h* U<P>    // Store net id in player, G* \, }" x# x8 C: Q! R& i
        pPlayerData-&gt;NetID = id;</P>
    2 o7 H7 ~; I, Z6 x6 I. L7 ?' A- f! t<P>    // Unlock the hash bucket
    ! T. S& x0 Z( r+ v9 w# i6 W3 n3 V    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();$ u) Z: s3 G8 J, S
    }</P>
    / A, p, w# W9 c9 ]
    " H) X) K" A8 |<P>$ {$ {& ]& D; v
    //-----------------------------------------------------------------------------$ S$ O% N: n; }# D
    // Name:
    - d, m* X0 h% ]2 R// Desc: 3 f6 g& `" g2 I4 P) Y
    //-----------------------------------------------------------------------------/ F  E. V; ~9 z3 K. W
    PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )% F& q7 b: u( I7 b0 _4 @
    {8 y/ E. W. \% L3 ^
        // Hash the ID to a bucket number' o9 L. P# e+ r2 a; E
        DWORD   bucket = IDHash( id );</P>
    : P( V7 a$ b* ]" O% F<P>    // Lock that hash bucket2 o4 _; H9 ^8 @5 S
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    9 l# T% I! u0 l) F7 ~, M/ F6 i    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    : R" D1 q; M- d" C/ B, P/ o- q. j+ H<P>    // Loop though players in bucket until we find the right one+ K9 Z, _+ b2 G+ I8 U3 i( a: M
        PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    $ X/ c7 c# i! r' A    while ( pPlayerData )
    + s! G0 \( N4 h; J! v, N    {# {8 m$ C/ V( _
            if( pPlayerData-&gt;NetID == id )
    2 @, ?1 D  \. E# l' v2 Z            break;! @+ y, v3 ]+ k
            pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    9 o6 [! q+ q3 f8 A# t    }</P>
    7 W  }: B$ U4 }  x! U* A+ Z9 ^<P>    // Unlock the hash bucket
    . Y5 ^# w9 Q. ^( K( o  z    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>
    ( Y4 u& e7 A( G# V3 [/ r<P>    // Return the player we found (will be NULL if we couldn't find it)
    % u. u5 Z, M) y; M8 h- T    return pPlayerData;. v# O* O: i; v5 B
    }</P>' ~- L, p1 @& x2 m) m3 ]7 a% R
    $ k- i6 G& a6 V4 R* ^. k! E7 Z
    <P>
    ' f. Y  O5 [' r- ?6 S//-----------------------------------------------------------------------------
    # W. a8 P1 `" B( x# k. k/ S( t/ ^5 @/ j// Name:
    1 x9 b" g$ b6 o+ ^7 [# _// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner
    % j' i1 {& T& P- w//-----------------------------------------------------------------------------
    " n: j% q% a* C% N, M7 fvoid CMazeServer:isplayNextConnectionInfo()3 x  |6 K7 b$ R+ ^2 C8 e
    {
    ; \+ I+ @( D6 u1 A) |: O! P    if( m_pNet )
    8 S, f' I5 J& A; H. t: K$ G    {
    ) I& x, q* v. L8 U        // Find the player that was displayed the longest time ago, and display it.( q. u. V) R7 I7 o: g( i# `
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
    ( M' Q$ X& ?) \, J$ U/ i        PlayerData* pOldestPlayerData = NULL;
    ) F1 L$ ~0 s3 c        FLOAT fOldestTime = 0.0f;</P>3 U2 F, _$ @9 A7 u2 P
    <P>        m_PlayerDataListLock.Enter();</P>" B: h* V' Y+ [! x: _9 L; }8 R
    <P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;5 d, R8 ^4 @& p$ ?' H
            while ( pPlayerData )' B# i7 l( k4 [2 |. F7 Q
            {
    ; Y1 |9 p" F  U  J' C            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
    ( S! @$ k: ?. f3 a, C6 R3 d7 w4 m            {! {: E+ U( D2 L7 d1 [7 [
                    fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;% c! n/ b0 |( b
                    pOldestPlayerData = pPlayerData;
    . L8 I' o2 ^  B1 x3 D' V( w            }</P>, ]2 G, Z0 e5 c" H9 u8 u
    <P>            pPlayerData = pPlayerData-&gt;pNext;
    ) n4 h8 X( M& t4 I        }</P>1 Z! N, {/ X7 V  [( t- p+ Z4 M, P% j
    <P>        // Display the player with the oldest CI field, and update its CI field.
    ; g) g0 y# G2 B7 }        if( pOldestPlayerData )
      \) {! e" G. q, V; c( {        {, b" @, B+ M3 u4 ?$ F* w8 Q
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );; D5 r& r. u" P) w6 {+ ?
                DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );" u1 N/ N: T) {* c# j# W
                pOldestPlayerData-&gt;fLastCITime = fCurTime;
    & h6 a; ?5 v+ b1 w" v8 u        }
    . A/ T/ m5 ^$ y        else/ b) _6 A! B% n! Y8 _
            {
    ( Q1 M) z* O% x% j9 u$ \' z$ p# J            ConsolePrintf( SLINE_LOG, TEXT("No players found") );4 I. R7 A9 _; \& Z* Y
            }</P>0 P. i; Y; V7 C# B9 v$ E; A
    <P>        m_PlayerDataListLock.Leave();8 @- R6 \1 {  X
        }9 t/ j$ N1 `. ~; B/ v: T
    }</P>7 C+ [8 B; h5 Z: e2 R
    ) z5 k9 ~. T7 c9 s
    <P>
      i5 W9 J# M) q; f; o//-----------------------------------------------------------------------------8 A* c2 m! F% i+ q2 H- j
    // Name:
    . Q8 a) t( l9 p8 K: U: U// Desc: 0 v, R% v- c" Q8 m. s2 M# C
    //-----------------------------------------------------------------------------3 b" w% a. J9 ?
    void CMazeServer:rintStats()
    2 u+ a% {& f' x" n* w4 f{9 e, b8 D. _; ~5 a; A7 d! Q
        ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
    $ m6 f4 j8 C1 D                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );" n6 y' J) G% P9 U
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
    " |' m+ g5 Y8 s7 M6 U                                    m_fAvgThreadTime, m_fMaxThreadTime );
    % W% j8 ~6 K  |' B* c4 W    ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
    / B% c" ~! k& T, I* e7 y    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );
    - b$ c2 T7 c1 h* q; r" u}</P>
    3 ?: C# L% p* u' M6 W; o( c8 C1 w9 r9 b9 y
    <P>
    ! z# d" G! c3 j0 i//-----------------------------------------------------------------------------
    2 Z) Q, J9 ?  W, _5 P+ S// Name:
    ) s& \% K2 f! i& y/ T: _5 r$ b5 c// Desc: - p; F7 h" s9 L% f4 i; @6 `( D
    //-----------------------------------------------------------------------------
    + y( O2 w3 c, b# Y" N7 ]void CMazeServer:isplayConnectionInfo( DWORD dwID )
    2 v, c% W) i! H" n+ e{
    ! }+ Y. H/ }. Q! d) A8 B" c* L    TCHAR strInfo[5000];
    ; c+ Q/ a$ d$ x; @2 w8 S+ k8 ^    TCHAR* strEndOfLine;/ ?; r9 G4 a! p5 Z. l) M
        TCHAR* strStartOfLine;</P>
    6 U6 a% m, f* @  G8 z7 U( _4 |<P>    // Query the IOutboudNet for info about the connection to this user
    , s. {5 b1 R" u    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>$ P  p; h4 m9 y# m
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );* e' |2 y+ r  A" H3 q
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>. F; S: o# T" K. G
    <P>    // Display each line seperately
    % U+ m! X6 l- o! l  h* K    strStartOfLine = strInfo;; z0 }0 Q& p8 M* n# ^6 I! A9 B
        while( TRUE )
    0 P8 z# O- e* T3 m    {
    & I& x0 o3 Q2 d: v        strEndOfLine = _tcschr( strStartOfLine, '\n' );
    * T& ~$ [# p4 A/ [1 P        if( strEndOfLine == NULL )
    ( h% ?  c& T& G4 K8 F' W            break;</P>8 U) X: \. @7 y, b
    <P>        *strEndOfLine = 0;7 D- i% _, S% R
            ConsolePrintf( SLINE_LOG, strStartOfLine );" ]8 J- U% Z; G( L2 d+ Q
            strStartOfLine = strEndOfLine + 1;
    5 A+ q' T' k- o% s    }
    ; ]2 G' G* F/ O+ R. A8 d}</P>) h3 R! {" l9 ?6 g

    5 Q2 [  H4 {$ @0 Z% |; |<P>7 [6 m$ ^2 a  k" U
    //-----------------------------------------------------------------------------' `  k, T' e5 z8 d
    // Name:
    " ^3 K' p5 a! @0 G: R9 |// Desc: - |" L; c9 D; p, O4 Z
    //-----------------------------------------------------------------------------# s9 v) Q2 I- l
    HRESULT CMazeServer::SendPacket( DWORD to, void* pData, 8 Y1 |/ ]: T$ t4 v! ^9 @% D
                                     DWORD size, BOOL reliable, DWORD dwTimeout )5 l. L; |/ B  i+ H8 P
    {! }; x/ S+ K. R
        // Chance of forcing any packet to be delivered reliably
    5 O3 g2 H# S9 A! d. m& e    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )8 T6 O2 h5 f) _( @2 _* _# X# m
            reliable = TRUE;</P>
      _2 J3 b# e8 T7 P* k9 h# X( S, H<P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );1 ?7 t1 o. `. ~$ w3 Q+ x
    }</P>& ^* c. `, @. z

    ! }% ]9 o! q# X<P>
    + ?* X- ^8 x. r4 ]$ m: x4 }+ A//-----------------------------------------------------------------------------
    : V( y8 G) y6 |9 k6 f8 J- O# n: D% n// Name:
    4 Y. r. |- z( U! v7 ~" j& G3 d3 x// Desc:
    ; }) m+ W) e" {+ |//-----------------------------------------------------------------------------
    ( m1 U8 _7 l' l6 V& [, M2 T* ^8 b' jvoid CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )
    # }! V% E" T+ k) T  `* I{% Z. T. E: M% Z1 y& ^1 Q' s! N
        // If we're up and running, then send this new information to all clients9 @7 o% b/ `9 {1 a. n1 R' p
        if( m_pNet )
    7 m% A8 B* {1 Z, H8 ~5 L5 G    {
    * V# h7 J' p8 t' ~        //Use the AllPlayers ID! f; a) G3 ~0 v6 y
            SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );, l% z0 r5 d' U  e  w/ ~. C/ _  c
        }
    1 H/ p4 [' Y: J! e7 a}</P>
    / x! W2 I! X9 D4 ~  d/ z- B; J0 T2 \# i
    <P>8 X3 v/ X9 n. d
    //-----------------------------------------------------------------------------, _5 \  F: H$ a7 k* x  _6 p
    // Name: ' B4 c# W7 @4 a9 ~( f( {2 N
    // Desc:
    ' A; k  Z; k4 z$ I1 K- B//-----------------------------------------------------------------------------
    ; C1 Q, J' R* `+ d* J+ Rvoid CMazeServer::SetClientReliableRate( DWORD percent )# D1 R3 B+ ^+ M8 m# B0 l
    {) v$ H2 s! K+ I! Q5 W
        // Update client config, and build packet containing that data/ @& L! c" A% F
        m_ClientNetConfigLock.Enter();' V+ C% ?5 |: c1 g  ]$ Q
        m_ClientNetConfig.ubReliableRate = BYTE(percent);
    + i' |, H: p) F* r/ S7 g    ServerConfigPacket packet( m_ClientNetConfig );7 M& L4 Z# R% C; k1 j
        m_ClientNetConfigLock.Leave();</P>. t1 k; U  F% C, }9 _
    <P>    SendConfigPacketToAll( &amp;packet );9 w& K$ _: ]5 A9 g
    }</P>7 h) L# ^, p3 S& h: m

    ' [! t& T# q& x" E/ [<P>& X. T6 F# R" c# k) z0 a, L+ [
    //-----------------------------------------------------------------------------
    4 w+ k" Y, r; z$ N// Name:
    0 |' G; u& Y- X// Desc:
    ' O) D5 l5 ?4 x' W  W8 {# P0 t5 g  e//-----------------------------------------------------------------------------
    - B2 A( x& r3 t' B( {void CMazeServer::SetClientUpdateRate( DWORD rate )
    / l6 v( Q3 t) D0 I: h; U, G7 C{
    ) N- y8 y$ y  J9 ~1 G6 v    // Update client config, and build packet containing that data
    6 i  l- t! n. n6 E2 x" P( J: D    m_ClientNetConfigLock.Enter();
    3 ^) L: Y9 u& Y% I  _+ u2 T+ y    m_ClientNetConfig.wUpdateRate = WORD(rate);
    ) ^$ M" W, j; W6 B) `; ?    ServerConfigPacket  packet( m_ClientNetConfig );
    $ _& M6 f$ ]! j$ a0 ]% X    m_ClientNetConfigLock.Leave();</P>
    , y) K; f* B5 _7 S1 o<P>    SendConfigPacketToAll( &amp;packet );3 `1 G- u' r6 b- Y
    }</P>- \. L  e0 ]5 W
    $ @* ^  x# ~$ Q* H9 A' {% {8 q( e
    <P>
    % N. V2 @  G; A- `1 {5 ?" z# e//-----------------------------------------------------------------------------
    $ n# d' ]* p8 U8 l& O// Name: # a! E* _. w: C# U" \7 N
    // Desc:
    % \2 `, U: ^6 o  K, `/ ~0 `. \//-----------------------------------------------------------------------------
    ! V% c: c! Z+ k9 ivoid CMazeServer::SetClientTimeout( DWORD timeout )
    * O& U& g9 ], O" t9 Z) ]9 M{
    / @! @6 v& B6 v2 E3 ?) T/ W    // Update client config, and build packet containing that data
    # Z& z. \  p& A, v) }    m_ClientNetConfigLock.Enter();
    2 B. s& I- a- U8 x( h# D8 U; m    m_ClientNetConfig.wTimeout = WORD(timeout);
    & E/ i0 ]( X9 P# G+ z( S( W% p    ServerConfigPacket  packet( m_ClientNetConfig );
    ; u; }7 u1 C: O# X1 Z    m_ClientNetConfigLock.Leave();</P>1 t$ n3 b+ q$ I9 x* ~
    <P>    SendConfigPacketToAll( &amp;packet );8 U: W7 G  v; V/ {, c, v
    }</P>! @. `) c5 r. G) D# I# q! f
    3 K9 V9 V! U& O. @- @
    <P>' R" O- ?$ ~! o. Y$ p( P. `5 R
    //-----------------------------------------------------------------------------( }: `  V7 \. f7 p7 K7 j
    // Name:
    ) K. k! Y# p- t5 ]5 I$ a; S& w// Desc:
    - z7 S* e2 \! N( Y9 T//-----------------------------------------------------------------------------  N( s7 L  m; w( x3 Z4 Z) x" x
    void CMazeServer::SetClientPackSize( DWORD size )
    + b/ g; E3 B$ Z6 z{
    1 H7 H8 f! ~: u5 _8 [7 m    // Update client config, and build packet containing that data
    # ]& b. s, W* b& P; ]+ s% ~    m_ClientNetConfigLock.Enter();; q5 J& Z2 o% N  r# o
       
    # e' P. E. r& _4 w3 ]8 C# H7 b    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.3 u1 Z5 O0 w! d6 ~8 J- H+ D9 @
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   - q  e8 l9 `9 G9 y  {. A- u1 W$ V
            m_ClientNetConfig.ubClientPackIndex = 0;</P>
    - c* b3 R" F. H0 m<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);+ q0 q: v& g7 H, n7 I0 c
        ServerConfigPacket packet( m_ClientNetConfig );
    6 Q' y2 a% ], X1 N    m_ClientNetConfigLock.Leave();</P>" B1 ^3 k  M( O6 H( E
    <P>    SendConfigPacketToAll( &amp;packet );' _# D% w  q% @4 P7 c
    }</P>
    9 r/ n2 S- t/ w
    - S$ Q( T- j2 n7 a! _( w. i<P>1 S2 F8 g9 ^" r7 ]7 L2 p
    //-----------------------------------------------------------------------------
    1 X# g4 m4 k5 h6 P// Name:
    6 _4 K/ V  Q+ U9 |9 N# M// Desc:
      `1 L; L7 n8 A- P//-----------------------------------------------------------------------------
    ' n6 i* ?$ K% f2 N2 ivoid CMazeServer::SetServerPackSize( DWORD size )/ C: W; V/ M; h+ t1 ~3 a
    {
    * r$ f# h" ~" k( o& ^    // Update client config, and build packet containing that data0 `0 }0 X+ K+ L" x
        m_ClientNetConfigLock.Enter();
    7 Z- j1 ?) [( u9 \1 a; j    ! ^- q; G- }7 I
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.2 K0 U- d/ U1 s) r
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   1 u6 E0 u& O: _6 _( I4 ?) B- H
            m_ClientNetConfig.ubServerPackIndex = 0;</P>; Z: T2 v. I( `* G- t. U9 ~
    <P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);7 h# r( W1 Z* n
        ServerConfigPacket packet( m_ClientNetConfig );6 H2 i0 ^- K. W& I- |4 [
        m_ClientNetConfigLock.Leave();</P>4 f- Q; x% r7 `) S' B
    <P>    SendConfigPacketToAll( &amp;packet );
    5 S' k0 v: }* O- t8 p}</P>
    ) `5 e8 c6 J/ w  I3 S1 K2 _* L5 q; _" [<P>
    " Z( M4 S# {/ o9 {, Y4 B//-----------------------------------------------------------------------------* o* B, w6 K* f3 q" l1 S
    // Name:
    - Y3 z& ?% K9 ]" D2 ]// Desc: 9 \. p, n" v7 ~3 F/ _! i3 ]2 G
    //-----------------------------------------------------------------------------
    & t' H: p, k7 Y- N$ i1 |: v! @void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )/ x7 l+ M4 s$ z4 }& M5 d
    {
    # i+ b. A6 s8 v8 |8 a3 g    // Update client config, and build packet containing that data
    ; ^) G. k' H& O+ B1 T( G, X    m_ClientNetConfigLock.Enter();2 }! h% ~% a* O/ r
        ; b# E6 G8 J7 y0 @0 T, G" @9 O  j
        m_ClientNetConfig.dwThreadWait = dwThreadWait;. i/ w8 c( J% v8 G1 y, d
        ServerConfigPacket packet( m_ClientNetConfig );
    4 s$ O2 K8 t' R, X+ k1 q9 L2 B    m_ClientNetConfigLock.Leave();</P>" w1 H+ G( }0 I4 w& Z6 G4 |
    <P>    SendConfigPacketToAll( &amp;packet );+ |% a6 |  q4 t6 F) o5 q$ a, x
    }</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 06:29 , Processed in 0.350861 second(s), 50 queries .

    回顶部