QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4171|回复: 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>1 @' `4 g  O/ n" N/ q) I
    <>// File: mazeserver.cpp
    2 ^- T( Y- N! L+ f% @5 O, o//
    % T- A4 F* j/ ^$ U* T// Desc: see main.cpp6 P, a+ ?# }# ~" C4 C* `
    //
    1 p% h" l; z1 D' N8 K' J// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
    # ^( D0 @4 b; f//-----------------------------------------------------------------------------
    ) {& v/ N4 I& m: G( ^1 f#define STRICT" k$ T: u" P% v5 b" i/ U& x9 B
    #define D3D_OVERLOADS
    % W4 U% D- a7 G* w9 [1 s#include &lt;windows.h&gt;+ H( Y7 ]8 A: W/ d2 }
    #include &lt;d3dx.h&gt;7 T9 r& N2 @% v1 k9 p
    #include &lt;stdio.h&gt;7 s, P, N# D* D  N
    #include &lt;math.h&gt;- x* R7 d+ m* g; a$ H
    #include &lt;mmsystem.h&gt;8 e9 l! G2 ~+ A9 X" U
    #include &lt;dplay8.h&gt;
    ! Q8 A$ T0 P7 o5 f9 Z; c& [2 Q#include &lt;dpaddr.h&gt;- {3 R# s* y: m8 i" v' X+ o) K
    #include &lt;dxerr8.h&gt;$ I! S, G: g6 _- V- E
    #include "DXUtil.h"( |! M  c( L8 l" U% n0 e2 I1 E
    #include "MazeServer.h"  h1 _- A0 ]: f/ T: o' s( f# i
    #include "ackets.h"
    / N7 U  M% ]' t0 L- f#include "Maze.h"9 w- Y# ~2 _  v
    #include &lt;malloc.h&gt;+ T8 }. O, Y2 a
    #include &lt;tchar.h&gt;</P>* y' j9 V& M, E7 G: a& p7 a

    0 [. M  T4 f/ m/ U* ^% c<>//-----------------------------------------------------------------------------) r; R9 Q' Q* c( |5 W
    // Name:
    6 N3 |! F; X* R7 j" n4 I( W3 r! I// Desc:
    6 q- C% {& J. I3 _" ?1 t//-----------------------------------------------------------------------------( e( w9 x: ]+ v/ b7 G! g
    CMazeServer::CMazeServer()
    0 ?* ~8 s% _* L4 f/ |5 U{/ W; \0 t& j. z! z! r5 F/ @2 G
        m_dwPlayerCount         = 0;
      S& E* m- ]9 F& ~, b/ a+ E- V      Q$ v0 K8 u9 W
        m_wActiveThreadCount   = 0;
    & W( H/ c0 B1 q) M    m_wMaxThreadCount      = 0;
      S" S2 b* Q: p$ ~# `/ G6 }! B* d" K$ d    m_fAvgThreadCount      = 0;  b1 W: \, {1 H* h* u
        m_fAvgThreadTime       = 0;/ J4 f: Z! L* A
        m_fMaxThreadTime       = 0;</P>+ ?/ e' h. G% Q4 [% T- n
    <>    m_dwServerReliableRate  = 15;
    4 o) p. R7 Y. A' x. L    m_dwServerTimeout       = 150;% M6 ?/ @' v/ a9 A3 d
        m_dwLogLevel            = 2;
    5 m! r$ L; H, H: l+ R9 Q) Z    m_pMaze                 = NULL;</P>
    % U. R+ E9 Y, B& N<>    m_ClientNetConfig.ubReliableRate = 15;3 {* X- E- F6 @1 w/ O  |9 c* A
        m_ClientNetConfig.wUpdateRate    = 150;
    ( P. Z- }* |& u2 d  W- }    m_ClientNetConfig.wTimeout       = 150;</P>; a4 e: f8 F8 m4 b, V# n1 t5 k  o" x
    <>    m_ClientNetConfig.dwThreadWait = 0;</P>
    4 @# N+ N/ g/ }- d% @7 ?<>    m_ClientNetConfig.ubClientPackIndex = 0;* L4 d. x! C8 c
        m_ClientNetConfig.ubServerPackIndex = 0;
    1 f9 _2 p5 c% ~& x. i6 k; C    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)
    + `9 M7 z$ P$ E    {7 b) s1 m6 T+ j$ l
            m_ClientNetConfig.wClientPackSizeArray[x] = 0;
    . H1 F8 m! e( }2 ]8 }6 ^# g4 H        m_ClientNetConfig.wServerPackSizeArray[x] = 0;+ _9 O7 |1 d* D9 \6 D+ y/ t" M
        }
      x0 l7 @% K4 m' t. P. H6 b}</P>. U, {* I$ Y. \' R7 z& a8 c3 z( a

    5 t: i' b, B. f. t4 P<>
    ' K/ ^- D+ i: Y$ r5 u4 D  e. x& U//-----------------------------------------------------------------------------
    , O0 n* w& H1 p1 ]: R' \3 f) U// Name: ' |3 t% k- t9 o& T' G+ F) j2 g
    // Desc: / E( m5 i" R1 N/ X
    //-----------------------------------------------------------------------------
    9 X# H7 d; A, p0 c0 M/ IHRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )/ r. i' f* Y5 i3 W% \+ x
    {
    7 K2 T% }3 \$ s5 |* H    m_bLocalLoopback = bLocalLoopback;
    6 |1 k8 Q6 v6 R    m_pMaze = pMaze;' d1 N- o7 i0 B* ~6 |  n
        if( m_pMaze == NULL )& p4 F( t$ {2 v% F. J8 o. a* X
            return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
    # Q  A! ~8 }/ O% G+ p" k3 M5 ^* j/ [<>    // Grab height and width of maze& x* Q1 w. ^/ W- x7 ?
        m_dwWidth = m_pMaze-&gt;GetWidth();( s( N5 M; u! _' {1 x
        m_dwHeight = m_pMaze-&gt;GetHeight();</P>( p0 R$ j* O, S9 Y
    <>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    ' V7 W/ E- k, O: e' Z& Z    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
    " N, |7 a7 k) j' Q7 X8 Y. C<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.
    6 J7 b+ A# ^# o- n+ T* o  }7 ]- ^8 S. V    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )( k" J7 p' P! v
            return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    0 _! V, \  r- ?    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )- ]( e* r! `* {
            return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>! v* p5 i, ?! }4 p7 S, F( U/ M
    <>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;) v/ Z+ r0 x* E9 ~
        m_dwMazeXShift = 0;
    ) Q* r3 N" Y% b: \    while ( (scale &gt;&gt;= 1) )
    ( c0 F  u/ o- k6 w        m_dwMazeXShift++;</P>' v7 i6 s4 }1 H# b+ B* A
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;$ n3 v! z) q* u/ x; D& s
        m_dwMazeYShift = 0;: f* \0 y) y4 t8 u/ k/ c
        while ( (scale &gt;&gt;= 1) )
    : Z) j% r4 P- }" K1 K9 c        m_dwMazeYShift++;</P>$ l. y$ R9 i, C5 e* d
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    - f1 h" G5 p0 X$ ^& t8 |        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )0 U1 I7 d/ o. r' _' [1 Z
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>" `. Q7 @/ v/ _, C
    <>    // Initialise the player list
    3 b* O0 h' u* F2 M    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );
    4 c( k' B1 a" d    m_pFirstActivePlayerData = NULL;
    . `6 b& z( n6 s9 O    m_pFirstFreePlayerData = m_PlayerDatas;
    5 v4 U) I' y/ w' u2 m9 z    for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )
    / F4 r9 z' ?: s1 L' K    {; H* r) {4 w; }& g$ N
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];, g+ X/ M4 z( U2 }) S" {+ ?/ T
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];, ?% q9 Z3 k% g# L" \# c
        }</P>; W) D  ~2 O1 R0 x  c: Q
    <>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];- P. x1 L+ M0 b( T0 ?, s
        m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];
    / V4 G. r; k- i$ [! _& A  X: f    m_dwActivePlayerDataCount = 0;
    ( E' v  J2 J4 V, r8 V4 U: B& H    m_dwPlayerDataUniqueValue = 0;</P>
    0 I0 ~" C. K3 R1 u( c; B1 T<>    // Initialise the cells
    $ A2 `9 o! q4 z' J# _# C; e    ZeroMemory( m_Cells, sizeof(m_Cells) );
    1 n1 b) u! \+ k3 P3 X7 z1 k. _    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>
    : l5 ]. }* ]0 @  L<>    return S_OK;$ p+ F6 L- _+ p9 o' [
    }</P>
    / g, W0 \3 h3 \2 r/ Q5 r9 S
    8 J7 ^* p& P, C% R<>
    ! i' V' w' l  v/ W- t//-----------------------------------------------------------------------------
    % @8 c5 y( @& T% K// Name:
    3 [  T" ~4 D$ v* H$ P// Desc: & F2 N- a- s" c- j* k2 w4 @" i
    //-----------------------------------------------------------------------------
    ) G0 D5 K+ L; r7 S) t# ivoid CMazeServer::Shutdown()
      M' q9 r$ Y7 R9 i{
    ! A! v1 j$ ^$ W& M  W}</P>
    - a' ~; n( I* E1 D' T% D7 P+ A4 s% e1 Z8 G. W
    <>
    ! i. j9 J  {% d* s3 i; |/ ]( ~# A! Q//-----------------------------------------------------------------------------
    " {% n: Y( e4 y: W// Name:
    , Y" N+ m+ c# B0 C4 }5 S) m// Desc:
    % K+ y/ V/ f# k2 R. x//-----------------------------------------------------------------------------2 G8 \( y; h# d$ i: E" U+ w6 O
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )# c' W* B( }4 p7 ^$ I
    {
    , O, f- K. V0 \( F+ S    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    9 W5 e& m: Y3 \! G3 V1 M+ y) i                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );8 b2 `" u" y6 t0 V. r- r( o
    }</P>
    % q8 [) x# J) E2 N
    6 r/ Y$ f) P+ H* B<>
    1 E- B6 R: e3 s# l) t1 ^//-----------------------------------------------------------------------------, Y- I2 Z' q9 M; A/ H: m- l
    // Name: ( A, x3 O$ {# G* Z0 B0 i* \- L. ^
    // Desc:
    ) z1 S" q9 A9 u# y4 H: B. {//-----------------------------------------------------------------------------! H: W  q+ i+ `. D4 t# T
    void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    & a  F  ?" ~$ e% y/ g) G/ X1 J{$ i  b: E2 L2 W1 F- \  k/ c( ~
        m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,+ G" P& k7 p. _$ s9 g
                                x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    , r; ]" l% u/ V2 S# A  g3 j}</P>9 i7 n# w+ E# ^* L; |
    / y: G  M. L7 h; R
    <># H3 `. N6 f( r& A( z5 k
    //-----------------------------------------------------------------------------5 Y, l2 `$ l" E# a1 a6 }0 T) t! q
    // Name: $ v. u/ [' U' p- K' P" ?+ k
    // Desc: " p* r7 u! B* h- L! O' K
    //-----------------------------------------------------------------------------5 a  U" R6 S8 ?! J4 N
    void CMazeServer:ockCell( DWORD x, DWORD y )( m9 `; ?! i) c, `& W% _
    {
    $ A& o& ~. |1 B! ]8 G    if( x == 0xffff )
    2 v6 B7 h, J" w& a$ c$ Y        m_OffMapLock.Enter();
    ! L# Y- B" G! o" U- E; Q# r    else/ k" D8 F* d: i6 o3 K
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    5 J. `* E- L/ `* h}</P>
    - i0 z# O3 y' Y9 U& H6 m* o
    0 k4 |3 P& Y2 ]; Q! Z<>
    & n. {/ k* u# w9 T% i8 x+ L# _//-----------------------------------------------------------------------------; s9 @( j( G* I' Z- N% }1 R
    // Name: ' r. V  e7 d# N2 L. F: f
    // Desc: / n: \, {' e7 m9 F( d
    //-----------------------------------------------------------------------------
    2 M2 s8 J; w' k: Ivoid CMazeServer::UnlockCell( DWORD x, DWORD y )
    1 t$ c2 v$ S2 f9 y& F+ U+ e{
    3 W# r9 P! G( x$ m7 u& R/ a& {    if( x == 0xffff )4 X: x* Y' |6 O; B6 j
            m_OffMapLock.Leave();+ I7 l8 d% a7 p, ~, _% B
        else
    . I/ j0 u& [, _5 S  o        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    1 E. F& K+ ]* c4 B}</P>
    ! x7 Y, i1 V0 d
    / e+ Y; C1 f2 d) ]1 x<>- Q( ]6 U6 r9 F6 `3 Z
    //-----------------------------------------------------------------------------
      ]$ R- F0 W5 \/ x; ?& m// Name:
    5 J$ k# }9 o1 e* z9 i6 k) `) d// Desc: 4 w& B# y; l6 M! T
    //-----------------------------------------------------------------------------* q1 Z1 H' V6 G1 _6 ?2 p( d
    void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    " I; z2 J5 \1 G  c3 Z/ r7 K+ ^7 p6 o{
    ' A& f4 E0 I* M  ~    if( x1 == x2 &amp;&amp; y1 == y2 )
    5 F1 [0 v4 Z/ C6 n& ]; ~" @    {
    ; h6 f: }1 _. `$ m2 x4 c3 ~, x        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )+ V: D% p5 M3 S" j- I0 e$ f- Z3 H# j
                LockCell( x1, y1 );
    + a$ `% }2 a2 }        else
    ; N* l% Y# K  q1 i            m_OffMapLock.Enter();</P>
    ) x& p) f  r* s, T) J/ Z<>        return;' l" N$ N6 x! i) J$ p
        }</P>
    0 i6 u6 b( E$ g1 N( f; c  d- F<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;- m: R7 Z7 a$ X' x
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    3 @/ _  U: E' v9 T  K, k- l: C    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    , Q8 f  D& U  n4 F    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>* A, E4 d. n- K* D
    <>    if( x1 == 0xffff )% D: T2 V! R7 f6 R
        {0 K7 K3 ]7 n; ?+ o/ c( {
            m_OffMapLock.Enter();
    - {% @0 _& q7 l& z4 l$ F9 _6 x6 z        m_LockGrid.LockCell(x2shift,y2shift);
    + e9 P! @9 ?& K4 m' ]4 t$ Y    }
    5 G2 V( H& w1 E4 F3 f7 V    else if( x2 == 0xffff )! s' x, ~/ ~! @4 I
        {
    9 C1 j2 \! n4 j        m_OffMapLock.Enter();5 S' U; d$ d9 u1 r9 m" {/ Z6 x
            m_LockGrid.LockCell(x1shift,y1shift);2 Q8 V  p( a5 |$ [# K
        }7 E9 l5 U0 e" u3 X9 Z+ |3 L4 E
        else 8 e( g( ?; F: l; ~+ @' t
        {
    6 Y6 r' X; F( Z( p$ X        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);8 w% ?3 H* z( |& n1 o
        }/ H. Q6 E. X( o3 G5 F
    }</P>: e$ S  P( r5 {: K- k

    8 P( s, K2 i, ?3 W<>( s' p# R: A6 @) z: A+ w) E
    //-----------------------------------------------------------------------------* T# g, @! L. X5 y; d" h
    // Name: ! \* ?. _% n/ I$ G2 g' G' z' [
    // Desc:
    0 ~" F3 T# G! X9 b2 L" E1 n//-----------------------------------------------------------------------------
    & D8 u( K  U+ s% ?/ L! B& ]" d" Wvoid CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    # }5 c& A8 N& b{
    8 p7 T5 b9 u! p' ]! f    if( x1 == x2 &amp;&amp; y1 == y2 )+ h* {4 T9 I* @; X4 e7 |1 N6 x
        {( q! L, s3 j/ w, w4 J* L3 P
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    ) }+ [* e. c4 a2 L+ m9 O  B            UnlockCell( x1, y1 );0 {+ Q4 @% w9 g8 {: z, a/ K/ _
            else
    * G( o$ F/ g# \            m_OffMapLock.Leave();</P>
    & L0 l! A" G2 q; B3 p* P1 U<>        return;
    # w: H" e. l( T' d/ P+ l0 S    }</P>
    2 C  \. q( T0 i4 B+ S<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    % g0 z* z4 d$ W. ]    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;/ N, h6 W' I. t
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    9 Q# M: Y5 |8 k& _* v8 y    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>$ d% }, h4 B* {  W
    <P>    if( x1 == 0xffff )
    % e: B2 x6 m5 S3 F    {7 H9 F( `$ U1 [8 M4 {, v! q4 F5 m
            m_LockGrid.UnlockCell(x2shift,y2shift);
    8 E# x- V5 K/ ?! G        m_OffMapLock.Leave();& a/ h$ m9 r% w4 c5 e
        }4 V# P& n9 _4 y# [! Y7 j
        else if( x2 == 0xffff )
    5 G/ T" V* `) ?" ^    {
    % K# i* g8 l; I        m_LockGrid.UnlockCell(x1shift,y1shift);+ G; C& [: T; @" B) p
            m_OffMapLock.Leave();
    5 ~( _/ K! }% Y: |! f3 k# G    }
    1 z& d  G# _9 `  Z% n- N- y    else 1 P( {1 h$ ]9 m2 l3 V
        {
    1 T7 _2 F( A# @1 A4 V& l5 A        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);! q8 }" D/ X$ G
        }
    + }% n; o- k, Q% Y}</P>
    # \( f  M  P/ b8 e& d
    . y" M" k# b4 _$ K( s3 h% Z<P>4 E6 w" U* ?9 m* l( Y: ^4 |5 V8 ~* I9 N
    //-----------------------------------------------------------------------------
    8 K7 V# d5 Z$ _( H) t& V// Name:
    + j2 ^3 z. l* Z/ q) D( }// Desc: . }4 n8 Q0 l0 d3 f. |, r
    //-----------------------------------------------------------------------------
    % E: c! q1 T' g7 T# E' _: ~void CMazeServer::OnAddConnection( DWORD id )9 t3 z5 I* K' D3 n
    {( ^1 V. ~% s5 `; [# }) L* J
        m_AddRemoveLock.Enter();</P>
    : K) R5 _' D5 a- Q) T<P>    // Increment our count of players4 s5 z/ }& e1 A& U& W/ A
        m_dwPlayerCount++;
    2 `+ ^6 R0 P: k2 a  H) Z    if( m_dwLogLevel &gt; 0 )  V" U# D5 d/ N% P# ?2 Y1 B* V+ h
        {, m; n# w6 `0 g6 o) n5 F
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );9 n0 w9 w) u7 v7 j4 k
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );+ L! a$ g( ?6 V! N% j& Z1 s: w
        }</P>
    % c5 Y0 |3 [3 b3 k<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    # |4 r# a: b8 O  @        m_dwPeakPlayerCount = m_dwPlayerCount;</P>/ `) T) G: j# V8 g2 ?$ k
    <P>    // Create a player for this client8 ]5 v/ F) c( s' J4 _4 F7 E
        PlayerData* pPlayerData = CreatePlayerData();; x# ^4 N7 F- i6 `) [8 ]
        if( pPlayerData == NULL )
    ! _' g" ]" W$ o    {/ B1 {9 C* _. a# A, v4 a6 K! s
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );7 i1 X* w, m1 D& u/ l. e
            DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );
    ( y; Z  N; u" Y7 d7 g6 z1 i) B        m_AddRemoveLock.Leave();, s, k2 ?1 W# m2 F! l
            return;
    ; n& v8 `, T7 m  w9 n6 i    }</P>
    7 L1 ]; |1 y8 h* x5 a; z( W<P>    // Store that pointer as local player data
    ! D: y8 u9 J: d; t; }& \    SetPlayerDataForID( id, pPlayerData );</P>1 ~, m0 ]6 u" g3 a; x
    <P>    // Grab net config into to send to client, P. q: w3 ]; K0 k$ k8 \" L! e
        m_ClientNetConfigLock.Enter();
    2 c! U2 n  U/ Y! ^# I    ServerConfigPacket packet( m_ClientNetConfig );! Y/ X, P: X4 S5 |9 u9 ?. x1 H9 \
        m_ClientNetConfigLock.Leave();</P>8 A6 Q% K5 A9 k- |
    <P>    // Send it
    6 v$ b! S% z, d% _/ f+ ?    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>+ t% @0 y' [/ c! {; _1 \6 e
    <P>    m_AddRemoveLock.Leave();
    + t2 {! B9 g1 s8 X% l}</P>0 R8 ~( d7 b& N% F/ k1 _$ K# d

    1 b5 E0 N" s  j' p2 Z  J1 D. R<P>* C7 v9 W+ }/ L9 i( {; m2 n! x
    //-----------------------------------------------------------------------------1 e0 j8 D* N6 {/ G
    // Name: 7 H5 o( K. ]$ A
    // Desc:
    , @( D" p- d% z/ h0 |//-----------------------------------------------------------------------------+ X. e# `0 \; M" ], v% ]! y
    void CMazeServer::OnRemoveConnection( DWORD id )$ L; v( [4 V- B+ k8 F
    {  V* _) q5 B, F) ~
        m_AddRemoveLock.Enter();</P>5 g: m7 |+ i  Z% x. M
    <P>    // Decrement count of players
    3 d; e9 |% \3 C    m_dwPlayerCount--;</P>9 W5 J3 Y$ I( ~
    <P>    if( m_dwLogLevel &gt; 0 )4 c; `/ X+ P- ~
        {9 {! q" m, o2 d9 G9 p0 }$ W* n
            ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
    5 v, W6 i- a6 w        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    ; j: Q! y* e8 d) X+ y: z    }</P>' H3 j% |, n! b+ j- K0 A" n
    <P>    // Find playerdata for this client
    8 w. ~$ ]+ t2 U/ Y. \    PlayerData* pPlayerData = GetPlayerDataForID( id );
    & j+ e- M, H; r& o# k+ `7 W    if( pPlayerData != NULL )
    % ?8 l9 X3 q2 t% o1 ?) w1 V9 B9 B    {
    / n+ C1 Y! P' e5 V3 {        // Destroy it3 `& L; _/ U' `! Y' R
            RemovePlayerDataID( pPlayerData );+ {+ G/ w) _8 I: C8 y! r2 d( B
            DestroyPlayerData( pPlayerData );
    1 O0 u& i+ b9 n5 q    }</P>3 Q( X$ l: m4 p" C+ a
    <P>    m_AddRemoveLock.Leave();
    - y& J5 t! P; D; Z# a}</P>- e( J0 f0 P" h

    8 E9 f  I+ A7 H% {) F<P>
    " Z/ ]3 u: _- p2 `/ T* }//-----------------------------------------------------------------------------, T* q0 O! ]& o  x
    // Name: $ s. G$ M7 @6 p- G4 o6 G
    // Desc:
    ( T1 Q' a& c3 h' o' ]% F% ?! ?//-----------------------------------------------------------------------------
    6 F6 V. A, L3 O6 JHRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )
    " d9 _# `; w# }3 y6 U+ V{5 M, v! G/ u4 `9 B/ r) n! {
        BOOL fFoundSize = FALSE;</P>
    4 w- Y- Z3 G# I4 H2 E0 g* F  P+ E<P>    // Increment the number of thread we have in this process.
    6 K# J4 `/ p2 m- q    m_csThreadCountLock.Enter();</P>
    1 S# W3 d* B; f* L! s<P>    //Get the start time of when we entered the message handler.5 E* `( a4 N  H, B& }, Y# t9 f
        FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
    : M7 g- n. X  L; ^, E% ]; O2 N<P>    m_wActiveThreadCount++;
    9 X5 K8 I  N3 @9 V7 q% i: x: e    if(m_wActiveThreadCount &gt; m_wMaxThreadCount). l( \* k( O7 u( {( |
            m_wMaxThreadCount = m_wActiveThreadCount;
    # v$ C4 y+ _- Y# N# Q2 n   
    , a* V7 k; I/ }) U1 o6 g* F$ N6 |    // Calculate and average.
    * |: u1 c5 U8 R4 m1 W    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
    * w0 [( Z8 ~4 e, D: u& B- N7 j    m_fAvgThreadCount += fdiff/32;3 g9 Y+ T$ g% c3 A
        1 X+ d2 z: f$ D/ S( B3 t8 Y
        m_csThreadCountLock.Leave();</P>
    $ e$ y* p2 {. a9 U1 O<P>
    7 }6 v8 `) o9 D0 C    ClientPacket* pClientPack = (ClientPacket*)pData;
    " L0 _1 s" H2 l) R$ H    switch( pClientPack-&gt;wType )' ~$ O' z  G' r4 `2 g
        {
    4 N% j8 q6 |  P, `5 \$ s0 n% d  i" T        case PACKETTYPE_CLIENT_POS:; W* [$ o4 r- I0 F
                
    / @) B8 ]7 S& z- N8 s1 `            // Check to see if the packet has a valid size. Including
    ' |7 `* A9 V* Q" e( h            // the custom pack size.+ P( {; O* X% {
                if( size &lt; sizeof(ClientPosPacket))0 B4 ~9 m5 ~5 ]6 [2 q$ A1 y! Y5 Y. p
                    fFoundSize = FALSE;2 X; U, j9 s) r; A8 U
                else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))# n! M! v/ \4 N+ \3 w' u5 }( k+ e1 r
                    fFoundSize = FALSE;. b. p0 J# |) o' n1 |( ]# |4 x! y$ D
                else
    ( `7 p+ a# q4 I/ C                fFoundSize = TRUE;</P>
      J$ v, ^" R8 C$ h7 _<P>            // If valid sized packet, handle the position.
    $ W& m: f5 h! K3 Z; n            if(fFoundSize)- a# L$ d6 q. Q6 T& X" c+ X3 c
                    HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );8 ~/ D8 H* c- k: _  _5 I5 |
                else
    0 ?5 m3 o5 `1 m, r                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>3 m- z9 f4 e! i, ]& g+ T
    <P>            break;</P>
    - W' ?5 b1 M& U4 A<P>        case PACKETTYPE_CLIENT_VERSION:" B% ]5 j% g, {
                if( size == sizeof(ClientVersionPacket) ), h1 K( p9 y- _6 W8 K! e$ `! A0 s
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );
    # Q, d$ d5 e  Z& R            else
    ; s5 S* C2 s2 E& P! u                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );6 U& E7 A7 ^2 f2 q! J
                break;</P>  M3 f# A' `0 J" m" c: c, s3 |
    <P>        case PACKETTYPE_SERVER_CONFIG:</P>
    ; \% l4 C2 ~0 T5 |7 h( r; M4 T6 r6 E<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>/ ~/ C9 l* Z. p: s' v
    <P>            break;9 ~/ {$ m: w# [
            default:2 R- A$ m. g( G$ @; d& x6 f3 p" v# P0 P
                HandleUnknownPacket( dwFrom, pClientPack, size );  \# r9 R, T, [6 t
                break;6 h/ t2 ~5 Q; \
        }</P>& L/ q. e1 q! G
    <P>    //If the user wants to hold the thread, Sleep for given amount of time.% s! i7 Q3 E$ r. S
        if ( m_dwServerThreadWait &gt; 0 )+ Y  @& X/ V5 z! f
        {- B3 Y5 ], g/ Z, X% t* ^
            Sleep( m_dwServerThreadWait );( I( ?7 m  B3 a
        }& L8 ]* U6 C' x0 Q0 l/ A1 L
        " S$ G/ k  f+ @- R; s( t- w
        // Retrieve thread data for this process.
    0 z. N0 r! M" b( p: P+ p    m_csThreadCountLock.Enter();</P>
    : D( |  j% \3 i* F  X5 `<P>    m_wActiveThreadCount--;</P>
    2 r! b& L3 K$ [% |# H2 @: l; T<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;. r+ z6 X" r) P; Q
        m_fAvgThreadTime += fDiffTime/32;</P>; Z, n* A6 I8 x; v5 d
    <P>    //Get the Max time in the thread.
    / [( b- {2 [+ t- Q* r    if ( fDiffTime &gt; m_fMaxThreadTime )
    % i! X2 ~% L5 |; D% D0 |9 N    {
    6 z/ M+ f+ T. w1 N" z        m_fMaxThreadTime = fDiffTime;
    / M0 z. ]$ [) A" C. ~5 Z    }</P>. Y9 k) f; a" p" h. o$ ^( Q2 J
    <P>    m_csThreadCountLock.Leave();</P>/ ?2 _( v% n: s/ L# K
    <P>    return S_OK;
    % g3 i: n+ V/ J2 @}</P>
    / ^5 i% W7 `" V- l. Y3 @! C3 |  G" d: O$ m
    <P>//-----------------------------------------------------------------------------+ a2 y, d( C" T
    // Name:
    8 Z- v7 A$ v7 d& w// Desc: , ^7 G1 d9 V" ?6 k0 [2 v4 m
    //-----------------------------------------------------------------------------
    ! m9 ^( L8 E8 e8 ]4 y; c1 c" eBOOL CMazeServer::IsValidPackSize( DWORD dwSize )1 o% i; V. I2 U( `- G
    {1 p! a- {' i0 t' {- h  G* L+ {! T2 [
        BOOL fFoundSize = FALSE;: I$ p& |/ x* i' z% p
        BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;! R8 N8 i) [+ s/ ]& [
        6 b3 N# R2 ^0 L! F* E2 u* S4 n
        // Check through the array of valid pack sizes.& O" q- e' Q0 R7 X6 a6 z- R
        if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    ! m0 j7 y: _, l- }0 q    {
      N2 w9 s/ u& `( n+ W3 M- z7 [        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)/ L, o- L2 s  m4 h. u6 w9 S
            {) D1 B" U; Z* ~& w$ L
                if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])( i7 p3 Z% Q. x. g1 Q# l
                {" f9 g) p/ E- C6 Q; i  Z" `. a! J3 _
                    // Found valid size in the array.
    ! R- D9 s( B' @- \2 `, v                fFoundSize = TRUE;
    6 T/ X; U5 j4 d- c                break;8 }# i2 @! j2 t2 d0 I3 J- h
                }
    . J% \) a3 }8 v- M  X            if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array." v, c  u. D( \2 V
            }
    ' _& e5 A, y; C& G+ l    }: a0 o0 R. l5 E  }- G: J
        else
    ' x! q, \0 ^0 z3 {& X3 [' u+ e    {
    ) B: O! u! f! ^5 K: j5 j6 K        fFoundSize = TRUE;* k" C" n: t! k/ g5 n2 A, [1 J5 i
        }</P>% g: C! r# d7 n( w& M, y
    <P>    return fFoundSize;: M: c) J5 m% b& a+ K: R) S% w
    }</P>, B4 s0 S. ~7 Y
    <P>1 ~0 ~7 X" C2 N/ z; q# l5 b1 U1 U+ _
    //-----------------------------------------------------------------------------
    * K6 J1 |! _4 T: `9 [// Name: 9 ?8 c/ O- j1 l! a' q2 C- b
    // Desc:
    3 Y& p. r( G( j( T! P+ E//-----------------------------------------------------------------------------5 E  b  {& n& S: n7 l: L9 H
    void CMazeServer::OnSessionLost( DWORD dwReason )& R' T( ?- _3 m0 r
    {
    3 i4 V4 {4 o1 c: _    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
    * X2 k' G, c. z6 B5 X& g! n}</P>6 g3 t7 n& t' Y7 k; a
    7 R$ `3 I. t) ?% R
    <P>2 N$ x! p5 q% e0 V" I8 \% ^5 M- p
    //-----------------------------------------------------------------------------1 ]4 Q3 z, w4 o. z/ Y* |
    // Name: . P1 V& R6 k6 Z7 M7 S/ P" H
    // Desc: / R  f3 F- |) C4 g4 y5 ]
    //-----------------------------------------------------------------------------
    ' Z+ c* r9 H. c: E0 q" S% CPlayerData* CMazeServer::CreatePlayerData()/ B0 k) a4 v7 W
    {" G  M8 _' g4 c+ k8 c$ N9 N! r
        m_PlayerDataListLock.Enter();</P>
    ; y' m, m8 P0 ]- N<P>    // Grab first free player in the list  n! m2 X- l, K( l
        PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>
    ; o6 H& V9 m5 b+ ?8 e<P>    if( pPlayerData )7 [4 P8 ^1 a* t; Y1 E
        {, [: \7 w8 \6 |- G; S
            LockPlayerData( pPlayerData );</P>1 t# z5 m! W: t3 s7 B
    <P>        // Got one, so remove it from the free list
    % O( [' H- w  B" T- c        if( pPlayerData-&gt;pPrevious )& S# ~, u& ]* l: ?" m
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    5 T, ?  {0 v* R6 |        if( pPlayerData-&gt;pNext )
    ' a- V/ A0 i8 z. M" J. X. [3 G            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
    5 `9 Z$ W5 W' r; C+ R/ ?2 `        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>+ _/ i5 }. Q; C3 U' D$ s3 f! d% z
    <P>        // Add it to the active list8 E' Y: r7 [* @9 u% G  O
            if( m_pFirstActivePlayerData )
      c. ^& C$ H: _! R" |/ [            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;4 E$ N" m% y& ]- X  C
            pPlayerData-&gt;pNext = m_pFirstActivePlayerData;
    & Q0 g; k6 A; W2 s6 I        pPlayerData-&gt;pPrevious = NULL;7 ^% t+ V& E1 K9 Y" V* o- k& @
            m_pFirstActivePlayerData = pPlayerData;</P>' e  d# r0 t' R% t
    <P>        // Update count of players6 u7 a7 V# z6 w* |5 e
            m_dwActivePlayerDataCount++;</P>% J( R9 L6 Z4 e7 a8 Q$ x# X
    <P>        // Generate the ID for this player
    : {# R0 l( j) y. L/ [! T        m_dwPlayerDataUniqueValue++;; G' G  \5 s5 ?1 A
            pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
    ! v. L- O3 n# }: D2 D% S. c<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;2 z- P9 u; b0 q/ f6 Q* m( d% B
            pPlayerData-&gt;NetID = 0;
    & g1 P: w6 r+ y. O2 X( p2 H        pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>' o3 ?4 c0 ^$ y- B0 C
    <P>        // Insert into the "off-map" cell: i/ ~1 }( ^0 z0 L6 _: m! A
            pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;
      h4 Y( B! q+ D# T        pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;
    : |% W; [8 x7 q9 @& w" o        m_OffMapLock.Enter();
    0 d* J  j" ?8 O6 u! B( G- K        pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;
    1 w* {  L" d3 @: ]' U( Q% ]        m_OffMapCell.pFirstPlayerData = pPlayerData;+ \% l; R! M- `7 E# o# }
            m_OffMapLock.Leave();</P>2 W3 ]/ ?  K1 ?* n+ ~3 z
    <P>        // Mark as active' U2 ]/ R! O4 K/ x4 F
            pPlayerData-&gt;bActive = TRUE;</P>
    # T6 [7 q" u  L<P>        UnlockPlayerData( pPlayerData );
    8 m1 B; o9 h  F8 t    }</P>* N* I9 K; r' t7 e0 R- P) M
    <P>    m_PlayerDataListLock.Leave();</P>* l6 ?( D; e0 h. _& F
    <P>    return pPlayerData;8 R  C5 P0 H5 C6 _, c- @& z
    }</P>' _- N9 o% M! ^5 n: h$ B1 ~

    / l; ~9 L: z5 J0 A+ `0 t0 S  r<P>0 h1 y. F8 q3 I
    //-----------------------------------------------------------------------------7 f: a5 U% _( Q7 e/ m
    // Name:
    + h. R0 V. L5 E; K7 H! e// Desc: , b. P; j" [) u; D! i
    //-----------------------------------------------------------------------------9 L9 m5 H3 d  S) H# q
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )
    / }) S5 r' D: V# i' j5 a{
    - S8 P/ C" E$ M& m$ x' B, O    m_PlayerDataListLock.Enter();( [, }& T- r' F2 W' H
        LockPlayerData( pPlayerData );</P>9 l' u; M. n% g- h  N& E
    <P>    // Remove the player from its cell
    : g; i& J1 a9 e' V. x: ], S    RemovePlayerDataFromCell( pPlayerData );</P>
    0 |3 K) q; t+ X7 a6 F. a7 d7 B<P>    // Mark as inactive
    5 [1 @- A. m" p% u+ g9 j7 ]* R, q    pPlayerData-&gt;bActive = FALSE;</P>
    / b  U, U7 O+ o* t<P>    // Remove player from active list! Q0 l2 {+ Z' {7 Z
        if( pPlayerData-&gt;pPrevious )3 l: P* |9 c& M4 h& y: S
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;5 `) g. ~1 R0 H: {1 _
        if( pPlayerData-&gt;pNext )* X8 a* t" n  d
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>  m- N& D8 g' i; P
    <P>    if( m_pFirstActivePlayerData == pPlayerData )
    0 _# m* [  v* f# T9 {        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>
    " f" M( V: K% c<P>    // Add it to the free list
    & N/ f4 h( o: ?+ F    if( m_pFirstFreePlayerData )
    + A4 P) z+ i8 Z* l        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;& u) `3 G$ M6 n* R! U! w0 Z* b
        pPlayerData-&gt;pNext = m_pFirstFreePlayerData;
    , x& q' S* P( b. o3 y  s% Y/ f    pPlayerData-&gt;pPrevious = NULL;$ @; P" x0 Z6 [/ b/ o+ g! M$ a7 B
        m_pFirstFreePlayerData = pPlayerData;</P>
    / ]7 Z9 G. V5 Z/ j<P>    // Update count of players" d7 S0 ?' E' a5 ^0 a
        m_dwActivePlayerDataCount--;</P>
    ; O% A" }* A! f4 H7 q" D6 g<P>    UnlockPlayerData( pPlayerData );
    % |0 T% V. c) }/ {    m_PlayerDataListLock.Leave();
    ) |% t, _7 i+ p}</P>
    8 j/ x& P6 {; Z' I1 h) Q% m8 c& @, I
    / S* \8 b* a4 G, [' G/ Y1 f: T" @9 R<P>+ J9 m0 r( l4 I' A  j! j; g, V% k1 D
    //-----------------------------------------------------------------------------
    ( q1 T: I( ^! J) f+ w# M" q// Name:
    - B( U3 X, j+ H  t  ^- w// Desc:   V6 Y5 Q6 G2 Y) Z( R9 C
    //-----------------------------------------------------------------------------
    8 h0 [6 L5 [* K9 ]void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )( k& H2 P" V$ g' W
    {4 V. p  V( }0 ~3 l- q( a
        // Lock the player
      Z/ d6 \9 a. I' P  \3 |! k6 n    LockPlayerData( pPlayerData );</P>
    : V, x" x/ [* ~3 Q- ~<P>    // Lock the cell the player is in
    + @6 X$ k- v$ q    ServerCell* pCell;
    7 ~+ l: U. [& T- L3 p! n' t, e+ @    if( pPlayerData-&gt;wCellX == 0xffff )3 _) o9 Y" g, Y7 ^; O
        {5 v1 X3 T4 G# C4 D1 }
            m_OffMapLock.Enter();3 X% T" V, I- w9 F6 P6 X! M
            pCell = &amp;m_OffMapCell;7 _0 p3 D+ f% m$ T$ \
        }: f; X6 v4 q  u, d/ k6 o
        else
    * E/ p. y2 m( M/ \    {+ H5 w* _* r# X: c- m* @# U
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );) }4 {, J! b9 D' r- |8 E. `0 q2 L
            pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
    / s6 v$ ~8 ^3 ?8 ^2 i    }</P>$ j. i0 e4 u( f
    <P>    // Remove it from the cell
    + l0 \& E" d! O, C    PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    4 m" |# l7 P( ?0 T, o( u2 Z    PlayerData* pPrev = NULL;
    6 Q+ `$ t" T0 Z. b1 m    while ( pPt )
    ) H. m$ q! M4 v4 O    {: y: ~- w6 G0 t$ U. F
            if( pPt == pPlayerData )
    3 J% f& m6 p5 P# Z1 |2 g        {) c1 m& Z( d) E. T1 K0 f1 X0 Y. E
                if( pPrev )
    6 K: a, @3 B" ?% Z' j$ p) }                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;4 B( \6 u% x: c) K! a' T/ ]
                else
    - \' }1 [" D# J  o5 U* Q3 ^                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
    8 y! T0 Z, ^) S<P>            pPlayerData-&gt;pNextInCell = NULL;( i5 w# O' D; c6 D1 I8 x" M
                break;
    4 `8 a( Y7 |6 K& o3 F0 O0 R* `# D        }& {, s; m7 w3 \, J, f" s) N+ R5 J
            pPrev = pPt;4 o2 G; o9 t3 V/ @8 F6 a( Z
            pPt = pPt-&gt;pNextInCell;( E) @- D: N7 ]( `8 W9 h8 g
        }</P>! U; c  x1 a& K  P- [
    <P>    // Unlock the cell& r) S) C8 r8 X4 P4 ^% U: }
        if( pPlayerData-&gt;wCellX == 0xffff )! c2 {+ [( z& _2 n) k* f5 S! D9 X
            m_OffMapLock.Leave();
    ( n* E' M  ~2 h; B6 J1 s( ^    else& U1 j% r. c, u5 }" E! I! J' {$ o
            UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>- k3 c) j/ ~1 I) ?2 R* Z9 g
    <P>    // Unlock the player
    5 p  O% U* G3 }    UnlockPlayerData( pPlayerData );% m0 a0 Q9 l5 F1 g$ o( X6 o5 u' ~
    }</P>0 o$ L# @' G5 u. O
    . E' a5 w+ X; k' }' f  M0 m3 Z
    <P>: W! r/ a  B- Q' k1 T" F
    //-----------------------------------------------------------------------------6 I7 r0 H, G+ J! v. F' g
    // Name:
    7 Y8 y! H2 l; F+ S, f& @# H// Desc: " X+ `. Z. x1 z' l+ t! G
    //-----------------------------------------------------------------------------
      ?; {% n6 f0 Y, s- Lvoid CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )4 ^/ h1 g0 P9 b  j6 j
    {
    & h3 q5 H4 c. ]" j2 e0 t  v    ServerCell* pCell = GetCell( pPlayerData );0 @: P0 d0 N" E: v. Z0 q
        PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
    / O# N8 F# S9 ]    PlayerData* pPrev = NULL;
    % Q! U( m" Z* c    while ( pPt ): R  Y- \- V1 _3 e
        {
    ! k, l( M& O% L4 c+ m+ B        if( pPt == pPlayerData )
    # ~& M7 K  H3 q2 ?4 h        {5 e4 {4 L8 U& b3 G& ?
                if( pPrev )3 t1 e7 T' t8 Y& h
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    ) _8 x! L! s& e0 H! a0 v            else) n& @; |6 R2 p: M% N
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;
    : L; X2 ?$ p# u1 B            pPlayerData-&gt;pNextInCell = NULL;  T' b! P1 z( C* r0 d1 `
                break;  h4 a7 G7 t( n+ H1 Y# W
            }  o  ]. E# ~2 v- Y5 \/ _5 F
            pPrev = pPt;, E( V  Z3 w$ Y% z% u" ~
            pPt = pPt-&gt;pNextInCell;  ]$ `1 h4 o! W7 a( L' `" ?
        }
      c- f. B2 T+ o& ]  I# H  Y  ~0 Q}</P>* L8 o+ ]5 j% k: }

    ' L5 {7 A/ G* ~7 }  l  s* W<P>
    2 n: d$ }7 j/ Q//-----------------------------------------------------------------------------
    0 N0 L/ f# K% X9 Q) q' \: [7 D  s7 i8 u// Name:
    % g& w& f8 ]# N9 y% S- w// Desc:
    ) p2 T7 h, D. i+ h& k' ?//-----------------------------------------------------------------------------
    5 N- T, b* y% E0 `9 [; B) g& ]void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )5 ^3 x8 M- t4 [9 P
    {4 H  w, M6 S, q
        ServerCell* pCell   = GetCell( pPlayerData );
    9 z2 k4 K) b8 C1 }. ~  Z    pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;9 b9 L% q- f0 t: f3 k
        pCell-&gt;pFirstPlayerData = pPlayerData;
    : S" M! D1 b- r/ c6 z# ]7 q}</P>- G" ~+ }8 f) \" R7 p

    % [7 T/ x: a& f( R; D' T8 |9 Y# k<P>
    * y# ~/ k$ D1 h" d' n% {6 a//-----------------------------------------------------------------------------; |7 Q1 a- C( f, R- F% D7 I
    // Name: 6 p& Z" M; T% w0 ~/ I
    // Desc:
    4 a4 Y7 g& O, }+ ~9 Z//-----------------------------------------------------------------------------
      q6 `# p1 ]0 N* l* c. B, avoid CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )
    5 S3 `4 Y* d8 c8 {( E, Y{$ O4 y) G+ n' o0 {' {3 A4 y
        // Grab player for this client and lock it! b9 k* \2 q# C+ B
        PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );2 _( h, G) `) s
        if( pFromPlayer == NULL )
    - q! D5 g0 T0 |% x    {
    ; q% V1 B, F9 H5 h        if( m_dwLogLevel &gt; 1 )
    0 H) J! c; m8 B7 T1 q; [' q            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );( t3 d* a( R5 E! n8 [8 {. D& Z
            return;
    - ]0 i* d; U7 T: i  u) s* V    }</P>
    7 d0 `0 o+ t; `9 `<P>    LockPlayerData( pFromPlayer );</P>
    & {& `$ q- w/ c7 j0 m& @<P>    if( FALSE == pFromPlayer-&gt;bAllow )
    # {' |: j7 y! Y$ I# f8 {9 Q. Q    {
    : u& t6 W' |6 q  t& H        if( m_dwLogLevel &gt; 0 )
    ! }& H4 L1 E7 v% G7 i            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
    9 @3 ^5 L: f, S6 a5 V: s<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    , z% F3 o% }) c- T, ?3 h* m        UnlockPlayerData( pFromPlayer );% j+ D: G; N! x; F$ d  o, t% T% D
            return;
    4 F: q: D# b. Y! [    }</P>
    ' F" H+ ~6 X; G0 w0 B<P>    // Compute the cell the player should be in now5 B# o4 x6 ]/ W
        DWORD newcellx = int(pClientPosPack-&gt;fX);
    . Q- e5 E. w- a$ a$ F6 l* p  N4 F8 [    DWORD newcelly = int(pClientPosPack-&gt;fY);1 J2 M' H2 T! O  ?! F6 S
        DWORD oldcellx = pFromPlayer-&gt;wCellX;+ ^0 {8 P# m4 j1 v  T
        DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>
    - ~! _- m. n4 u$ Q* K! V$ [<P>    // Have we moved cell?* F8 u4 `0 M( C$ _. W* ^1 b
        if( newcellx != oldcellx || newcelly != oldcelly )6 i- K7 p  e) S2 j0 {, [  O# y  _
        {
    , ?8 J! f8 ~) M! o  ^6 {( d3 ?        // Yes, so lock the pair of cells in question
    1 L. T5 o  ]9 B/ e0 H        LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>8 g; [" u" C0 Y- l& w; h
    <P>        // Remove from old cell and add to new cell
    8 O! s2 M+ p( r2 I% Q        UnsafeRemovePlayerDataFromCell( pFromPlayer );9 Y( O2 v- B2 x/ v8 T! `
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);$ I: ^) m% X& e, `! z) v
            UnsafeAddPlayerDataToCell( pFromPlayer );</P>
    ( x4 I2 L4 ]% R* V* T/ o<P>        // Unlock cells
    0 u1 u: P6 i: ]+ V" S5 b0 F        UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );/ ?+ s7 e4 m1 Y" p
        }</P>
    * _  |' [7 z- r<P>    // Update player position( \5 P; W, o1 `* J% X& J+ h
        pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
    6 A, C' L) G) w% y5 |    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;2 L- i! d* W3 u6 F7 q) Q: x2 Z
        pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>8 d9 Y4 m7 a6 K) ?# \! ~6 S* K
    <P>    // Allocate space to build the reply packet, and fill in header 1 |9 |4 K# g5 K; H. V1 J! U# v
        DWORD dwAllocSize;
    9 ]+ C0 ~9 P. B4 g) k* d% U  K. ~    ServerAckPacket* pSvrAckPack = NULL;</P>) X4 }5 {# k6 Y! y+ m. W3 G
    <P>    // Begin by allocating a buffer sized according to
    $ |) b- U. A' v! W    // the current number of nearby players + 4.  This will give - P6 j5 M4 c5 e1 g1 @/ o
        // a little room for more players to come 'near' without resize: n0 f5 }. O) |; N2 D8 f
        // the buffer.
    # r" j) H2 W: c    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>! I. ~- C& @5 D/ M7 r; g
    <P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    ! R7 t+ c1 f- W, i2 _- k    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    ; q3 L  S: L4 _9 g: H# f( \7 u$ i    if( NULL == pSvrAckPack )5 Z7 j9 C) N, ^/ ~5 I) k
        {2 ^% Q; k7 p; x" y7 S- H
            // Out of mem.  Cleanup and return7 l% {( C6 \/ m1 Q; F( I2 z, c+ s1 z
            UnlockPlayerData( pFromPlayer );5 p9 t0 {4 `" T* u- ?4 H/ B+ ~
            return;      
    ; C& r( l* }! c    }) O& \2 F- q! x. d) R9 G! z' o
        ZeroMemory( pSvrAckPack, dwAllocSize );</P># }9 y$ O# O  a8 @( E" |) P- j3 q: N7 Q7 v
    <P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);
    5 |/ }( X7 c* l# w8 {  Q& o) C    pSvrAckPack-&gt;wPlayerStatePacketCount = 0;
    ' R% s2 m9 f. v* U    PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P># B" x- h& D( {, |* m8 P1 `4 H
    <P>    // Compute range of cells we're going to scan for players to send
    % D! F/ Z' d) h- b* Z4 q3 y    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;
    6 n6 G) W0 M7 y; i) y    DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
    : B! J6 g* C+ Z3 M    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;
    ) M3 q/ g9 g# h9 K8 @    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>
    4 @9 ?: L$ \% Z<P>    // Lock that range of cells% E; A7 [( k5 a( e4 x4 y+ z' S
        LockRange( minx, miny, maxx, maxy );</P>
    ! @) D! t+ m* z1 m, E<P>    // Scan through the cells, tagging player data onto the end of
    0 O& }. c9 I. K! r% M    // our pSvrAckPacket until we run out of room7 o) M  {9 T$ ]/ I+ |3 J4 c
        for( DWORD y = miny; y &lt;= maxy; y++ )) x" Z& N& G' t' O! |) u! d
        {# r3 T: {$ N/ \3 t% R. a& U3 s
            for( DWORD x = minx; x &lt;= maxx; x++ )
    " [) v7 g# z0 s8 M        {  n4 D/ g$ `2 o; w0 B- g9 ?% C
                PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;
    $ V% l  n. {+ [; N+ z  w( o: A4 O4 G            while ( pCurPlayerData )8 S0 Z7 I, o& `7 n; Z: `" M. K# Q
                {
    9 R/ G5 m  j( x* G2 k6 D                if( pCurPlayerData != pFromPlayer )- c/ u' y0 v( A8 q. g
                    {1 O/ }( U/ W# `% ]4 \: B
                        if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )
    - ]# m; H- @9 w# \+ y* x5 L                    {4 D0 K, w% B( h* z3 U
                            // Make sure pChunk is where we think it is
    0 X% j3 f  O- A& m/ \5 h                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>! V; Z% K' @: n7 B$ y, l/ Z
    <P>                        // There are more than just 4 new nearby players, so resize the
    8 ?# e# j& p2 I: b                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
    . y+ {  q& g+ u* [3 |$ H! A                        dwMaxPlayerStatePackets += 16;
    8 g( H( ?# A) ]7 M" b2 l: k8 {                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);0 }4 M: U1 k' N4 {# q
                            ServerAckPacket* pNewSvrAckPack = NULL;
    , a8 |" r/ a# [& W. U9 J                        pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );- K2 f2 t, l+ T* x9 a) ~
                            if( NULL == pNewSvrAckPack )
    4 e8 s6 s, T+ c& t                        {0 v$ U  A: w/ {) P- A5 k/ T9 ]
                                // Out of mem.  Cleanup and return
    9 P+ V9 u3 T- t8 n                            free( pSvrAckPack );
    6 a/ Q) W8 x" D( r6 w: u                            UnlockRange( minx, miny, maxx, maxy );( z2 }& G/ N$ r# m5 R2 f
                                UnlockPlayerData( pFromPlayer );. s" N, w3 p/ j6 Z6 |2 u% M* [/ o
                                return;      
    + O: [# H& |2 D                        }</P>8 m  J; c; h  y8 U0 C
    <P>                        pSvrAckPack = pNewSvrAckPack;
    $ \  e7 j% s/ m                        pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
    ( U: u9 r% Z6 j<P>                        // Make sure pChunk is still where its supposed to be
    $ i" j$ v$ T& b( c6 g                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );7 o) M6 p. s/ D% u9 l9 j
                        }</P>
    $ V/ t& e4 u3 O<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;
    * ]" D, M" [9 T& h+ C                    pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
    - o1 i& t) l5 E% f1 a: q                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;8 l6 ]0 @& O/ A$ W& |' l5 \
                        pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;- X( V% J7 @# V8 v- Y
                        pChunk++;
    0 @: c* d% X  f& M; e8 q! A/ U                    pSvrAckPack-&gt;wPlayerStatePacketCount++;
    : x# ?7 @& x7 {7 i7 Q4 v+ X: ~                }
    / _# F6 \# p6 z7 l5 J: N                pCurPlayerData = pCurPlayerData-&gt;pNextInCell;& c6 u/ R+ W. |
                }
    . }; W& K( V2 x( J" @4 e/ h$ F6 ^        }
    $ r" Z: W5 @/ ^( Y    }</P>
    ( K! b4 r8 `) d. W6 z<P>    // Update the dwNumNearbyPlayers for this player
    - e( `* D- ]: M- @    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>
    + q3 R5 T" h$ r- `- m<P>    // Unlock range of cells
    $ e8 Q8 G6 r( t: ~    UnlockRange( minx, miny, maxx, maxy );</P>+ r  g9 x3 Q( T* C" r( r& ?( x
    <P>    if( m_dwLogLevel &gt; 2 )9 x' c6 i# N2 h$ \1 s4 B
        {
      G& S: L: n7 b$ G# ~  P# S        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );( {& _$ Q& ^! a3 u
        }/ k) _7 e. T+ S2 Y
        else if( m_dwLogLevel == 2 )( j* H+ [* @2 v, ^6 K, [' m5 `: t
        {
    7 }; d1 v* |5 B6 t3 v- a        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    7 f& |% k( [; K7 y, K        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )) j% \* _+ U! H/ d% P
            {
    8 ~" s; w# M2 Q            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );* V! K% K9 M& U$ |
                pFromPlayer-&gt;fLastDisplayTime = fTime;
    # B, K* z3 F/ p+ `& `+ U4 E        }5 X6 q2 {. A! I3 R; q
        }</P>6 I  Z4 [2 r& M+ Z1 X/ w
    <P>    // Unlock the playerdata
    2 Y+ l$ c: f2 M4 J    UnlockPlayerData( pFromPlayer );</P>
    2 t8 Z& H8 l( ]7 }<P>    // Send acknowledgement back to client, including list of nearby players
    + ~; ]; u! F% a6 [1 g" ^, j    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));1 P6 f! i! j, [, z+ ?& x
    ! C$ a* K1 D- y* L% L& ]. Q
        // Pack the buffer with dummy data.
    ; K. p, T8 Q( Z1 U4 F1 u    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)
    8 g4 a' U, d/ r  C/ o( s* |2 W    {
    & C5 A% _4 T+ T$ o% _' r        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];
    % Y4 S7 p% \" @' [. o7 f) y: U& e        VOID*   pTempBuffer = 0;</P>
    3 E7 \$ u7 \* E8 D" E2 k<P>        pTempBuffer = malloc(dwBufferSize);
    ' e3 p2 f0 N% o        if( NULL == pTempBuffer )5 z/ E8 G3 S* a( n5 A1 o" P
            {
    9 ]" M  t* P: u0 V; P. F5 C            //Out of memory7 U( r9 M( p! F. W. W/ S
                DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
    + q# `# j8 Y9 C2 R            free( pSvrAckPack );
    ) c; _+ Q( s' P9 k, o4 A9 w            return;
    $ D" J( j' @7 ]2 ]  I        }</P>, ^* j- S( b5 r, n& C# N8 [
    <P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');  ?$ d1 Z: P+ f; `4 t0 x9 s2 L4 z
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>
    $ C  W6 T+ }7 [: R<P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );; M4 H+ S! O  t  ?+ z
       
    6 c7 k7 G0 `, k+ I$ Y; V        free(pTempBuffer);+ }4 d' }; c) x3 @: A( E
        }   
    6 N5 o8 v$ K+ D; Y/ P    else
    / i& _9 P. R* u! K- _6 a: j    {. r/ V* G7 C: r) j: O, `2 c
            SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );
    + V5 ?  N' @1 e    }</P>. c8 Y  i: @% ]: E
    <P>    free( pSvrAckPack );</P>
    : v9 f7 I1 [7 s. g; l/ z0 g* h) _<P>}</P>5 V$ G: X; v* P: `6 b4 w6 K
    7 N: {, m6 @: t+ p& U# e
    <P>
    , I: S+ V8 |: D5 N2 K  E4 T//-----------------------------------------------------------------------------* K( P6 p) W4 m
    // Name:
    8 n1 |9 x  H- v/ f2 i! d5 X/ m// Desc:
    - `* {2 {% H4 S( `- `3 q9 h4 G) P! y//-----------------------------------------------------------------------------% i+ J- W0 {5 p+ t1 ~; O
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
    $ h) ]2 _' G) H{, i7 u! x6 e: w2 P7 o
        // Grab playerdata for this client and lock it5 v5 s- G! f8 q4 c& t
        PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );  `* _& i7 q5 g7 b1 x( Q* m! V; _
        if( pPlayerData == NULL )1 n1 @8 g0 d( r( k3 z
            return;
    ' g+ `8 B3 K4 a" E    LockPlayerData( pPlayerData );</P>7 m4 W- |' \7 y% |
    <P>    // Record the version number : \  k& m. y9 j4 i3 |1 Z
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
    5 U7 F+ b& C, Z0 n8 K: b<P>    if( m_bLocalLoopback ). i/ \' c; q/ _8 t! [
            pPlayerData-&gt;bAllow = TRUE;
    2 z/ \  E% n+ U+ y  L) a    else7 u2 \8 d- Y& Z7 i
            pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>( G  F# G# T% w2 ^8 x2 k
    <P>    if( m_dwLogLevel &gt; 0 )
    0 S% Q' ^( B( N7 A0 |" |        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># g% `; I$ v  u- V6 d0 c
    <P>    if( FALSE == pPlayerData-&gt;bAllow )
    * v/ I7 {; g' _2 B/ A% [    {+ \9 R* t$ j/ {9 m& \
            if( m_dwLogLevel &gt; 0 )
    ( Q& ?3 A2 @, J: f- @            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P># A$ t# @' R6 }9 y* `. L
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );9 N" i+ \" m; K# F
            UnlockPlayerData( pPlayerData );
    0 B. W* e8 u9 V4 N( r        return;' S: v. U/ w3 x. W$ s* V5 F
        }</P>
    ) s) m$ D% ~- K' D<P>    // Unlock the playerdata
    3 o& A& Z% k# g: e! @- a    UnlockPlayerData( pPlayerData );</P>0 y) R; L6 ]% j1 r/ A
    <P>    // Send acknowledgement to client that the client was either accepted or rejected0 i) {" P# |. x3 j; m/ V
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );
    8 D9 r* y6 j- Q  k    SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
    3 |$ k# D$ g5 M}</P>
    # o& Z9 L/ n# t. x( P
    + h- ]5 [; ~; p& ?7 M<P>: N* a7 |* v6 A' \! j
    //-----------------------------------------------------------------------------! f1 }( q, r6 N- L0 h) h
    // Name:
    : Y" A# H! l) |3 j& `// Desc:
    / W* U( G, g3 k8 o) w8 B7 n//-----------------------------------------------------------------------------
    % U5 z+ d( J: }$ m3 y) z; l1 a* `BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
    % n. `+ e6 Z7 r( w/ X6 U{
    ; }3 [, ]7 H$ p4 `0 v    switch( dwClientVersion )1 x- d2 R, }/ r
        {
    1 T( m1 c% D8 [/ v        case 107: // only v107 is supported
      K* O! {+ A- p% P7 L; D1 m            return TRUE;
    ; B+ m7 n+ S: F- X, T+ q2 d        default:, O( V# E& ^7 K
                return FALSE;* X% F0 ~* {) k, K0 y
        }
    . ~& }( g( B& ]. B6 t' v9 L}</P>6 B( q8 @( m" _: |* C
    % ^8 ]- m7 i+ I" L
    <P>+ j' `; C  p; W) |4 `) U! s% J
    //-----------------------------------------------------------------------------) v; N' d2 T* _
    // Name: ! b: X) D9 d1 w) q& a
    // Desc:
    " s8 G$ Z0 @' F//-----------------------------------------------------------------------------
    3 U& q; K$ D* E# F5 hvoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )2 y9 P5 p9 V, \" \/ D" Z
    {; [  ^. z2 t# r. u0 _" [1 N
        if( m_dwLogLevel &gt; 1 )
    + N1 A& e! F6 v% c# H9 U# K$ s: [+ s: ^        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>3 n" f6 V1 d. F$ I0 J- b
    <P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    3 E8 j- j" Z4 ]}</P>
    1 d% T3 f0 \9 O; Z, q! x( E+ K: E- {/ X+ x" c5 Q
    <P>
    : s/ z) R. ~" W* `//-----------------------------------------------------------------------------
    6 ?8 Y# {# s2 ?% q8 ?/ g// Name:
    2 V9 Y4 v4 W3 R" z! C// Desc:
    4 [. e: X8 v  D$ v//-----------------------------------------------------------------------------
    ) H# e  |9 {7 ODWORD   CMazeServer::IDHash( DWORD id )
    ; y0 {3 d( {- o{1 K- Y+ M" m/ |4 m+ G/ i
        DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);
    ) J. _* |+ y! E+ W: |$ z# y; r! R1 K' a    return hash;
    # w" w: x& T5 X9 j& z; q}</P>
      B8 b8 o& a* D) A! f+ z3 |7 ?# F- P; a* K$ S
    <P>. s0 u9 a) K: d4 M8 j4 E
    //-----------------------------------------------------------------------------; C5 E" j: `8 {$ J
    // Name:
      n3 f, a& H1 a7 r// Desc:
    ; o2 }7 @' |( o# @//-----------------------------------------------------------------------------
    5 T1 [' ?) m7 B# Q7 evoid CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )* Q/ f6 {/ O% q! O1 u! \- r
    {
    : n' s' ^2 \  A    // Hash the ID to a bucket number2 }% z2 O- E0 Y9 G
        DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>0 g* S6 |) M/ n. T5 ]6 o
    <P>    // Lock that hash bucket$ M! y; s& _/ o& g  E  Y# S2 o
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;' Z8 g( S2 j; n1 F
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>7 G8 y# D7 k  I7 Y7 ~
    <P>    // Loop though players in bucket until we find the right one
    5 z* t3 \0 y* Z6 Y* \' z; c7 @4 r: a! V) n    PlayerData* pPt = m_pstIDHashBucket[bucket];0 H1 ~8 Y9 w: N* V. C# t
        PlayerData* pPrev = NULL;* o$ L6 a$ \% |% \1 H
        while( pPt )5 e$ C' ]! ?) ?4 i; K) m+ f
        {
    + N  o. h) l! ]2 N1 ]/ R. G        if( pPt == pPlayerData )  @1 A! ]5 ?/ f  D# q
                break;
    . P, F) A: s' D- _; X- F2 ]+ ~        pPrev = pPt;
    # S0 \+ G# L: b7 B1 b        pPt = pPt-&gt;pNextInIDHashBucket;
    - o) ~5 q1 j4 B$ j$ T, Y$ _    }</P>& U( l* ?/ z% U/ a
    <P>    if( pPt )
    + Q& q0 d) y; X& h0 _    {" K4 j- p; P4 E% b6 H
            if( pPrev )
    - S$ G; e& A& ~2 ]: J6 m            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;0 p+ l- j7 a  k7 I  k3 |. F, }
            else/ k; S" y/ D5 ?7 A$ z5 k
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;% K2 @" |2 R' d) S6 z: d
            pPt-&gt;pNextInIDHashBucket = NULL;4 j! S5 ?2 H: x: c
        }</P>$ {: x4 E$ H- B) {
    <P>    // Unlock the hash bucket; g$ C% Y7 ^7 {# q3 Y
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    ! S- G3 }8 k! }# N* A8 R' n6 N& k}</P>& F) r/ ^5 v) `
    . ?& P+ T, e3 B+ v
    <P>) E0 j; z. E6 S% p( U
    //-----------------------------------------------------------------------------
    9 @8 d4 H3 k* f2 k/ l% }// Name: * U+ q& ]& X% |2 d; F
    // Desc: ) S6 p+ z; t3 T3 b2 e4 `. k9 ]
    //-----------------------------------------------------------------------------  @2 u- T4 ^: g3 f  N
    void CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
    - h" B# T" l/ i7 ^! _+ b5 c{; u4 ^* e% Y6 o
        // Make sure this player isn't added twice to the m_pstIDHashBucket[], H  y( \5 f) A* s) H
        // otherwise there will be a circular reference
    & m- S1 [1 T+ a) d    PlayerData* pSearch = GetPlayerDataForID( id );
    ' Z" R+ z3 d! N5 t! T6 `( J' s    if( pSearch != NULL )
      F# e3 t' x8 E5 n- ~- h: d2 F  d; B        return;</P>
    : ~& L7 ]  O& ~' ]+ T$ B<P>    // Hash the ID to a bucket number
    - C& ^& ~6 _+ R* d+ H    DWORD   bucket = IDHash( id );</P>
    . K& P  k0 {/ T<P>    // Lock that hash bucket
    & D$ B8 R4 S2 z2 |! Z    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;, l' w: o) m  F. _6 w2 t
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>8 G2 o# l. d1 n( ^
    <P>    // Add player onto hash bucket chain
    - }& @" n% I( G' J) j- T7 c    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];
    7 [4 R3 m, U# R0 g) C0 k    m_pstIDHashBucket[bucket] = pPlayerData;</P>
      `$ Y' R! ~# r) I( y* \( R<P>    // Store net id in player; r' e( L$ n6 K" M8 `: a5 t8 A
        pPlayerData-&gt;NetID = id;</P>  Z1 I( [0 L! r4 u  _) m0 \( x" [
    <P>    // Unlock the hash bucket  _6 m( u8 Y$ a9 d' _+ J. t
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    2 @# e0 s  x& y) H- ^, E8 l}</P>) F6 u$ f5 S$ ]3 A: \2 ~

      W' P/ k  k- p( {- N<P>/ r8 p, A- g/ T
    //-----------------------------------------------------------------------------
    ) G9 R, |3 L* r8 o// Name:
    # q4 u, B. A* u* ~" h. Q// Desc:
    0 h" j4 _7 M3 f; N/ B# B//-----------------------------------------------------------------------------: p/ n) }% K* j8 I4 E
    PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )
    / u! E$ T( Z3 n, I9 |{+ C* H# ]" t. @# ^
        // Hash the ID to a bucket number
    / o& Q& n6 ~2 P" E# Y1 p    DWORD   bucket = IDHash( id );</P>
    ( ]- h9 l' |  }3 @( O$ \<P>    // Lock that hash bucket& Q; I4 A+ P$ e2 e* c
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;0 j) Y( t6 _+ I' Z' w9 S
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>2 o$ ]6 ~4 r3 b: t4 M
    <P>    // Loop though players in bucket until we find the right one
    3 m! C( }! j) F  B    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    7 \+ v+ C" t$ c" o, i+ v3 `, y    while ( pPlayerData )
    - S. M3 X! m2 {1 E$ V" B; K$ j    {
    - h5 o& C; A. s; T: [4 E4 p2 v        if( pPlayerData-&gt;NetID == id )$ ^7 H  M8 b+ u, Q) [1 G1 |
                break;
    6 Z8 o3 ^6 W2 I2 D( R; x( y4 W9 w. s        pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;1 K3 m8 Y' A! K5 A& w
        }</P>
    7 p( t3 A4 k9 ~) M5 D5 d; @9 p<P>    // Unlock the hash bucket
    7 A' @* [* b/ L& G5 J! F    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>
      s( {3 z* }: R7 N6 V2 C3 S<P>    // Return the player we found (will be NULL if we couldn't find it)
    % t- z: z- _: j7 ?; B' q    return pPlayerData;
    ( N( p) v; Y. B+ f( i( n0 R}</P>
    6 `; |1 m, S- R! b4 a: T
    ; N5 f3 |6 e3 B% U9 `+ q<P>
    5 d6 {2 N1 m# q( U6 j$ V& P: |//-----------------------------------------------------------------------------
      \' l/ m% u* K! J  `8 ^: r// Name:
    : l1 F0 t( \8 e" h// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner/ Q( `3 k' V1 v/ m4 p
    //-----------------------------------------------------------------------------
    3 `: h1 x% Y) `void CMazeServer:isplayNextConnectionInfo()! G. ?4 n6 }5 a/ ], F9 l
    {/ ~7 O1 n& W0 L9 P/ V
        if( m_pNet )
    4 r. \9 r0 g/ C* ^3 v9 f6 S    {! J% Q( P4 f8 X& |
            // Find the player that was displayed the longest time ago, and display it.! e# |& @1 z0 c
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
    , m9 {! O  b8 S- W/ X        PlayerData* pOldestPlayerData = NULL;( j6 i# E/ @3 u
            FLOAT fOldestTime = 0.0f;</P>5 I$ \9 Y$ }& |
    <P>        m_PlayerDataListLock.Enter();</P>
    ( }" C! n/ L7 M  Y2 G1 Z<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;" T2 |" k- e; i, h- ]6 B: y
            while ( pPlayerData )) g5 b- V8 G2 t7 G1 ~
            {
    ' O5 q+ l. K+ J$ L            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )3 N. j7 [" U. q6 K. C9 ~
                {% \# Y2 v! W: L2 l: o
                    fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;
    " L2 @' L! [& T. Z3 [8 t6 T! z                pOldestPlayerData = pPlayerData;3 G; I7 E% F' h
                }</P>7 Y% E* N$ N4 z8 }6 R
    <P>            pPlayerData = pPlayerData-&gt;pNext;- K9 \. M6 ~5 C. ^3 |/ q
            }</P>7 x# f% v- U5 }8 r0 b. F
    <P>        // Display the player with the oldest CI field, and update its CI field.3 W, H; d8 N; m  \
            if( pOldestPlayerData )
    6 ]/ w$ h4 O+ I& e        {/ J6 a- C: x4 }4 m. O* v) @6 W
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );: n) Z/ ?- A$ e/ v8 {) k7 t; \
                DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
    7 ?! h' ]. d1 T8 i            pOldestPlayerData-&gt;fLastCITime = fCurTime;
    # K+ n' U. p. _1 \  R$ e        }- c; l  ]# R0 n% b3 g/ Z* ~* L
            else% c& l. a  W4 J1 @  U' I& H( F4 N9 l
            {9 L3 v' k4 h0 R  g9 t
                ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    2 K6 B9 \. P' I0 P        }</P>
    + j: w. X7 h( r9 R7 h+ w<P>        m_PlayerDataListLock.Leave();. d* Z4 Y, R5 @, f- l" X0 f$ ?
        }6 z7 S3 K5 O  {8 }8 I, n
    }</P>
    , L" U1 v' Z5 S, |8 y
    + I% ?' \# y/ |, c7 r5 v<P>
    $ F" [0 v7 D9 R! N  a//-----------------------------------------------------------------------------
    2 l' r  {$ l+ I4 E9 }// Name: - @8 t) m. [( n0 P) W& V
    // Desc: / k1 F5 O! X$ B6 U. E
    //-----------------------------------------------------------------------------8 a& p8 z8 ?) Z
    void CMazeServer:rintStats()* O6 D9 J* J" J. Z2 `
    {4 ^' Y8 }5 p8 i3 O: ^- P1 K7 Z
        ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
    0 T0 r4 Z; T% B                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );$ j5 A6 e) R# z. \6 H& ]7 X* s" E
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),- P; i+ b! x/ p. b4 C9 H+ k$ j0 L
                                        m_fAvgThreadTime, m_fMaxThreadTime );
    ; G8 X1 C. _3 `% D: _: b' Z3 x    ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
    $ A  X9 i& e- I5 V$ p6 P3 N    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );* c8 F- q! l: Z  g8 A  C8 B
    }</P>+ r/ p6 S- ?) N3 P: O( @% R

    ) _& B6 Y8 f: F. E7 b1 s<P>
    / h* ]* b4 k3 b0 w$ k//-----------------------------------------------------------------------------& o- u- U7 x5 l3 S6 j0 k  I
    // Name:
    ; ]1 w: H9 P/ I% L: O5 L. c& U// Desc:
    % ^1 ?( n. G$ f* A3 ~8 Y//-----------------------------------------------------------------------------) E0 c; V1 `+ F* h0 c- Z
    void CMazeServer:isplayConnectionInfo( DWORD dwID )
    % ^4 o! d9 r' o+ H/ V5 s{
    3 y7 B" C$ f% O0 J) A( l( p    TCHAR strInfo[5000];9 E' H4 F) \( o& Y9 H
        TCHAR* strEndOfLine;/ ^4 x) K/ f2 n8 c# l
        TCHAR* strStartOfLine;</P>
    $ e5 u4 X' a7 b' r<P>    // Query the IOutboudNet for info about the connection to this user
    2 W8 Y' A. N2 \4 t+ P5 G4 D    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>- |3 H- a0 D3 t+ I0 V% ^* M+ j7 V" ^
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );; V2 }; [& H7 N0 l$ d
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    % l, |: W% |) u<P>    // Display each line seperately  E; q9 @$ M4 s, Z
        strStartOfLine = strInfo;8 [2 M5 \  {5 ^  P. w/ T* H
        while( TRUE )
    . s0 n0 C# w* b. K    {! u+ M  J' i* \( w
            strEndOfLine = _tcschr( strStartOfLine, '\n' );
    9 Q' [% {" ^+ d' l5 A) c( T: W        if( strEndOfLine == NULL )* F8 h- o# V+ [& d* A
                break;</P>& m7 N( J, r9 N# d- ^/ I% W; O& `
    <P>        *strEndOfLine = 0;
    * h, ]  K' w* p2 F        ConsolePrintf( SLINE_LOG, strStartOfLine );5 ~0 \/ c9 }2 y3 v3 ^' c
            strStartOfLine = strEndOfLine + 1;
    + p2 n# q) X% A- Z  I% ?* w9 Y    }
    7 [7 E* b/ z- ~/ O}</P>% p4 d- [+ b: [. H2 D2 z( |# u
    5 j/ T% V# J  U. K, H8 w/ Q
    <P>) s, ^7 U1 H9 o+ b6 v9 A# \
    //-----------------------------------------------------------------------------6 z5 v; S. [: U+ t% e: M
    // Name:
    4 ?) K7 _6 H* _& g5 D// Desc:
    . E6 ~" B  ^3 j/ {& _- R) ?: J//-----------------------------------------------------------------------------
    : ^* P! i7 y9 u) _$ S+ o3 NHRESULT CMazeServer::SendPacket( DWORD to, void* pData, 7 n* u/ R5 a3 h. P% L
                                     DWORD size, BOOL reliable, DWORD dwTimeout ): P8 G' ?  ~) H% V
    {
    - Z5 f/ W4 m9 b+ U' s) f$ f    // Chance of forcing any packet to be delivered reliably; t. T# Y# |: R! G
        if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )+ w. H9 C5 [3 z% G! e
            reliable = TRUE;</P>
    ) s: j% \2 N+ M; |8 q9 X# V<P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    . U/ q5 G2 j' }0 ?}</P>2 p6 \% j1 P5 u1 |2 U
    ; i& z1 c0 C1 Q) K& A) N$ N- A6 o
    <P>
    4 Q; G5 r, F; y( l) B4 b8 C//-----------------------------------------------------------------------------
    1 s8 v8 G- B* A; ^' D" R// Name:
    % H! r' I3 x* Z: r9 y( ^// Desc: ) l2 h& e3 [( c1 I: N$ G( ^) k
    //-----------------------------------------------------------------------------$ A  Z. G9 C7 e& p3 i. @( K
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )
    . L* H- a. x/ D$ g5 h{
    " t" I2 r- M% o3 c1 d# n. l" Z    // If we're up and running, then send this new information to all clients) @4 ]3 k' t5 I' M8 `9 M
        if( m_pNet )% E, I. l1 w1 c; M" k
        {
    5 s: k9 k& `  i        //Use the AllPlayers ID: v9 \# R- {( M3 G3 w8 K8 y8 Y
            SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );* L, R& `0 i  K! R3 m! ~  w
        }
    " ~, I" ^5 m: w( d}</P>
    8 X: |- m' O9 M* W0 }. H
    $ n% [' a/ C7 H<P>
    1 [% |. |; ~, f# S2 ~& B+ s1 x//-----------------------------------------------------------------------------
      q  _1 Z8 \% \1 N// Name: 9 y, p3 \1 V# C! }6 P. T( N+ H5 Z0 i
    // Desc: 7 }6 a: C+ X5 g" \$ M
    //-----------------------------------------------------------------------------
    ( ?) O) O7 O+ X9 t2 e9 F- ~9 Avoid CMazeServer::SetClientReliableRate( DWORD percent )
      i' A+ w. a( }3 R{
    8 q( r2 u" O/ p    // Update client config, and build packet containing that data' r4 {1 J8 _3 _# f, Y1 Q* n: q
        m_ClientNetConfigLock.Enter();
    ! k2 o0 U9 a: V    m_ClientNetConfig.ubReliableRate = BYTE(percent);
    + N2 B# \9 m0 }& A    ServerConfigPacket packet( m_ClientNetConfig );
    8 d3 `. O, r! d# q& U7 D1 w    m_ClientNetConfigLock.Leave();</P>- ?9 ^, F% c- i6 p: f
    <P>    SendConfigPacketToAll( &amp;packet );
    ! `& u1 S) l& A6 W}</P>( s5 ?$ `1 e1 t5 t! b) D
    1 s7 L3 y# V) I( q6 p
    <P>% _2 |7 I  L+ G2 T$ q$ L
    //-----------------------------------------------------------------------------6 ?: m, O' U( b2 K1 w; ^/ f
    // Name: / t8 D4 j4 T( K: i& a
    // Desc:
    $ N  N( C, w. t, Q/ K( w. O  R//-----------------------------------------------------------------------------
    - V% n5 M0 `; j' o, m- Fvoid CMazeServer::SetClientUpdateRate( DWORD rate )( X* ~1 w7 I6 H& t
    {4 y1 h* E8 {4 V) u9 r# D
        // Update client config, and build packet containing that data
    % v% Z4 q! ^4 M5 I: C    m_ClientNetConfigLock.Enter();* k* o+ x1 D4 M5 R2 j- r
        m_ClientNetConfig.wUpdateRate = WORD(rate);+ F  N1 Q: \( k4 D* n' M" ^  }9 `
        ServerConfigPacket  packet( m_ClientNetConfig );9 q5 e  u/ `* F" L( r5 E: Y8 l
        m_ClientNetConfigLock.Leave();</P>
      j( L4 y* V! [8 q, B7 P<P>    SendConfigPacketToAll( &amp;packet );
    9 f9 p1 |" U1 K}</P>! `, `7 Q8 Y2 v. B+ Z) X: e* d7 F: A

    0 H! L) ~1 i2 J5 _( f: r9 `<P>& _7 ]/ l0 r+ p  @# s
    //-----------------------------------------------------------------------------9 Q3 i: v+ Z  F; m5 p, U1 l
    // Name:
    ' N2 o. z5 ^& @! Z' T// Desc: 4 u# U- I) r, J: E# k
    //-----------------------------------------------------------------------------
    & F3 M2 t; S# \void CMazeServer::SetClientTimeout( DWORD timeout )
    1 F9 R* u6 d" z7 Q  L{
    , @% [6 g$ K) u& Z* B8 X    // Update client config, and build packet containing that data) r2 D. n$ N+ ]2 F; N
        m_ClientNetConfigLock.Enter();
    6 M4 u2 C& ?) N    m_ClientNetConfig.wTimeout = WORD(timeout);! H- R9 D$ o1 ^/ k
        ServerConfigPacket  packet( m_ClientNetConfig );
    ! A5 c" H+ C" t. {0 D    m_ClientNetConfigLock.Leave();</P>
    * p4 K3 [  _, `1 M% v% L3 Q<P>    SendConfigPacketToAll( &amp;packet );
    % {0 u6 X5 r/ W4 X; b}</P>
    % @2 Q1 Q" a% {$ e6 m) a& X
    : t6 E  e$ R( S5 Z( [' h<P>, {, U- l9 z7 z8 i
    //-----------------------------------------------------------------------------4 I! M5 a3 |( L
    // Name:
    # H( i% D' a. m3 q! h3 h  }// Desc: & g4 u9 P( n8 h6 c3 E; g9 S' P9 t+ Z
    //-----------------------------------------------------------------------------
    $ S9 t  P& d: u% q9 r; Gvoid CMazeServer::SetClientPackSize( DWORD size )
    ! N% J' f0 r0 a) q6 u8 |7 I{- x, C7 }! r7 h9 _, J* `/ p
        // Update client config, and build packet containing that data  A2 w! ^4 C, t) O( Q, j
        m_ClientNetConfigLock.Enter();
    5 c0 ]; [: Z6 f1 W    3 B$ d: S' E, g3 z5 E+ ^
        m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.
    ' m+ l* J/ P+ j: }: v- b) S. i    if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   * O8 \6 S( a' Z" E
            m_ClientNetConfig.ubClientPackIndex = 0;</P>/ O+ n- `/ t, A
    <P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);7 c3 S5 G& ~, R, L& c0 e3 R5 @+ {
        ServerConfigPacket packet( m_ClientNetConfig );  h4 I, K& k* O) z( o( Y9 J
        m_ClientNetConfigLock.Leave();</P>
    5 T$ |! a& V8 q5 t, q7 Q0 Y5 x<P>    SendConfigPacketToAll( &amp;packet );! P, M* B5 `$ Q* c: U5 a4 ^
    }</P>5 c" Z1 Z+ `! y7 W3 ~) s% S  D
    1 E; b! X3 I5 U4 J0 }) }
    <P>
      H2 M4 {1 x& e1 x//-----------------------------------------------------------------------------( I9 N0 z. X$ H6 V4 p% f3 t
    // Name:
    0 t3 b9 G( N1 _9 C5 }& K3 l' I/ Y// Desc: 6 m2 x( K" u$ R, i% F7 t5 A
    //-----------------------------------------------------------------------------
    , S7 U3 h/ `: z' cvoid CMazeServer::SetServerPackSize( DWORD size )
    + N) h* k8 p$ r{5 v) {1 w  d% y4 |6 r$ a
        // Update client config, and build packet containing that data* B* e; C0 X4 a7 _  q
        m_ClientNetConfigLock.Enter();
    % }7 [; `: t) H! T# `: |6 l/ @4 r    , o1 j9 M& ]3 W! O, a: C; n
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.
    % C- a# x0 R; @& \5 y    if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   
    6 H4 X  k3 Q, K. B1 K: Y8 G3 U        m_ClientNetConfig.ubServerPackIndex = 0;</P>
    3 X$ l" I) a' {) A) g! ]7 {( y<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);, @4 b6 P9 D7 I* c6 Y: W4 ~
        ServerConfigPacket packet( m_ClientNetConfig );
    ! _2 J+ U. {7 s4 ~: \( t$ E    m_ClientNetConfigLock.Leave();</P>
    6 J0 _7 W! G2 @2 H) O, J<P>    SendConfigPacketToAll( &amp;packet );0 X+ u- F6 k- A4 _" f* p
    }</P>4 [, q# U3 J# r9 y7 X
    <P>
    . N1 V- g3 E/ Q& b) @# p! t//-----------------------------------------------------------------------------
    , N& p4 b( g  M* H! }// Name: ! b- f- P' l( r+ [0 D+ E! L
    // Desc: 8 N2 a- u# V4 ^8 @! i' A0 ~+ [' @
    //-----------------------------------------------------------------------------$ C/ v* B% O5 E* ?  b+ r6 S% H, M
    void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
    / y7 V/ U2 y9 @, u5 j* W{
    $ Y4 ^. [4 x& q7 q) Y' E" J" y    // Update client config, and build packet containing that data
    " w. m3 _# a  T) J4 X    m_ClientNetConfigLock.Enter();
    1 j, Q' T+ D! ^3 _    4 M8 e) m) F9 _- f, v& `2 p
        m_ClientNetConfig.dwThreadWait = dwThreadWait;+ S0 s$ N0 r( }: S
        ServerConfigPacket packet( m_ClientNetConfig );7 Q2 O: b* h/ O& H
        m_ClientNetConfigLock.Leave();</P>  j* h5 i0 {1 \) b, W4 _, ^( o
    <P>    SendConfigPacketToAll( &amp;packet );
    : c4 A* T' ~/ P2 N1 t2 }- k0 J* {}</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-16 13:32 , Processed in 0.470562 second(s), 51 queries .

    回顶部