QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4242|回复: 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>; w+ u! i/ y' A
    <>// File: mazeserver.cpp/ O. B$ y5 F3 U
    //7 a- l& P: F+ Q0 M  b, y* H
    // Desc: see main.cpp
    0 C4 q5 q8 s6 g//5 c7 y  k" O% g- v& M1 x/ T
    // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
    / Y$ F3 G  e2 U1 H% g& X//-----------------------------------------------------------------------------
    8 Q6 B9 S! N8 x- ?5 G, F& q#define STRICT
    " R  p0 X6 k1 {, G$ p& y7 j#define D3D_OVERLOADS
    ; @/ K# F$ A$ G! B: X; c8 J#include &lt;windows.h&gt;/ h- A4 O2 Z; z+ U
    #include &lt;d3dx.h&gt;
    : A2 A0 J8 e2 m; I#include &lt;stdio.h&gt;
    ! _( E4 u; H) U, d- l& j3 q9 _#include &lt;math.h&gt;" O; X- v% @+ ^" P4 M" o' I+ A
    #include &lt;mmsystem.h&gt;6 a' R. {" n  q/ x+ o1 I9 P! a
    #include &lt;dplay8.h&gt;
    ) [/ f9 y, C  y3 T/ D* j#include &lt;dpaddr.h&gt;& Q4 H) d7 B' Z0 A" c
    #include &lt;dxerr8.h&gt;
    + e% a+ I' }2 @  Q# s$ g% t#include "DXUtil.h"
    & o  J: ]+ e9 J# `/ N6 T, n#include "MazeServer.h". W, |$ p8 C% A/ t3 C/ }
    #include "ackets.h"
    0 O& d8 u; J" D$ C; c9 I" C7 d& C  e+ x#include "Maze.h"
    3 L2 Z. n( j' f% B9 J% O$ a9 Z#include &lt;malloc.h&gt;, `, ^$ A2 Q$ y" W" N. I' d
    #include &lt;tchar.h&gt;</P>* y  x4 B: K  A
    ' T0 ?; v% ^  N% ?
    <>//-----------------------------------------------------------------------------. R0 I( [% q7 ?/ r) V6 {  Q. h( A  e) q
    // Name: : K1 o2 N2 {" u2 V+ N. ~$ ?& U
    // Desc: 7 `" C  o$ O. s2 m8 K5 l# g
    //-----------------------------------------------------------------------------3 }& P0 Q  {5 ?% j
    CMazeServer::CMazeServer()
    3 U5 d* ~' ]. S- p0 g{3 ^2 ~6 p7 V, G" {0 D9 p
        m_dwPlayerCount         = 0;
    5 a2 f) J" g4 y( j   
    , p. C# \9 @  G/ V4 Y( J0 L    m_wActiveThreadCount   = 0;
    + [+ r. o& X4 e* k' d    m_wMaxThreadCount      = 0;
    ( k) F, c& N4 a  H- T, b: W    m_fAvgThreadCount      = 0;* p2 Z" h# s  R8 s- ]" v; F
        m_fAvgThreadTime       = 0;& E3 \" j, J8 C! z
        m_fMaxThreadTime       = 0;</P>
    5 i0 i4 `9 I9 ^<>    m_dwServerReliableRate  = 15;
      ^. T4 p* w' [. A1 {6 a    m_dwServerTimeout       = 150;" w$ ]  I5 K& R' h
        m_dwLogLevel            = 2;
    0 ~6 Z' ?6 s7 V- B    m_pMaze                 = NULL;</P>$ i8 o1 V( e% |6 A, y8 y0 s) r) t
    <>    m_ClientNetConfig.ubReliableRate = 15;
    ) a, i& J4 d3 n9 Z: E8 P" C    m_ClientNetConfig.wUpdateRate    = 150;
    : j& {! y3 K) B9 n/ a    m_ClientNetConfig.wTimeout       = 150;</P>
    ( r' A; Z4 k6 ]  l' K<>    m_ClientNetConfig.dwThreadWait = 0;</P>0 k4 y! V7 U7 m) C8 H5 e4 _2 a1 k
    <>    m_ClientNetConfig.ubClientPackIndex = 0;
    1 y; M+ {3 y! G. X0 {    m_ClientNetConfig.ubServerPackIndex = 0;
    & ?9 Y7 X& c6 _8 I& s    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)  M3 w3 q9 p+ U
        {3 q) m" H+ K% |* t( A% y5 H
            m_ClientNetConfig.wClientPackSizeArray[x] = 0;" t& {+ ]4 v/ t! S( p" u4 q
            m_ClientNetConfig.wServerPackSizeArray[x] = 0;" T3 n+ Y" [, s* z
        }
    0 j2 h3 F* A! W0 N, n  I/ G- V}</P>
    $ g1 M$ _7 i1 c. y8 {- Z1 F
    . v; x. y( z3 _8 Q<>
    1 @5 ~+ f1 n+ M1 A& M8 F) G//-----------------------------------------------------------------------------
    % ~' C5 p4 E; t' L4 E  T2 v; I4 q// Name: * M/ x: K0 e, s0 y$ F" X
    // Desc: ! h; L) v% M3 h$ c# K7 A8 [# l9 p
    //-----------------------------------------------------------------------------+ T% V2 c7 u& h
    HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )
    ' n" b; r3 |' o" s2 }{
    . R+ _2 f6 A! C  M  f' q2 u/ f    m_bLocalLoopback = bLocalLoopback;& E) {* q6 i5 u! D% V
        m_pMaze = pMaze;. g8 m: a* z) v7 v: G
        if( m_pMaze == NULL )
    " N5 R! ?' ^# Y/ X; \        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
    0 z- l) D, l6 b& j& O<>    // Grab height and width of maze
    3 d8 k/ M& Z2 c    m_dwWidth = m_pMaze-&gt;GetWidth();
    # M2 Y0 ?& P" z& _    m_dwHeight = m_pMaze-&gt;GetHeight();</P>
    ) R( I1 B  a: ~2 }5 [+ ~2 E) C<>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;( C$ x; X2 T: T) \/ Z0 ]7 Z0 u
        m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
    4 w& ^' L5 D0 h1 J4 i: B8 u<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.3 t" {+ b0 w' ?$ o% G& v
        if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    . V! o! B4 G! ~        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    ! }- P% }; w2 [9 G2 G+ f) \/ O    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )
    1 w! y: f! o) |        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
    8 e, R! V- q4 M2 ~- \1 K" z<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;  @! Q3 ?' ]( h. f4 v
        m_dwMazeXShift = 0;3 l4 }5 }4 D! v& n& j, p4 N# m
        while ( (scale &gt;&gt;= 1) )
    - q5 F; J0 k- K* T* o        m_dwMazeXShift++;</P>
    ) A- s6 K/ X( h<>    scale = m_dwHeight / LOCK_GRID_SIZE;
    3 {( n7 T. t8 I    m_dwMazeYShift = 0;8 H: \  J# @. \. m
        while ( (scale &gt;&gt;= 1) )* {- U3 w( v" G3 U0 S" l% @
            m_dwMazeYShift++;</P>" {% t; J1 Y  n  x; S( j
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||( n' G1 K. X8 N6 T; V
            ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )$ z# ^7 z! Q6 S, X- N' G3 |
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>
    ! @1 P) E6 ~8 U$ D<>    // Initialise the player list$ N& j6 ]6 q; C3 q* P
        ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );
    6 `! o" m, E- f7 v1 d    m_pFirstActivePlayerData = NULL;
    . N, `- e( [0 h. {0 h    m_pFirstFreePlayerData = m_PlayerDatas;' X& N6 y, ?. t5 X& L
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )# i# e- B" I9 c9 [4 I
        {; o$ v. n+ F+ A- _' N+ v
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];
    0 a) H6 l8 e# Q        m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
    - h( C* c) h; F/ w  G    }</P>7 j+ d- s. c" E
    <>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
    # x2 C5 ?7 {$ m5 }6 s! x! Y    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];  ^# n) h/ v: U8 @) o3 u
        m_dwActivePlayerDataCount = 0;- n: S: ~2 u1 s- K" i! m
        m_dwPlayerDataUniqueValue = 0;</P>
    ' w8 D; p( z/ \% W( ~5 z5 |5 L; j! o<>    // Initialise the cells
    0 P2 W$ Z( A+ M8 Q8 j    ZeroMemory( m_Cells, sizeof(m_Cells) );* ^) X: f# s% A+ e+ J2 f6 _+ J
        ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>
    4 @& B3 P- J; ?1 C<>    return S_OK;0 N+ ]5 W" ]! b1 G% ]! g
    }</P>
    5 P/ R5 S7 d7 q/ v: M. m3 Z' q$ |$ T. b+ W2 F- M& t) d
    <>
    ( x# g6 i6 x% x4 Z# h//-----------------------------------------------------------------------------
    ' r: S; C9 A; S; f  J// Name:
    , G2 Z6 {$ e0 i5 P// Desc: ! g  w$ P/ Y- N6 z5 j
    //-----------------------------------------------------------------------------; a+ j6 M1 K* Z
    void CMazeServer::Shutdown()' e0 C3 @. s: u
    {
    2 `! E0 L7 i. M* x! j$ Z% |}</P>: O$ J* h$ \* J2 U  n; p

      }8 W  R% C( Y1 u$ r<>
    # u5 x4 H( E9 e4 j$ Z//-----------------------------------------------------------------------------
    / X+ ]7 G: T, z4 D- E& |( @5 Z// Name: 4 W; D# k% Y, N7 G" k. a5 {: v6 X
    // Desc:
    ) Q# `2 \/ L$ i% D, n/ X: m% |//-----------------------------------------------------------------------------& B  |6 Y8 [) R# m: M
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    ; x1 k1 x' G# Y* Y" D{
    3 m7 [+ a2 l* l    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,9 U- ^) s" y) s/ Y9 a
                              x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );6 a3 X# X. s, X) W! x
    }</P>, P9 V2 D! Q- M1 k' a

      d/ w/ O9 f0 q- A4 m% r; _* E<>
    3 S% F# U5 S  l) h2 H//-----------------------------------------------------------------------------& {! A) ]  c  ]! U( u7 ^
    // Name:
    * v9 J8 A/ @0 {8 _' ^, \6 @// Desc: - i3 F1 N: q6 _  h8 r
    //-----------------------------------------------------------------------------
    + W' W0 V6 p9 l4 t3 Q  pvoid CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )2 N) n8 M5 B1 H4 S6 {: ?
    {
    & b* y9 ]" h, x& Q    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,6 v/ y6 M6 ?, }6 Q  R, u0 `
                                x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );. ~7 B- X' _( q+ n
    }</P>
    ( X: q6 v( l/ H9 x% E# m. U; o6 D+ s5 R1 }, l$ B: h  B8 H# V
    <>% h1 }3 p3 s" A3 y% p- S
    //-----------------------------------------------------------------------------1 ~  I) o+ a3 l$ T% d
    // Name: ! j% a$ b( t9 r( h: Z* v
    // Desc:
    - c% J' P) x& @, z2 c//-----------------------------------------------------------------------------& H" N/ V& E# d) X, z+ [& y4 e
    void CMazeServer:ockCell( DWORD x, DWORD y )5 U7 Y$ C+ S, Q- E
    {  ?  k% p6 k& w6 t$ x7 t% d# ?) u
        if( x == 0xffff )
    1 i. u" J+ ~: k: k4 J2 z        m_OffMapLock.Enter();
    3 E) A/ {$ @& K( |# f) l    else
    8 q0 F3 O, i7 @! P1 `        m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    % k. V1 _- g& y4 V7 W! n}</P>0 U: T. S4 l# T( k2 F) K

    * U8 ~3 v9 V% b: o' q<>
    8 K4 J4 y' P7 m2 R( ?8 d//-----------------------------------------------------------------------------
    + |6 H3 m! X# }, S0 @0 U! N' ?// Name:
    7 ?6 J4 ?) E+ Q* D// Desc: 8 v' O5 ]0 ?2 E+ _4 Z
    //-----------------------------------------------------------------------------7 R/ H7 x! W' k# w3 Q8 N2 K! b
    void CMazeServer::UnlockCell( DWORD x, DWORD y )
    7 s# a# U+ L& \, w: k' ^{
    4 v, [7 H. b/ z; E    if( x == 0xffff )
    " A" M/ g' o* u        m_OffMapLock.Leave();
    . b: F  ]! h  R2 I    else
    % V2 K+ u- I: v$ R/ Z        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    ! V0 @, ]; O- v}</P>
    ) O& K5 r9 ]; _
    $ L. d& P2 O7 {0 |4 {+ W<>8 M4 I6 e$ ?8 F4 C8 U1 I! r
    //-----------------------------------------------------------------------------
    ) v8 U- S: X, u& R( c! {) x// Name: 5 b. i$ m4 C# A8 o! `
    // Desc:
    6 y, ^+ c/ |" J//-----------------------------------------------------------------------------
    - g, D* h: b- ?/ _$ @& T8 g4 Pvoid CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    3 g" t* E2 F" H1 O4 n+ E+ l& o" o{+ s2 D; K) ^# S5 n; O+ O4 ^
        if( x1 == x2 &amp;&amp; y1 == y2 )
    0 ^' q/ U" o$ `: z2 [    {' u! G  \, H* Q4 Z* m' H
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    1 p) J; B( `% o            LockCell( x1, y1 );
    . ^: [1 z3 X4 p        else
    ' o: e; ?3 P4 l" ^5 A% P            m_OffMapLock.Enter();</P>
    2 r2 w% h. m3 C( ?7 G<>        return;
    & C  E3 L2 B( H0 H    }</P>
    & }6 H' k! K* v1 o6 ^<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;6 p; C: |; ^( d! E
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;' `! H. l4 L. ]3 }9 S' G( h
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;, N4 \1 O; E* J) P6 G8 X
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>$ z! Z) \1 W6 Z- |$ }2 T+ M
    <>    if( x1 == 0xffff )6 h  S0 u3 M* ]7 v
        {
    2 j+ k4 K" Y% s! ^6 @+ w        m_OffMapLock.Enter();  H, {& j* o' `4 S7 @4 B& M2 F" `' m
            m_LockGrid.LockCell(x2shift,y2shift);4 m  X* K* B- u, c
        }
      X& k  }/ j4 Z+ O) c5 H/ {    else if( x2 == 0xffff )& B$ R7 k  A+ o3 o$ [
        {
    ! e5 |6 ]9 p. Q" u        m_OffMapLock.Enter();1 n" @' @4 L0 L5 q
            m_LockGrid.LockCell(x1shift,y1shift);2 O+ x! y8 T! N  Z& B+ x7 `
        }: L5 B" w: A7 l( W
        else
    - @* N2 Q8 o( @/ h8 [/ t' z( T" p    {
    - f1 f% ^  i  A5 m1 H        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);
    ' s3 o: H& a4 C: H4 q6 |  Q; l" d    }
    * h8 G% e( B) U$ M; q}</P>  L+ B% t4 B2 k
    ( N" }/ N! H* E( c  p
    <>
    - N" ~6 I, t6 J4 w4 @//-----------------------------------------------------------------------------
    1 m! o  j( d) x1 @/ E9 G2 {// Name:
    ! f; e- f8 {. x3 J* S" g// Desc:
    4 \) z( Z% T+ X; k( `//-----------------------------------------------------------------------------
    - l$ Z2 f/ o/ p6 }  gvoid CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 ): Y" X) d7 q5 ^# o9 i* e6 P
    {
    ( l+ T8 R* M; V" M# Q8 ?2 B5 f    if( x1 == x2 &amp;&amp; y1 == y2 )
    8 j( \6 f* n$ B7 y& B    {( V6 ?0 F* L7 }0 l" j
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    9 x% y0 Q+ p8 A6 r$ E# G7 v: }. J            UnlockCell( x1, y1 );
    * j0 M- j* U* E+ S        else0 q, w6 Z2 y5 I/ e' d  U; H
                m_OffMapLock.Leave();</P>
    2 C* [8 \2 s( _6 s<>        return;2 L) s; H7 F% m' ]9 `3 x
        }</P>
    : v6 J$ S1 x5 K3 p<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;- A5 X0 Z# M$ I* q9 y
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;2 ?8 e* ?5 L2 m; }
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;7 H: n2 V. r/ c2 Z3 g
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    - K6 ~; _% o. s$ {  ?<P>    if( x1 == 0xffff )
    - q% n2 t9 b/ ^, e0 ?    {
    4 Z4 y/ Y( l1 C# p        m_LockGrid.UnlockCell(x2shift,y2shift);
    , N9 K9 f8 @- a: Y; N' ], X        m_OffMapLock.Leave();* O4 o0 R6 ?) u) ], E# V9 a
        }. D* [+ F0 Y) ^
        else if( x2 == 0xffff )1 n- `9 D* }2 u+ D2 A3 T* Z& u
        {
    ; |9 p9 H& x0 f- |0 _- `7 c        m_LockGrid.UnlockCell(x1shift,y1shift);: @/ F8 t/ m! e" U
            m_OffMapLock.Leave();
    + ]/ A% e0 G, |0 c    }( X7 e9 M/ G+ a; K3 T3 t& S
        else
    - d* _$ P9 ~, @8 r0 ], K    {7 R8 D6 T1 @5 H8 \9 D4 W1 ?% h
            m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
    1 M5 O7 N8 z$ a: u% Q    }
    * H+ _/ \! X" F! n}</P>
    9 C0 C( S8 M  z) b+ |" n: H1 f, w, R' K8 P' K! q; N; ^
    <P>
    9 R( \% i" E, c5 ~! p/ d//-----------------------------------------------------------------------------
    2 @# }: r( T/ U, d! A// Name:
      R( K" _1 D8 H( W1 w// Desc: - s6 F. [3 H: W0 c, t' y; E
    //-----------------------------------------------------------------------------
    0 i3 Q" H3 [# e1 C0 t& vvoid CMazeServer::OnAddConnection( DWORD id )/ K2 R6 N8 c; J* C9 S3 h; [
    {
    + Z6 {. r; R  c6 W6 R    m_AddRemoveLock.Enter();</P>  I2 h8 f! e7 z3 B/ \: Y3 H8 ~- B5 G
    <P>    // Increment our count of players
    8 i' A! ]3 B" s4 k0 Q' x/ J4 s    m_dwPlayerCount++;* u" l- Q! j: B; x# ~. z
        if( m_dwLogLevel &gt; 0 )* @. X( j9 b0 l/ V. i! k
        {9 N/ S: Y4 Q! j- p% r3 `) G% ^: n
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );* S5 d  p$ i7 x2 N, S* G. u
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );2 t! U! M0 s- _# A7 P/ P
        }</P>
      ]1 ^2 X1 Z9 ?: X4 m<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )6 u) d4 H( e! T6 _
            m_dwPeakPlayerCount = m_dwPlayerCount;</P>
    , E4 K7 x" x) ]6 k+ G<P>    // Create a player for this client+ h9 n" U0 B" l# H/ l6 Q: x
        PlayerData* pPlayerData = CreatePlayerData();
    % v4 n9 f$ ?- P3 g0 K, W( e) \    if( pPlayerData == NULL )
    4 ^1 x' U. g0 T" n$ @" V6 s    {7 p9 W. a. T: I0 X! a
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );5 x- K- M( y8 e+ E0 Q" v8 ^
            DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );
    ) c1 z/ O6 ^2 r. r# |        m_AddRemoveLock.Leave();% g) C7 A' |7 B( L/ @
            return;
    5 m" Y3 W* H' Z    }</P>
    7 c, N( W# w& @" n' G8 `7 n<P>    // Store that pointer as local player data
    3 E0 ~, a2 h0 A. Z6 \2 g    SetPlayerDataForID( id, pPlayerData );</P>5 B4 `# f6 \; z2 ~' e! v
    <P>    // Grab net config into to send to client6 U* ]' M# x5 p6 R# S2 r. u* J
        m_ClientNetConfigLock.Enter();! K# Y* F  `2 V
        ServerConfigPacket packet( m_ClientNetConfig );
    5 b, o  ^$ d7 g6 t: {    m_ClientNetConfigLock.Leave();</P>
    6 R# r  r) \1 Y<P>    // Send it3 _" Z$ B' ~5 x: c$ R0 v% n
        SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>) p( ?0 v4 n' H8 N
    <P>    m_AddRemoveLock.Leave();
    $ S$ F1 {) E* S2 @$ [" Q}</P>5 O1 O& \: L  h, @! S& Z

    8 c: j; r, [& P  R8 L0 E+ ]<P>  q2 w* D& b- O! F5 X$ R1 b4 U' q
    //-----------------------------------------------------------------------------$ r! d6 l4 m" J  C
    // Name: # ~0 k0 Y4 A! ~  t1 h
    // Desc: 6 o  [( W0 d) F/ n9 q
    //-----------------------------------------------------------------------------
    1 ]- `* k* U& S2 o7 rvoid CMazeServer::OnRemoveConnection( DWORD id )
    3 @0 _4 c9 t" }. o$ L{% r( C1 G4 k: y3 t; D
        m_AddRemoveLock.Enter();</P>: a' y8 i3 A3 S1 c- v7 n# k5 V
    <P>    // Decrement count of players
    ' e/ t. B% B, U( b* p4 s    m_dwPlayerCount--;</P>
    4 T+ t$ j9 I$ \<P>    if( m_dwLogLevel &gt; 0 )4 e- D( o! }6 o
        {
    ! K" w( n% G3 A% l        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );' Y) O( S! m0 q7 {5 K* E6 l
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );" {3 h3 p: A$ |5 s" A  U! z
        }</P>
    0 ]0 @8 j  I2 M7 W<P>    // Find playerdata for this client2 u0 |+ i& W& S7 X: v
        PlayerData* pPlayerData = GetPlayerDataForID( id );
      |8 s  q( c8 G( v0 j2 H6 w    if( pPlayerData != NULL )+ G2 a8 ?2 v' ]# W( _+ n
        {) C, T6 e/ z3 ^  C2 b' }- ?
            // Destroy it4 r; m0 N. M7 y  b  U, G
            RemovePlayerDataID( pPlayerData );. L8 J; h2 ^1 h# y' ?2 g
            DestroyPlayerData( pPlayerData );% h* P6 M5 a- g  S- N
        }</P>
    : ]. r  e- J7 [<P>    m_AddRemoveLock.Leave();
    / F9 W/ Y, K; E( U7 y; Z% `7 s}</P>
    3 f( W0 ?* p" j5 i9 ^: [; S& E
    - J5 Z; \7 D' K* v$ Y5 g* _3 V<P>
    / S+ F2 m7 c$ P" ?//-----------------------------------------------------------------------------
    1 g; r6 u1 n( }, Q/ q8 q6 o( [// Name: 5 S; ]* u0 {9 T9 [$ T
    // Desc:
    : O* z+ \4 ^; ]" Y& r, G4 D7 K: Q//-----------------------------------------------------------------------------
    5 k' l0 Q/ T5 h$ }HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size ). ^- Q* T) T3 e; i& W" r! t4 M3 ^
    {
    9 V. E3 Q. \; P. N4 E4 f    BOOL fFoundSize = FALSE;</P>
    + v7 Q% {* P+ R/ ^% g& a% x<P>    // Increment the number of thread we have in this process.
    ! e# ]  G6 K8 ?% d    m_csThreadCountLock.Enter();</P>- V. l0 n: O% ?7 p
    <P>    //Get the start time of when we entered the message handler.6 v6 @" i( P* T7 |# k; ^
        FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
    + ]% t5 [" |3 V. R! T8 L<P>    m_wActiveThreadCount++;
    3 [1 b8 K- p: _, H5 W    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)% t7 ?2 c4 z$ c  a) E+ H
            m_wMaxThreadCount = m_wActiveThreadCount;
    . g( d$ Y" \" r9 C2 W  z8 o& T   
    0 r+ C. k$ b; X3 t  g5 N( W  S    // Calculate and average.
    " @8 m8 l8 P; F) B* \  A1 ^0 V7 o7 }    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
    % G9 `5 v/ b6 b2 t! x2 m5 j    m_fAvgThreadCount += fdiff/32;
    " R- ^8 P+ M+ r( s   
    ) J! p6 L. h2 x9 G4 X: @    m_csThreadCountLock.Leave();</P>
    : U- d( B. G# V' |<P>
    6 D8 \. K- m/ I9 N% q7 X- B    ClientPacket* pClientPack = (ClientPacket*)pData;
    2 j& U1 ]$ u1 ^* C- D' A* H9 Q    switch( pClientPack-&gt;wType )
    - D/ k! {/ Z6 `0 m% T! k6 T5 w8 l" m! p    {. D2 L$ [: l+ c$ m' }7 l) [
            case PACKETTYPE_CLIENT_POS:
    7 W" @" b% p0 g, Y, F$ i) d9 }. e            + e5 H; ]! l) z. o& Y2 A, z0 `6 T
                // Check to see if the packet has a valid size. Including 5 ?6 l) ~" N: Y% r" |
                // the custom pack size.
    ) r( s% E0 p1 u& }9 D9 c! P  M            if( size &lt; sizeof(ClientPosPacket))
    4 ]) c2 T: d, M7 P, g. `                fFoundSize = FALSE;
    ! L1 S2 F$ ^3 G1 N& ^! v, H4 d+ d) V            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket))), L, k. K( J+ _* L
                    fFoundSize = FALSE;& a- e5 @' y& P
                else
    7 D; v( s9 M- ~; O                fFoundSize = TRUE;</P>& S. |9 M* o9 \2 R% I$ s6 {
    <P>            // If valid sized packet, handle the position.- z; _% n7 E8 {
                if(fFoundSize)
    * h/ O0 {( V- }% g& F6 b/ b) Q9 F                HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );
    3 R' O9 b$ q  ^% r1 ]- l( U            else" ]. \9 t7 e3 a; s" T: u
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>$ N! H" }1 Y. E9 K. @
    <P>            break;</P>5 p/ E/ E9 ^8 m8 l! A* Y
    <P>        case PACKETTYPE_CLIENT_VERSION:
    - q: M3 I" d8 N% }; P/ l            if( size == sizeof(ClientVersionPacket) )
    ' G. q) d: [4 Y; Z: [2 }                HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );6 U, ]/ c/ @: Y" p8 t
                else
    ' l: K3 u+ K% A! H                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    " R  c6 o, s2 F. g2 B            break;</P>! n  @9 F8 d  g: x+ J/ N
    <P>        case PACKETTYPE_SERVER_CONFIG:</P>
    7 X# f2 ?4 h( ]* B) l, B) X1 e/ }$ I<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>
    . m& L( S1 g& P: W<P>            break;$ B; S6 w8 j7 c5 ?4 c. m1 P9 }
            default:# b7 v1 T8 G8 _! M/ l, b( r
                HandleUnknownPacket( dwFrom, pClientPack, size );
      \6 y' ^. }) U            break;9 Q# ?( r0 L! [1 r" G' f
        }</P>8 ]! s% c- d. I6 d' s+ U( ?$ u1 [* O
    <P>    //If the user wants to hold the thread, Sleep for given amount of time.3 X7 d. Q# j0 w# i$ f1 f0 F
        if ( m_dwServerThreadWait &gt; 0 )6 u2 V' [  _- v( A; _2 H
        {, f: J2 n* b8 x: U  `; q8 _* }) d
            Sleep( m_dwServerThreadWait );! o8 h8 G; I+ d2 N6 I
        }; P, ^5 k2 W* ~; t( z
       
    : H2 P* n" R; z4 A    // Retrieve thread data for this process.7 j0 d* r( d, @
        m_csThreadCountLock.Enter();</P>" K5 o' j* Q4 B8 F
    <P>    m_wActiveThreadCount--;</P>% S/ }/ W! L) e0 c9 d
    <P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;2 L( ]8 Z4 d9 _, U1 [! P
        m_fAvgThreadTime += fDiffTime/32;</P>
    ( R# P5 m, C9 v7 R, w: q8 g<P>    //Get the Max time in the thread.. O6 M8 H0 K9 ~
        if ( fDiffTime &gt; m_fMaxThreadTime )
    1 q/ h+ t  \# x! g! ^: U- S9 _    {
    ! m6 X& }' B. N( ~1 o9 a        m_fMaxThreadTime = fDiffTime;
    & ?3 N- o' K0 o1 {# ~6 B" H    }</P>9 b: X  O0 ]5 f9 {
    <P>    m_csThreadCountLock.Leave();</P>  J( a0 i/ G7 S3 y' C  r. E* ^
    <P>    return S_OK;5 j! U' U& g( _
    }</P>" ?  a6 L3 W2 h+ d4 o; i' c! Y
    & [- `7 Z& t8 d* M1 x" m9 [$ H+ a
    <P>//-----------------------------------------------------------------------------
    $ r. ~2 s9 i! x- q! U/ s// Name: 0 {% x. s, h3 U& z3 w6 w
    // Desc:
    6 A9 G$ J. ^6 z3 u+ n//-----------------------------------------------------------------------------
    , d% ~" P2 i4 S, pBOOL CMazeServer::IsValidPackSize( DWORD dwSize )
    1 g3 a# `8 j$ f! H* q2 h{
    % }6 @2 q! w$ B1 _    BOOL fFoundSize = FALSE;
    . p" _5 {1 r* c! q    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;
    - V7 T9 C- H6 z) F8 ^( q" o! r5 C    5 K/ }% w0 F8 O' q; p4 U) h( C$ j
        // Check through the array of valid pack sizes.
    ' [: Q; p8 [: F4 Y: ]& m    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])) C! J4 O" }  O( R. c, {0 U, T1 y
        {8 R' Q& e3 c4 O$ z( p
            for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)+ j4 `& \* N5 X
            {% ]& I, i: G/ |) h" M+ _* V
                if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    & Z% d; t4 P$ e  Y3 J& \9 g            {
    ; s. J! w3 W/ ?5 L                // Found valid size in the array./ U- V* A4 p: N# v/ Q; j
                    fFoundSize = TRUE;
    # I6 W  p0 k6 F" z- d                break;
    ; c# U( p8 ^$ ]4 r- {8 G            }4 Y8 |$ e) T0 U
                if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
    + o2 H) t! o' @  C$ ~: P1 K8 k        }
    9 H, Q% }1 Q3 I. i% I0 r. x    }5 Y1 V5 o$ W% N5 _$ A
        else, t+ _0 u/ M  \7 P4 D' }
        {
    ' j7 Q# n4 Q+ s! f  N& a        fFoundSize = TRUE;
    / b" d; g( y, u# w: x$ h    }</P>5 {, a/ ]7 @! G' l# T( v4 Q2 L
    <P>    return fFoundSize;8 I0 m# |5 W* B& i+ v3 {1 y7 W5 i. L
    }</P>
    - d8 }& N9 n7 L2 T, y! W2 y  @" I- z<P>8 s* |+ S" m' k* h4 m
    //-----------------------------------------------------------------------------5 n/ i. g  m: c5 B. z4 ^0 b) |
    // Name: & W0 C' K' E+ I! l& q/ V! l
    // Desc:
    ( z, f" ^0 O+ Z: Y% c* r//-----------------------------------------------------------------------------* [! G' {7 {6 K( R# V1 q1 L6 |
    void CMazeServer::OnSessionLost( DWORD dwReason )
    * F2 X9 ?+ y7 U, J$ I5 t{
    9 F, B/ G! M$ {1 v7 v    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
    + d' B6 Y- T! e- r* y}</P>
      P1 R4 O( v0 [: C$ Z# w4 b
    0 a) `! P( W0 ]4 X1 E<P>* A9 }; A) c5 w4 i
    //-----------------------------------------------------------------------------2 s. K) `7 X* }. u
    // Name:
    . v6 M! O4 o/ M3 R1 P( s& @, g2 R// Desc:
    6 \/ D: {( g: B, J//-----------------------------------------------------------------------------$ [6 {3 w- c7 e. L9 u
    PlayerData* CMazeServer::CreatePlayerData()
    7 X. [5 c! W3 Y{
    ; u2 m- Y( t1 g8 [    m_PlayerDataListLock.Enter();</P>" |; P/ ^+ I+ z! W: r
    <P>    // Grab first free player in the list
    ! w( [% C' x  @( g9 {' _    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>) t3 P& Q  y! `" W% t
    <P>    if( pPlayerData )
    , {- S* _- e& y2 w0 d    {9 ^/ G. Y- G) v
            LockPlayerData( pPlayerData );</P>. |2 G& ~3 R: o: q
    <P>        // Got one, so remove it from the free list5 v3 T9 h% Q  v& l6 ]! r- u
            if( pPlayerData-&gt;pPrevious )1 P8 a; F- B: E" E3 s7 M! F
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;0 K$ s6 G& v9 Z  M8 U; x  l: T
            if( pPlayerData-&gt;pNext )4 V4 X6 H( F5 _
                pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;. ?: Z7 Q1 r7 _& G
            m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>2 q( y7 |7 x, y
    <P>        // Add it to the active list
    4 B+ {/ k& J: ]9 ?        if( m_pFirstActivePlayerData )
    ) G' e1 f" E6 _" g0 Z2 P4 W            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
    , C8 Z' T" ?$ Y4 o* t: D2 Z        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;0 G" p$ D' n- f
            pPlayerData-&gt;pPrevious = NULL;0 {0 h# L' A/ v9 I5 N5 A
            m_pFirstActivePlayerData = pPlayerData;</P>
    ( X6 E0 X! J! A' o/ G- P$ f<P>        // Update count of players
    1 {  q- ]  g# ?* \. c: G        m_dwActivePlayerDataCount++;</P>' @& p! b' H' ^" o! Z
    <P>        // Generate the ID for this player  d3 _4 b6 l8 m* [1 G0 ?& A9 A0 y- F
            m_dwPlayerDataUniqueValue++;! E) {& P. Q3 ?% `
            pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>* f) o" \3 c5 ~+ d$ \: S" D# {* `
    <P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
    / W5 G, ^/ c& ~2 S9 g        pPlayerData-&gt;NetID = 0;
    ( T8 V( Z  c7 G, ^( z: l/ A        pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>2 w/ O( z* H4 Y3 O$ y2 s4 t
    <P>        // Insert into the "off-map" cell. \( C% }( R# F/ F* C2 w( \
            pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;& G' f2 Q- w# O7 ?
            pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;$ o- n! ]3 p# q& j
            m_OffMapLock.Enter();2 w' r0 M. O+ ^' C* C
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;
      N& |9 m' ^9 r( L1 p8 ]. x5 C% g' @        m_OffMapCell.pFirstPlayerData = pPlayerData;1 b0 _2 y5 \, I; S: K
            m_OffMapLock.Leave();</P>, _4 p4 o/ B; @
    <P>        // Mark as active
    # {; B8 [7 T' X1 Q# D3 }% D* n        pPlayerData-&gt;bActive = TRUE;</P>
    + j; H7 R$ U  T* Q0 ?7 @5 \) ]<P>        UnlockPlayerData( pPlayerData );% E( m: T6 G- Y/ s  O; }0 i+ _( p& b: _
        }</P>
    1 s9 o7 L, B8 k$ @5 |<P>    m_PlayerDataListLock.Leave();</P>
    . I) N; v. O/ h' g<P>    return pPlayerData;
    9 I( l8 N+ l* \8 K/ X}</P>  ~9 C5 @1 f5 g

    # g* U+ q7 p6 Q  q, ?<P>& A; i! H) k; n" W
    //-----------------------------------------------------------------------------
      a8 a1 q2 p! A- C0 F1 B+ m( ~$ F// Name: 8 p% t0 i: F; }1 v
    // Desc: ! P' f9 Q# m" L1 K
    //-----------------------------------------------------------------------------# W  ^( R/ Q: n. z  ^6 w$ o5 x
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )* n* _3 B% f, O3 n& W
    {$ U1 V* I! \9 ^
        m_PlayerDataListLock.Enter();, k, `7 x3 e2 f/ [
        LockPlayerData( pPlayerData );</P>/ U* A7 E7 \: s9 h
    <P>    // Remove the player from its cell
    - w) a7 C6 A3 |# z    RemovePlayerDataFromCell( pPlayerData );</P>
    8 N% G& v4 Y- }) u. m$ V<P>    // Mark as inactive  C4 t/ ~% w! z2 E: w
        pPlayerData-&gt;bActive = FALSE;</P>; d% A+ R  @, j1 u4 |1 @/ H# y
    <P>    // Remove player from active list2 X- n1 @# B% w
        if( pPlayerData-&gt;pPrevious )4 D/ G7 [( u; x3 f! L5 y
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    # b: C8 f2 s# D: T( {    if( pPlayerData-&gt;pNext )
    ' {- X- s" \) u+ P. q" W        pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>6 O  x' e$ u9 q
    <P>    if( m_pFirstActivePlayerData == pPlayerData )
    / A1 ~6 ^( z* d! l- O        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P># v; `4 d$ x; W5 }% \2 c
    <P>    // Add it to the free list
    4 [* y8 U- n9 X8 w$ t    if( m_pFirstFreePlayerData )9 k+ D% F2 g  H+ e4 l9 L5 C
            m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
    : Z3 }3 Z, o7 m) f6 Z7 ?# J! w    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;6 r$ y8 w, X; u9 j. S
        pPlayerData-&gt;pPrevious = NULL;
    ' ^/ _+ T1 F  x- ?' [    m_pFirstFreePlayerData = pPlayerData;</P>
    ' V* h" l$ x2 D3 ?  x4 r<P>    // Update count of players& X, o+ g. K2 ]; A( Y
        m_dwActivePlayerDataCount--;</P>
    4 N2 R# G- [5 h& w, N$ I# H<P>    UnlockPlayerData( pPlayerData );
    0 y# X# S) g# B2 d$ B8 P. O    m_PlayerDataListLock.Leave();
    " D& |7 p; k. C! E9 f& B$ U( G}</P>, e& N% z3 n& }5 {, y2 ^: Y

    9 p; `' C: E/ l$ Z: ?4 l<P>
    5 n8 Y7 S1 U* ]( ~8 }- J6 O//-----------------------------------------------------------------------------: }& Q% R; U! H6 j1 k& N& Z/ O
    // Name: 8 j3 ~* r$ k6 G) f( |
    // Desc: ' c0 s* X, \% ^8 Q0 T7 f: d
    //-----------------------------------------------------------------------------& K% r) p, f# u: P6 E3 L0 a6 D
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )7 I8 h1 [& _% }, ?7 L
    {
    2 N% b' b, K8 L# g/ ]0 q2 e    // Lock the player+ n5 K" x; h3 ?, O. m  M) _
        LockPlayerData( pPlayerData );</P>' i: C; t/ f8 V: g! K* \0 P
    <P>    // Lock the cell the player is in; S4 w9 M2 `. j( i2 S8 b2 W8 C
        ServerCell* pCell;
    % m5 `1 H5 R% V    if( pPlayerData-&gt;wCellX == 0xffff )
    $ Y2 |/ t: F/ C, R; t; g    {* P' m  \- M8 V( Z" m
            m_OffMapLock.Enter();- ^  W% s5 a1 D+ ]9 ~* p
            pCell = &amp;m_OffMapCell;4 H& B7 k: j% f
        }
    1 b! I+ N, m  l6 M% G6 S    else4 i% t5 L- G6 U' v5 `6 R6 D& E7 X$ d
        {
    & s1 J5 I0 H% R' W% E0 e        LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );. k/ B% _: s# {
            pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];8 x: O; E) X- o9 U7 j2 D
        }</P>
    ; ]6 i, f7 f, |5 F<P>    // Remove it from the cell
    & g  J" h& v  v% n    PlayerData* pPt = pCell-&gt;pFirstPlayerData;8 ~0 k, H8 D3 @' P' Q
        PlayerData* pPrev = NULL;
    1 U, ?# i/ F6 w. y$ \5 k5 f    while ( pPt )
    6 J* ]& t# ?$ e+ ]% T4 ~8 `+ m# k    {
    0 Z, T% U" o- `4 H+ |5 Z+ q7 S        if( pPt == pPlayerData )
    5 N- t- z/ z* `  s* l) r        {) y6 j3 }! |: |8 m( _
                if( pPrev )! Z/ {/ v: d) {' ~
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    . B; n4 n3 B/ P, @! Y9 t7 h( V& P; T5 i            else3 X$ X( r! S# d6 [, g
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
    ) I  y3 P$ I* Q. r: I9 o<P>            pPlayerData-&gt;pNextInCell = NULL;) L! n7 Z! x' s
                break;
    9 ]8 |+ n* G4 o  j        }% t: }+ f" x- g, g( |3 o; z
            pPrev = pPt;
    ! t! @% b' A/ q7 ]9 s  z1 [% }        pPt = pPt-&gt;pNextInCell;
    ' J( \# r  O! Z* U; i' A/ X    }</P>
    , {/ f. |  O- |& q# l) m<P>    // Unlock the cell) }' E4 ~6 |+ p$ \  `7 S! O: X
        if( pPlayerData-&gt;wCellX == 0xffff )6 H1 N# A) c. k5 O5 D5 N
            m_OffMapLock.Leave();
    * Y& R$ C  ?+ |5 g- B    else9 Z7 Z" Z; r6 V8 G! \
            UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>/ g' I5 D& q$ `8 B- @; Y% D
    <P>    // Unlock the player+ J( G; o* w4 y5 N6 u2 A7 v7 ?
        UnlockPlayerData( pPlayerData );- k) T# |6 H! [! F- V- `1 E: d
    }</P>: `. A) j* T" g: s8 @5 u

    6 g: N9 J2 E/ E0 B& U) s' N<P>+ d  \* u+ y: ]' M8 _2 C
    //-----------------------------------------------------------------------------
    ; @5 ^8 m# `* y3 b) P0 F* }3 [; r// Name: ! H/ M8 a; h8 a! C! S4 @7 M4 o
    // Desc:
    & E6 W# x# E1 ]3 S' w//-----------------------------------------------------------------------------
    ( q/ C- H* P4 J8 lvoid CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )( l5 W7 C7 M5 G5 S5 h+ q
    {* h$ y6 |0 S# L# G2 p  Y
        ServerCell* pCell = GetCell( pPlayerData );1 S# a* {! p0 j: ~7 d* P$ [; C; v
        PlayerData* pPt  = pCell-&gt;pFirstPlayerData;3 K( Y' a) l* N
        PlayerData* pPrev = NULL;" P6 g, A- p& i( e5 X  @
        while ( pPt )
    ! I& ~; i; v& ]) |    {
    , k. g* r& D# Z        if( pPt == pPlayerData )" i' v, [2 x3 I' f4 L# A! o
            {
    0 `! s# m" B4 v5 H& |            if( pPrev )
    2 P2 |9 C6 H; L; _! [                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;/ Q" a+ ?' c' E8 h2 I: c( c- D% X) V
                else
    # g1 p* X, u7 E; S, i9 m                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;
    7 r0 ?( c7 |7 v  T            pPlayerData-&gt;pNextInCell = NULL;
    ' m: W; D: ]6 s            break;: A/ T7 [2 E  ~/ c- O
            }# |0 Z. ]) f$ n; y( o
            pPrev = pPt;
    & h! |# M4 p  ^9 g6 ?- }; X! G, n        pPt = pPt-&gt;pNextInCell;
    6 c  r* T  r! _8 G, {6 q* F! G' c    }* U3 Y$ m6 J! c  Q8 L' x
    }</P>: R* \2 W- `; g- i- W4 W# c  G9 ]
    5 I, O1 X- {4 `$ I7 s
    <P>
    : X! W" D& [$ h% L7 N//-----------------------------------------------------------------------------2 M. I! P+ k- p; ]
    // Name:
    1 k" n6 x: ^' }+ U// Desc: 3 h* ?! c# @4 u5 z
    //-----------------------------------------------------------------------------, R; e7 P( j, X3 [2 N5 s
    void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )
    6 ?) }; T& R" k) N( `% u4 J{3 o+ j& G* L& B' \  H& P" I% D8 H/ N
        ServerCell* pCell   = GetCell( pPlayerData );
    5 _! c' R: \3 L  ]5 |' ?1 y' T7 b4 C    pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;
    ! b3 }7 z5 W' f) \5 p! _2 C% F    pCell-&gt;pFirstPlayerData = pPlayerData;# R; Q* W7 q" L* [
    }</P>. L4 T/ y9 b6 b7 `
    : ^6 @- i/ f9 m2 Y
    <P>3 A$ |* t$ c$ _3 s, r4 T7 M0 S! z- O
    //-----------------------------------------------------------------------------) b  R; q& ~9 ~& X7 |
    // Name: , t% t/ D8 D, W% C8 d+ h' ~( p. h: z
    // Desc: # {3 U: d; b# @- @+ |6 L# W
    //-----------------------------------------------------------------------------
    # N5 n' ^4 `8 S" }# P. {1 S: S" G& B( \% dvoid CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )% g" V$ [" [- @
    {
    ; |7 x: y( z5 S, m2 `% ^4 y/ P    // Grab player for this client and lock it7 X/ n# ^# b  Z8 }
        PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );
    8 e+ ^% j5 O% b" d    if( pFromPlayer == NULL )5 O6 ~5 v3 K* i. V* d
        {+ P/ @' K' {, M. {! d7 w; ?
            if( m_dwLogLevel &gt; 1 )6 O- u% }5 C" @1 f
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );
    # M+ K2 a4 \* `        return;
    0 I0 v( Z' f# X" J: u8 ~    }</P>' R: F1 t' Y- ]. D+ P
    <P>    LockPlayerData( pFromPlayer );</P>
    , x: s( W0 h6 X* g. [/ {/ V<P>    if( FALSE == pFromPlayer-&gt;bAllow )+ |/ `& _5 x1 f# Q$ C) A/ X: D0 L; _
        {
    + ~9 t  j3 {% ]3 j' W3 E& b8 n        if( m_dwLogLevel &gt; 0 )
      O2 d& b3 Q' \  G. b            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
    6 q2 N3 \3 X& w& F( ^<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    ' `; ^3 ?" H4 L5 t3 X* l        UnlockPlayerData( pFromPlayer );
    # k. k8 [$ A. s; j        return;" X+ S& u# Y( ?; b2 d- N* e
        }</P>
    # K0 e5 t& ]0 [7 o  O( Y% y<P>    // Compute the cell the player should be in now$ j5 P9 U# {8 [$ q" ?- i  H
        DWORD newcellx = int(pClientPosPack-&gt;fX);
    5 e4 ]5 e4 g' p6 h9 f    DWORD newcelly = int(pClientPosPack-&gt;fY);; h. h5 S% c% A( X: M
        DWORD oldcellx = pFromPlayer-&gt;wCellX;6 A* k8 ~- J0 q( _
        DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>2 q; x5 h* g6 k2 R
    <P>    // Have we moved cell?
    1 T9 m, m* [. i  u    if( newcellx != oldcellx || newcelly != oldcelly )
    : E$ S; p5 t7 B5 Y    {  N  l4 S  y) h
            // Yes, so lock the pair of cells in question+ T; A% t/ f2 F1 E3 S" Q6 t& ?
            LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
    ; _" {, K7 ^+ n2 {0 h: A<P>        // Remove from old cell and add to new cell; t1 @7 J8 Y7 b; h
            UnsafeRemovePlayerDataFromCell( pFromPlayer );+ V4 ^! A( w3 P& I5 m8 G# G- N
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);' W- [; u, C; {1 d
            UnsafeAddPlayerDataToCell( pFromPlayer );</P>
    9 I( x- s2 ]2 t  L6 W- k6 Q* f<P>        // Unlock cells
    8 o; u, T0 [' s  A        UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );
    : E  Y/ y+ i1 U  }    }</P>
    0 R7 `; j% O& _. y4 f, }2 J<P>    // Update player position
    ' X7 j/ @% y5 C    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
    - W  h6 g& D+ @% l5 c    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    & {& r, i' E! ]) O( n5 \    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>3 V9 J" ^. I- \  o
    <P>    // Allocate space to build the reply packet, and fill in header 7 V, @) k9 h% ?1 D5 o& q  h
        DWORD dwAllocSize;/ P( J, M" v9 R) i* }# X7 y
        ServerAckPacket* pSvrAckPack = NULL;</P>  u1 q/ ?3 j! w' T* r# y9 O
    <P>    // Begin by allocating a buffer sized according to+ G2 b* p$ \9 k' S; U& M
        // the current number of nearby players + 4.  This will give
    ' @: A' q, t* X& w5 Q7 g3 h    // a little room for more players to come 'near' without resize' x/ v* ~" x' k
        // the buffer.2 m1 E( c! N- V! e( O
        DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>' Z& b8 A2 N  s. L7 A& \2 i
    <P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);4 ^- K: I6 @- g. \4 H
        pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    5 y$ i, f& S, Q/ v; j    if( NULL == pSvrAckPack )7 t9 w% P' L/ t
        {/ ?: D+ b9 K' P: }9 E4 ?
            // Out of mem.  Cleanup and return
    ( r9 N0 x  x2 B9 k& l5 g# v; v+ p        UnlockPlayerData( pFromPlayer );
    5 N& L2 v7 M/ x* g+ J6 e6 q  ^- B        return;       # f9 B2 {3 A/ Z5 L' M8 H
        }
    " L( p! N  R& v6 e0 k. H) J' _5 m    ZeroMemory( pSvrAckPack, dwAllocSize );</P>
    ' D+ x9 B! t9 s8 W$ O<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);, F" d: x1 t& t# O7 \* b: N
        pSvrAckPack-&gt;wPlayerStatePacketCount = 0;! [* a. \) A0 a: n; A! R5 w
        PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>9 r1 N9 u1 |. M
    <P>    // Compute range of cells we're going to scan for players to send
    ) l( w: y5 |1 q! _& ^5 `2 T    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;- X! k( L0 r' p! f- I, m6 p* |( l' e9 W
        DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;$ b/ Y' `7 q' r, S, d2 v
        DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;
    7 v* w. [; u9 A1 N    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>2 Q$ T" J' f; }- J# \: T& S0 O
    <P>    // Lock that range of cells5 r/ H( m3 {- z7 k1 U
        LockRange( minx, miny, maxx, maxy );</P>. I5 D( k  \* T. W; q
    <P>    // Scan through the cells, tagging player data onto the end of
    ) f& S, f+ _3 Z; E$ x    // our pSvrAckPacket until we run out of room! {% F+ n: J. t4 Y# G0 G1 W+ L1 k  S
        for( DWORD y = miny; y &lt;= maxy; y++ )
    / F: }( R- |- }    {% T& U* E7 x. N, ]# J4 q* l
            for( DWORD x = minx; x &lt;= maxx; x++ )
    ; ?2 k2 B- n( a        {' X9 s% p& I' j  k6 M
                PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;5 `1 E) k# a9 V1 A, o8 n+ D, y
                while ( pCurPlayerData )3 F7 n1 v( j& \9 j
                {
    6 E% ~9 e# D) d; I- q6 {9 l; `/ D                if( pCurPlayerData != pFromPlayer )
    - |+ S/ _  t5 t" I                {
    3 v! m0 a. z8 F' N  [& T                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )# @0 j; N2 Z' l" ?3 Q2 Y  Y, o6 i7 X
                        {
    . C: P8 ~3 l  R+ V( Y3 T1 x; x9 p                        // Make sure pChunk is where we think it is
    - C- P! R# `9 x  X; D+ g8 x2 C                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>: X: o1 x4 A: s8 W9 ^
    <P>                        // There are more than just 4 new nearby players, so resize the
    4 A/ A( @6 q) b# r& ]2 k                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
    ( `! Z' M$ b) |1 D                        dwMaxPlayerStatePackets += 16;
    ! w- G( S' l- o: g# @                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    - {% |1 p$ y/ ~" N" S. J                        ServerAckPacket* pNewSvrAckPack = NULL;
    ) N$ L% u8 N9 p% a7 G                        pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );) P( Y0 g) [0 [2 ~# S; v" e
                            if( NULL == pNewSvrAckPack )
    * U& @% K3 D# A0 C/ E, f# U                        {$ o0 x! S1 `. w2 {9 ]
                                // Out of mem.  Cleanup and return5 n: ?) x, Y) ~
                                free( pSvrAckPack );% H( H( t4 s! O
                                UnlockRange( minx, miny, maxx, maxy );, w" t% f+ G$ m8 j) G4 g8 ]
                                UnlockPlayerData( pFromPlayer );
    1 t: ~1 d! r4 D: Q                            return;      
    8 ~1 j  m( u+ E7 V  l                        }</P>
    ; D- s( c) Y# f3 G5 {2 O<P>                        pSvrAckPack = pNewSvrAckPack;
    : W5 g% I6 s, I( a+ L                        pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
    $ a5 F: h' y, i3 b6 e: v<P>                        // Make sure pChunk is still where its supposed to be1 e6 o" w/ l" m4 w' L
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );+ S1 q2 M6 M: L
                        }</P>
    & K' N$ E% A! R' C- }9 X<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;3 i3 y5 `+ D! z; R
                        pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
    5 a& i: V) k& X" A: M9 i9 {* W  y                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;( T. B, o; H7 s9 b( Q+ Z: S
                        pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;' B, I8 n! ]3 h$ s- e; d. w, f
                        pChunk++;
    2 v/ k/ m4 o) m* K                    pSvrAckPack-&gt;wPlayerStatePacketCount++;
    $ T. f2 j, r' u; ?8 e                }
    % J/ Q' \# Z8 E# q                pCurPlayerData = pCurPlayerData-&gt;pNextInCell;# [7 S: X& y. h% E' g9 m! R
                }
    8 C0 E( g' {+ g7 b7 q        }
    ) g2 Y2 {$ S2 T' ?1 T    }</P>: r" x# A. S4 e/ j" U
    <P>    // Update the dwNumNearbyPlayers for this player
    + J/ R* C2 o- C0 i7 b3 s5 F. W$ R& p: r    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>; A# z" ~( v5 v; y- V- o  J) X! y
    <P>    // Unlock range of cells/ V2 p" @. @' A8 M" V/ b0 F
        UnlockRange( minx, miny, maxx, maxy );</P>
    6 @; G1 D. b0 k) j: G/ P<P>    if( m_dwLogLevel &gt; 2 )
    0 W; ~- f( {  a  _; ?* l# k    {, n, E" O5 o* ]5 p, M3 I  t( X% f" e
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    , z5 a5 p$ p0 U5 W5 m4 [    }
    4 J, Z8 x4 @! a- ^: W* x! G    else if( m_dwLogLevel == 2 )
    1 i) f7 j4 Q7 l/ o" J$ s    {
    # f6 k' W3 F3 \/ J7 I% h        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );1 [. w1 I6 c% g6 ~# M' [
            if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )
    3 d- X0 h3 t. P; M        {) Y5 A' @7 z1 |0 e& }! D8 N
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    - v2 n. {  v$ R, A! k+ F1 D! W            pFromPlayer-&gt;fLastDisplayTime = fTime;
    9 z8 R# m) c5 }5 l        }
    6 x; s1 M4 F, V! c& [1 [. a    }</P>
    " M4 R$ Z( W/ f<P>    // Unlock the playerdata9 t4 b' ^+ M* l1 r8 y7 M' O9 E
        UnlockPlayerData( pFromPlayer );</P>
    ' L$ _# [6 P' F+ C$ K<P>    // Send acknowledgement back to client, including list of nearby players
    3 a0 j0 n8 ^9 \3 b/ `    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));& a' B$ J& i* L% g) n, [
    ( A! q' L# Z' Q
        // Pack the buffer with dummy data.
    ; }1 l& h+ o, t/ @5 V    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)
    7 ^2 H& q9 L( q% a3 y7 g; g    {7 Y& r9 C" l1 X3 `1 T+ q9 |
            DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];
    ) x2 K' m+ a7 W' D' i! j! c        VOID*   pTempBuffer = 0;</P>
      U* c* p& `0 L$ J: z7 ~  S: n. v+ G<P>        pTempBuffer = malloc(dwBufferSize);
    & o0 @, Q  Y( ^: F) ^: p% o        if( NULL == pTempBuffer )
    : L4 Y- ]1 ~' g. ]0 z: [2 M        {
    ! ?# K9 S0 [5 ~. X! D            //Out of memory
    " y+ c' D. x2 z1 |7 Z            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );; U- ?' m& h% ?, [# _4 R
                free( pSvrAckPack );2 Y" ~# W0 a- Q: p. x  M
                return;
    & s4 {; f$ g- s' G# F        }</P>
    $ o; J% a- X! u+ i) R<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');
    & ^9 M7 P: k4 B9 A        memcpy(pTempBuffer, pSvrAckPack, acksize);</P>
    7 {5 r7 i* J- V  R( U<P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );0 R/ A( Q* z+ B! [- z. w
        & P& Y7 I: j: P; P0 r$ U
            free(pTempBuffer);% g7 k& r5 m3 T1 D5 \
        }   0 _& a' {% ?2 I8 j% S
        else. r) q  D/ M  x# Y7 g1 b
        {; {" E6 h  O! E+ ~
            SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );
    8 v; |0 K7 F+ v  w5 k    }</P>, N& L" L; r, s
    <P>    free( pSvrAckPack );</P>! X9 d* R3 j. H6 S. B- u2 D. W" m2 ]
    <P>}</P>
    0 k% c# y: w' F. g* |* O, ~) P8 X% n; K/ k7 b
    <P>
    8 ], z7 L2 G! F; h4 W; t//-----------------------------------------------------------------------------
    " L4 {3 \, Y' b: j* P, u// Name: $ Z$ I  S" |# S1 x1 r
    // Desc:
    ; D. W3 N' T  F! }4 z//-----------------------------------------------------------------------------, z6 N0 i& x( q  t9 d$ ^4 P% d
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )0 X+ Q, g" t5 L" H4 m# v
    {
    7 Q1 X7 P9 X+ i( S' ?- o0 g7 W    // Grab playerdata for this client and lock it9 Z3 T& s6 a* u9 g
        PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );" C" R9 `5 c& m) _* ~; q& T( ]
        if( pPlayerData == NULL )" l6 Y2 X4 [0 Q( W
            return;
    6 Y% A. q1 D+ l  q) y% G2 m# u    LockPlayerData( pPlayerData );</P>* @7 E( T$ y' x
    <P>    // Record the version number 5 k0 L$ g5 }' }7 v
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>* g" M( N2 _0 F$ {
    <P>    if( m_bLocalLoopback )3 h. b, [7 [% u( V* U5 p
            pPlayerData-&gt;bAllow = TRUE;
    * D7 C! A' a$ I, C    else
    : W" U8 D+ i7 h$ M# Z; i- ?        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>+ k7 u/ X) m  B) ^, |% q
    <P>    if( m_dwLogLevel &gt; 0 )
    5 r$ w7 h" L. U9 `7 N% [2 t/ B        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>) U, F" A6 w. V* Q1 s& b
    <P>    if( FALSE == pPlayerData-&gt;bAllow )' F/ Y- v  v: j& h4 V9 f. Z
        {: d+ f8 T) j5 O& {' B. Q
            if( m_dwLogLevel &gt; 0 )0 G. @4 o* b/ `8 {! o- D
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>
    % [; h3 D) y& S( l: |  S<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    ; k# G$ \8 F9 Q0 d! D( j7 G9 A  {        UnlockPlayerData( pPlayerData );
    ( g, U# Q/ G6 t0 l% k        return;
    ! W) O1 Y; ?+ @- v% B    }</P>
    # `% ~) Q5 O* `<P>    // Unlock the playerdata
    6 @( m( _7 l6 y9 M    UnlockPlayerData( pPlayerData );</P>
    - e3 p* {# d, T6 N' {( v. a; Q  @) {<P>    // Send acknowledgement to client that the client was either accepted or rejected' @! K' B. M8 A- u- ]) ^7 u
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );2 u( z! o9 N! W* {
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
    * y$ W5 M& Y) E- I}</P>9 _" k5 D8 o! x+ v" p# |2 u

    3 r' T% ?- H' f$ B$ f, o<P>7 E* ~  Z4 a6 ~7 W. v% {4 W
    //------------------------------------------------------------------------------ I9 X5 L& }( `/ k* H( I$ t
    // Name: % i% _& V, I. v. [% n% `2 }! y
    // Desc:
    / V' J3 b4 g6 X, B* j//-----------------------------------------------------------------------------
    5 S; d* ^3 c% a1 o6 {0 w9 P0 {" vBOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
      K/ h9 I/ ]1 O8 B% e8 k8 w3 h5 O4 H0 d{$ L1 X/ i: h* l7 j. o) B4 m2 F5 y
        switch( dwClientVersion )8 }  L& l& b# c. Z5 O+ P( `( q
        {6 J, J2 g& y0 o( \5 G" e
            case 107: // only v107 is supported- E2 Q. z7 `( }" F
                return TRUE;& E: U0 [5 ~8 w; v
            default:
    - M2 V% t2 E: h" _6 x6 ~            return FALSE;! d# C: a: }! S
        }9 Z4 K( [5 D+ C' \
    }</P>$ i2 Y& D: n) n& i1 e0 ^

    ! N# l4 \) V& x! Q<P>
    3 K$ w" j8 R/ n- E' k//-----------------------------------------------------------------------------: a  \. A# q  F; b% W
    // Name: , [% E& n4 k4 [7 V7 K
    // Desc: * F# _& }- X3 J# D3 [% B1 E5 \
    //-----------------------------------------------------------------------------
    % _; V+ v" f" `3 `1 n% Q: O3 v1 g" kvoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
    + A; A. B7 j$ r9 x! f+ ^: e{
    - O  H$ F8 Y1 q$ _    if( m_dwLogLevel &gt; 1 )3 B8 F2 N* M+ F( d+ K) C$ v: q
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>; R1 k) E$ `! S5 |
    <P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    1 F# w2 R2 o% g1 z}</P>( k9 q6 N3 L7 c2 B2 _
    0 V' U/ ?$ J/ d  q" m. l
    <P>7 p' Z" s+ S/ g0 [8 h5 t" b# N1 o" M
    //-----------------------------------------------------------------------------% `% q/ Q& R5 X% T/ I
    // Name:
    * ^) n  s( a' `- r# ^3 E( i// Desc:
    $ {& m9 v/ p2 [3 S/ f& N//-----------------------------------------------------------------------------. }: i6 W& ]! Z% |
    DWORD   CMazeServer::IDHash( DWORD id ): @  S* x, e" F' n  J
    {
    0 m" H2 f4 N& e, N4 {4 H    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);5 T( s$ ]" m: a( l+ w+ _; R
        return hash;% U9 i3 C3 T2 m; x7 t8 L
    }</P>( U2 `, h( ?' Q% e" F) V( R
    ) i" _& {4 m3 n3 J1 l- w5 [+ m
    <P>* `( u8 s9 Z* r: X% t: J
    //-----------------------------------------------------------------------------) c) {5 U/ p7 ~2 G+ }( ~. I
    // Name:
    0 Z2 u( A  q7 O5 }7 O+ F% i// Desc:
    9 |" ]1 q/ o" V: L//-----------------------------------------------------------------------------7 c% g. j/ X3 w% L
    void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
    ' ]# N! E% X1 P7 k* ^' \1 v1 ~, b{
    ! P7 D$ y- Y" L# [    // Hash the ID to a bucket number
    8 z+ m2 F. n: a, A5 J: [4 M    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
    " i8 w% b! Y- a' F<P>    // Lock that hash bucket" I3 b# |: |) R+ c& }. x
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;! C8 R- n5 O6 }' A
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>6 n7 i' i# y- ~8 l* w$ Q& P. X
    <P>    // Loop though players in bucket until we find the right one
    $ }: I) o3 Y4 ]5 ]5 n    PlayerData* pPt = m_pstIDHashBucket[bucket];5 T, a# @  k+ _. h
        PlayerData* pPrev = NULL;
    . @3 J0 ?& ~) g( l    while( pPt )$ i8 O$ S4 R# Y; ~
        {7 O% @9 L1 X7 K; M5 l8 j
            if( pPt == pPlayerData )
    " f; G! C: N6 `3 D2 d            break;
    + F9 o. q( Y5 b  b% r8 F" z        pPrev = pPt;" ~( k; m3 v5 ]7 q- B' C
            pPt = pPt-&gt;pNextInIDHashBucket;
    1 n0 ?* q* R; ~6 M$ ?0 T4 l' `    }</P>
    8 [' z5 U3 A& q' H1 A$ D+ u5 ~# c<P>    if( pPt )
    1 p) g6 {7 t+ ?    {
    1 e+ J( b; O$ ~$ O6 \1 E! @+ _  d        if( pPrev )
    8 u, O0 G8 w3 E( ^, L: s            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;/ p" U" }7 L& p! l6 j8 m! a
            else) o: }0 h) k, k0 D( W9 j% X. x
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
    6 L" z% c2 R5 w+ c. v) S        pPt-&gt;pNextInIDHashBucket = NULL;# o" o% R. @* F9 ~
        }</P>
    " l& l& o/ }: u6 E& o* S, |<P>    // Unlock the hash bucket
    / S* x" w% \8 |8 w5 `    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    # J6 @" m7 f- V# \$ H, ^$ \0 K}</P>: q. v0 D/ ]7 b: U

    ) f+ m/ @  E7 F- o2 H1 Y<P>( H- i7 F8 G0 i& x( v+ _7 C$ `
    //-----------------------------------------------------------------------------
    * K! j* b$ I0 t/ i9 j8 r0 O// Name:
    : J7 S5 }% v) I// Desc:
    5 X2 m# V# q+ R7 E0 I//-----------------------------------------------------------------------------
    1 H7 q9 K/ k# Rvoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )/ ~; y% M  b" A* }/ i8 ?2 D5 u7 F6 t6 y
    {
    4 e& c+ N% H, Q7 l8 x4 d    // Make sure this player isn't added twice to the m_pstIDHashBucket[]
    ! D6 r0 o% W9 ^# C* Y) ^" @" Y    // otherwise there will be a circular reference
      {! f, Y; x5 t* \3 l    PlayerData* pSearch = GetPlayerDataForID( id );
    0 B9 F# d7 X: D" N    if( pSearch != NULL )
    2 W% U# b4 u4 M3 G6 |# i: e        return;</P>1 d* I, [2 p2 G- v+ F$ P
    <P>    // Hash the ID to a bucket number
    8 e. w" M5 P$ u. l1 {    DWORD   bucket = IDHash( id );</P>
    * P( C9 C9 M8 h. a6 S; s( l<P>    // Lock that hash bucket
    ' G" z- U# `/ J) D& `* |    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;" w. f! _6 Z$ y6 g3 {
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>. h3 @0 Q& x$ V) M/ `% W
    <P>    // Add player onto hash bucket chain
    ! U* p; ?/ l$ Z0 I% w5 ~: T    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];/ m2 P5 r* U0 z0 H  [' J' H
        m_pstIDHashBucket[bucket] = pPlayerData;</P>
    - p4 V7 k. O1 [2 G<P>    // Store net id in player4 j9 F8 z. ~2 F% H- m4 J  y/ L
        pPlayerData-&gt;NetID = id;</P>
    ; ?# C' i. I1 u: M) O& V) y7 W: Y<P>    // Unlock the hash bucket
    / z/ H9 q- h8 a. |# w8 r% W$ K0 H    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();5 t. q) W3 O" O+ r( Y6 @
    }</P>% ~  u) Q) d+ n5 H/ H& P0 s

    $ b( W5 d6 r! d1 _3 Q5 {; _<P>0 A+ J! e- I8 l* z$ [( B/ T1 T
    //-----------------------------------------------------------------------------
    + E8 ~' ~1 w, }4 {4 d// Name:
    - l' v8 k, e# K" a" v" M/ I1 d// Desc: 1 I: q, Q( n! K6 U
    //-----------------------------------------------------------------------------
    0 u3 x7 }! h3 s$ o) cPlayerData* CMazeServer::GetPlayerDataForID( DWORD id )3 U( q2 S6 O4 V1 d5 H
    {
    ) q  H& L  @: d. h+ u1 p    // Hash the ID to a bucket number
    1 M: V+ X, b1 ]    DWORD   bucket = IDHash( id );</P>& p( i# [  W  I  m
    <P>    // Lock that hash bucket
    ! B7 s3 Z: l8 E" h& G$ G5 f5 ]; Q    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;2 m2 Z0 b$ L' `! k: u5 r
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    5 d3 E* M" f3 Z/ R" m; h6 Y4 R% l! z8 S<P>    // Loop though players in bucket until we find the right one
    : C; x! s  w4 u$ e! ~    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    - E7 m' m1 }1 l    while ( pPlayerData )
    4 v/ ?) T) o$ E    {
    , l  j/ n: f  N" {' U; l5 Q. `        if( pPlayerData-&gt;NetID == id )8 p" n7 Y  p! S2 ]
                break;
    * W1 R0 A. y0 c8 y. K        pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    # R% I, Z& }3 J# d5 R! q    }</P>
    , d' z% G  u+ I  G" ]<P>    // Unlock the hash bucket
    4 H8 u$ O1 k; @, B    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>5 H% O/ v& |; {( z9 {! j
    <P>    // Return the player we found (will be NULL if we couldn't find it)
    # a% H1 _# d4 T3 l* K0 S' O    return pPlayerData;
    - k; b! i# k  }" q6 Z% F7 R5 h( v}</P>5 j3 d: e- p4 |
    4 N6 Y. o) w( D  j/ w; h  [9 |
    <P>) n* w; F1 D& i4 F* }
    //-----------------------------------------------------------------------------
      Z3 p7 ^0 a+ \// Name: / q# o4 T) k% ?
    // Desc: calls DisplayConnectionInfo for each connection in a round-robin manner, [& p9 A: j; R$ q6 N- X& ~
    //-----------------------------------------------------------------------------  S5 r0 {# ~( d4 G! s' W: v
    void CMazeServer:isplayNextConnectionInfo()! A0 g( }) d1 e* o; w
    {
    3 h9 L3 t! Y; [! p/ r# O  s4 ^( v& w+ Z    if( m_pNet )
    9 d6 _- E* [# ^+ t8 f7 o# ?% H$ R/ @    {  W* |7 u9 d! [
            // Find the player that was displayed the longest time ago, and display it.
    . ]2 J" ]# P9 `4 C  v        FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
      W+ V2 [6 M7 ]  @: D        PlayerData* pOldestPlayerData = NULL;
    4 m3 }+ K) |1 H7 K        FLOAT fOldestTime = 0.0f;</P>
    1 v2 V' e: T, X! Y! {<P>        m_PlayerDataListLock.Enter();</P>$ r5 ]* }) ~# f5 d* E4 e
    <P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
    ) P* K7 |) c/ n( B2 @+ @        while ( pPlayerData )0 b. a9 ~) B7 d6 n+ B* O
            {3 d3 H5 s- {) f) n* O
                if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )/ z% h: B9 H) [& p
                {" [8 T5 f# p1 b6 _: o- T. D
                    fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;
    1 d( e- ^) U9 Z, W                pOldestPlayerData = pPlayerData;0 k9 ^! f( _% L4 i% N
                }</P>
    - c8 r1 V9 ~7 V<P>            pPlayerData = pPlayerData-&gt;pNext;7 @& R- \0 }7 {8 m
            }</P>
    & f4 i+ `8 P, [2 |- I<P>        // Display the player with the oldest CI field, and update its CI field.
    " U& B. L2 b4 c& H/ }        if( pOldestPlayerData )8 Y2 D" c% @1 e. J
            {: Z1 F* u8 I* u/ E0 B9 k
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );" _  {" N/ t. v1 w
                DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
    8 Q2 i* z" o5 R! I& v# T) z            pOldestPlayerData-&gt;fLastCITime = fCurTime;. w. {# c, ]) I: X2 E/ ?* C
            }7 B3 f* k/ ^8 v, L
            else' x' B  e- v1 s' Z4 P' Q
            {  b% F! S2 n3 y; D9 R
                ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    ) {4 C6 k6 [2 f        }</P>8 Z' B# {* O/ D; c
    <P>        m_PlayerDataListLock.Leave();" ~6 g# r* V# J2 `& |5 v; [; b, i
        }- I' F% m  v1 M! f- `* j
    }</P>
    * @; R- d3 U* c# I7 d8 N
    9 p  |- w+ \8 B. }<P>; r6 ~6 `, e" m
    //-----------------------------------------------------------------------------
    : a4 o; ]  f' y. Y; S// Name: 2 p6 h2 r" v/ i6 \% c5 Y/ i
    // Desc: ' Z9 ^% ^% T" u( A/ j* V4 N
    //-----------------------------------------------------------------------------
    9 B+ e4 r. ^% a7 I" k6 |: qvoid CMazeServer:rintStats()
    9 Y' M6 o$ m! U) L{
    1 K- P, ?# W; n; t9 d. t% s& K& p    ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
    / w+ [  C  \  u/ e8 Y, }                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );' S" g/ z( Q- {& [
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
    & |. Y; n2 h0 [% m' r3 ]                                    m_fAvgThreadTime, m_fMaxThreadTime );9 a+ n. n, E6 N6 V( E3 @$ n
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
    ; P) f% D6 N! L$ g- A    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );
    7 \- K7 V* |/ C- i7 K; w}</P>; U) w/ d) `3 y* T# ^& G

    ; s7 j& y5 C/ K+ p0 u0 Y" @5 C/ u<P>- z3 w- h3 m1 k9 ?) o
    //-----------------------------------------------------------------------------! O" n+ k' b6 W, E
    // Name: % U( x$ y4 }! w. R6 h
    // Desc:
    * y9 \) e2 i$ N//-----------------------------------------------------------------------------. X8 Z& |9 X' f
    void CMazeServer:isplayConnectionInfo( DWORD dwID )- S5 G! x4 k) `
    {" m/ [1 d% `% q: }' x5 j: O
        TCHAR strInfo[5000];1 u* J5 x! E5 o6 H6 L) Z
        TCHAR* strEndOfLine;
    % o: f2 x& k0 C4 U( _    TCHAR* strStartOfLine;</P>
    9 S" o9 |: B; V6 J<P>    // Query the IOutboudNet for info about the connection to this user
    6 S/ `# R+ _" N% `- t; u    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>9 W" Z/ A1 L8 m* c6 I" ~
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );
    + a6 i9 R% z. g2 L    ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    : S. w1 r% M2 s  r<P>    // Display each line seperately8 C9 L* |  V4 {; ^
        strStartOfLine = strInfo;
    5 u9 A1 P1 U7 q# d+ M8 }0 \/ M    while( TRUE )
    # Z7 c" c  g; [7 S+ m    {5 d- H( i1 m* |* @: Q/ B$ k
            strEndOfLine = _tcschr( strStartOfLine, '\n' );, H6 p. _/ y, }9 k0 I5 z1 P7 S; h
            if( strEndOfLine == NULL )7 Q& y* L2 V  @6 V+ Y% |
                break;</P>
    ; U' i3 d' Y; e. k9 v2 C<P>        *strEndOfLine = 0;
    1 Y3 P& r) B' `" G4 G2 {& R6 E        ConsolePrintf( SLINE_LOG, strStartOfLine );
    5 }3 s; P' b  x  U; R        strStartOfLine = strEndOfLine + 1;
    $ O- u+ F3 s# r    }# N5 E( o( k* T1 X! c; [5 m5 R
    }</P>4 x# A; N+ I3 M$ p6 X- B. q
    # x" |9 R/ C- i- m9 t( ^4 F  r
    <P>
    8 H/ l% h) Y$ B) l9 d//-----------------------------------------------------------------------------
    % V+ K  Q4 h. \: x! s, E8 E// Name:
    / Y3 d" o( H4 S5 I; W+ F// Desc: 5 b# H3 q( H& a1 {$ d; S& i/ W
    //-----------------------------------------------------------------------------
      [" Q, b* r  H( B. {# c0 A4 S0 `( aHRESULT CMazeServer::SendPacket( DWORD to, void* pData, $ E$ b( O) A  P( Y2 r8 F. ?2 I
                                     DWORD size, BOOL reliable, DWORD dwTimeout )
    4 I# B+ P8 B; D% |* i{6 S9 A; S0 s5 N6 c; ]8 @. E
        // Chance of forcing any packet to be delivered reliably( K3 T* o! \& }7 \6 N, q8 G
        if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )
    5 b# }2 S' L- b3 V4 _        reliable = TRUE;</P>
    3 T# i+ g, s0 _! t<P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    ; l6 d& U3 l9 E6 w7 @0 A9 h2 C}</P>
    $ a, I8 @0 q! B' t* g( k, U( z7 r, M* P
    <P>- j2 ]* U3 x7 ]5 N) F% w& C
    //-----------------------------------------------------------------------------7 Y5 K& B* z4 l/ `, B) v& w7 H
    // Name:
    , v4 k6 p1 A% D4 b' y// Desc:
    3 c4 l: }+ U# X2 \2 C  x//-----------------------------------------------------------------------------3 k- ]( o" L: }) ?5 l# b" O
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )
    ( E% h0 k# f8 y  A' k: O* n  Z8 w* @: |{
    + g6 j4 ~3 A8 K. r, B    // If we're up and running, then send this new information to all clients
    ; {- ~9 z, n" ~+ c7 i  h, W    if( m_pNet )
    9 o; R  J7 P+ N    {
    2 F# X# J( V1 q9 h! e        //Use the AllPlayers ID
    ; k5 `$ w9 {! {* G. K! m        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );
    : @! f5 |/ o% Q2 \. P( ]    }  z% e8 p: c( P6 f
    }</P>- q/ m, A+ [9 [8 q8 @* i
    ! r5 M( a- Z7 Z, e6 r; y/ R
    <P>
    ; E( n5 V  `1 X6 y) S) C) u8 D//-----------------------------------------------------------------------------
    + v* y2 M- ?4 U( l% V) C6 H// Name:
    7 v; w% T3 q$ n: \7 P9 T; N// Desc: 6 p. @& C9 ], V9 c3 {
    //-----------------------------------------------------------------------------
    4 f' j: ~; ~; }) A. u- [+ y0 mvoid CMazeServer::SetClientReliableRate( DWORD percent )
    ) K0 ~2 x5 u% J5 d0 [0 n$ k" ^" m% S{
    2 W& H5 t! m# S& \) o$ V; ^, M* F6 @    // Update client config, and build packet containing that data
    + k6 v/ ?2 Q" V$ o  A# X# D) L    m_ClientNetConfigLock.Enter();" W+ }1 }2 }- H3 m* H) R& ~8 E
        m_ClientNetConfig.ubReliableRate = BYTE(percent);& _& w8 O4 v" X" f9 Z* A& B4 s
        ServerConfigPacket packet( m_ClientNetConfig );
      P" z- r/ B6 u+ ^    m_ClientNetConfigLock.Leave();</P>1 H' M3 Y/ x3 ?9 T
    <P>    SendConfigPacketToAll( &amp;packet );
    6 V0 K  {* c8 W1 F4 v) b}</P>3 u  {) W$ }/ v* a+ C+ k, P
    % r3 f6 e- d  p# k
    <P>
    ; a' Y$ m5 W: D9 s//-----------------------------------------------------------------------------5 n3 M8 q3 A4 m1 M
    // Name: , s$ q3 U  c8 [3 _% A1 `
    // Desc:   J7 E! I, s6 q, w0 W( m/ c
    //-----------------------------------------------------------------------------/ T. F$ O; m/ f+ N5 C' m. f
    void CMazeServer::SetClientUpdateRate( DWORD rate )8 K; K( ~) ~6 u5 C% ~
    {
    - ?3 S$ d8 r; o/ \    // Update client config, and build packet containing that data9 F! C( ]& D" P" d. r8 n) ]+ K" W2 C
        m_ClientNetConfigLock.Enter();! n# [  `/ ~2 L- k$ a
        m_ClientNetConfig.wUpdateRate = WORD(rate);
    : \" j+ [9 K# W) H    ServerConfigPacket  packet( m_ClientNetConfig );# N' P7 D0 D. M, L2 H, U0 A
        m_ClientNetConfigLock.Leave();</P>
    $ `9 `" e) J* R: m9 {$ a" F0 g<P>    SendConfigPacketToAll( &amp;packet );
    # q# O5 A1 b5 S9 f) Y5 O}</P>! s! S; u8 H: |+ N' a) `) a# Y- P

    4 C: j* H5 w: E1 Q: r<P>
    ( x/ b: P# j$ E  X  z9 J3 l//-----------------------------------------------------------------------------
    1 V/ u& \  W( p7 a# C// Name:
    7 k0 d$ f$ V$ ]4 A// Desc:
    # Y3 n' ]; z! c1 O5 `. P2 d/ |//-----------------------------------------------------------------------------
    1 N' f/ a' o: Uvoid CMazeServer::SetClientTimeout( DWORD timeout )
    % Y6 V, v# B- P% n  G{8 }1 z  F- W, W6 ~9 X7 M
        // Update client config, and build packet containing that data5 O  l' J; z: p( R6 P' M' k: L- Y
        m_ClientNetConfigLock.Enter();. T& @* t% S& [; \( J) e3 z
        m_ClientNetConfig.wTimeout = WORD(timeout);$ X! I7 a! a+ E- t
        ServerConfigPacket  packet( m_ClientNetConfig );/ o/ z( _) b/ w* r+ _/ E
        m_ClientNetConfigLock.Leave();</P>5 f; M2 L' P% L: N9 v, r5 o
    <P>    SendConfigPacketToAll( &amp;packet );0 J4 \" |, `4 i- c$ O# s
    }</P>; H8 s" f' J  R. o% u3 {
    8 W' Q2 `6 U& Z7 ?$ }# r
    <P>% M& X# j7 q/ K3 x- p+ y
    //-----------------------------------------------------------------------------
    " J# E9 g$ Z. h// Name: ) D( ]6 i$ j. G
    // Desc: 9 l0 C; A& z6 I; H8 ]0 r8 b
    //-----------------------------------------------------------------------------4 e: w% C! E; }$ u5 ]0 p
    void CMazeServer::SetClientPackSize( DWORD size )
    , J9 I/ D. ^8 O+ \9 g; [{
    ) r" W( h* E6 x( U    // Update client config, and build packet containing that data/ |, @, N5 k5 g: v; p6 K& d
        m_ClientNetConfigLock.Enter();
    + ]; }7 R6 q+ o7 |' A$ B- F   
    5 s% b& A! |) s    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.$ g% h3 M9 O; [+ N3 R" l, w
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   
    9 U" r. e5 ~0 B5 u. ]; e2 I) Y  ?        m_ClientNetConfig.ubClientPackIndex = 0;</P>
    9 T- {( V! q# M) |2 T) C- Y<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);$ Y3 ^6 V/ z( Z4 R: z. Z, b3 Z
        ServerConfigPacket packet( m_ClientNetConfig );2 O" V* p9 v0 A' {3 ^% ?9 M
        m_ClientNetConfigLock.Leave();</P>1 S% C' U, Y# r% @3 S9 ^0 X
    <P>    SendConfigPacketToAll( &amp;packet );
    : l' T% z. B; ^; k+ b}</P>
    # |5 n6 |9 k( r/ ~5 Y
    $ [; L2 G3 t9 w* Y/ C<P>2 A  `9 V+ M9 j$ e5 ~$ j
    //-----------------------------------------------------------------------------: o# u  t' l1 K( Q0 K1 |) Q8 ^
    // Name: % a  a7 ^- J+ y7 T* I( a! p
    // Desc: ( y( N9 x9 H& Y. u9 Q7 S
    //-----------------------------------------------------------------------------( g) p; C: t4 a  I
    void CMazeServer::SetServerPackSize( DWORD size )7 ^. u; n+ {. Z
    {
    ! F( A1 q2 Q' ^3 @# U    // Update client config, and build packet containing that data
    , m% |+ W( ^% `' G9 z( v3 }    m_ClientNetConfigLock.Enter();
    6 h/ @$ H! ?* T- ~$ x    6 F3 O# p% ]' w; o/ z" s
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.
    ) o# E! o7 x: g4 [  R    if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   
    ! V! N( t& B" H" W( A# K        m_ClientNetConfig.ubServerPackIndex = 0;</P>
    & |/ [' P  t+ y* x4 p- Q2 N<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
      E- M6 a3 M: m: A7 Y: r    ServerConfigPacket packet( m_ClientNetConfig );
    5 b. z& g7 D, C! Q    m_ClientNetConfigLock.Leave();</P>
    , {$ t8 l* q0 c. b% N: i3 s  N2 \<P>    SendConfigPacketToAll( &amp;packet );
    . E5 ^, z6 {! y$ ?0 e2 F}</P>! r; G: f' G& F% p6 S; A) W: A
    <P>
    ) v9 x5 T3 N5 m5 t, b//-----------------------------------------------------------------------------
    7 Q8 U  [% i/ U5 q9 N* p// Name: ! h6 C7 \1 n" z- v3 u- b' x
    // Desc:
    . B+ v0 U: E; E3 c$ `//-----------------------------------------------------------------------------! @  `& m4 I) x
    void CMazeServer::SetClientThreadWait( DWORD dwThreadWait ); w) z/ r! Y4 I8 h# d0 W: {
    {' I# Z1 t" ^1 e1 p0 H! l: i( _
        // Update client config, and build packet containing that data
    % D7 F/ V+ w+ B( G* E4 L% O& g  K    m_ClientNetConfigLock.Enter();/ U' A7 P3 ]3 x7 k  t7 H  I1 I
       
    ( Z  [: P( A$ d    m_ClientNetConfig.dwThreadWait = dwThreadWait;
    + W7 F5 U2 z# ~    ServerConfigPacket packet( m_ClientNetConfig );
    2 w7 h, t4 ]$ H; j    m_ClientNetConfigLock.Leave();</P>
    2 w0 z( t$ B( T<P>    SendConfigPacketToAll( &amp;packet );* L# S) ]' @7 }" i- O2 O& N0 m$ R
    }</P></DIV>
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2026-10-8 07:26 , Processed in 0.343138 second(s), 50 queries .

    回顶部