QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4181|回复: 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>7 t0 T  A; s9 E& |0 Y" w
    <>// File: mazeserver.cpp% q3 s1 v  Z7 i- m( u: b
    //
    6 A9 \  y8 P9 q# O+ }3 ^% E; _$ t// Desc: see main.cpp
    2 Q7 n7 \, s8 S- l5 [+ ~) m//
    * T+ ~6 {2 D: D' E0 O5 \4 O* d/ q// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
    9 i8 L) C7 \/ g( |. c7 D//-----------------------------------------------------------------------------2 o9 v& f8 n5 X& d6 ^
    #define STRICT. T% e7 q, I0 A. j" R9 Q
    #define D3D_OVERLOADS8 H8 k) N3 \# @8 K4 `" A
    #include &lt;windows.h&gt;
    0 c6 g$ p8 i2 _2 G#include &lt;d3dx.h&gt;
      V  {( [& U6 [& }) q8 l#include &lt;stdio.h&gt;: I+ J" z% j, |) o$ m) u
    #include &lt;math.h&gt;
    ! R6 _  n6 Z; t0 e. w#include &lt;mmsystem.h&gt;. M9 L! n% E" |
    #include &lt;dplay8.h&gt;: D# o! I1 O6 e# t8 R
    #include &lt;dpaddr.h&gt;" I7 I3 u8 S. \% r
    #include &lt;dxerr8.h&gt;
    5 K% Y" @& Y# y" P( _#include "DXUtil.h"
      j6 |4 Q! a/ N* `7 ]0 M1 A- k" o#include "MazeServer.h"
    7 f/ K& e! A% J7 M#include "ackets.h"
    ' N- j6 x: {; @! U0 ^* q+ R7 i0 i1 E#include "Maze.h"
    0 b/ T2 B# V2 q2 H" f& O#include &lt;malloc.h&gt;
    " c( q! L3 Y# m: }1 k#include &lt;tchar.h&gt;</P>! c4 [/ L7 \" {# m) K

    / l$ _" C" h  b. A4 V<>//-----------------------------------------------------------------------------3 [, Y/ l4 F. R7 ^1 [
    // Name:
    % I$ f+ y4 F; u! u9 U; A) a' P% Y0 U// Desc:
    2 z1 y7 U, M' c0 E0 D" R9 I//-----------------------------------------------------------------------------! Q8 M' x! G1 F( D* X
    CMazeServer::CMazeServer()4 P' \% U& }( y( w
    {; t' d8 o6 n+ m% `2 w# D
        m_dwPlayerCount         = 0;
    * S/ r5 I5 S" n) F1 q  ~$ J' G    1 L9 e' B: u& @) Z
        m_wActiveThreadCount   = 0;9 @9 \$ S+ c/ @0 t5 t8 }5 P+ j
        m_wMaxThreadCount      = 0;
    3 A' C" K' @  \) z' T) q2 S! m2 l' X    m_fAvgThreadCount      = 0;
    : ^/ n' ^$ K" G4 h) O    m_fAvgThreadTime       = 0;
    $ e# K. p) p" q    m_fMaxThreadTime       = 0;</P>
    , p( m5 m% r! o<>    m_dwServerReliableRate  = 15;
    - \9 Y/ t8 f. K+ F, L2 P    m_dwServerTimeout       = 150;5 S6 z& t* |, c( T' f9 x# w  u
        m_dwLogLevel            = 2;
    , N3 _8 {: ?8 {, ?- Q3 h  H! _5 M    m_pMaze                 = NULL;</P>
    , M' P" |: M* p) r( }6 u! g<>    m_ClientNetConfig.ubReliableRate = 15;
    ; d" {+ [7 [+ I% I' H/ V; w8 U/ B    m_ClientNetConfig.wUpdateRate    = 150;1 O7 T% D) T5 E
        m_ClientNetConfig.wTimeout       = 150;</P>; Z; v. {1 @1 x1 r5 Z# X. E8 @( Y' q
    <>    m_ClientNetConfig.dwThreadWait = 0;</P>' S+ i7 L  l' C) c- G0 u! I5 l! C! S
    <>    m_ClientNetConfig.ubClientPackIndex = 0;4 a8 ~, z- g3 ~& e' F+ v
        m_ClientNetConfig.ubServerPackIndex = 0;
    + |$ {" B2 t* D    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)
    ' Z' F7 e) B4 I6 U& y% e4 ?    {; U5 z9 s# R7 m9 K6 }
            m_ClientNetConfig.wClientPackSizeArray[x] = 0;' t* Z( a# k! [, b; x$ C- ]
            m_ClientNetConfig.wServerPackSizeArray[x] = 0;
    : q; F1 \8 N: }! ^    }$ @9 i. r8 L" n# r
    }</P>$ o- d9 G" w' e# c9 t& d  p

    6 Y' k8 \4 Y% B4 e: V0 [<>( }  v1 F$ y5 v3 d- a% D4 ^2 d
    //-----------------------------------------------------------------------------# D! F4 w3 r& w* h  E/ C  q/ O7 F
    // Name:
    , l1 T" i" Q4 U" H/ G& |9 E' ?// Desc:
    ) T# C1 V6 p; w# \7 Q4 |! m//-----------------------------------------------------------------------------
    - N6 b. C1 X* s2 K$ y+ m! bHRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )8 b0 r' B/ e5 C
    {
    # K3 |7 A6 w8 ^) n    m_bLocalLoopback = bLocalLoopback;
    ' b, l$ ^0 s% f! E9 t% E3 C8 \3 k    m_pMaze = pMaze;
    + r2 ]4 N7 i- h, k0 j    if( m_pMaze == NULL )4 z5 M# H6 {- W5 N# V/ \
            return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
    9 B- ?9 f! k4 h2 s6 k0 V( y; }<>    // Grab height and width of maze' M4 I. R2 j% q+ h% ~4 Z
        m_dwWidth = m_pMaze-&gt;GetWidth();
    , R% s- F0 k# I1 J9 _3 \% U    m_dwHeight = m_pMaze-&gt;GetHeight();</P>
    ; ]0 P4 |: x: I0 i6 e1 P<>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;2 k( ?& N) q- B
        m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
    ) i5 l- H' O0 k, r' o; I' t5 y  H<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.
    ' f* }9 M: f9 d. p) j' C- o0 b    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )3 z0 N# \  A. o
            return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
      v4 F. H2 I4 d. v" n& f0 Q  m' K  R    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )
    9 r  ^! e( i  J, ]( v        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
    ; |9 ]# b. }- P! J+ L8 V5 N% r3 q<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;* d& A9 u. p: W9 U1 Y
        m_dwMazeXShift = 0;4 l0 \- ]& {( ^9 O9 g
        while ( (scale &gt;&gt;= 1) )
    . D$ d0 `0 @0 C1 o- w% O        m_dwMazeXShift++;</P>
    8 |2 J! ]: A3 c<>    scale = m_dwHeight / LOCK_GRID_SIZE;' C6 C2 Y( C3 y8 X
        m_dwMazeYShift = 0;
    9 D' p& S/ K; T0 w3 e0 I' A. {! ?    while ( (scale &gt;&gt;= 1) )+ P1 c4 x7 J( ]+ ]
            m_dwMazeYShift++;</P>
    # d4 a  X' p/ |; R+ [6 `<>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    2 D, e1 ]8 g$ W3 e" m& i  s, H        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )
    2 H" l, u0 F* U7 j        return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>$ l& P/ ]+ a! @+ u4 q
    <>    // Initialise the player list5 ^" x. G  z# _9 `; e* u
        ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );
    ; n0 S0 e* R* f. F9 |    m_pFirstActivePlayerData = NULL;
    . k4 K) S/ U+ e* m( C    m_pFirstFreePlayerData = m_PlayerDatas;
    % ^1 w+ N9 G! P0 H* x    for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )
    , ?2 ^: B( E# g; R$ W1 a% l6 N' V    {, p. P. R2 c% |7 `' U9 T' S
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];
    ; p7 W5 B1 e6 Z" o4 C; n2 a        m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
    3 P: m$ V3 h- Z' h) w; v    }</P>
    9 |6 P& v( s: z3 ~; L+ W5 y<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
    3 e, p1 ?# \4 n- j    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];
    : N, Y% @' i) H) z  N4 s2 u    m_dwActivePlayerDataCount = 0;
    % c# A) }) |' |9 F! j8 h5 Q9 _    m_dwPlayerDataUniqueValue = 0;</P>
    1 T# y6 m( c5 H0 U3 U. I<>    // Initialise the cells! ~( `1 k6 {  c4 E' ]9 @# ~
        ZeroMemory( m_Cells, sizeof(m_Cells) );
    ; I2 i/ ^( p8 z6 R2 K    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>' x1 Q, j" E9 A
    <>    return S_OK;( z0 ^* g) |6 Z3 }: s; D: D
    }</P>
    ' P. ?: T3 ~$ H  p
    / e9 w) V/ \; x$ w1 H% B) p<>) f1 m$ {" g& y( d# ~
    //-----------------------------------------------------------------------------! ?1 ~- h5 U) |* ^( s
    // Name:
    - E3 ~. ?; X2 b0 c// Desc: 7 N  O8 O* v0 x( r, _% f
    //-----------------------------------------------------------------------------  k& [8 {. [; I+ L7 y
    void CMazeServer::Shutdown()1 ?+ N, L& Z# ^- w% U) k
    {
    9 C$ ]+ ~- {4 N, Y}</P>
    # E. S+ ?3 y1 r& S( a
    9 D  f4 _& d  k7 F  G<>
    4 I% X. `* U$ `$ b2 y- r" U; Z/ i//-----------------------------------------------------------------------------0 E6 y, d" `) m' N* @# k  z
    // Name: 7 R6 u, k& U" U
    // Desc: , q( |: I6 x  v; `6 `- \
    //-----------------------------------------------------------------------------$ }1 c9 ~3 [7 G: c8 s9 H' t2 k3 `  |% T
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )  [- E5 O  ^( g
    {
    1 ]% H* m$ P/ r4 F& K# ~+ m    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    5 q) z- |- o; [& [" Q1 r5 k                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );" }+ _" |8 @9 Q: r
    }</P>
    7 f8 u1 D! r3 D+ c; [1 d% B/ i$ }3 @+ n
    <>
    0 a5 d* U  A0 \, y5 S. W" w+ g: p//-----------------------------------------------------------------------------
    & T- l  Z. ^% C3 h" D+ Q& n9 W// Name: 2 G1 A: ]5 Z$ C6 w
    // Desc:
    , Z  h4 N' ^8 o3 I0 e/ q//-----------------------------------------------------------------------------
    2 ^2 E) U* D! @void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )% A- T6 x( R$ B7 {) S! ?4 p
    {
    ' X: Q; r* i# G8 }  f' |8 t/ u    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,9 ~) w- ]5 s( p. R5 W& i+ d3 E
                                x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    ( x* z3 ~1 [) N}</P>
    " Y% [5 @& `( X5 d& H9 d( T6 I
    * X9 ]$ s2 M8 M: Z1 \* Y$ g1 v* K( _<>
    ) Y& T( \, n9 _  `//-----------------------------------------------------------------------------. F! |4 x: G. ]
    // Name: ) f  O" c0 w" U6 H+ V
    // Desc:
    : U9 X- ~9 j  ^6 J//-----------------------------------------------------------------------------7 l! S5 t5 r: N) y6 F
    void CMazeServer:ockCell( DWORD x, DWORD y )
    3 p( C- w& M% _; U{
    . J8 n! a& ?; |( d& ]- Z' |    if( x == 0xffff )
    # k1 {; f1 z5 u2 o) H: Q2 \        m_OffMapLock.Enter();( N! v6 J# l6 B. H
        else3 k) {, P, J! j( a; V
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    5 ~* }5 k; r2 F}</P>- v" o+ N, J1 M! U7 Z7 O3 Q
    ! F5 V* @  o" B' G: G# J* {
    <>% g) J" {# |5 r. H% o3 e  W6 h
    //-----------------------------------------------------------------------------
    ( K& b$ C% ~. @  Z2 g9 V1 g+ x1 ^// Name: * s5 }# O! i( ~! t
    // Desc:
    0 l4 l( z' P+ d. ^1 R: H5 K//-----------------------------------------------------------------------------5 U# h& x$ s) a1 L+ L, [$ l
    void CMazeServer::UnlockCell( DWORD x, DWORD y )4 Z: \( {' L+ |' x' m1 ?
    {  z( |# [5 O) c$ Q; G  a& c7 J. E$ l
        if( x == 0xffff )( c8 l( q! @0 G* T$ j
            m_OffMapLock.Leave();
    " Y1 `" H& A/ V! }+ I3 s    else
    . Z+ i7 D: _6 y6 g  G        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    & m0 G9 K  {* [6 @3 b& u}</P>
    ) M3 t7 x% [. c& ^# \( G+ d3 I/ _6 x
    <>! s8 r; F0 v/ l; r/ D$ {5 R- [+ g
    //-----------------------------------------------------------------------------
    . u' n0 y0 V8 i7 F5 |7 _// Name:
    & `7 f3 ~- h! ?// Desc:
    0 ]) F5 q! T+ c2 D& Y//-----------------------------------------------------------------------------
    , F4 J) q# |0 C. a/ {0 c$ m9 avoid CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    ; k! K" d. j4 e0 \{  W. h1 _6 x: P) Q, o- c2 v6 r, M
        if( x1 == x2 &amp;&amp; y1 == y2 )
    ; u$ E7 f1 ^& Y    {& X6 _' ^( o; z
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    * q3 H" i+ z2 j0 m/ h  M5 x            LockCell( x1, y1 );
    2 C& y8 \6 v0 z( i        else
    # u; M/ `3 M8 `            m_OffMapLock.Enter();</P>& F. ^& V$ Y1 D' |
    <>        return;9 o$ V( ?1 x% [. w. A+ j7 s5 Z5 }
        }</P>
    9 n' [0 `4 D' ^+ U- \7 _7 d<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;6 _! c- o( t7 Y7 d8 c! a3 x: y
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    2 q) R% v. H$ y1 a# Q) d/ U    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    ) O1 o4 [" _% J* z1 ~    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    ; l  ]- u  u! T/ s<>    if( x1 == 0xffff )
    9 k7 ]/ F/ F/ Z% z    {0 L; Z5 n5 z. \0 q4 y
            m_OffMapLock.Enter();0 @! ^! M+ T1 A  `. ^* K* K$ _
            m_LockGrid.LockCell(x2shift,y2shift);
    , L+ U) w3 a3 ^; P: R    }
    9 \) O! }8 L3 L+ ]- L& F3 z    else if( x2 == 0xffff )
    ! h  H' ^, a9 S2 p    {1 |0 T2 m) O0 O5 X
            m_OffMapLock.Enter();
    9 |/ h0 ^; h& r* S) B9 {        m_LockGrid.LockCell(x1shift,y1shift);! o6 `) u5 H9 I. n
        }
    - V( s5 {* j3 F% J- P& r2 a7 ]    else
    6 ~" q. V8 _) z# e. H, _    {7 e7 Z2 n: O7 J& n4 t& T1 e% u
            m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);( X* D1 e% G8 Y
        }, E9 j) r$ c5 d9 r) j6 Y. H
    }</P>3 |5 @0 _) _7 O# D0 v1 M/ A, v: a

    5 J0 I: `- v5 N# a5 k  c<>
    3 I, b8 x3 \  K//-----------------------------------------------------------------------------
    - d, f# A& s0 [- E- {// Name:
    0 p: q: T; d( C4 q0 E: A4 E6 |; M9 m// Desc:
    5 t& p5 `$ c' F/ q; H& ^//-----------------------------------------------------------------------------0 l# h  p5 r5 f7 f0 g4 O; ^
    void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    4 u7 V% A4 T) B- i( g/ U{9 S2 F( S8 ~. F" x  A
        if( x1 == x2 &amp;&amp; y1 == y2 )) ~( {' Y  U' A0 G6 k. |
        {0 |) s7 V. I4 p, `. [1 R
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    % p; L* }+ J- G# i. g            UnlockCell( x1, y1 );5 \( j/ n4 h5 W, \' @
            else3 P& J4 @. n* \/ P7 R: ^# g4 n2 d2 Q
                m_OffMapLock.Leave();</P>- o% `7 M2 n5 n/ y
    <>        return;
    , Q( f6 ]# h6 e6 K7 D3 T7 \    }</P>
    8 e4 o# z/ H  X' C. P<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    ! \7 n* q9 J' X( o) U# `    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;# O! Q) g2 P- g' ?" D- |. U
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;) F7 `! c4 H1 V5 N
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>6 T% e% V, f" P" T9 Y* [
    <P>    if( x1 == 0xffff ), t) x/ k( i/ b
        {9 X3 M$ C8 D" B7 ^
            m_LockGrid.UnlockCell(x2shift,y2shift);
    2 ^$ F; @$ ?# U  \$ Z8 J( Z        m_OffMapLock.Leave();3 V6 z9 s- o. d/ w# C
        }
    0 n  w' q0 U1 Z- |& T4 W/ W! T) T    else if( x2 == 0xffff )3 I! R$ U; V2 a( C3 H3 H) W
        {
    3 s3 L' s; Q$ ]# F; I' M" v( }3 ^        m_LockGrid.UnlockCell(x1shift,y1shift);
    & h+ }9 N+ ~- E( `        m_OffMapLock.Leave();: m2 C1 V- Y. h# t8 {  j0 P4 A
        }$ a! d# I5 l- Z3 K' ?1 d% p) ]
        else
    8 [" h# J: ^/ [- E# O$ P    {( k5 l; T$ o4 C+ b
            m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);. p3 ~* A0 Q# Q" Q, ?. y# L* r
        }0 z8 C! ~2 z7 `3 M$ X
    }</P>- F+ c; X+ e1 ~" {" u
    0 H" K) J3 L% L" u# z$ _
    <P>
    & u4 U  \) @& ^! D- r$ ], |' y8 o$ t//-----------------------------------------------------------------------------* W1 l( n7 ]6 g" r4 ]' a8 o9 g1 l$ ^
    // Name: : z" f) E$ N/ ]
    // Desc:
    ) _, W& ?6 N8 e  E8 H//-----------------------------------------------------------------------------
    9 \: k9 {) \# U: K/ zvoid CMazeServer::OnAddConnection( DWORD id )
    / I; a1 B$ W6 k' v3 x; ^{
    , b' l" s& T/ a& M- O2 a  m! {    m_AddRemoveLock.Enter();</P>
      q( O1 M% Y7 e6 K' J<P>    // Increment our count of players) k9 D9 u) T( H4 M4 }
        m_dwPlayerCount++;
    ( O/ Y; F' J- O# q5 @" d# D. Z) Y& ]  l    if( m_dwLogLevel &gt; 0 )9 G) m# V  n: B2 V0 p- ^7 T7 Q
        {
    ; Y7 p3 o9 P9 Z: Z, H2 O  I. B2 o        ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );/ L, W  E2 u0 L! @/ D5 g  T7 b
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    % r. O" A: Z) H" T    }</P># Z" z" s( E6 y) f
    <P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    . m: \! y- I' w        m_dwPeakPlayerCount = m_dwPlayerCount;</P>
    ) U5 x/ a7 G" N<P>    // Create a player for this client
    0 b. u; p$ w& |1 p    PlayerData* pPlayerData = CreatePlayerData();* F% G& ]: N7 Y5 U2 k- X
        if( pPlayerData == NULL )
    0 X! Z, C, |+ j5 C    {
    9 M0 L: h( z" l" r5 W" V        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
    * a- i: k% |8 \/ I2 l* ]3 r. b( Q        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );5 Z/ d. T. T- v# X: }6 g) _2 V
            m_AddRemoveLock.Leave();
    ! t* o5 C9 G0 R) W        return;% x0 c( i: }: Y2 D1 V
        }</P>1 Q2 o5 ]" d, J2 u2 X
    <P>    // Store that pointer as local player data$ |- a; F% U" J1 V* m) }. s* G
        SetPlayerDataForID( id, pPlayerData );</P>  L- y& k) L% `% K% x4 y4 H9 o
    <P>    // Grab net config into to send to client
    $ e' v1 y1 C! z) {/ e/ ?) I" @5 S    m_ClientNetConfigLock.Enter();
    5 r) r" v: e+ L    ServerConfigPacket packet( m_ClientNetConfig );% A% y$ C: t, S; }% A* M3 v. l
        m_ClientNetConfigLock.Leave();</P>
    9 y3 M3 @8 D5 v<P>    // Send it0 R$ x3 Q! l/ H7 Y( W
        SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>  k5 Z; x, ]7 B+ S
    <P>    m_AddRemoveLock.Leave();
    5 s/ o- S0 E) W6 B9 [8 I  o}</P>1 o0 P+ N) {' g
    $ B8 c: Z/ `) O( J+ e" g
    <P>
    * R4 \: P8 Z  M$ w6 c2 m//-----------------------------------------------------------------------------! \4 ]% P3 X3 o5 b3 T( Z7 |
    // Name: % W% @. X1 a; ?% X
    // Desc:
    1 M4 S5 C( k. w6 }//-----------------------------------------------------------------------------3 |/ o% c8 z! C
    void CMazeServer::OnRemoveConnection( DWORD id )
    $ l1 [9 {& @, w  }{0 o1 O  r6 c) x6 G5 ~& n% h# j
        m_AddRemoveLock.Enter();</P>
    % ]" X9 K2 G0 T- ]( d<P>    // Decrement count of players
    * f; P$ @9 d6 J" b+ t, R8 M    m_dwPlayerCount--;</P>: A" A  h( g2 ]0 e9 b2 _- K, v
    <P>    if( m_dwLogLevel &gt; 0 )
    * E& p$ P: A/ W/ C* ]6 k    {
    - v/ J, r9 A0 p        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
    - e/ L* L5 A) T" K. ^$ L" d        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );1 L( m( [/ P4 r; C/ p+ ]3 F9 R
        }</P>
    ' d$ D" B/ H( h0 b/ H<P>    // Find playerdata for this client3 H7 j- L, e% P7 Q5 ?
        PlayerData* pPlayerData = GetPlayerDataForID( id );
    . Y- u4 ^1 G& z% ]" C    if( pPlayerData != NULL )
    % W2 ~2 d" w9 K3 t4 m    {& x7 V! Y6 `. b9 c
            // Destroy it  W) o& s, {6 r, [
            RemovePlayerDataID( pPlayerData );& G$ X6 I5 J# E; m- ^7 K
            DestroyPlayerData( pPlayerData );5 `6 q: ^  e9 K
        }</P>4 J; ]- Z5 \/ P+ H# `$ v
    <P>    m_AddRemoveLock.Leave();
    8 P7 [. K! Y: q}</P>
      M2 M6 N7 q1 W8 \! K6 ~% ?; ^% Z3 {7 j
    <P>9 [! y1 K9 D6 }/ _
    //-----------------------------------------------------------------------------1 a! f- S! M& N1 ~- y4 x+ s' d
    // Name: 6 r) @- {2 }! ^, |; S( L1 z
    // Desc:
    + c- m( z$ I1 w//-----------------------------------------------------------------------------8 N& v# n1 A3 D! h. y, s
    HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )
    5 {+ R0 F. {9 s{# P% j+ S. x5 B) P- X9 H1 u3 p% A
        BOOL fFoundSize = FALSE;</P>( `3 Z7 F( z: b9 ]/ w6 J
    <P>    // Increment the number of thread we have in this process.. T5 x- O! v! U; h, E! B& C
        m_csThreadCountLock.Enter();</P>
    ! f( W& p- ^% f+ S<P>    //Get the start time of when we entered the message handler.* z; p2 i" t$ R1 j+ Y9 R  j
        FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
    4 D! d' j: a$ s3 A  }" O<P>    m_wActiveThreadCount++;9 `8 W/ O' a9 V4 @; g* U
        if(m_wActiveThreadCount &gt; m_wMaxThreadCount). O1 {$ R3 b# \+ `" R9 d* P
            m_wMaxThreadCount = m_wActiveThreadCount;7 o2 s8 f* Y/ _8 U/ G# S
       
    4 Q. R  H+ |  q8 u$ j    // Calculate and average.  b% U3 l; w) k! G# n/ P
        FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;+ Q# j% _3 @9 K& o8 s! p9 y
        m_fAvgThreadCount += fdiff/32;; u9 Q$ n2 E7 Z) @) [) w: T. u
       
    1 q% ^% d" @1 x$ q    m_csThreadCountLock.Leave();</P>
    " v3 k" W& C8 T1 U5 N$ T<P>' S/ t2 T( |$ G+ o- P. |2 @& r
        ClientPacket* pClientPack = (ClientPacket*)pData;" m0 B8 T; I# A, s; p7 T
        switch( pClientPack-&gt;wType )" w4 C: s6 o: D* o' O  D
        {
    . o; ]( e! h, [: X, c$ ^; _        case PACKETTYPE_CLIENT_POS:
    : {% D+ s% C. h. ]& [            ) d9 s: u! g( b
                // Check to see if the packet has a valid size. Including ' w4 x8 I; s3 {' O5 _+ ~
                // the custom pack size.
    % ?$ O1 I* O9 j8 I$ B! J            if( size &lt; sizeof(ClientPosPacket))+ Z" X0 I; g( C  E& ~& N
                    fFoundSize = FALSE;
    ) E% ~) j4 i7 e, L3 A; [            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))% C0 y! p8 n! ]; i$ H- h
                    fFoundSize = FALSE;- a, N& l( d; `- n
                else
    5 d# O5 O, O3 M                fFoundSize = TRUE;</P>. Z: x7 A5 I2 H; q6 q  l2 v6 S5 P6 N
    <P>            // If valid sized packet, handle the position.& y9 u4 O. [7 j& Z, {8 X/ |# u3 N
                if(fFoundSize), N/ G0 {2 w" _
                    HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );
    ! h" Z+ [& C* Q2 M            else
    6 u7 N" x' S. I3 p6 G                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
    ! t/ Q% j3 G+ D2 c2 W* [$ b<P>            break;</P>! q/ ?( z, ~$ w" g6 V  C
    <P>        case PACKETTYPE_CLIENT_VERSION:
    7 s, `2 @9 G+ U            if( size == sizeof(ClientVersionPacket) )' E! V4 K( l9 ?: ]# m3 Z: G
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );8 a6 l% b8 y" O0 L. }, _" q
                else9 F+ g6 }! K6 v, g$ y# L% ]
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    & h$ j5 g. f; I2 t6 K& }8 y            break;</P>
    * B. s3 D# I" I7 Z& A  f3 J<P>        case PACKETTYPE_SERVER_CONFIG:</P>
    . h+ {- i  I/ a* n1 u* d5 m<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>
    ' Z! k1 z: M6 K; p  ?4 ?, k3 g<P>            break;
    ) m! j1 z" U, k8 m$ t        default:
    * p, `1 m8 w( {            HandleUnknownPacket( dwFrom, pClientPack, size );
    % n3 ?$ P# K% z! `3 ]; s/ I( v            break;
    ' @/ d* v  u, r# H8 Q0 L/ D% C    }</P>$ r9 S' m& ?- }& J: u
    <P>    //If the user wants to hold the thread, Sleep for given amount of time.
    " k1 @6 G5 K, {/ ~# O    if ( m_dwServerThreadWait &gt; 0 )
    6 n+ ~* r8 i$ \4 N- h/ R) y    {: w! T% b2 Y$ W: C) D( f9 d
            Sleep( m_dwServerThreadWait );
      o; ]# u5 \# o* K0 |$ d8 a    }
    + H) ], V; s# m& l. N# C    % |" e  J" M$ i  ~$ B! m4 N
        // Retrieve thread data for this process.
      a. p5 j0 s) {: v, j5 q    m_csThreadCountLock.Enter();</P>  {6 R, x7 b' f2 X( |( P
    <P>    m_wActiveThreadCount--;</P>
      z# q8 `8 K* R) S8 |<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;* t9 V$ ^4 F& f, w: p! o0 D
        m_fAvgThreadTime += fDiffTime/32;</P>8 \: V8 F9 Z6 s: F& m0 i
    <P>    //Get the Max time in the thread.
    # ^5 g% X0 x& a. S& [! t    if ( fDiffTime &gt; m_fMaxThreadTime )
    ' G% s) ]+ L6 M! n  c    {# Q' c, s) Q# w8 ?) D" t
            m_fMaxThreadTime = fDiffTime;
    ; d' [/ O* m4 q6 ?9 E    }</P>
    9 e" y' N1 z: y: d<P>    m_csThreadCountLock.Leave();</P>/ L$ \  a, D( T9 y. S
    <P>    return S_OK;
    : ?  l* l* x3 \1 q( O9 T5 b}</P>" H! O' J. t9 z; e

    9 ~* h% @4 `: _0 P5 z( |1 V+ ]<P>//------------------------------------------------------------------------------ ~1 ?/ j0 ]0 I' u3 T3 A) T
    // Name:
    2 L# s4 v; p. _// Desc:
    $ W% b7 Q# f: ~1 c0 ^2 w. C; K//-----------------------------------------------------------------------------6 o4 m/ k+ o+ u+ j
    BOOL CMazeServer::IsValidPackSize( DWORD dwSize )4 C' P& e& _% U9 V0 p( F& u
    {
    $ C3 o6 D8 w6 F3 s    BOOL fFoundSize = FALSE;+ n1 D7 s& P# ]1 R9 C
        BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;
      W+ D/ X7 \+ {1 C+ z    & X% q: i) i9 b+ l& E
        // Check through the array of valid pack sizes.
    3 d% l& B0 k7 p$ s    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])% J9 s' I2 z9 `1 w8 S0 v5 b
        {" c/ C' V9 N9 o* I& N) ]/ h
            for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)5 @+ S2 W: F1 u! h! e1 ~
            {
    2 B" b! y* D7 W. K& D7 W3 z            if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])6 w, z/ A+ @% G2 v+ Z$ I/ e9 p
                {+ I; t/ @: H5 B) E* w
                    // Found valid size in the array.
    * e* C0 t& l- g) |* {# }                fFoundSize = TRUE;
    $ X: G. v' r$ z, M  J7 s% E                break;
    + R4 ]# R* x. X            }0 n$ Z) n: c7 f5 a3 t
                if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
    7 d% X8 S  ?7 ]" |2 {5 x+ {        }# ]' p/ y9 l/ f  t5 L# l4 X
        }, B9 W5 G1 x$ Q- \% j/ b/ x. m4 n
        else
    ' A! Y( F" Q- S1 ]% @    {
    1 F) K9 k+ u' a* Q+ h        fFoundSize = TRUE;, [% I! r7 [# T5 w5 b4 F; h2 x
        }</P># k9 Q6 }) ~' ?, U% L  I" \! S
    <P>    return fFoundSize;
    7 `9 i( |# B3 v4 p" \8 R}</P>
    / \% {+ X0 `5 l7 T/ n0 |<P>
    ( h3 l! Y  U/ y) M//-----------------------------------------------------------------------------! `9 n8 N  b. T/ a) k6 g" j* n7 W
    // Name: 3 ^* Y9 P/ g' x. H: \9 @: y
    // Desc: 4 [, M# A9 ^5 Y7 Z3 O
    //-----------------------------------------------------------------------------
    : Q7 t: \. d7 l. |void CMazeServer::OnSessionLost( DWORD dwReason )5 H  ^: L  @! U' G
    {4 }1 ^- V% D2 ?0 E6 l( t6 i/ k
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );0 ~$ B* z, l7 C6 w) X" }- x
    }</P>; _/ k+ O5 ~1 E. [

    ( `5 L2 I& l9 ]<P>
    4 h' |/ \. \* }//-----------------------------------------------------------------------------
    8 R6 A7 A) ]5 o" N# {1 G// Name:
    0 I1 S+ Y! L& J9 a: G// Desc: 5 V: C0 `# b% |5 A1 K) P6 y$ x1 `
    //-----------------------------------------------------------------------------! G- I; O6 `9 P" w9 N8 Z
    PlayerData* CMazeServer::CreatePlayerData()
    " t$ Z/ y; B3 ~+ Q+ k" b: Y8 C{
    : T0 ?$ o' m4 x0 G5 y; y4 r! R    m_PlayerDataListLock.Enter();</P>% k2 |1 B' V4 ]& ^$ u$ [
    <P>    // Grab first free player in the list
    ( c/ n. u6 B7 C' A- m    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>0 T0 c0 m: ~3 g" E5 e1 [
    <P>    if( pPlayerData )& ^2 m& L. Y* b' W6 e
        {
    ; P' ~+ q2 \5 K        LockPlayerData( pPlayerData );</P>
    ' c# W. _4 P7 F7 a  K7 @<P>        // Got one, so remove it from the free list
    / w+ U  Z* M8 I% f; M- J        if( pPlayerData-&gt;pPrevious )/ {" s3 M( z9 F# t* |6 C3 s' z
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    " G# ~+ T7 W1 i+ k5 K        if( pPlayerData-&gt;pNext )
    % \2 q4 k1 K! x) ]5 s$ o  A            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
    ) X6 K4 I( ]- Y        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>
    " s) F( G; F+ T3 H: _- b<P>        // Add it to the active list
    + }; d1 L* H' U: q5 ^3 d3 H        if( m_pFirstActivePlayerData )
    . b2 V9 z9 ?7 S. a0 Y% K            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
    % m1 A- M$ c& _7 W- s        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;
    : A, @/ u* b5 _; t) C        pPlayerData-&gt;pPrevious = NULL;
    " f) V$ B8 D6 s        m_pFirstActivePlayerData = pPlayerData;</P>
    $ h" s$ u% `3 w5 z4 C<P>        // Update count of players
    / c) j' t7 o# M: y        m_dwActivePlayerDataCount++;</P>
    9 B8 t& n2 y2 `' g+ c6 a<P>        // Generate the ID for this player' }. \" y  J* \# B
            m_dwPlayerDataUniqueValue++;5 W8 }4 s, r; W/ K. P
            pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>4 n4 d+ F' [! i( o" b: R" t1 K
    <P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
    : M7 g% t& V" m* J; q        pPlayerData-&gt;NetID = 0;
    0 u* v3 T" {0 H+ }        pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>
    " D; i" a* ]5 \) ?" |. N, J6 O<P>        // Insert into the "off-map" cell7 ]& |$ t! R$ d" Z
            pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;3 G6 G, \; G, D( n
            pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;
    % e8 T% _/ @5 `6 G- h) P9 X2 J: X        m_OffMapLock.Enter();$ m) U6 x+ l# v7 Z
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;
    ! c; Y9 k% i  r; J, M        m_OffMapCell.pFirstPlayerData = pPlayerData;
    0 D/ n; j$ K) s; L        m_OffMapLock.Leave();</P>7 J& O3 q/ f" n+ \6 g
    <P>        // Mark as active
    5 k  N$ `* o; Y0 t3 n5 V* o        pPlayerData-&gt;bActive = TRUE;</P>0 r; U# T. E3 H- r' u
    <P>        UnlockPlayerData( pPlayerData );
      E3 l% l& Y$ e! T    }</P>4 r6 Z! R0 V8 s: |, o/ ]
    <P>    m_PlayerDataListLock.Leave();</P>, b+ ?! d: f7 X  u) ]
    <P>    return pPlayerData;7 A6 p' X; [9 x3 L
    }</P>
    / C* n  y# B0 N& Z4 }4 |. j- ]' f% D& ?) p) Y
    <P>
    % T0 c* j5 L+ C# A4 L6 \3 h/ @5 z//-----------------------------------------------------------------------------
    3 H: E$ i6 `  f+ h( J& b7 t// Name: ' C- j- O& W$ ?. b
    // Desc: ! N+ q( N9 Q9 E3 G
    //-----------------------------------------------------------------------------6 ^2 l6 g2 U, \% V
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )' ^- h0 j6 Y/ C* ?' t/ o
    {
    & |+ \7 ^6 ^- k/ u    m_PlayerDataListLock.Enter();4 R. G' T  ~( j1 D
        LockPlayerData( pPlayerData );</P>
    2 @4 ^5 W, N* i<P>    // Remove the player from its cell# K$ j8 {5 S8 C. l. }
        RemovePlayerDataFromCell( pPlayerData );</P>( k4 ?4 {) k% Y+ }, N1 y7 J
    <P>    // Mark as inactive
    $ e5 k% h5 [0 ?1 `    pPlayerData-&gt;bActive = FALSE;</P>$ ^: ^, Q7 w8 f+ k$ k+ M
    <P>    // Remove player from active list
    ; [6 I. z5 E0 S# t! K8 ?' O    if( pPlayerData-&gt;pPrevious )
    ' ?9 c" L. n5 G3 H& c; G        pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;# [1 h+ {" C9 ]' B3 R. T  A' G
        if( pPlayerData-&gt;pNext )5 F% L4 M$ p, u- C/ Y4 K; k1 G, q
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>
    . A, D! k; n) v* Y<P>    if( m_pFirstActivePlayerData == pPlayerData )
    " Z/ q+ }; }/ V- V3 B9 e: i        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>
    $ c2 O& a# P- H: f" n' N# J<P>    // Add it to the free list
    ) L& C4 E4 h" o( v. R! u; F    if( m_pFirstFreePlayerData )
    1 P- H/ m- o0 ~        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;$ _& x3 a: c5 k  P0 R1 F
        pPlayerData-&gt;pNext = m_pFirstFreePlayerData;- h# w* s$ M8 A: h
        pPlayerData-&gt;pPrevious = NULL;  k8 i! W+ S  {  H' \% r8 G
        m_pFirstFreePlayerData = pPlayerData;</P>
    + L5 u' N# z# @$ q<P>    // Update count of players  g) v& `5 [( {/ M* q6 B2 \
        m_dwActivePlayerDataCount--;</P>( J  _+ @6 h) \; `0 I7 M
    <P>    UnlockPlayerData( pPlayerData );  p8 o" H+ W+ w1 j6 l+ N
        m_PlayerDataListLock.Leave();! z+ E+ @1 E( d9 x. T
    }</P>; C. k% b* Q4 A0 X" m

    ) J8 Y: Q; Y( [7 ?<P>9 b/ ^: M. Q5 a- o
    //-----------------------------------------------------------------------------' q. j) v% I7 [0 n, F
    // Name: 1 k+ \2 W5 o7 E& G9 ~
    // Desc:
    ( g' ?( k- C2 o% r* K* `; {' p$ Z' _8 ^//-----------------------------------------------------------------------------
    7 o# A  c7 B$ _8 p* g0 y# r6 C8 d6 Kvoid CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )4 \; M% l! n! d9 K7 t
    {; m7 {( C9 V5 c4 M2 }
        // Lock the player
    4 k  d* [/ Y* @  b    LockPlayerData( pPlayerData );</P>
    7 B# p& i, t7 ~1 J, G5 ^<P>    // Lock the cell the player is in5 `% ^) h; O6 w" g  }$ X# r
        ServerCell* pCell;
    ) Y$ V3 P# Q% h- \    if( pPlayerData-&gt;wCellX == 0xffff )4 o* G' K8 e3 X
        {6 J8 E' ^* a# u
            m_OffMapLock.Enter();
    ! `) H  d# R% b& _        pCell = &amp;m_OffMapCell;1 x1 W2 k* x6 z
        }
    % A3 f* B2 k7 V8 J    else
    1 a! v9 X' X) ]; f" l; U- |    {9 ]0 ?# F& y% @9 w
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );
    0 |' H# h& N" s; i: E) S  j) I' m        pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];! ?( X( v# y/ s& N2 L
        }</P>
    0 a. U4 _3 a; V2 j: z7 {) J" d<P>    // Remove it from the cell9 B( `% P0 r, u: b* S: W! c
        PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    1 [! g6 G, Q+ j# [* s8 c. T: V9 L    PlayerData* pPrev = NULL;  w! n- M2 s, a
        while ( pPt )
    8 k; t% j' F  ]' q2 t    {
    . [  b. p. ~( k- z        if( pPt == pPlayerData )- s, Z0 }8 W2 t/ D/ Q$ Q
            {8 y" L& E, q5 W1 H  h/ w/ l
                if( pPrev )  A" s+ U# r1 R3 \0 ]3 M
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;8 V; C; J5 ?! x; a
                else6 W& Z+ J' ^) C9 S1 b2 ?
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
    ) w0 c4 i# g8 _" x- d( \<P>            pPlayerData-&gt;pNextInCell = NULL;& [8 z3 v7 a2 q& U
                break;
    ( G8 H0 X. v4 w        }
    / z- K7 N7 T4 R, ?' k% s        pPrev = pPt;0 Y2 ~& a3 K/ P  i0 w$ w
            pPt = pPt-&gt;pNextInCell;4 g8 h3 G5 e& y
        }</P>- [. D6 a' `+ O3 B% ]8 J# y' c
    <P>    // Unlock the cell0 z9 r! L5 h& `  J: h
        if( pPlayerData-&gt;wCellX == 0xffff )
    & e9 s, }3 D3 v3 \& Q1 c        m_OffMapLock.Leave();
    ; e" |# d: ?" t9 I3 P7 o    else0 O  W/ |$ J7 n
            UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>$ [7 P. W1 A1 \. Y
    <P>    // Unlock the player0 j& r  y4 Q; J% ~. F: _
        UnlockPlayerData( pPlayerData );
    3 M1 U5 P, z7 X* }( s! T, B}</P>, Q) X/ w+ B  }! n
    % T" r0 q9 S5 u- Z
    <P>0 g6 o- Q, n6 Z* M. K; y8 @$ r
    //-----------------------------------------------------------------------------
    6 e; L! s! K0 y) d! b9 o( Z2 E; ?// Name: 7 n$ R/ @1 ^9 u+ X
    // Desc:
    ) X! n  @1 z$ Z  a6 J//-----------------------------------------------------------------------------
    2 W3 V8 w, r  J; l  T0 Yvoid CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
    + }! g$ p1 \' ?+ b- ~{$ J$ h! ^( t( R6 T1 l
        ServerCell* pCell = GetCell( pPlayerData );
    1 n- j( u2 k: x1 U5 T* G7 q    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;# X$ x1 `. Z. e2 b8 V
        PlayerData* pPrev = NULL;* O$ Z3 N" X8 ]. ?# m, V0 e3 J7 p4 t* R
        while ( pPt )
    # l# C* W  c3 x) a" c    {" I" w, v. f0 O- K' p- \, @( B
            if( pPt == pPlayerData )# U! `$ Y- p; ?% V
            {
    5 X8 x8 y1 Y- q+ ~  p' Q9 e0 L" V7 ^            if( pPrev )3 X- m, F8 X: T1 H( ~
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;/ c$ m' R9 A6 Y7 X6 g, \+ V& ~
                else
    / \) f, T. O$ y5 B" x; {                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;( i* b$ }/ A. }2 P4 K
                pPlayerData-&gt;pNextInCell = NULL;
    2 d% k& W' m2 |+ ?/ L            break;
    2 U: Z, l7 I4 q% P( R  C        }: g+ C7 c( Y" S) p5 y6 a* s
            pPrev = pPt;
    9 C" q7 T3 E5 \8 |3 B; y        pPt = pPt-&gt;pNextInCell;
    $ ^  Y: k9 s$ s9 W    }
      ^# X, o  X2 {1 x5 J9 R3 R! B$ e}</P>+ j8 k0 {# z; a$ B1 t7 ~; r
    " T* B. ~# C- A5 f- O
    <P>9 K% R4 T% W7 B' ?6 r; n% O
    //-----------------------------------------------------------------------------
    ) d7 a' s& U4 Z7 y6 i- O5 {// Name:
    2 X6 J7 ?/ E% n0 e2 n( Z// Desc: . u8 A: z1 N0 v' D* V
    //-----------------------------------------------------------------------------
    4 b) z- q% d" t: f# H* cvoid CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )
    ( F5 h) r1 c0 P' z0 z+ x' _{
    . n5 P- a1 ~4 \    ServerCell* pCell   = GetCell( pPlayerData );
    7 ~7 Q! p! W/ B6 D" {) H2 R, G    pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;
    3 ]- s$ m7 i6 i    pCell-&gt;pFirstPlayerData = pPlayerData;
    6 Z: d- j: f- F6 F* J5 J$ x}</P>  v: I7 K% {6 V  T4 e
    + d$ `$ s: U( Z/ K
    <P>
    # Y7 W! x0 G" Q' G( p. S//-----------------------------------------------------------------------------
    " c# |4 c% O& p. o" S7 z// Name: / f$ X9 l3 b5 O! o4 `: V- q/ q# }
    // Desc: 3 I9 S6 p- Z) i* u# @0 @. p/ `/ t/ N
    //-----------------------------------------------------------------------------
    . ]1 a- \- N9 G* k9 e( n$ {void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )) k1 l/ X' }% }. t* x% u
    {
    % _( B& Y# |. I8 `, Y6 Y    // Grab player for this client and lock it
    - z# v* v& W) g    PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );
    9 Q' C7 B1 {+ [8 r3 y% [7 f    if( pFromPlayer == NULL )* A) P: y1 p, N( l7 _+ z( j; M9 i
        {
    + Z. z2 S- z0 {. B        if( m_dwLogLevel &gt; 1 )
    7 I& T3 x) o9 p% Q' C% i            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );
    ' \9 C7 b1 F" D$ D        return;, M- E8 s7 P" y/ t+ E: o
        }</P>5 b; x' L# o* h( n$ \6 X) z
    <P>    LockPlayerData( pFromPlayer );</P>
    6 \; q5 W0 t! t: r2 G<P>    if( FALSE == pFromPlayer-&gt;bAllow )
    : T3 A: S, X: j5 h    {* {: }6 Z- [3 h4 V& R
            if( m_dwLogLevel &gt; 0 )
    " M- a3 q9 P0 J, ~. o& \            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>; s8 Q& H% Q/ P, ^+ @4 Z
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );9 B6 h$ [  T' f8 F* g+ o# T
            UnlockPlayerData( pFromPlayer );
    8 R% y: [( }: u, ^$ v3 Z        return;
    1 l: U4 W9 o4 P    }</P>' z3 w6 F1 T7 k, J% C
    <P>    // Compute the cell the player should be in now- {7 I$ P/ r& ~
        DWORD newcellx = int(pClientPosPack-&gt;fX);
    9 R* w- T4 z6 u* W7 a9 b% d    DWORD newcelly = int(pClientPosPack-&gt;fY);
    . w: p4 @. t7 y. O7 m- e    DWORD oldcellx = pFromPlayer-&gt;wCellX;
    5 @  Q/ D) I4 X; Z    DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>
    # n. I. z% Z* s! l. q/ \<P>    // Have we moved cell?, }* X9 D# m3 q* `  I3 h
        if( newcellx != oldcellx || newcelly != oldcelly )
    ) F, c: J/ z& e    {4 Y- N3 |" a( ~3 U3 W# m9 G
            // Yes, so lock the pair of cells in question
    5 z' r8 s# c! G) y& F! K% `        LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>. g% C0 A4 u) D
    <P>        // Remove from old cell and add to new cell2 l* ^  ~( a* X2 y* H7 p
            UnsafeRemovePlayerDataFromCell( pFromPlayer );  ]) R6 f. W$ D. G' c0 n! Y
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);4 \: C6 m( q  c: z- q% `+ F
            UnsafeAddPlayerDataToCell( pFromPlayer );</P>& k, ~, B) C1 S/ Z6 U* }
    <P>        // Unlock cells
    $ y5 a& B) `% m: k        UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );
    4 q3 e+ u) v3 p7 S) C    }</P>. J# m! x7 T. x0 t1 \
    <P>    // Update player position: o- R) m( ]+ a- R+ G1 E9 [
        pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;1 c, b9 i6 P& E* y
        pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    & y. D4 u& a6 ]: T; X+ |3 J    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>0 U" h! q8 [- l
    <P>    // Allocate space to build the reply packet, and fill in header 5 c' S4 c* S: J6 s+ H( ^3 e4 [
        DWORD dwAllocSize;
    , W, C  [) Q& Z4 P+ v; ~7 o5 C4 D- H    ServerAckPacket* pSvrAckPack = NULL;</P># k5 c0 O6 ^4 q' B$ @0 \# V, [7 z
    <P>    // Begin by allocating a buffer sized according to
    # ]! }9 j' K1 d: X& d2 p    // the current number of nearby players + 4.  This will give ( }7 l0 K( X* H
        // a little room for more players to come 'near' without resize$ J  h+ t5 E6 N$ K6 z5 F
        // the buffer.) J, \6 D& \2 m0 X9 z% `
        DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>
    6 M+ R5 \+ d$ p  Y5 [+ e# N<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);: J, o- e# s1 F& x: y6 U
        pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    . V% c4 W) o. h: c9 H    if( NULL == pSvrAckPack )
    * ?2 J+ F5 y0 G, ?: t    {
    " ^. P/ X# I( |+ Z        // Out of mem.  Cleanup and return
    $ C" R5 A: K1 R: H+ ^        UnlockPlayerData( pFromPlayer );4 D+ n0 Q4 k# L1 ~. t1 `
            return;      
    . J; B4 r& W& u& G" X. {* @& [    }7 e6 }  x9 G" l/ m) a$ U% M
        ZeroMemory( pSvrAckPack, dwAllocSize );</P>' p2 R( i8 G, T6 b9 _9 D
    <P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);
    ) B8 H) `8 v0 ~* G2 h1 \    pSvrAckPack-&gt;wPlayerStatePacketCount = 0;+ j; h& J- m9 v3 V
        PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>
    ) X" y# T1 Y" e/ o$ b, J<P>    // Compute range of cells we're going to scan for players to send
    * z0 C+ Y( y, G% H0 g) j    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;& K+ D  u8 Z9 i+ h0 q
        DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;! e6 x2 j, S# v2 _8 j3 @4 K
        DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;
    ' ]+ w4 R. s2 K8 e; i% J6 J9 H2 S    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>
    $ O8 d6 m# l3 [1 N2 w+ \<P>    // Lock that range of cells. x  }7 i- a; f5 a6 @0 @3 q
        LockRange( minx, miny, maxx, maxy );</P>
    ' H* ^% R4 B# A# b# q<P>    // Scan through the cells, tagging player data onto the end of) e* H' J( ~/ I. d; G  _
        // our pSvrAckPacket until we run out of room- j8 \' ]4 k, C" A3 [0 n4 O# D$ Y
        for( DWORD y = miny; y &lt;= maxy; y++ )2 Q- n8 X0 w3 R+ ]9 W
        {
    # _6 |1 R. X1 m8 O$ L1 X# t8 D        for( DWORD x = minx; x &lt;= maxx; x++ )+ z( M. k! h6 @/ c5 h0 G% |/ }+ _0 j- E
            {: |5 v3 m$ f1 v( P0 S- d
                PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;
    ' i8 V( o: c) A# T% i. ~            while ( pCurPlayerData ): [! n+ h6 O$ ~2 p/ J
                {* l. J- `; ~) x6 t0 d
                    if( pCurPlayerData != pFromPlayer )
    2 b  f2 y) l/ g9 z                {
    - C& Z/ w2 P$ O/ X+ e2 z                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )
    ) z0 g) D+ x3 G2 o/ Q' b                    {* y; e0 G! n) s* D+ u- Z( c8 z" b5 S
                            // Make sure pChunk is where we think it is! p5 g3 `7 A2 V5 v
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>8 J: U/ y! _2 k; H
    <P>                        // There are more than just 4 new nearby players, so resize the
    ) E2 h! d) `( u8 _! q" X                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
    5 P0 L8 |, g1 c+ T& i5 ~                        dwMaxPlayerStatePackets += 16;+ t; j; i+ g4 ?9 B
                            dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);* B$ y9 h5 ]4 _8 W* ]! t
                            ServerAckPacket* pNewSvrAckPack = NULL;0 E6 \" X4 g. d) l, N9 ?+ H* ~
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    & ?) m0 [6 S" A* u6 e                        if( NULL == pNewSvrAckPack ). Z) _5 W2 v/ j/ M
                            {
    ! r4 ^0 j, A4 s8 Z+ a' m                            // Out of mem.  Cleanup and return
    4 q) a) u& b/ {0 j( H8 H/ N                            free( pSvrAckPack );, k' P, h6 L5 ^2 q
                                UnlockRange( minx, miny, maxx, maxy );
    3 r4 ?1 D  m+ ]/ ^                            UnlockPlayerData( pFromPlayer );
    ' ]' ]% `5 Y. i4 d                            return;      
    0 }% c1 C; {7 P                        }</P>
    2 s' Q% t/ [7 M7 A<P>                        pSvrAckPack = pNewSvrAckPack;3 O% @- Y4 R& o6 O! d. ]0 H7 j
                            pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>: V+ D1 u! s4 D' @
    <P>                        // Make sure pChunk is still where its supposed to be; n+ a; i) Q( Z8 i
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );
    0 F5 G- O  h$ ^% K                    }</P>
    " v) ^7 q" G0 }<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;, ^- u9 Y+ ^" X2 }. z) G
                        pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
    / K8 C) T8 k; m* l4 n6 ^                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;
    6 a$ m( N/ a2 W                    pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;# p$ t2 i7 R9 M9 }
                        pChunk++;
    6 `; c+ H* w5 n! p  a, @6 [                    pSvrAckPack-&gt;wPlayerStatePacketCount++;" A: k* |! B: ~+ Z) @% z
                    }" g/ |7 r' W- b1 |4 B* G
                    pCurPlayerData = pCurPlayerData-&gt;pNextInCell;
    ! k& [6 c$ Q' \2 e. g            }* l/ i) k8 b. w+ r7 W; j1 X
            }
    % G( i0 x5 x. b5 W" c    }</P>/ C7 O7 f5 p, x$ |/ u! N! B
    <P>    // Update the dwNumNearbyPlayers for this player
    " L, ~+ S5 t% ~0 R& \2 s# G    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>) D! F/ r/ j& s  r
    <P>    // Unlock range of cells& K6 ^) [0 ~1 D5 d" Y) G+ o
        UnlockRange( minx, miny, maxx, maxy );</P>
    ; d$ p# a2 J0 t; S/ h% u<P>    if( m_dwLogLevel &gt; 2 )
    - U0 S! @: O* A+ c, m    {
    , s1 t9 R' R4 ~. o        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );) U9 i+ r) v* T/ w$ b! d
        }
    ' r, g& u! b1 x5 T2 ^    else if( m_dwLogLevel == 2 )
    $ i9 `: g0 J6 N! h& q; m) ~7 H    {4 {- \; m! N4 S; l2 A6 }: G
            FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    ; ]0 g; f, ^1 C# }6 f  ^5 X        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )
    6 Z" m6 \! G& n0 j* _        {; ?$ n$ W2 |5 L
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    ! Y$ v' R: ?2 Z            pFromPlayer-&gt;fLastDisplayTime = fTime;! r; W$ O4 O/ x0 ^! M2 {
            }
    6 m, w+ r, t( f1 T    }</P>
    . [; c: T$ K$ p<P>    // Unlock the playerdata4 _) \4 d3 B9 q. H$ I2 }
        UnlockPlayerData( pFromPlayer );</P>1 w3 Y/ ]) F) }5 @5 X# C
    <P>    // Send acknowledgement back to client, including list of nearby players
    . x' {. ?% S2 @# p  R    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));
    * Y& _% e9 ^$ u6 D  H; m * j9 o, X, ^) q6 h4 v& E8 z
        // Pack the buffer with dummy data.
    3 j7 O6 \+ _! m( w* l    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)7 F9 p+ |, ~- U$ a$ J% m
        {0 l* h& g, X$ K  \9 J
            DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];
    " y- U  N: R% e- n        VOID*   pTempBuffer = 0;</P>
    & B! [5 S/ l7 z% R' j) Z1 s<P>        pTempBuffer = malloc(dwBufferSize);( p& Y( p7 W$ m
            if( NULL == pTempBuffer )" Q7 q6 d6 C; u+ w/ K
            {
    9 m2 I: d  o+ ~& E. @            //Out of memory. ?- X0 `5 Z5 R, q; a
                DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
    - K5 c& R- s& d            free( pSvrAckPack );
    4 w8 F: S/ A1 T" N            return;
    $ r- j; ^' N; f5 s        }</P>9 I; C9 J7 p( b  b  b2 g1 \
    <P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');
    8 [6 [! z% M' ?$ W; U        memcpy(pTempBuffer, pSvrAckPack, acksize);</P>. F  j! C( A2 O1 K8 A' \: Z
    <P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );
    / K; M+ ?$ @2 N    ! ?$ |  r# f( T4 U. R
            free(pTempBuffer);
    ) w. \6 H- w' |' r2 D: A    }   
    0 U, X8 K# }+ x1 a% B    else: P( \% Q4 F+ V  R* j
        {. S$ f% X4 U- H2 T, h. u7 P
            SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );
    & T: P  R+ E8 _0 D4 m2 b2 z" g    }</P>2 G( a, _+ I5 h7 W9 g
    <P>    free( pSvrAckPack );</P>
    ' z7 D1 ~3 ], G7 }( n- N<P>}</P>6 {$ T  Q# n( G
    ' ]/ L% O9 g0 R2 T
    <P>+ Q( F3 s  V$ Z+ z
    //-----------------------------------------------------------------------------
    ; R" T; d2 W+ D1 @- u% R// Name: 8 V* d* N; q% n: e, N
    // Desc:
    , ^  w. r: R* Z//-----------------------------------------------------------------------------
    3 k# d4 c" C* B# Zvoid CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
    5 H) U3 v% h3 v# w9 d9 F{# J4 ?$ E3 u5 q: i( n7 T
        // Grab playerdata for this client and lock it- v" K/ @/ e, c3 c  n4 A
        PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
    - {; K3 D  X5 h: v% L% r    if( pPlayerData == NULL )* e3 h+ Q1 w( _: m
            return;
    0 _! d' J9 b4 m    LockPlayerData( pPlayerData );</P>
      @  P( }9 e/ L0 n2 G+ }9 K( w<P>    // Record the version number
    0 q* h6 M2 e$ |    pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
    0 t( _4 Q7 {  ^( r! [<P>    if( m_bLocalLoopback )5 m' l; M3 S  r; j
            pPlayerData-&gt;bAllow = TRUE;& t8 k  }. G+ D1 V, P. g
        else3 N% F3 N7 [4 D) k$ Q
            pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>
    ; G* v5 A* s7 I$ U; ]<P>    if( m_dwLogLevel &gt; 0 )  U; y& Q' S5 [
            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>
    7 I! I) P0 n& e<P>    if( FALSE == pPlayerData-&gt;bAllow )  l1 c/ h7 A8 O2 W9 Y) J2 i/ Y
        {3 v  R2 u. h* ]3 `! b: q
            if( m_dwLogLevel &gt; 0 )
    7 ~5 [/ C0 v" G# I            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>2 d: e8 a& y. i
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    " u. @! p$ d% V# y+ P' _        UnlockPlayerData( pPlayerData );6 P) R! g" B/ {" y4 ~1 V
            return;' a) J) _$ Y, }* _
        }</P>9 Z4 H6 _  J' r; l. {5 c9 R
    <P>    // Unlock the playerdata
      k& J( ?7 l" [& X9 d0 q( J    UnlockPlayerData( pPlayerData );</P>
    8 }: g+ {7 @& |2 J1 x0 P<P>    // Send acknowledgement to client that the client was either accepted or rejected9 b6 I* P( _% N; N' L) c( j
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );
    ' h% W+ k6 \/ P    SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );% g3 R3 S, ?) n
    }</P>( T* E' g7 Y8 P6 u3 v. A- M

    * |: Q7 v1 c( X* ~8 d& c: X<P>
    9 R7 ]' O6 Y. \$ m+ A- W//-----------------------------------------------------------------------------
    # }6 V  d( `6 g% |, h7 `" ^// Name:
    - ^& U1 R3 V9 V// Desc: : |5 r# R2 u8 }6 X+ ]7 k0 Q" m& l
    //-----------------------------------------------------------------------------/ C  c7 j5 w0 x* l0 c& ~; ~6 B
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )+ e! a1 g1 c5 [7 w8 G
    {6 a- J: p& z3 h1 A; f
        switch( dwClientVersion ): m2 z9 u" e' \
        {
    + F1 q! T( t/ Z9 A# w7 X- B: J+ W; }        case 107: // only v107 is supported
    & J* S, i; y3 P  T            return TRUE;+ m! l& d. k: m6 M; l! @
            default:
    7 ]' l  P( J" I8 S9 \            return FALSE;5 j; l; t& N* W; w- i% N8 P& a1 c. @; g
        }
    ) r7 L" |* j: B9 o9 ?( ^}</P>& ^2 ]! Q" `9 V6 u( Y# e; u
    9 b1 y5 k8 h6 P8 f: `
    <P>* s9 G. i/ `$ m8 m7 ~/ O9 }
    //-----------------------------------------------------------------------------9 s) s) R) `1 Z# Z
    // Name:
    9 a7 Z( s; V& K# y) {// Desc: 1 G' M3 p- Q* i# d! C3 f3 p
    //-----------------------------------------------------------------------------
    - d% G* f3 @$ \- C( t. f% Nvoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
    0 ?4 S8 E, Q2 W# P! V; A  F. Q) E% F. S{
    0 X; ^1 V1 E: j- E7 N; B/ `* `    if( m_dwLogLevel &gt; 1 )
    ! X3 c0 b/ Z5 A# E        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>
    7 X- i" L# y9 [; _- p4 f" u( X<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    0 s1 u) q- g" m  X8 d6 q}</P>7 T. ?1 o' W$ a& u& F; q
    . H( e& e, e  z
    <P>
    " E7 `8 {8 g! ]2 h: V//-----------------------------------------------------------------------------
    ; v2 f8 U  A9 K% V0 y* K1 h' L. q// Name:
    + U- Y' l' ~4 Z/ U+ n. E: U) S// Desc: * g7 X1 G0 m+ M- I3 M& h# p) C
    //-----------------------------------------------------------------------------
    % w7 _# D, H& x. Z* oDWORD   CMazeServer::IDHash( DWORD id )
    5 W3 P# \$ ~8 z4 h6 d  H" h{
    * j$ J# V7 Q* v( ~0 b    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);& e# q/ t, t3 }: k; O6 [% }' f
        return hash;9 U' r: n9 i, T1 D8 {
    }</P>
    " S- s6 o: p. L4 Q" D. R* e, ]% {5 t& t* c4 a' W  K% w
    <P>/ x0 B8 s% I& V* a. |/ |% p8 h, v
    //-----------------------------------------------------------------------------
    8 l8 ?) b  z7 v/ A0 v// Name: % D  C- Z+ _' T& i: \8 O3 A7 m
    // Desc: # n8 |$ S3 g" y5 u
    //-----------------------------------------------------------------------------3 l. a- p$ A8 T1 |6 F# i/ Y
    void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData ). G2 x$ ^1 U8 O( g3 n% A
    {* \3 Y1 E3 |' A$ A' Z: U& I
        // Hash the ID to a bucket number
    3 }2 L$ Y1 X& w' m4 w8 Y! D2 ~    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>: d, r  U+ V$ `
    <P>    // Lock that hash bucket
    ( v$ j" R; O4 m- h    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    9 S2 h9 p: `. q) }  e2 {    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>- q" b2 @* w, x
    <P>    // Loop though players in bucket until we find the right one
    2 N: M3 l& @7 \9 |4 ~    PlayerData* pPt = m_pstIDHashBucket[bucket];4 ^. d  l4 U- e& }9 K
        PlayerData* pPrev = NULL;" ]8 u6 t. ]* H2 U. R: J
        while( pPt )
    / L5 m6 j, E3 r) l2 c    {, ]6 c8 F3 |8 N+ l& P
            if( pPt == pPlayerData )% O+ m' y4 A0 R8 K1 r$ X
                break;8 d+ {/ i8 n" i! m( @# k! n
            pPrev = pPt;& x6 w# X- s- d" M% Z' t# E. a
            pPt = pPt-&gt;pNextInIDHashBucket;
    ; n; b2 y9 w1 i* [. f5 {    }</P>1 ^% E& c: N6 c$ w% z% s
    <P>    if( pPt )
    $ `) U/ F  }( {# h! s6 S2 {0 {    {% x' k" z' K/ J- b) ^) X
            if( pPrev )
    * q' `' `4 x6 ]; M            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;1 m" ~* b2 {: C& b
            else7 |" @( k( H' g- Y/ H  F  n+ z: _
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
    . q% |& F; j+ N+ W1 R        pPt-&gt;pNextInIDHashBucket = NULL;" ]# l, a2 y, Y4 l
        }</P># y9 [" d* q0 e& _7 G: n( d! a  Q
    <P>    // Unlock the hash bucket& S5 K" Q4 w* R9 W0 N9 Q
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    7 ^; e; H# I4 q2 T7 S+ ?. n}</P>5 ~* {& B+ g1 l. Y) d- o, u! n5 E

    : \; v* ?3 A% ^" ~8 v! v- I- t<P># c: p, _. s% P: m+ e, V' }: A
    //-----------------------------------------------------------------------------0 ?' A$ d, E) c6 _  Z0 v. m
    // Name: , e+ K& n) M+ _/ Y( p9 u; J& V/ o
    // Desc:
    % ^: z( I) @6 [* z//-----------------------------------------------------------------------------9 f3 q7 s0 Q8 w/ V) p7 _
    void CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
    , k4 v% H4 S- [! O+ M3 h0 j+ V- h1 W{
    & e  G2 B$ d7 z3 S    // Make sure this player isn't added twice to the m_pstIDHashBucket[]
    " t/ O  M1 L, g, c* j$ D    // otherwise there will be a circular reference
    % O% }$ r8 E3 n) f/ W: r    PlayerData* pSearch = GetPlayerDataForID( id );
    - K0 ~3 n& o6 U" Y( \6 x, J. F    if( pSearch != NULL )' L1 O2 m" ]- q
            return;</P>
    2 S' h$ j8 J) n$ x$ D" B* v/ B<P>    // Hash the ID to a bucket number
    3 m4 U1 J6 h9 ]    DWORD   bucket = IDHash( id );</P>
    - k. U! v6 T# }7 P: X<P>    // Lock that hash bucket9 X  g5 a, D# @9 h5 T
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;, u1 }& D( L, S9 {
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>5 F% J) U) x: ?
    <P>    // Add player onto hash bucket chain% a) o! M# E7 }- E( ^7 k7 L, b
        pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];" @' z2 V2 T* I) o9 |' `
        m_pstIDHashBucket[bucket] = pPlayerData;</P>4 \4 x( `  p& e: M/ X) B
    <P>    // Store net id in player
    . \  g: H$ V' A( A* ?    pPlayerData-&gt;NetID = id;</P>0 _4 @+ I, C% {, L4 \! K
    <P>    // Unlock the hash bucket9 s! Z7 g, C7 C" G
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();( c( s3 f3 b4 E" D: i
    }</P>
    . a8 G0 t/ K) x* S$ n& h% B6 H* c: L( }- Y
    <P>
    1 q% ~$ g$ ?( C//-----------------------------------------------------------------------------
    8 I9 z' y  [9 a/ Z8 K. t8 x- G$ Z( Z; K// Name: % Q% b3 x9 L" C! z9 j" n9 E
    // Desc:
    ! x* k% m# Q* @  i  n8 z, G7 k//-----------------------------------------------------------------------------
    - n* ?& h5 O& Y5 Q9 B: Q" @PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )
    4 r) f0 Z' e! B3 _2 D$ g: b{$ y% O' n. h0 j$ X
        // Hash the ID to a bucket number' `9 _2 t0 r- b! q6 L' |& Q
        DWORD   bucket = IDHash( id );</P>
    ! H3 o0 J: h, l1 o+ p5 r5 i' }" W<P>    // Lock that hash bucket
    " m3 z% q0 Y; H    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    7 Q) [. l4 ?: y. c+ l: g+ O9 P    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>' k" p2 K2 {  b( E. t9 j7 _+ y
    <P>    // Loop though players in bucket until we find the right one( E) {* n8 P; @. O/ a
        PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    ( Z( ^3 y5 R9 n& _    while ( pPlayerData )
    $ H4 i3 Q2 \8 g    {/ Z! \% y) W) T8 I; \) i# a* t
            if( pPlayerData-&gt;NetID == id )9 [3 X1 g7 w1 ]
                break;4 |: U. d. A2 h% a
            pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;; D2 q$ C  d" ^9 w/ f
        }</P>
    7 Q  z, S6 M! v' P1 K, u* |<P>    // Unlock the hash bucket
    ; b9 i9 e3 J, k. R' Q    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>$ \+ G5 Q; E2 s/ M
    <P>    // Return the player we found (will be NULL if we couldn't find it)
    * U  W" ~2 y8 i0 ~; I9 s7 Q3 a+ T    return pPlayerData;0 O" o  R- a! k
    }</P>6 H1 y2 n, L) J

    # ~1 T: K) E5 ~1 R1 C0 |<P>
    ! Z! ^: v9 b  G4 J+ L1 [; n//-----------------------------------------------------------------------------8 |" }) X& }# a
    // Name: 0 Q6 }8 @; J. `4 N. u
    // Desc: calls DisplayConnectionInfo for each connection in a round-robin manner
    5 g5 K# e8 Q7 }5 L/ r//-----------------------------------------------------------------------------
    6 z1 s( o# m. }4 gvoid CMazeServer:isplayNextConnectionInfo()
    % ]' Q6 X5 o5 ?3 _5 K{+ t. _# r% k5 d1 c1 L3 }+ W
        if( m_pNet )
    . a( @8 A% s( v% [    {
    5 m* y9 @) @/ @, Q        // Find the player that was displayed the longest time ago, and display it.4 }$ x4 n/ r9 H! e
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
    / P+ p2 t/ u2 c0 |$ p# v9 L        PlayerData* pOldestPlayerData = NULL;5 x# A+ D. F; ~, o8 c8 |
            FLOAT fOldestTime = 0.0f;</P>
    1 ]% y  E7 Z! ]1 R% h<P>        m_PlayerDataListLock.Enter();</P>) _! }3 J' L- h. K# p  w& T8 U, x/ x
    <P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
    ( V7 |; r  W; K& O6 V6 n3 e        while ( pPlayerData )
    # `/ P$ F  l  Q  E# U        {$ m6 E4 S& i4 U$ |
                if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
    ( a0 [( m+ L8 q- ]; n( b            {
    : E! r2 |6 {( G' {1 p& P2 h% `                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;" @* `: @6 g( Q" B5 n* h
                    pOldestPlayerData = pPlayerData;) d" d: r4 i* ?& z$ Q
                }</P>
    & c" h0 L. e/ d3 c, g. e& E6 _<P>            pPlayerData = pPlayerData-&gt;pNext;
    6 j* m: p2 G1 _8 [1 ^        }</P>
    : r) A0 v' W; x* m; \9 S  ~" ~* R<P>        // Display the player with the oldest CI field, and update its CI field./ {7 K4 A! }. i0 S! j, r, A
            if( pOldestPlayerData )5 z# C3 }1 R; Y, {5 W/ i
            {
    ( a$ U! f  g2 p; N- G            ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
    # Q/ i# G7 A/ d! d5 A% B9 v. e            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
    6 K: n, p& u1 B& c; u; S7 N  @            pOldestPlayerData-&gt;fLastCITime = fCurTime;
    ! O! P! H8 }8 v; g  M2 I  M        }
    / T: \9 p/ N, _        else
    1 S! ], I, W0 F/ a. o, M, _        {
    / _( m7 T( b& Z            ConsolePrintf( SLINE_LOG, TEXT("No players found") );& b) n- O: ]: C6 J4 b
            }</P>
    7 ~9 r; O: b3 {' c<P>        m_PlayerDataListLock.Leave();
    - X$ @" ?; v' n    }+ q* h; B) ^- I6 C" \
    }</P>
    ( _" k& N9 w" v4 Q
    , H! d: M# i, W) N' J3 t<P>" d) ]1 x) [) B6 D  ^4 A( w5 b7 l5 q
    //-----------------------------------------------------------------------------
    7 w  r3 U4 T( B' @0 r9 _5 V// Name:
    % o8 b4 s5 @# t  H6 f* Q6 Q// Desc: # k! k) j$ v: h7 u
    //-----------------------------------------------------------------------------0 E( ?1 G2 }! V" E2 Y0 D9 ?- _
    void CMazeServer:rintStats()$ e6 p5 C. C! B3 u0 ~7 V
    {
    , f; N' K2 r1 b7 E+ Q% z    ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"), ' N2 T8 }. w7 l1 k0 W4 Z2 C
                                        m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );
    ; k) K. y: J% P- |2 h/ b* a7 z5 e6 X    ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),# |8 m# n! H' l3 o' n
                                        m_fAvgThreadTime, m_fMaxThreadTime );
    ( \- r# k, x: D$ S) b4 b! U    ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );, C9 l. T3 ^  s" J
        ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );& K3 c* |* M5 K+ ~  m- B+ a
    }</P>  u1 U% T# q- X6 q5 f# E" A

    7 A% a2 M$ ~; z2 F) g0 i<P>9 c& t+ ?* p) F6 J0 P8 J, J( K! z
    //-----------------------------------------------------------------------------
    0 m$ o; C7 d: W* l- M! I// Name:   A; w0 I# x0 e# t5 Z
    // Desc:
    : E0 b2 N6 }. c; q//-----------------------------------------------------------------------------
    ! ^0 U4 w& s9 l. O7 mvoid CMazeServer:isplayConnectionInfo( DWORD dwID )$ D$ m8 b' L8 o5 _* q8 [
    {7 L( s. r' ~9 S2 V- e: m
        TCHAR strInfo[5000];
    + a* g& {# Q; l% D4 r! Y    TCHAR* strEndOfLine;
    4 ]: r# o% ^$ m- {* J    TCHAR* strStartOfLine;</P>
    ; N( @* ^/ {- M2 X( o5 Y<P>    // Query the IOutboudNet for info about the connection to this user3 j- O/ o" S# v+ C* p
        m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>
    $ N7 J: X2 k9 @3 z: m, M$ R<P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );  v8 N* g7 k2 q; l% {& m
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>& c2 w  D. f! D, p1 u, K
    <P>    // Display each line seperately& `3 A* z1 S; c4 @
        strStartOfLine = strInfo;- Q+ |) d0 S. Q  j; w" t; d
        while( TRUE )0 s+ Q5 @1 I9 ^: a/ Z
        {- M9 o# g3 [, X% M/ G; J# M
            strEndOfLine = _tcschr( strStartOfLine, '\n' );+ O8 M# k7 ~; X* _
            if( strEndOfLine == NULL )
    3 \3 p6 ]" e/ N& }7 |, w            break;</P>
    ! ~# S. Q( ?) `4 M( U<P>        *strEndOfLine = 0;6 ~  O0 D) S% }; L" t
            ConsolePrintf( SLINE_LOG, strStartOfLine );( u" x4 }) w/ P4 ?
            strStartOfLine = strEndOfLine + 1;
    5 U3 ^5 M/ q/ ^5 `    }
    % f% a. }! g: {6 k- v- T3 M: ]5 m' T}</P>3 S7 S1 C  p) b( e0 A; r* Y1 B9 ]7 n( u
    2 S8 T1 Z2 V2 V/ f! S, O2 ?7 Z1 |/ f
    <P>
    ; M4 R+ e. ^% W5 s2 H//-----------------------------------------------------------------------------; {# W% g: [* p( R9 p+ X
    // Name: : x1 }0 I) N8 A, E5 w! t8 T8 z
    // Desc:
    7 q5 ?1 D; p: f/ V4 T/ Q* Q//-----------------------------------------------------------------------------
    3 ]1 j8 l' W2 X' S! M  ?( [HRESULT CMazeServer::SendPacket( DWORD to, void* pData,
    ( ?% Z2 {1 m" T' H. S: I6 u                                 DWORD size, BOOL reliable, DWORD dwTimeout )! X& f( S0 D( d  P' [
    {
    4 z, e0 T; ]. A: F- @    // Chance of forcing any packet to be delivered reliably
    - x, Y( [" T# x# ~- f    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate ). c' r3 x6 a& X% F( p
            reliable = TRUE;</P>& T1 b0 u( \( p5 g/ C  _3 {
    <P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    * }7 V/ ]! T  c! ?2 p( \}</P>7 ]' G2 I" m  [6 G3 |' X

    - f8 K& Q; ?/ h8 ]<P>6 K6 r" L. i$ C6 l( z5 i
    //-----------------------------------------------------------------------------
    / w& N* n+ m; K5 |; \1 q// Name:
    6 F1 D6 C% ?( u# {# i// Desc: & J2 \4 E/ }: i
    //-----------------------------------------------------------------------------
    ) c+ K; v  K; F  d4 g* avoid CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )  c) L+ A, h1 G- u
    {
    / T; I- M: |" p' C4 }8 i' z1 s    // If we're up and running, then send this new information to all clients( J2 U9 C) @( g* U
        if( m_pNet )
    7 i4 t9 T; W# \; N( y$ Y    {
      _+ f" K' N* g9 b  @+ ?' j. v        //Use the AllPlayers ID* p! P6 g1 Y* ~" [: n! c6 j1 r) b7 i
            SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );
    ! G. I$ O  k9 o- p9 E$ L5 w7 j    }9 J/ j! x2 |5 ~5 L* R- |1 K/ u+ v
    }</P>
    4 B8 g( T- ]+ m
    " ?. |2 T! I7 h. M<P>
      H; a  C* M, b7 J# D1 ?$ I//-----------------------------------------------------------------------------
    " H/ u! O% v) U- i  k// Name:   u5 O5 V3 Z+ G  C. t, ]6 v; S
    // Desc: : T# i1 \8 @$ l- U& ?; X* c
    //-----------------------------------------------------------------------------
    5 ^7 D/ j! d8 Z2 Yvoid CMazeServer::SetClientReliableRate( DWORD percent )
    # U6 L5 s% N$ P2 s! N{* K) u  d, M: H: d2 P
        // Update client config, and build packet containing that data
    % y% E' Y9 N0 n6 l7 ~    m_ClientNetConfigLock.Enter();; P+ j3 Q  S0 Q$ C( P
        m_ClientNetConfig.ubReliableRate = BYTE(percent);$ ~% }' i8 i* Y/ h8 Z
        ServerConfigPacket packet( m_ClientNetConfig );
    4 j1 V- w# F" u6 Q: }4 w" I" {/ h    m_ClientNetConfigLock.Leave();</P>( H  ^8 y4 h- R& B. x
    <P>    SendConfigPacketToAll( &amp;packet );
    ( p2 U) r: E0 h" ~# P. y1 ?}</P>
    : [( H" y8 x' S$ p# o
    ) R$ S* }' U: m1 a<P>
    3 r. v! K7 H5 C/ p9 l% ]//-----------------------------------------------------------------------------
    8 {6 b) v' l6 N1 q// Name: - E& p% Y- y- @
    // Desc:
    ( q4 q4 Y, d, p" A" D//-----------------------------------------------------------------------------
    * f/ d; W: k) q7 [0 J- evoid CMazeServer::SetClientUpdateRate( DWORD rate )
    ; M7 Q) Z0 p  y) D, Z{; \: R; }2 d0 o8 x+ c
        // Update client config, and build packet containing that data
    9 r% [# ~9 X* l2 z! y    m_ClientNetConfigLock.Enter();$ q9 M- Z* }8 j1 E
        m_ClientNetConfig.wUpdateRate = WORD(rate);
    * }, b2 y8 i- i1 J    ServerConfigPacket  packet( m_ClientNetConfig );
    - W  H# b3 J: t9 @' _    m_ClientNetConfigLock.Leave();</P>
    7 z6 P* {4 N% D<P>    SendConfigPacketToAll( &amp;packet );
    5 l+ X! Y9 K2 g5 q}</P>
    4 {" S+ k" H5 [5 C4 [
    % b. w/ {4 {  o4 ^2 y' s<P>
    % a4 ?& T, L2 c; Z% @//-----------------------------------------------------------------------------
    5 }0 k( E$ R7 n" X& B// Name:   I) O7 ^$ t5 f2 |2 g8 D* N
    // Desc: 1 R+ F1 K3 \# W+ f. w  V+ m
    //-----------------------------------------------------------------------------
    . s, _5 Y9 `* x- ?void CMazeServer::SetClientTimeout( DWORD timeout )2 r' u; `# T5 \
    {# I" O% I! r, ~2 Z# K1 V
        // Update client config, and build packet containing that data
    2 r$ |: j7 v# }+ e8 T5 N$ [    m_ClientNetConfigLock.Enter();
    3 o! R+ B% E- C4 v1 A, p4 m( e    m_ClientNetConfig.wTimeout = WORD(timeout);
    3 F7 E1 E& @5 r6 k3 F9 V1 b- y    ServerConfigPacket  packet( m_ClientNetConfig );, K6 Q9 z/ R) Q8 a3 k8 @5 y& p
        m_ClientNetConfigLock.Leave();</P>. F: H# N/ c/ r) v: G+ M! j
    <P>    SendConfigPacketToAll( &amp;packet );' _$ C5 P5 o# k* W( L! P% \
    }</P>
    1 q0 p7 K2 N' l+ ^1 B- j+ _0 _) w4 {5 p/ N$ n! O
    <P>
      j6 M2 z; c; T$ d/ @) b//-----------------------------------------------------------------------------6 B0 N9 N1 M$ ?; c, x) S
    // Name:
    & }; g. ^) M" Q2 _2 p) P9 q// Desc: & J# G* E" V; h8 I
    //-----------------------------------------------------------------------------: T/ ~) m6 q7 G$ H) d$ r
    void CMazeServer::SetClientPackSize( DWORD size )
    , S$ a; k- i2 W# z7 o( T5 b{3 L; ]$ O2 K* Q/ n9 S/ {- u
        // Update client config, and build packet containing that data
    , _7 u7 }) f3 o- p" `/ A    m_ClientNetConfigLock.Enter();
    3 v" U: \; o* }   
    : Q* V; n' K5 e: @    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.
    * T7 K; w; j) S/ {. \    if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)     ~* I/ H* X5 i9 d; n: m4 @7 B+ `6 v
            m_ClientNetConfig.ubClientPackIndex = 0;</P>6 X6 C4 _( A( d
    <P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);
    ' R! g7 m1 x+ V* l. p1 B    ServerConfigPacket packet( m_ClientNetConfig );& a9 A9 t% i- [) }/ A
        m_ClientNetConfigLock.Leave();</P>: f, k6 {2 l: Z3 d
    <P>    SendConfigPacketToAll( &amp;packet );
    ! d  l9 j, Y) M6 l% c}</P>
    : q- l$ M/ @  P/ h0 l! B9 h2 }- Y: j/ `
    <P>& f! M! n* x& {7 v, _
    //-----------------------------------------------------------------------------
    / T* l' }8 k1 z) j// Name:
    % ^- f8 ^5 G; z# a, h( i$ j0 n// Desc: 2 t2 T* m. D, y  c7 B. @
    //-----------------------------------------------------------------------------
    $ s: G" A6 r3 _+ R9 }) Evoid CMazeServer::SetServerPackSize( DWORD size )
    # d9 g$ L6 l: R/ I. F6 E{
      W; M" v7 u; q  _0 d2 L6 f    // Update client config, and build packet containing that data. a5 K' ^8 W3 g0 l
        m_ClientNetConfigLock.Enter();$ |' R( r8 l2 O! T5 t3 M2 J" A
       
    / O+ i$ y9 E4 a    m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.% l% S: B  M: ?$ |: B' s6 N" N. X; K
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   ( m2 ?8 Z$ R9 o3 g
            m_ClientNetConfig.ubServerPackIndex = 0;</P>0 `$ o, t. D5 @# z
    <P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
    $ j$ ]$ L" M$ o* C# }8 ?9 D    ServerConfigPacket packet( m_ClientNetConfig );1 J1 v) _# z& c* @; n4 D
        m_ClientNetConfigLock.Leave();</P>
    2 G0 a! [8 w% @6 K' V5 r) ^/ T% s<P>    SendConfigPacketToAll( &amp;packet );
    5 j; W$ w- q0 t0 I/ z- H0 G}</P>
    ) y5 y, j9 i; p: u* n1 ~" `1 ~<P>( q8 k6 A' R% y/ j1 S
    //-----------------------------------------------------------------------------' D! `* F2 \$ o) w
    // Name:   w  K5 e1 p4 P8 K1 [4 H
    // Desc:
    7 [, B) @, x  a& p1 |* P//-----------------------------------------------------------------------------( g" e$ U, B& m0 W! U  I
    void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )7 k/ J; ~% L3 w
    {
    3 Z4 o2 R$ K4 D/ D! N# p+ m    // Update client config, and build packet containing that data- Q3 o1 n9 e6 N3 W, \
        m_ClientNetConfigLock.Enter();
    9 y* }# _& h( Z$ ]* \' j* [' }. u7 x   
    ( ?, g& S/ z; |: J# d' f; H    m_ClientNetConfig.dwThreadWait = dwThreadWait;/ ~! E' b! g+ d5 }( T  Z. w3 h
        ServerConfigPacket packet( m_ClientNetConfig );
    - w1 f0 L/ }0 _4 ^7 |    m_ClientNetConfigLock.Leave();</P>- `# g4 M2 i: f( T6 u
    <P>    SendConfigPacketToAll( &amp;packet );2 e, `8 W8 G, D/ m
    }</P></DIV>
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2026-6-11 13:19 , Processed in 0.490281 second(s), 50 queries .

    回顶部