QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4166|回复: 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>. m; C: t4 a8 ~! @+ [
    <>// File: mazeserver.cpp) B/ O+ E; ]  b8 x' A
    //+ V" A" p% @: ], L4 }
    // Desc: see main.cpp2 Z4 v7 ^* f& n2 b2 s- L
    //' B- b9 Z; w( O* h+ E9 D" d* t! J
    // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
    1 v* H: I4 c: G& ^//-----------------------------------------------------------------------------
    " w4 }' L$ q0 ^. y6 I1 s#define STRICT
    - ~6 v# w/ o- j6 N: J#define D3D_OVERLOADS0 [; A; U0 j1 \$ H% p
    #include &lt;windows.h&gt;# J3 {# g  q( i0 Z$ h0 Y1 p3 |
    #include &lt;d3dx.h&gt;! @5 P. o( R% E. [2 [
    #include &lt;stdio.h&gt;2 W8 q( E3 Y) E6 c5 s
    #include &lt;math.h&gt;
    + ^, I7 Z1 m4 t  {4 C* L* ]/ F4 f( |0 i#include &lt;mmsystem.h&gt;
    0 l( @  c9 L% a; ^9 m& G/ j#include &lt;dplay8.h&gt;
    5 ~2 s) m; ~" z  R2 Z, W+ C6 U#include &lt;dpaddr.h&gt;1 C: z/ p( ?8 n9 U# c! u5 I% r
    #include &lt;dxerr8.h&gt;, }& m4 F7 P2 L+ G! i$ d
    #include "DXUtil.h"
    8 F' f8 {- F1 x- p/ c#include "MazeServer.h"
    / U( E+ g4 C' c& H1 l- F0 m#include "ackets.h"& t7 W) b6 T$ V+ `$ g! _% K
    #include "Maze.h"% m) g& O* M2 {
    #include &lt;malloc.h&gt;# ~8 L9 {; Z# S" V3 u" P% @3 N
    #include &lt;tchar.h&gt;</P>
    . c8 h7 e7 A" |; R) l% D6 v* p( J
    7 I* L* a1 v  u" ]$ ^8 u<>//-----------------------------------------------------------------------------5 N/ K) U- H7 p  N) a% a" x
    // Name:
    + \  h4 X% b; S. v4 G. N5 p// Desc: " j2 [' c8 X) O. s# l
    //-----------------------------------------------------------------------------
    / J/ v( k3 W# ]& M4 O- lCMazeServer::CMazeServer()- {: g9 k3 w" J+ n; |1 M8 \
    {
    0 ?9 s# O* ~5 O4 E' O8 m. K4 V3 q    m_dwPlayerCount         = 0;
    6 R" ]9 [7 r; k5 l" q: U4 @& h   
    . T! v5 R2 [( _6 ?7 i    m_wActiveThreadCount   = 0;
    6 b3 a7 J# e3 ^8 _    m_wMaxThreadCount      = 0;
    / d$ a; B3 t# D6 @1 f! Z$ j' y+ J    m_fAvgThreadCount      = 0;# s* r, W8 `" O- }/ J; t# w3 ~
        m_fAvgThreadTime       = 0;8 ]' h& a8 d1 m$ _& [
        m_fMaxThreadTime       = 0;</P>
    5 t1 ]9 E0 y% E- O' a<>    m_dwServerReliableRate  = 15;
    : ^- x+ M* R6 U2 J) @3 B( B- x( W  @    m_dwServerTimeout       = 150;$ H  |  c* B0 i7 R1 E
        m_dwLogLevel            = 2;
    : M( U: \7 |1 \1 e/ c+ A. }1 I    m_pMaze                 = NULL;</P>
    ; Z' @, w- i) {' P0 e<>    m_ClientNetConfig.ubReliableRate = 15;
    % c7 b7 n. @% t1 H! c3 F( |- n    m_ClientNetConfig.wUpdateRate    = 150;
    6 l& `3 s6 W% n    m_ClientNetConfig.wTimeout       = 150;</P>
    # {" @- Q$ M( O/ \<>    m_ClientNetConfig.dwThreadWait = 0;</P>
    # x0 H& Q$ V9 {; Q4 n* I<>    m_ClientNetConfig.ubClientPackIndex = 0;
    $ F! b& `8 a% C2 c    m_ClientNetConfig.ubServerPackIndex = 0;
    $ g# ~2 g3 q9 K/ g7 c% @    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)) @' F0 |5 Q" _
        {
    0 R- P+ N7 |3 }        m_ClientNetConfig.wClientPackSizeArray[x] = 0;
    , k: H+ M# o  ]6 w. w( o1 Q. \* d5 r% E        m_ClientNetConfig.wServerPackSizeArray[x] = 0;
    ! _3 H. Y3 v- j+ T    }3 s7 s( o/ N% S* F! @& f- }/ K
    }</P>; u; T( _% o+ b: q9 b- I- q
    6 M& u( c$ P* |- P4 a) B: E# ^& Q
    <>% r2 k! a9 {6 K3 e
    //-----------------------------------------------------------------------------
    ; }) f6 _- B$ H* C) X# M7 t- O7 E// Name: ! X1 ~0 ~# a1 M: ?  Y8 F' x
    // Desc:
    % Q  F. n/ y$ l1 x( X//-----------------------------------------------------------------------------( P! i8 }9 W$ k$ j
    HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze ); V: _( s; m: R; D0 h2 E# {8 b
    {
    ' T) T6 h5 U' C- u! g    m_bLocalLoopback = bLocalLoopback;
    7 n, C7 h" Y8 c    m_pMaze = pMaze;
    # S4 p" v2 j; f3 z; b; ]    if( m_pMaze == NULL )
    * h$ y/ R! V% V3 x) v  m5 L1 A# w6 A        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>, _" a8 D6 N7 A% s
    <>    // Grab height and width of maze/ a/ [2 g# ]! i5 D8 t; _$ q' L' I: s
        m_dwWidth = m_pMaze-&gt;GetWidth();9 X, O/ M! D( h7 S/ o: a1 f# C
        m_dwHeight = m_pMaze-&gt;GetHeight();</P>/ M0 i) z  c; E/ c2 I3 Q# T
    <>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    1 D) x7 X# j! w2 ]    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>* z7 k+ A, h2 p; u' ?+ Z
    <>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.
    1 a' b2 _4 n$ p0 n! I" j# [. x    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    2 j! t5 ?# Z) Z- ?! a4 F        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    ' y4 _% I7 Q; P2 K0 L2 w    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )6 L$ ~  n: ]+ Q# }+ h
            return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>" z" L9 E; `- }5 {
    <>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;. U! q/ V+ {6 O" ^' j8 l# z" s- A
        m_dwMazeXShift = 0;
    # |" ?6 t6 [% Y. |  X! k8 [7 \' W9 _    while ( (scale &gt;&gt;= 1) )8 ?0 {" y4 M  Z. X$ O9 A
            m_dwMazeXShift++;</P>
    4 V% [" ~* L, M! ]. }6 V; ?<>    scale = m_dwHeight / LOCK_GRID_SIZE;6 l* ~0 {2 A5 {5 l' d" u5 h
        m_dwMazeYShift = 0;- p: F0 G- D* N: v7 N; `# w& M
        while ( (scale &gt;&gt;= 1) )
    ; l4 P; j; s4 [+ B9 v8 K        m_dwMazeYShift++;</P>7 x  U/ p) p! ~2 K) I1 ?
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    ) W" ^5 Y1 M/ H9 L        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) ), G; i5 y& i  a+ x+ a; c3 }* h& W
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>% J. I* Q5 w9 T$ \  t0 g( p# Q( k
    <>    // Initialise the player list" p4 G: U' @/ \0 ~
        ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );/ [* M% M& f* v
        m_pFirstActivePlayerData = NULL;
    2 z2 z: T  o$ |! f+ I7 c8 s# N    m_pFirstFreePlayerData = m_PlayerDatas;/ s$ A3 G; a  M8 A, E
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )
    6 Q9 e) A$ }" q; O# x' ~    {
    & [7 w( ~" T* O+ e0 h# X        m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];
    6 `; O% [8 d$ S$ k3 Z        m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
    : i+ }0 w+ ]# `/ ?  ^& ]    }</P>
    * Q1 H/ I) G( l2 |& i( g. ]: L" x, U1 }<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
    ! ^! _, H7 _+ z! Q- W7 F    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];
    ; s( k3 ?6 F7 L6 V" g    m_dwActivePlayerDataCount = 0;" w' b4 j4 E7 W0 Q$ Z
        m_dwPlayerDataUniqueValue = 0;</P>$ Z# Z' A6 e, ^5 E
    <>    // Initialise the cells
    8 D  O6 k% q8 s0 ?" L% k8 j    ZeroMemory( m_Cells, sizeof(m_Cells) );
    , d) i% p  x4 t! s    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>% g7 y  ^; V- }* d
    <>    return S_OK;& D% A  }2 M- U: J2 S) [7 O
    }</P>
    / L' D- V) V( k. l9 j: C+ k2 n, f9 ]) `: R
    <>
    ) r/ }7 m( q* \! M4 [$ i6 n//-----------------------------------------------------------------------------
    - h" x( B0 x: k+ l- U( e// Name:
    4 P% U/ e, v0 z0 n// Desc:
    4 [1 I4 Q2 C0 B  d& H7 d6 W9 t, _) P0 _- G//-----------------------------------------------------------------------------; e& e' F3 Q# \# ^* _
    void CMazeServer::Shutdown()
    8 u6 R" U8 k! z" q+ ]. A5 G' \3 w3 f{
    " k$ Q; F  Y9 n, L: l}</P>
    - H: K9 I9 B, A" q3 l7 {1 l$ ^0 ]1 \5 `- U7 G% V; t2 j( B
    <>
    / b) f% D7 ^' G" Z//-----------------------------------------------------------------------------
    7 E& u- w# C; E/ @7 h// Name:
    6 f  ?7 u* s3 w- b8 P" |, d6 Y// Desc: $ f) l/ E/ {: @0 A5 h
    //-----------------------------------------------------------------------------* z7 {0 Z3 m& Q' w2 S
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    ( x8 V: ~- q: N$ S{- N0 K7 f  |9 d* g
        m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    * e; N7 y- c" j0 O                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    3 `1 ~& N. O2 D1 }}</P>
    6 g& l5 ]0 N1 C& p9 K4 Z) y' E4 E, E
    <>
    3 @  E9 b( ?2 ]4 N0 s5 I//-----------------------------------------------------------------------------4 M$ ]* z+ U, p7 y
    // Name:   r6 f, `+ s1 q, F8 |# N
    // Desc: 9 `* i+ w( H8 }* Z1 m0 d2 m
    //-----------------------------------------------------------------------------
    8 X6 v3 j# X3 f6 R& Xvoid CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    4 ^' O8 D& p& i# [{
    9 r0 O/ j' b; p) n    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    . I. j1 D/ ?# @! {                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    2 P* I' \7 v$ v" t1 r& J% ^( C}</P>
    - _* M, }) m; W
    7 V+ A7 }  c2 Z+ x- A8 G<>$ v4 P# Z) h( A
    //-----------------------------------------------------------------------------/ [; [6 l& ~; ?" ?$ _! o; v# F: |/ J
    // Name:
    5 h) m4 q# Y& U// Desc: 7 V4 d% o9 X; o/ J
    //-----------------------------------------------------------------------------1 ?% x  @: I6 q# ]- l% k
    void CMazeServer:ockCell( DWORD x, DWORD y ); }5 `; z7 E0 V& t. i0 a
    {
    . D0 X2 @8 ^' p    if( x == 0xffff )
    : j! r8 w+ \/ }# N5 A% S+ d        m_OffMapLock.Enter();
    ( d" }- q" s" s5 l    else
    1 o' s. k" J6 a6 T        m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);3 I" B- _9 @5 Y+ D# c6 l8 U$ C9 X3 C
    }</P>' E( l' z+ q& ?( c  |/ H+ X; ^

    ) u6 G: g# g6 c8 Y' p<>
    ; Z7 o) L) G. e  Q9 m' C0 t( W//-----------------------------------------------------------------------------7 M0 C+ |" }8 Y9 u
    // Name:
    ! \% o5 @$ W' U% g8 ~) H6 g$ d7 _// Desc:
    & H3 w8 }& K" U2 o& m3 ]1 v# V( ~//-----------------------------------------------------------------------------) U/ K1 n& W2 U/ T2 P$ }# ^% h
    void CMazeServer::UnlockCell( DWORD x, DWORD y )  p1 y9 ?6 F' N* ?# T
    {. F1 D9 c. }3 j  N9 `
        if( x == 0xffff )7 D8 \6 {! O8 j3 V, p: D
            m_OffMapLock.Leave();
    + q1 p( X5 K3 g+ D5 P    else
    / E* Z2 ^) q; p3 |        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);* l* C- I4 h/ j* u
    }</P>- A( C- @) b  D7 v3 |2 @3 p
    2 O3 ^" l6 Q1 S; h* H3 g
    <>
    9 T; j. Y; g. y' i# S//-----------------------------------------------------------------------------
    ( e) t1 i- L2 I// Name: 8 d8 x8 `2 K7 s# t
    // Desc:
    " I' R$ B. l8 s& o' K- [//-----------------------------------------------------------------------------
    * i( B5 m0 q2 ?2 H. r/ }void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )  q0 p6 \3 q9 B% G* m6 E
    {
    # Q0 W# o8 N  S/ D9 z% {$ m( n7 X. @+ ?    if( x1 == x2 &amp;&amp; y1 == y2 )2 F, r  Z! o4 x* E
        {8 A& e( n5 n+ D2 {
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    ; u4 V6 A( v) X9 b7 a; \5 q# j            LockCell( x1, y1 );+ p, E) o% O. r, O& P  G
            else
    4 ]0 M& r0 H% L  ^4 }: C* b$ F1 m            m_OffMapLock.Enter();</P>
    - b4 o# |: `* Q6 ]7 }4 |4 U<>        return;
    $ Y; Y" B% R* y, `; t    }</P>/ b9 _, t7 l4 J6 P8 o8 O! L4 D
    <>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    ( ?5 w" R! y' O$ N0 T    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    * e1 f: y% c2 b' N    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;$ R! i" B7 S2 ^1 o
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    & @" i% g; v8 ?9 ?+ R: q6 U/ T<>    if( x1 == 0xffff )3 E- l0 P# @/ u2 f, C. l$ s
        {
    4 W! q0 r5 Y" a. T( e  s2 E* P        m_OffMapLock.Enter();
    " P' c) ]' l( f# t0 f        m_LockGrid.LockCell(x2shift,y2shift);
    6 p0 G5 l: L0 P9 m" F. g    }
    4 P8 O. @2 Z( [# I. }. z/ y  ^0 M    else if( x2 == 0xffff )
    , o! w+ J' T5 J+ L    {. _2 G; k3 q% n8 p/ E0 O
            m_OffMapLock.Enter();, ?, p* e+ g1 `4 r
            m_LockGrid.LockCell(x1shift,y1shift);. t: B6 O; P4 i, p' K$ s& i
        }+ W+ ~8 z! _, w: A; m
        else
    " p8 W9 x. v; D# V- s    {
    # {& D" _9 M) W; x        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);
    2 E* F' s! {; N1 y$ ?3 B    }; w7 O* x* @$ |- m
    }</P>1 }6 A, T2 p, i- A/ H/ a( ]

    0 h$ A. W. F' x) f. u* N( E, I<>
    * A/ V1 u6 N3 m0 }4 o3 h//-----------------------------------------------------------------------------
    . C: X6 O7 R" {// Name: . o- F( f! ^1 d. O! r% Q! m
    // Desc:
    7 g4 _$ C6 d. X2 {/ `! ]//-----------------------------------------------------------------------------1 K2 h/ Y  \. ~0 d$ H% m
    void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    1 x9 l/ O* y# E% u5 }{- G: K7 z3 {$ v: l6 f5 W$ ~. E
        if( x1 == x2 &amp;&amp; y1 == y2 )" y) O8 H3 H* c8 B( Y0 w
        {
    8 t( t' m. K5 G$ q6 W; _        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    . t- S2 k& E$ ?" u5 q! ]' v            UnlockCell( x1, y1 );
    - q5 {$ }; f2 y  z. ]3 M3 ?        else3 \# z! j1 [7 j; K9 p
                m_OffMapLock.Leave();</P>
    - y4 H, s  f7 z6 _, t3 A<>        return;9 ^& B+ b5 J$ m$ V" \
        }</P>
    1 j5 b3 Q! K7 V& o<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;  j0 i: F: z* o; r* }
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;9 U3 H; z9 c7 v! e: U
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;( u$ ~! e0 L) `! x7 ~+ J) |
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    4 c- x3 G4 s  z* k$ k* ~; [" W( N<P>    if( x1 == 0xffff )/ e+ x- e  }+ r( D2 O1 N, x. g
        {' P/ L& F& z( X9 j3 J6 t( k2 U
            m_LockGrid.UnlockCell(x2shift,y2shift);/ `8 V( t6 I5 S" u6 U- Q9 `' t. k0 b
            m_OffMapLock.Leave();
    1 S  y0 T6 ?6 F; W4 ~& A    }
    ( W+ b' k6 v1 b  I/ j+ O# H    else if( x2 == 0xffff )+ K+ m, @* t% ^
        {0 J) c; q: e7 _" |9 l- x
            m_LockGrid.UnlockCell(x1shift,y1shift);# _  l: {9 E1 Q* I6 M) c
            m_OffMapLock.Leave();
    , w5 w/ ~% T2 U  g    }# g0 P# U# C& q5 _, [" ~6 `
        else
    " E( ]0 r" M( Z! q* M7 r. H    {7 _% V$ f( f. g1 g( S3 C
            m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
    : b) L9 k' Q# d    }! L7 k; s( i, J( N
    }</P>; N+ ?  [% o. s6 c
    ! d" E& c8 l7 O1 ~
    <P>* ~, L  t' U7 d) x$ t
    //-----------------------------------------------------------------------------& _7 i) ]# V) {7 @& R! C, W
    // Name:
    ! l3 G' V7 O# B// Desc: 5 J( G2 I+ s/ M+ |0 ^: `
    //-----------------------------------------------------------------------------8 Q0 J" ^3 Y5 Y
    void CMazeServer::OnAddConnection( DWORD id )
    4 d" [: }$ Q, r) x% l{
    4 \* ^! _7 X* ?. E& q# Q    m_AddRemoveLock.Enter();</P>  S  G: K) ?: u
    <P>    // Increment our count of players/ y  N5 G8 G0 ]: C
        m_dwPlayerCount++;
    8 q  z, x( E2 J- X6 ~, U7 s! R% q    if( m_dwLogLevel &gt; 0 )
    7 a. |7 \/ Y* F4 L& g    {/ z/ D8 R6 ~, k! S+ H7 g1 E2 D3 ?
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
    1 Q* h. J/ y/ T0 `        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );5 b' W& L$ n+ e# g
        }</P>2 y7 ]6 x4 |: W6 o
    <P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )! g# n$ O: C5 x+ C% d
            m_dwPeakPlayerCount = m_dwPlayerCount;</P># G* k. w( V9 I9 _# n
    <P>    // Create a player for this client
    / `3 q2 a2 g' Q- Y* z    PlayerData* pPlayerData = CreatePlayerData();
    ' d. [, z/ t- A& ~5 u7 d( A    if( pPlayerData == NULL )0 A  |2 Q4 O. ^6 V
        {" E: R' m- C2 c# }7 ]
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
    ; }3 x( l  m! l: Z9 ~) J        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );) E" |3 b4 d# W) @+ g* t
            m_AddRemoveLock.Leave();
    , {4 u) y7 Y6 ~. K* y        return;
    + A$ T% C5 |9 ~& O% r    }</P>
    + p, R5 G6 n/ B; T9 H3 W<P>    // Store that pointer as local player data
    ! `7 e( V+ n" w    SetPlayerDataForID( id, pPlayerData );</P>/ M! t( G, l3 c7 J& N
    <P>    // Grab net config into to send to client
    4 U: ^1 u% z) u; W8 @    m_ClientNetConfigLock.Enter();# A: f+ B) h8 A; |+ H1 ^
        ServerConfigPacket packet( m_ClientNetConfig );
    / A" t6 C( l5 G) {* a% W    m_ClientNetConfigLock.Leave();</P>0 Z, y' y2 u3 e( }6 Y
    <P>    // Send it/ ?3 T7 S# p. [: i7 y  ^5 M
        SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>0 L" J- f% V3 O
    <P>    m_AddRemoveLock.Leave();5 J* w- d9 |' t) W7 B
    }</P>
    - q! r4 P$ A! V' Z1 Q$ @) M6 n8 y# {& V3 F/ {9 W% T9 j: u' F# E" E
    <P>
    % J+ W5 U' _; @8 U( o6 p# n8 Z//-----------------------------------------------------------------------------( [: G3 q3 w* r+ \! a
    // Name: ! E3 t! F% A% s1 m2 ~' I
    // Desc:
    " T3 T0 L* B5 u3 F8 k& O8 v3 I//-----------------------------------------------------------------------------2 y7 B# d. _, U8 U7 ~: y. @5 a6 W" Q
    void CMazeServer::OnRemoveConnection( DWORD id ). O. H  Q! i- `/ K! G6 H) Z. y, t
    {' y& h! u1 j4 Z6 R3 }$ I
        m_AddRemoveLock.Enter();</P>% ~( I6 \( L! X: M
    <P>    // Decrement count of players
    # C7 w) m9 x3 t1 B5 M    m_dwPlayerCount--;</P>. ?$ R4 I* ^0 U0 X1 |  t9 K
    <P>    if( m_dwLogLevel &gt; 0 )
    - V- d, g4 O  W  D: o! s  ]    {
    9 `1 A7 m* u4 A: T# E/ I        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
      P) S# ]8 m; X' h, R& c        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );4 b" s6 \* p; I. R4 {
        }</P>
    9 o) {  S! C, R/ v6 j<P>    // Find playerdata for this client
    , Y- U* X. T7 ^, J9 n! }    PlayerData* pPlayerData = GetPlayerDataForID( id );
    6 s4 N+ U6 l# g5 W+ N( c( R    if( pPlayerData != NULL )
    & l, @5 X3 C/ ]8 s" s! X( c    {
    ' M4 m6 K! @1 s! s! W        // Destroy it, p0 Q" q6 J* e7 b. ], ?8 L
            RemovePlayerDataID( pPlayerData );
    ! s/ B( p& c3 W- K        DestroyPlayerData( pPlayerData );
    0 r8 J% G/ `) J- p1 V8 V& S: W  e) k    }</P>' N$ V- {; y! k( w) W( G
    <P>    m_AddRemoveLock.Leave();% Z- j/ T# s. I- l3 k% Q
    }</P>* Y9 U2 ~* z% P8 C* e) R% H

    # r4 q2 x: C- x+ U& ^<P>
    " l1 ?4 v. [9 I: ^//-----------------------------------------------------------------------------
    $ t$ G! J) D1 b% n8 I// Name:
    4 W* j. k+ ~" I% n9 b& u4 z// Desc:
    2 n: q/ {$ Q9 q  v//-----------------------------------------------------------------------------
    7 H$ g1 K& G! p3 j+ DHRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )
    ; \$ _. {  f) \, O/ R  P{
    / Z' n5 w6 J( s8 l, `2 W1 I& g( X    BOOL fFoundSize = FALSE;</P>/ S8 D2 l" }& w# v5 [2 U
    <P>    // Increment the number of thread we have in this process.. p8 {* {8 c3 l+ X* k
        m_csThreadCountLock.Enter();</P>
    ' X( R' g, @7 Q; H<P>    //Get the start time of when we entered the message handler.( h8 W4 [& Q. j9 W
        FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>: _$ L. s( y( q6 l& B4 Z
    <P>    m_wActiveThreadCount++;
    ) K+ f3 E- J6 B' s    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)/ ?8 ]# d+ Y- }% ^& G: F
            m_wMaxThreadCount = m_wActiveThreadCount;
    $ w% [3 f( m& q1 w7 l, T; M6 X    * H2 F$ b& p: T* Z* w
        // Calculate and average.$ {( k( K3 ~  p& D0 s
        FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
    , ?# S: B( i8 a" N% @, D    m_fAvgThreadCount += fdiff/32;6 u3 C! A1 b  D, c  o
        ' d& y  j8 V: j! [5 v; t
        m_csThreadCountLock.Leave();</P>
    ) F2 P$ o0 P, y" d0 @+ G; n/ J<P>2 L; s" G# z7 v) e+ Z& I
        ClientPacket* pClientPack = (ClientPacket*)pData;% }. V9 j! ~  T! ]5 ~) a
        switch( pClientPack-&gt;wType )+ j$ T6 n1 o9 v6 D* P1 }$ t" C
        {
    " N9 D" l, M) R  b  v        case PACKETTYPE_CLIENT_POS:7 l& s( A0 I5 `
                ' |8 A+ j+ ~- s7 P
                // Check to see if the packet has a valid size. Including
    1 S' \6 k6 t( a, s7 y5 i            // the custom pack size." @& u0 x+ q; t. m; m# u% Z
                if( size &lt; sizeof(ClientPosPacket))
    ( s6 w9 p$ r; p8 ^                fFoundSize = FALSE;  y/ f$ D- w% c& B; O2 c$ Q( [; l
                else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))5 @3 O3 |. b7 P5 m
                    fFoundSize = FALSE;/ x3 D0 g1 j+ }" M$ q& J( I
                else
    " s9 Z8 Q" R4 p; ?9 X5 N3 a( l                fFoundSize = TRUE;</P>
    ; ]7 z& z) k' G& E; Y$ B<P>            // If valid sized packet, handle the position.+ S( B! S, j! o! q4 u/ c2 e' d
                if(fFoundSize)3 Y- W! D: D/ q$ ^  }; @4 q
                    HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );3 j7 C$ z$ _5 O  l! l
                else
    , t% |# e# g: ?( h6 ^5 L                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
    ) ~' K, d9 A5 q1 p6 Q7 y7 C( c0 S<P>            break;</P>
    , H; l& c( `* K% M' j! F: L2 x' I) m<P>        case PACKETTYPE_CLIENT_VERSION:9 }  D" f6 U& Q" l$ X, K' z
                if( size == sizeof(ClientVersionPacket) )
    : l! u' y) S) f. O2 \                HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );
    : v( a) [. o9 c% t* j# R            else. ^% ^0 X6 O* j  W  q! p: A
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    & ~5 h# E1 G5 E$ B6 \  V( d' \            break;</P>
    6 C1 M& y  i" f& i1 y3 y<P>        case PACKETTYPE_SERVER_CONFIG:</P>+ Y* C. T$ C# v% s3 |
    <P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>: B* H& }  u( {  g
    <P>            break;
    # \+ X8 e& K# [) H        default:5 n, B- [; b2 o3 ^6 [$ b
                HandleUnknownPacket( dwFrom, pClientPack, size );
    $ @$ I9 C( ~9 b& v4 f' v$ u            break;
    3 K: A4 E0 a1 m+ s    }</P>, y9 m* j2 Z7 S+ p
    <P>    //If the user wants to hold the thread, Sleep for given amount of time.6 q& ~% W, r! U- t# c9 W. o
        if ( m_dwServerThreadWait &gt; 0 )7 U8 ]+ T4 I$ H1 e
        {  C! x% W. o0 i% z
            Sleep( m_dwServerThreadWait );: s* ~4 T) P8 e9 [/ q6 W8 k
        }" h6 ^9 x6 W0 t) i& M0 f) j
        7 m" C! i- {( A7 U% w
        // Retrieve thread data for this process.
    . N2 s) c. R  ^, d    m_csThreadCountLock.Enter();</P>$ P+ N3 i( b; T% l9 \, h* |
    <P>    m_wActiveThreadCount--;</P>
    1 o8 W/ P# {; O8 I/ d3 ]<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
    4 w4 f  x4 g3 t& e* I' S3 V9 N    m_fAvgThreadTime += fDiffTime/32;</P>* H% j3 m1 W. W
    <P>    //Get the Max time in the thread.
    ) g2 w, B) R& s* e6 r    if ( fDiffTime &gt; m_fMaxThreadTime )
    + x! H7 G2 X7 ]5 b: |6 k    {
    2 n) J% p2 k% X        m_fMaxThreadTime = fDiffTime;
    1 W( Q( b+ u/ W, a" `    }</P>
    ) I# D4 O/ L( E; ]& S0 w! y<P>    m_csThreadCountLock.Leave();</P>
    5 T, G! \# [4 N# u! G& [1 G' v2 P<P>    return S_OK;
    : j- |8 Z! p$ i6 V( t( O* D}</P>
    0 K' W$ c6 o2 K) P
    + ]0 E5 ^4 M  c1 O! g2 }# }7 Y<P>//-----------------------------------------------------------------------------# T9 z- W& W, z5 U* V9 C
    // Name: & e# f  [8 t* m6 b6 K2 S
    // Desc:
    ; i, O7 @/ r1 z$ I6 j* {//-----------------------------------------------------------------------------; T6 @) B3 ?& y4 x# X0 Y
    BOOL CMazeServer::IsValidPackSize( DWORD dwSize )) H& N, F! n9 E( L/ P2 G+ m4 c
    {
    # {3 o7 |( t6 `, e    BOOL fFoundSize = FALSE;4 U# _' V- `+ T& b+ x7 T/ b
        BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;9 m9 p# Q  S% t# V
       
    " S6 y5 b; c( p) \3 A5 z    // Check through the array of valid pack sizes.+ Z9 G7 B+ Q: W3 l" _
        if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])4 e  Z0 k+ |# k0 _/ i
        {
    8 u- d, u% G% l# y- `& s2 V0 h        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)" }# f4 s* f% [0 V+ j" _2 ]
            {
    $ l4 `; F/ S, [0 A: C* U            if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    3 V$ i7 N3 Y8 O0 P            {2 ^5 _) H" |8 g  }
                    // Found valid size in the array.
    8 \, Q% A) Z4 w# F2 V                fFoundSize = TRUE;) f2 v" p5 m% I/ E8 t$ E
                    break;; v4 [0 B0 _& }- E* V# H8 \: S, L
                }7 M2 v. l$ r1 y* j5 u1 x
                if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.! C5 N2 y, V# {" `5 O1 M5 [
            }
    : S" R0 v& }$ [, }. L2 C    }( T2 V, j6 @% e' U1 S
        else3 B6 o( P9 f" ?' U# v3 \! ^5 x
        {5 j2 I( t# a0 h6 J/ \' x) v
            fFoundSize = TRUE;
    2 \, b8 K3 v, J0 L, [% M+ |, t6 ~    }</P>
    # K- Y$ j) D' U/ ]$ c- V" f<P>    return fFoundSize;
    6 a! m5 H) h" r% H}</P>
    5 `. p* ?' }+ p- p+ f, W. S! \4 ?$ U<P>
    , H, f/ R! q6 Y% K  d& t//-----------------------------------------------------------------------------; K& r0 R3 E) a  b
    // Name: ; J6 u) G# n! [/ z" o
    // Desc: 4 }- m! f. S- Z) x  i6 g
    //-----------------------------------------------------------------------------
    9 W; e$ f( j2 j) ]) I' \( yvoid CMazeServer::OnSessionLost( DWORD dwReason )
    ' Q! B3 g, M1 g% G; N{, O; C8 b; g- Y$ d; @5 e+ q
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );  F& @3 `5 H4 b% @
    }</P>6 `1 {0 {! x" r; H6 u/ g- f5 J# R
    6 v% \# Z0 S$ ~+ c& E
    <P>, n+ F9 y: ~8 Q
    //-----------------------------------------------------------------------------& k" r% X5 `# j9 v: I- F- V
    // Name:
    / A2 R9 y( _6 F) S* w9 j: {% X// Desc: , }* {( S- u2 e/ P9 v) H( g
    //-----------------------------------------------------------------------------
    * K9 {7 d) H/ F8 U* kPlayerData* CMazeServer::CreatePlayerData()# ?: g5 z$ J3 H  m
    {
    6 Z& m4 H3 u4 K& Y    m_PlayerDataListLock.Enter();</P>/ T! c/ d- ~2 ~& K+ t- \
    <P>    // Grab first free player in the list
    & s% o7 G  X. o  S4 o9 j6 g0 e' u    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>
    3 e  I+ p7 d  \+ \% F<P>    if( pPlayerData )! o1 e! }* O0 g- E
        {4 A' d6 G( c& }( H! g/ i
            LockPlayerData( pPlayerData );</P>: W, v6 v! d7 X5 N/ a5 a* a% N; Z
    <P>        // Got one, so remove it from the free list1 b' J* K/ w& |
            if( pPlayerData-&gt;pPrevious )  o) O8 c3 P: x5 q* f+ o
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    7 P1 I1 W5 r9 j) s9 m! U! U        if( pPlayerData-&gt;pNext )! D" {- J% ^/ Y  C
                pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
    ( @9 R5 n% S# j* }        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>
    / R: d& u5 g* ~+ k<P>        // Add it to the active list
    2 W# ]6 |, u! f# K, }% ?1 n        if( m_pFirstActivePlayerData )
    ! k, I- H6 Z, G: d1 @            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
    6 V2 ?4 _4 X9 U, f, w$ {7 Z; W        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;4 t* c: r! a& [2 X$ \$ o3 L4 n
            pPlayerData-&gt;pPrevious = NULL;
    6 h8 B4 I+ M) q5 h- u. e% m        m_pFirstActivePlayerData = pPlayerData;</P>( |. R! a8 h/ y- B0 j& @  d
    <P>        // Update count of players
    7 a% y/ b1 U2 N* s8 ]( \( [        m_dwActivePlayerDataCount++;</P>% M+ o/ c5 B  t" j) g; |+ O& t1 x
    <P>        // Generate the ID for this player# X( g3 J1 N8 l: k8 Q- C; p( e0 Y
            m_dwPlayerDataUniqueValue++;
    " V- h( O3 C3 R. l1 f- K        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>* `/ Q2 B6 i4 y- g% S: O, h
    <P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
    ( S4 \/ E! d- w7 F. M0 k7 ^( B& x        pPlayerData-&gt;NetID = 0;% e; \, p/ X& o! p0 i
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>
    2 K# \; c: M/ M5 M<P>        // Insert into the "off-map" cell
    8 J. R: F0 \, i4 ?, F        pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;* V7 ]+ M3 e* b. M" c* P% H# I
            pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;4 x; a( S7 g5 c) [2 k7 F
            m_OffMapLock.Enter();
    2 Y2 S- R# K. y- _3 u2 r        pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;; }& k3 q$ m! j
            m_OffMapCell.pFirstPlayerData = pPlayerData;
    ' I; W1 g5 D* L- Q        m_OffMapLock.Leave();</P>' U# e' |) A6 b! }
    <P>        // Mark as active0 r2 r9 F- B. o- K  B' B6 K
            pPlayerData-&gt;bActive = TRUE;</P>
    7 D4 G8 b/ a- o; n* A& Q& U<P>        UnlockPlayerData( pPlayerData );
    2 o- ?6 x) a% b$ U+ v) y    }</P>: N0 E, l9 q1 ^# a4 v9 `
    <P>    m_PlayerDataListLock.Leave();</P>
    $ N8 W) F7 F% Y<P>    return pPlayerData;
    4 f1 D8 V  Z% k$ g' d9 Y' X5 X}</P>8 X5 f* F1 p7 A/ \
    , C, @% h- ?2 Q. s+ o
    <P>
    * K- @1 P0 O( @- d: y//-----------------------------------------------------------------------------
    - A. w# Z  V8 o5 Q3 l+ v// Name: ) \- |! b' k5 m8 Z
    // Desc:
    9 n. |* d5 Q: g6 P" B//-----------------------------------------------------------------------------
    " b& ?+ X6 O8 `& mvoid CMazeServer:estroyPlayerData( PlayerData* pPlayerData )5 A2 y& }& |2 f+ }2 ?5 U( j% a1 t
    {
      w; _0 K, O* B; ?5 c    m_PlayerDataListLock.Enter();
    7 l2 ]1 Z1 q. s& G    LockPlayerData( pPlayerData );</P>
    # D, @' P* ]0 m# x<P>    // Remove the player from its cell+ j4 |3 [9 L0 e& I4 i. J0 ^
        RemovePlayerDataFromCell( pPlayerData );</P>! a1 B6 l+ S  @; E' Q7 z% S
    <P>    // Mark as inactive* @+ r; d4 S0 Q8 [5 B
        pPlayerData-&gt;bActive = FALSE;</P>
    , I9 Z( ^# l: g; ?. Y3 l6 @<P>    // Remove player from active list
    1 B1 P! [; x( y3 D5 C; X0 U    if( pPlayerData-&gt;pPrevious )
    7 A6 d6 J% u& d+ n        pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    ! d& Z/ s6 ]5 c/ ^    if( pPlayerData-&gt;pNext )
    ; u8 c1 ?: g$ n7 ^& W- B+ o        pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>; G1 d" l: j7 h( g9 L: k
    <P>    if( m_pFirstActivePlayerData == pPlayerData )" g7 h' I8 |  P$ V# `4 n% Z
            m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>0 I7 U$ ^9 C6 [& p8 c
    <P>    // Add it to the free list; h8 t9 K# F3 w& G. S1 f2 s
        if( m_pFirstFreePlayerData ), K- s/ R: C% y, x6 [; |
            m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
    ' E% K) Y: u9 Q9 f: _7 A$ y/ a    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;
    % j! `0 {# [" q% i    pPlayerData-&gt;pPrevious = NULL;
    * t- ~' `" v7 e( e    m_pFirstFreePlayerData = pPlayerData;</P>2 I  v+ }9 Y# S: l% T; O
    <P>    // Update count of players
    / ^+ u# K  Q7 J9 \" z6 e/ O- Z7 f    m_dwActivePlayerDataCount--;</P>
    9 X! z' H' B% J+ e6 G<P>    UnlockPlayerData( pPlayerData );2 [& G3 G( H1 V5 c$ a# S& s
        m_PlayerDataListLock.Leave();
    - Y  ^, F2 l! r}</P>
      \# Z) s; \. B( l/ d4 u) K. Z& ?0 `2 ?/ i% X
    <P>
    7 x' Y& r  M; a$ N% c# S//-----------------------------------------------------------------------------! ~6 I2 D' `/ e+ V
    // Name: 1 y; i( T7 s& U* w# ]  O
    // Desc: ) ~4 N1 ^4 C; j0 L5 s7 X
    //-----------------------------------------------------------------------------% [+ r& K7 P% ?& f2 A* c
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )
    3 {% k# [( x) b2 D* j, m. o( o{, l5 K0 C# L3 Q6 t  D
        // Lock the player' m' Q! O1 Z, |
        LockPlayerData( pPlayerData );</P>
    ( f9 z6 k/ {, c7 n' @7 B9 z<P>    // Lock the cell the player is in3 Y5 F3 y+ S* t, N/ t
        ServerCell* pCell;
    $ ?/ Z6 l& j7 w: P' _- I5 s    if( pPlayerData-&gt;wCellX == 0xffff )+ J+ P& P- ~0 j# \+ A% s4 G
        {0 |" I& J" D# i! T' C" Y: ?
            m_OffMapLock.Enter();7 B/ N9 [" M  B) k( s5 \3 Y
            pCell = &amp;m_OffMapCell;
    ( A9 O# q) z1 ^    }
    + j5 H! I; q; c( X  f# A    else: I+ t0 l4 `+ ^% n' z4 K
        {5 Q' X' R( s" n- O
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );
    / V) s5 F! v3 Z2 G) U        pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
    , n; C, G% C  [/ ^' X3 G6 n    }</P>3 X! v7 C' v8 `) [2 P
    <P>    // Remove it from the cell3 @1 @$ a: J7 ]0 K3 V- C& S4 n
        PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    + _$ T3 f6 P1 ^    PlayerData* pPrev = NULL;
    * V* }: ^6 C# l$ {( ]- X$ T    while ( pPt )
    $ w' P9 e" q5 i1 @$ K% w0 m) H    {% ?5 k1 r, z" H0 g8 e
            if( pPt == pPlayerData )! b  O3 c- k: t# W7 w2 y
            {
    # S9 }* ^9 n# k% }* D- p) {8 u$ G            if( pPrev )  g( a2 M5 Y# {: Q- L2 o' e
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    0 J5 k4 Y3 |' Q# e            else- E5 K. i/ E6 @
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
    , S5 |6 E$ H% K4 m; d  _( W<P>            pPlayerData-&gt;pNextInCell = NULL;
    8 U- j/ K2 n' ?: g  z            break;/ _4 k, h5 G( T  w3 n5 l
            }
    " u+ {/ s- d0 o- O8 B7 e1 `        pPrev = pPt;
    # C% d2 P7 c. X# k+ }, \% N4 x        pPt = pPt-&gt;pNextInCell;
    & i+ O7 k% u+ [/ M    }</P>+ B+ g" F5 {. Q$ I  c# ^
    <P>    // Unlock the cell' Y8 e  c; ?. K0 W& ?, ?
        if( pPlayerData-&gt;wCellX == 0xffff )
    + f( {- Q1 F3 R* M8 x        m_OffMapLock.Leave();
    ) E6 H$ I( l6 G    else
    % o  B: f5 _  N1 W        UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>4 k( T2 Y, w. j* I
    <P>    // Unlock the player  k  k. B" n" W) q! K0 o4 `6 r! b
        UnlockPlayerData( pPlayerData );
    , b6 C3 y+ \5 W( ^4 D% {+ h}</P>4 a5 x, K+ i; Z2 G/ u

    - ?) {1 l' A0 A% D<P>; i6 |# z9 G; j* R. M
    //-----------------------------------------------------------------------------, v5 R  O8 l" E, ?1 P
    // Name:
    ; _8 v* S. F* x5 _/ r# j// Desc: 2 u6 Q, D4 M3 @/ n8 W
    //-----------------------------------------------------------------------------
    4 w4 w4 t1 n& o- Dvoid CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
      G+ r+ M  _- L: ^{' M4 O) l& i1 J* i; Q3 D+ i
        ServerCell* pCell = GetCell( pPlayerData );
    6 S9 D  q& @" [/ a, n+ W    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
    ! q; \& U0 e* f5 ]9 A7 D    PlayerData* pPrev = NULL;
    ) |9 D1 ?- H; ]- B, ]    while ( pPt )- h! n( Q6 U! \: \$ D
        {
    ; Y. |7 [+ Q6 D8 t+ R4 _        if( pPt == pPlayerData )
    5 N2 e% k; H/ ^- P, t7 c! y        {8 p+ \3 x5 ^. |! \* ]+ @
                if( pPrev )7 u* A) ^7 Q+ L% Z% s
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;' n& D2 _% L! b  m, H
                else  {3 a. j  U/ D
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;
    4 W! g7 ~; _4 l( E7 p7 S            pPlayerData-&gt;pNextInCell = NULL;
    1 \+ ~. v1 u; m6 V2 l) W2 P            break;
    2 z3 ^0 w+ ]" M1 g9 P( A        }: G7 I6 y4 I3 `( q2 q. [" P5 z
            pPrev = pPt;
    # c. U4 c/ S! e. K$ u! _        pPt = pPt-&gt;pNextInCell;
    , I2 w0 Y+ ]! v4 V; f    }, T1 Y/ d6 U2 F. l9 p3 l) w# F
    }</P>
    3 w  M3 C7 ]4 v- ~' x) c- Z. V
    4 r! L4 l, ]9 C9 O  W<P>
    # Y! X: j/ z. f9 T+ |$ o* |8 Q//-----------------------------------------------------------------------------: r8 S$ P8 h3 j- j" D
    // Name:
    ) ?4 p9 e  L7 P! X// Desc: ' ?0 P; w8 [8 p
    //-----------------------------------------------------------------------------
    6 g4 h: a* e2 c1 Y- e. b  Qvoid CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )
    - Z4 [+ F" K. d/ w  o( a3 K{
    ! r& a9 P) `- ~- d    ServerCell* pCell   = GetCell( pPlayerData );
    : ?# O5 O. e/ n9 W! K% _( e5 J    pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;" h- `6 {4 I9 A* v* L0 c: I+ q# z
        pCell-&gt;pFirstPlayerData = pPlayerData;
    $ }' ^6 C9 E  V}</P>! G! O6 Q- s4 C+ f6 s6 `2 D

    , \3 w3 `% h, j* E" V' t6 D' b<P>* U- ?5 N# [, G1 J
    //-----------------------------------------------------------------------------
    , E( l0 U  v* D, B4 j// Name: ' A$ @5 A  ?: k, V, [# r
    // Desc: % `( g7 E0 l8 `# ?0 m
    //-----------------------------------------------------------------------------+ g+ ?5 k0 V$ x6 k3 }( H( W/ i
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )
    , _+ I& y4 Y& h: n! p  w{: R# L/ M  s4 o
        // Grab player for this client and lock it
    5 H) V( Y  Z* S( ~& ~    PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );
    % x6 y3 f$ ?! j$ k    if( pFromPlayer == NULL )
    " M  a. D$ a# [# p7 M& k    {
    6 X, S- B" |) B0 E        if( m_dwLogLevel &gt; 1 )1 K- R2 w6 q5 N
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );
    ! l6 _4 u8 j2 n4 F        return;
    - g1 k( t5 j9 }& X: _% \6 h/ v: ~    }</P>
    - t5 r2 v/ E& z) p5 s; ?<P>    LockPlayerData( pFromPlayer );</P>
    % R# ?  L# n. c, x" E  `, v<P>    if( FALSE == pFromPlayer-&gt;bAllow )
    / s3 @5 v% @4 S7 G    {
    , f1 P# O5 p, V, y        if( m_dwLogLevel &gt; 0 ), T" m. Z% j$ c7 U
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>0 X& v3 ]9 C; Y$ h* l  M' R
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    ' c' J! F& C# u; H6 `& v  S        UnlockPlayerData( pFromPlayer );
    4 i8 u, {+ }: P. j( n        return;
    * Q8 M) u+ g4 n2 W    }</P>2 ?2 c2 ]2 b7 P% l: f
    <P>    // Compute the cell the player should be in now* A8 p$ k3 @6 C2 j/ c
        DWORD newcellx = int(pClientPosPack-&gt;fX);
    $ p. h0 z- }# E- `# I6 y* v    DWORD newcelly = int(pClientPosPack-&gt;fY);, s# E# ~  u7 Q" i( @4 S; g
        DWORD oldcellx = pFromPlayer-&gt;wCellX;4 x& O' w9 }. r/ N
        DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>1 T. Z* q8 m" M; g
    <P>    // Have we moved cell?0 u. B1 L* k! p1 D7 }
        if( newcellx != oldcellx || newcelly != oldcelly )
    9 W1 @# s0 I% [2 j( {" p    {
    , b* F, z3 }( i+ m# P8 B        // Yes, so lock the pair of cells in question) C! g; d$ ]9 j* o+ `- _
            LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
    ; n2 W2 h4 j" j$ q<P>        // Remove from old cell and add to new cell$ O! b: K* o' _9 f$ s
            UnsafeRemovePlayerDataFromCell( pFromPlayer );/ T  a2 l! t  v, f% u) l
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    / x. P  i/ B* d/ i0 v3 e! M1 @: ^. K        UnsafeAddPlayerDataToCell( pFromPlayer );</P>
    8 R; o) }4 C$ r# D, `<P>        // Unlock cells3 D; K  O" ~/ _3 Q# e( [
            UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );* \$ X; M- D- h& X& Q. v) t
        }</P>( ?6 _; b# y+ t1 U4 @
    <P>    // Update player position
    " f  N3 M" R* Y7 I# W- r. d* r    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
    3 _9 O& A3 q  _" a* U3 C1 H    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    5 Z2 F! h) F2 V$ K4 S) a) G    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>6 ~' t0 ~" I* s; T/ c5 v: Z
    <P>    // Allocate space to build the reply packet, and fill in header % L* b  n+ F" W8 Z6 X/ l
        DWORD dwAllocSize;
    ( o7 Q5 h# C! o) |* y/ J. x2 R& D    ServerAckPacket* pSvrAckPack = NULL;</P>/ c+ \$ \+ B6 j2 b
    <P>    // Begin by allocating a buffer sized according to* ^4 S, ?$ h( W8 W1 ?0 Y( l. K& ~
        // the current number of nearby players + 4.  This will give
    - M- o" f+ ?5 ~; r, d' X4 S) T, H    // a little room for more players to come 'near' without resize  }) b' z8 v; o6 v0 R' y4 ?
        // the buffer.
    , z# l8 v' ?9 X& |; U5 l    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>5 Q, V0 H' T! \: \& l
    <P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    1 [/ I/ ~& g( o( p, }+ B    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    % f7 K8 L6 \* `" H4 e9 o    if( NULL == pSvrAckPack )
    6 h" V- ~4 _9 e; K    {
    3 f2 H4 @$ y( \  W! z1 g8 R        // Out of mem.  Cleanup and return
    : A0 \1 O$ Y# B( m1 g; `6 ?) E        UnlockPlayerData( pFromPlayer );
    7 p) p( b, O- j! |) T) K$ ]% s        return;       * R2 l/ v$ S. O9 x5 J. u% l
        }1 c3 Q2 |) o) U( p
        ZeroMemory( pSvrAckPack, dwAllocSize );</P>
    - m/ D5 G: v9 B/ u<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);
    6 p' S  t0 ^+ b% Z    pSvrAckPack-&gt;wPlayerStatePacketCount = 0;$ [. J1 V- k) c0 w& U
        PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>
    . |+ J, Q: R. G& r<P>    // Compute range of cells we're going to scan for players to send' I0 U; g# r2 ?( K7 L
        DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;
    ' {: _% B+ ]4 K4 A    DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;+ p" j# s( w, O+ N$ o- y: `
        DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;
    5 @# u) v, {9 f% `1 h1 j    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>
    / D: T" g; S# L7 H5 k<P>    // Lock that range of cells* c* e3 r$ A9 A
        LockRange( minx, miny, maxx, maxy );</P>, H! b6 q9 \( W8 t; M3 e
    <P>    // Scan through the cells, tagging player data onto the end of  l, w0 K- W, V. Z3 ^7 k
        // our pSvrAckPacket until we run out of room
    " a5 v  t% n2 |8 T    for( DWORD y = miny; y &lt;= maxy; y++ )
    ; f% Q& l( L1 c/ Y; m" _    {, {5 |# I/ O( c& P6 f* k
            for( DWORD x = minx; x &lt;= maxx; x++ )
    " \. r1 w0 h5 p8 x        {
    / H$ b5 F2 H2 _            PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;) C6 I$ ?6 u5 A: j
                while ( pCurPlayerData )
    2 ^+ N& r& ]. ^& X  Q$ K1 j" t            {1 u4 Y1 T9 Q% i) ?1 }4 a6 ~- d
                    if( pCurPlayerData != pFromPlayer )" w, q, {+ k; u2 ]' F$ e0 @
                    {, K1 ~1 q' ]1 K; `3 x" ]! ~: z8 v9 ~( H9 K
                        if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )
    ) z* H; `& R- ^- ?                    {
    * r; R6 P1 {1 p) |  e/ h                        // Make sure pChunk is where we think it is5 ^5 Z+ J  V+ o
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>4 G/ f4 {$ H6 d! q" f& K2 ^# \
    <P>                        // There are more than just 4 new nearby players, so resize the   N" h& ], k) g2 s- f1 h
                            // buffer pSvrAckPack to allow 16 more PlayerStatePacket's., ?( j3 y  e, v: X* H
                            dwMaxPlayerStatePackets += 16;
    1 ]: b' `4 _: b$ v5 {                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    7 [5 {0 t  e2 l) ~9 y                        ServerAckPacket* pNewSvrAckPack = NULL;  X$ d. ^+ X6 H8 j$ o/ N; [
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );  A& @$ i( H# u( Y
                            if( NULL == pNewSvrAckPack )
    ( {, @6 m% G/ }                        {2 N2 L! W9 y! `8 i  J  [
                                // Out of mem.  Cleanup and return8 h; J; S3 V& _2 j& u" o; l
                                free( pSvrAckPack );$ I! s! ]+ `/ t- ]' ~  a& e/ r
                                UnlockRange( minx, miny, maxx, maxy );
    3 `" C' m1 O; \                            UnlockPlayerData( pFromPlayer );9 d; R5 o- e- \8 E  a
                                return;       ) a, Z0 i) w4 q& d, L1 B* G6 ]/ Y7 K
                            }</P>
    + e) J: l( O- s; n. \) t<P>                        pSvrAckPack = pNewSvrAckPack;, V& z! O* {- ]* A
                            pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
    + q2 w% z# G- @4 S: K<P>                        // Make sure pChunk is still where its supposed to be
    " t' _0 o. t# C8 a) \1 V4 O7 X                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );# [' P: m) h5 X( ?& n( v0 k& I% i
                        }</P>
    ' _- J2 S4 A0 k9 s/ ^<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;
    + Q8 I6 p6 m  y" ]. E  h                    pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
    : P$ p! S4 i- x% w4 k                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;4 y$ N% _4 v' ?& {0 i2 q
                        pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;) K8 s$ {3 U9 M# q8 _" V
                        pChunk++;
    , C* q4 e8 J7 l0 |                    pSvrAckPack-&gt;wPlayerStatePacketCount++;
    + a) R# k4 z5 b! P" D2 b2 C9 A. i5 c                }
    6 J* l- C/ ?+ i+ ~4 Q% Y                pCurPlayerData = pCurPlayerData-&gt;pNextInCell;" {0 D2 u3 Q$ F. }- x' z, t2 v0 q# ~: I4 c
                }
    # U0 p$ v" Z9 k9 o9 u6 ?        }
    $ E* J$ [# I' O! [* ]9 ]' i    }</P>, O6 E, c* q! z+ ~: C8 k$ I+ |
    <P>    // Update the dwNumNearbyPlayers for this player
    5 U( M; y/ [* i/ ^/ `  D0 j" n    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>) G; y* [& G" r
    <P>    // Unlock range of cells6 X* z: j& ~/ \% u
        UnlockRange( minx, miny, maxx, maxy );</P>
    - o/ p% ?" {* r8 ^1 Z<P>    if( m_dwLogLevel &gt; 2 )8 ^( B% F6 X9 J1 j
        {0 G# s5 w+ j3 Y6 N& N/ p; d' V
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    - q5 `! j: a: R" F% F" u4 p7 {: W    }' G0 x0 ^7 w: \$ y, R
        else if( m_dwLogLevel == 2 )
    & q* j" H3 R: D$ F) e+ j    {- @+ C1 ]: ^( Q# X  C+ W8 Q- R
            FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );  G" \% ^  w) @$ C& k* O5 T
            if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )
    7 [& t. d* J- y6 l7 p$ r- [        {+ r% N" P6 V& B" y) B
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );5 e$ g$ ~- y0 z' l% a2 h
                pFromPlayer-&gt;fLastDisplayTime = fTime;5 _& P5 D5 n7 O" O0 @
            }2 t" P0 b' T/ R! l0 _! z, ~# j" X
        }</P>
    6 ]( j8 ^4 `+ ]! E/ F5 N<P>    // Unlock the playerdata
    9 M2 w/ x* B9 E: J    UnlockPlayerData( pFromPlayer );</P>
    . y1 _  W$ ]6 m- T2 O<P>    // Send acknowledgement back to client, including list of nearby players
    - ?& g# t: E* b) K+ Y; k$ S) l! E    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));8 h  z" A5 H5 n- s" m1 O
    . w# r% D5 v) ~9 B+ j
        // Pack the buffer with dummy data.6 Y5 u8 U- m0 o
        if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)
    ! G$ D+ ?& n$ Z# L) P    {: Q( R/ T* I( ~- [2 q* K& z" Y* p
            DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];  `$ F' w# g+ P* Y. M0 ~
            VOID*   pTempBuffer = 0;</P>3 b4 k$ B4 R: W( y1 M. p/ s' v
    <P>        pTempBuffer = malloc(dwBufferSize);0 @  {5 P( k8 [; E5 r; }
            if( NULL == pTempBuffer )' c8 d* z, i  q' Y1 j
            {7 y' n/ k' X& ?
                //Out of memory
    ' J! ^4 Y- }/ ^            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
    $ g7 _% f7 J  }5 d7 I            free( pSvrAckPack );' \' Q$ S( v/ w
                return;
    % i6 T+ X: A/ y* ?* ^3 u        }</P>( R) L. E4 X  H
    <P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');
    4 J7 {' t8 ?/ U1 c( |        memcpy(pTempBuffer, pSvrAckPack, acksize);</P>1 a8 _$ U" g4 M4 t, w7 M/ d/ b$ i
    <P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );) G. n& U) k0 x$ Z1 Q* V+ H
        # h) z+ {$ t( X
            free(pTempBuffer);% J' |' \* f- P: |% Z3 Q7 m
        }   
    ! h# m* x& p( H8 y    else7 M: K6 g6 Q* D! u! ^
        {
    + t& G5 v3 \, S9 O7 \' t. n9 C) R  ]        SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );# w  H6 X' Y, j6 R
        }</P>% Z3 n. X2 R6 E1 M
    <P>    free( pSvrAckPack );</P>- u" l6 C, f& F
    <P>}</P>9 m8 {6 B+ ]0 ^1 ?2 R" t

    3 _/ l% m8 \$ U2 R: o; o- i<P>! L% W+ v8 D1 e! U6 Q% I
    //-----------------------------------------------------------------------------, H& C) z9 A; u# u9 V
    // Name:
    1 B9 X3 @7 y+ h2 s3 q( G// Desc: 4 {6 |' v) u& v/ @7 r
    //-----------------------------------------------------------------------------  Y( C6 ~5 o. }- \& [8 c. V/ S
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
    0 v* \" u  I! P9 t2 F- b{) J+ x  c! \* o5 h: Q9 y
        // Grab playerdata for this client and lock it
    , U- A, k) |0 p3 R    PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );3 r2 u5 f( \! `/ |8 S% G
        if( pPlayerData == NULL )
    1 V( P* n1 k$ y1 \1 W5 L        return;$ Y. q8 Z0 M- E6 k# m' S
        LockPlayerData( pPlayerData );</P>
    , W5 @% V  w* l: g# a<P>    // Record the version number
    + h6 D) f  K* l6 |    pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>% ]- B' o8 r, |+ C! |4 Q
    <P>    if( m_bLocalLoopback )
    $ h+ M( \/ \2 O, J; a! Y0 M        pPlayerData-&gt;bAllow = TRUE;& ^5 d+ A9 j% y1 Q5 K" I' a) I
        else
    3 `. g# V5 c' f: Z/ A$ @$ ^        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>; V, B, c3 y! s0 |  E
    <P>    if( m_dwLogLevel &gt; 0 )
    4 g; O4 M# ]0 ^* K# O6 r        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>9 ~' {% M+ n3 t9 c! `, H( ]
    <P>    if( FALSE == pPlayerData-&gt;bAllow )
    0 s: n; t6 ^4 N' Q# x! q    {/ g& [* |) }' Y& T/ a5 E
            if( m_dwLogLevel &gt; 0 )
    , g8 y; a- U0 w; g/ x            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>
    0 R3 y) B& ~8 `1 _6 d; ]& ^  C<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    5 I$ V5 c: a  j* s/ v        UnlockPlayerData( pPlayerData );
    6 F& l  n2 z6 G+ v+ N( V/ T& o' D        return;* i' Z- L- Q& q: [; J: [
        }</P>& C) Z- s1 v6 v$ S* X3 {) }8 A
    <P>    // Unlock the playerdata
    1 |/ l( Z8 t* d6 e' U3 o: S( ]    UnlockPlayerData( pPlayerData );</P># b; ^% G- `- F
    <P>    // Send acknowledgement to client that the client was either accepted or rejected
    % ?) M& u9 ^) ]5 U; u( n, e; p    ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );; I+ Z* a( `8 g$ w; H
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
    ' J. ?" W$ I$ Z6 `  x0 U}</P>2 r# y3 U/ ?5 n) Z1 A

    , z+ O% x& K/ s; F. M1 ~$ [<P>
    7 ?6 _) n6 M/ P5 l. [//-----------------------------------------------------------------------------  m# l3 c5 v' S% A6 ^2 e: x
    // Name:
    $ Y" G; t# o9 H2 G// Desc: 7 `5 g. }7 r  \% c9 f% v$ h) R
    //-----------------------------------------------------------------------------$ Q1 n$ D0 N5 R& }  b
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
    : R. }+ ~8 d/ |5 x& H2 p{) Q3 c, Q3 b8 l
        switch( dwClientVersion )$ D6 E! d- E; C
        {' d( U  f& U% Z6 F+ J3 l+ m2 `% P
            case 107: // only v107 is supported( c- I9 v/ \5 u( s
                return TRUE;
    7 w- N6 f/ p6 }! F+ X8 [        default:
    5 {; }9 C+ U% \+ U/ T. e7 q            return FALSE;* x7 I7 O& i3 H7 h0 |
        }
    6 w& _5 g  B0 X, w2 g}</P>' \" a$ E8 w) k, }% K
    # v' y8 s( y" M, G* o
    <P>
    3 p1 x- v$ u7 r; U  |//-----------------------------------------------------------------------------: l% s8 l3 F6 o8 f$ O+ F( _
    // Name: 1 ^- X0 S6 v% f* p) |
    // Desc: ; Q2 g. q, Z6 G
    //-----------------------------------------------------------------------------
    - o% O8 Q8 Q( l( d; A) |3 |. mvoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )* i1 P+ w5 i: i
    {
    ) R( H$ P# e, g  |  J2 P5 _    if( m_dwLogLevel &gt; 1 )/ x: z7 n2 }0 d- F4 l7 q4 k
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>4 S& \1 V: O% v) r( f
    <P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    * c4 s1 @/ h8 {5 _}</P>
    * l& s4 R0 z, l1 ?+ G: O' C- o2 I' L/ N1 `
    <P>) w" L7 v7 ?% h; B: D
    //-----------------------------------------------------------------------------$ {+ l+ c3 V/ R) k. N
    // Name: " w. s. h+ q+ |. y2 }
    // Desc: % D9 e* {! ^, B
    //-----------------------------------------------------------------------------) B' K; K1 n' |$ y' e
    DWORD   CMazeServer::IDHash( DWORD id )
    3 {; I# Q- s; @4 Q{$ W! i4 I  X7 t/ C1 M, {
        DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);- l- K8 N+ A/ a# y  h
        return hash;! @6 d0 l8 s9 c0 w8 P. P
    }</P>
    ) W& i( o$ T( L/ N- {1 M' D* k
    " v& Y3 t+ n  L# S8 g) g( V- ?( R<P>
    1 ^5 \8 j7 A" h4 F! b3 K//-----------------------------------------------------------------------------2 k* P2 w* e& V/ y
    // Name:
    / V5 y: \# \: g3 c- r5 a// Desc:
    - L! W$ _  w+ O8 @5 F//-----------------------------------------------------------------------------
    ' {6 q2 F, z% wvoid CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
    ) w3 \8 v% z. G. b4 p, W{
    ( K1 J- H+ ^0 A1 y1 o    // Hash the ID to a bucket number
    7 _$ v0 h8 d, k6 b, b& w  G/ K    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
    7 O& i7 d) W1 N5 f) x<P>    // Lock that hash bucket* k( i& H. j- |5 W  G& d
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;8 C* x) J6 O, d6 H; q
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    ' d, [. e/ O/ h0 e- g1 [<P>    // Loop though players in bucket until we find the right one
    1 Y( i6 Q9 f5 f" I2 ~( {    PlayerData* pPt = m_pstIDHashBucket[bucket];, s" B, H% o% T* U, T+ Q( t" I
        PlayerData* pPrev = NULL;
    1 Z1 @* P# \( _. w) Q    while( pPt )
    6 ]. E- f4 E! L: W, C6 y    {
    : K& u& r* J+ G" |        if( pPt == pPlayerData ); E" e6 j  b  x5 X0 V9 e
                break;
    ! a. E7 h% ~1 v& @: Y        pPrev = pPt;
    ; I5 Q2 s  d! U        pPt = pPt-&gt;pNextInIDHashBucket;
    - X9 o1 x+ ]% @+ K* J* v- r    }</P>
    - ]) t/ U! D, q6 y8 e- C- O  T" }<P>    if( pPt )
    . [& t0 B/ C$ F, n! w    {: y4 z/ l' N8 ?4 Z+ P/ D
            if( pPrev )$ H  T6 h, m& D( i6 }& n
                pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;. b+ w9 ?2 \: L
            else- U- i$ `6 T7 s5 y7 x7 F
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;% Y6 `# A' P( k
            pPt-&gt;pNextInIDHashBucket = NULL;
    2 D2 A) G: [1 S- Y* q0 z  V1 p9 O    }</P>
    , A9 s2 r2 M6 d* h  C<P>    // Unlock the hash bucket7 W" ^: A5 t% l' K
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();* d/ T9 |6 Z$ w7 L) q
    }</P>
    2 K3 |* ?, u# k7 d1 s- _. P  ^+ u
    4 ^9 V) n2 A3 m, {+ Z<P>  D: A4 e4 z" V  [+ c* M* i
    //-----------------------------------------------------------------------------
    ) o1 Z, l; T5 |* t// Name: 6 k, @! I! H& s& s' u1 n5 \6 e* Z
    // Desc: 1 E9 f7 X7 X# y3 m3 }
    //-----------------------------------------------------------------------------
    3 Y( p9 h$ M/ C5 Wvoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )8 X: D  n4 }4 s; L$ @9 [
    {. C$ e* g2 t1 \1 K( |
        // Make sure this player isn't added twice to the m_pstIDHashBucket[]: v$ D+ ~- H2 v, v
        // otherwise there will be a circular reference2 Y/ W: \' o& ]- a8 h' ?& o
        PlayerData* pSearch = GetPlayerDataForID( id );
    9 _2 J7 t  I5 C' N    if( pSearch != NULL )
    + J. Z3 ~1 Y/ M5 H' Y! ^        return;</P>
    7 v( n8 t: W9 _3 v<P>    // Hash the ID to a bucket number
    # w( I- W! W3 v  H: x' ^8 ~) l    DWORD   bucket = IDHash( id );</P>- _1 `+ Y8 D( g, S9 {5 Q
    <P>    // Lock that hash bucket
    * l5 |2 T0 S  `, o7 G    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;5 H2 o8 o4 g. R
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    + E0 O5 y/ f7 L4 p/ H+ Z% l8 E<P>    // Add player onto hash bucket chain" `# ?& j& `# X
        pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];2 E* N) Q! e# D- [
        m_pstIDHashBucket[bucket] = pPlayerData;</P>
      N0 S# `+ W' M* L& l4 \<P>    // Store net id in player
    $ }  B2 p( ]+ n2 P, \    pPlayerData-&gt;NetID = id;</P>
    0 c3 n% g) \4 c7 x7 h. `<P>    // Unlock the hash bucket4 s; W4 s: H! \$ M9 ]" m: r
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();* q4 z% f. f" ^
    }</P>
    ) \  y2 q1 k# f5 E$ I, B% w# X- x" z- h- n. H1 t3 U
    <P>
      @- B: Y% D2 j0 `( G5 ~//-----------------------------------------------------------------------------( _5 @  P* E" M" H9 x  S
    // Name:
    $ T7 o* V  G# V) U4 Y// Desc: ; m5 b. H5 x# J3 X
    //-----------------------------------------------------------------------------
    % d: k1 E0 O- APlayerData* CMazeServer::GetPlayerDataForID( DWORD id )
    * r  R1 H! j  d% A( X* D3 n{; f4 \; o5 u9 D) d3 n  q/ @' e
        // Hash the ID to a bucket number
    4 S( T  j6 C* Q3 b: N: |) J0 q    DWORD   bucket = IDHash( id );</P>8 d7 h! f3 P) s* l4 }  [0 [# ?
    <P>    // Lock that hash bucket
    ; B; G* l! R# c( S) h    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;0 }! G0 f$ ^4 J% M6 \4 s
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>2 h3 _& k: y/ T) P
    <P>    // Loop though players in bucket until we find the right one: C2 A. V! h- W9 h$ Q& A
        PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    ; Q0 A, k, }3 I- o' L    while ( pPlayerData )5 J6 z2 P, }7 D% r# W0 R' |
        {
    ; K' U9 j7 e! Z        if( pPlayerData-&gt;NetID == id )) p2 j, A* n2 N  U" ^: U% l. [
                break;% h; d* N. \, `" _
            pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    5 K- L1 {8 M, h# I. L    }</P>3 x2 [9 [# M4 ^. \( Y8 S. G
    <P>    // Unlock the hash bucket6 u; u$ z2 }  F6 E
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>
    - s/ J! B: k, Q! b& N3 }<P>    // Return the player we found (will be NULL if we couldn't find it)8 s& p, f5 `2 w# T9 C! v8 i# F
        return pPlayerData;
    $ f* i% z+ }8 c1 l( k, F  G}</P>- I0 i# p5 X; ]% r7 c1 {2 H5 \

    $ X9 V$ l( M' r) P' z* {<P>
    ( c" i# B& t/ F" C//-----------------------------------------------------------------------------$ _7 T: {+ t/ Q& r9 {
    // Name: & _3 b5 q7 B3 D
    // Desc: calls DisplayConnectionInfo for each connection in a round-robin manner
    : k0 l' _8 G" ]//-----------------------------------------------------------------------------
    " u7 q8 I# t% J4 O: W$ {' _. svoid CMazeServer:isplayNextConnectionInfo()( S9 d' Z% t* y" W8 `
    {
    2 A5 I- P* d! [6 b    if( m_pNet ). L  L8 C$ A( o: E' Q( s: ]& w
        {- y& C0 Y: [3 e8 ]+ d2 v+ \4 b
            // Find the player that was displayed the longest time ago, and display it.
    0 n! a$ N5 R( m; ~* i        FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
    $ }. X8 r' v. R. i        PlayerData* pOldestPlayerData = NULL;
    / n$ J; u! E) f        FLOAT fOldestTime = 0.0f;</P>
    ( D7 i  v0 f2 A<P>        m_PlayerDataListLock.Enter();</P>* @9 ~. T5 `$ P$ z- L  \) U
    <P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;# k; q. F/ @" F" f0 n' W$ J
            while ( pPlayerData )9 h3 m% q" z' ^/ H2 Y
            {
    * d& s! c. X! m& Q            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )( W6 o  |0 c' U7 Z
                {# E0 _3 A) c; J! i- t
                    fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;8 Q2 l  o$ ?' I
                    pOldestPlayerData = pPlayerData;/ S! E9 Z# s1 z0 ?
                }</P>) U. @9 h- {5 J! p5 ~
    <P>            pPlayerData = pPlayerData-&gt;pNext;, @- n! g6 t3 |
            }</P>( Z( y1 I  {/ J( o( `# w, E% s8 j
    <P>        // Display the player with the oldest CI field, and update its CI field.
    * S/ z) w, P/ v5 _# a0 l        if( pOldestPlayerData )0 E) u" d4 x6 u8 g
            {. U! o: q2 U( |! D/ ~
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );+ K& i; A6 D4 P6 m6 N/ m
                DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );5 j# }- o$ P$ Y4 G8 N3 k
                pOldestPlayerData-&gt;fLastCITime = fCurTime;
    $ y5 ]2 N& e/ `3 g- Q$ `# u3 J: J        }
    1 u4 l" L6 d! V- E/ D% a' C' f        else; f; U6 Y) }0 [4 a
            {4 z- S1 b2 o' r* a. X- Y
                ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    / G9 |- X+ @, l6 d7 \4 C/ q, o        }</P># l4 q. K3 [! I# a
    <P>        m_PlayerDataListLock.Leave();+ B+ X. T% t& j0 B+ R
        }
    ( R. Z5 ~, d9 V  ~6 K}</P>
    ) u! c( I4 P, I$ l
    2 s6 r& k/ W) p0 J0 q' p<P>. O/ B, M. v8 T0 s7 w2 i
    //-----------------------------------------------------------------------------) p) |0 C- m9 t+ p( C$ L7 s
    // Name: 2 u9 B, N/ {" V' B% r
    // Desc:
    + v& y. M& m$ p7 h3 k//-----------------------------------------------------------------------------2 A' b7 }/ g; ^7 }- x3 x/ G- F
    void CMazeServer:rintStats()) b& M4 \3 X+ b" S# ~. Y' _# ~
    {
    " c& w4 ^0 b( C    ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"), / G2 l. M; O, `/ m6 l: f
                                        m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );
    ; A6 M9 ?& t3 d    ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),# w6 n; @' n  k
                                        m_fAvgThreadTime, m_fMaxThreadTime );5 o2 H  F  v/ \, b6 W
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );8 d4 n$ W$ K# x  @# p% C' A
        ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );, R: ?- o7 ~4 [$ Y- {# z
    }</P>
    6 g. ~3 k! c* B1 D: T- k3 {! s6 H; \! f% Z* C
    <P>
    6 C. P+ z; N" d" u6 `//-----------------------------------------------------------------------------4 t( D8 Y+ Y( b
    // Name:
    ; U' u2 p; K4 u- H5 J% A7 z4 t, v// Desc: % q( D; k: y# F' C
    //-----------------------------------------------------------------------------
    . T' a5 P- w5 O' w0 l0 g5 _: ^void CMazeServer:isplayConnectionInfo( DWORD dwID )
    8 @$ d0 O, r9 @! W1 `{. r; E: z' F) A* u0 I" u2 P
        TCHAR strInfo[5000];* o% S/ o" N, N( n) {0 U1 h6 Z
        TCHAR* strEndOfLine;4 A" T# [& N) ]/ K
        TCHAR* strStartOfLine;</P>
    ; A# U) w+ T4 u9 i9 T0 \6 B<P>    // Query the IOutboudNet for info about the connection to this user
    1 ?/ G  a/ B1 @4 a    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>6 A! m9 p% `. T5 B
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );
    / D9 ?+ _2 d/ p$ p; I# S/ I    ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>( D3 j8 G8 X: B" Q% U
    <P>    // Display each line seperately6 u/ j$ _4 s& X4 V! }2 `
        strStartOfLine = strInfo;* o5 S( L6 }( D8 f" O
        while( TRUE )
    6 j. N7 t( ~( ^/ y; L. C- _( t    {
    1 \/ p1 l' z$ k( S        strEndOfLine = _tcschr( strStartOfLine, '\n' );
    & |3 b) M" r, o        if( strEndOfLine == NULL )
    0 l3 \" X5 r) F% }2 v! z            break;</P>
    + n6 M1 g# G) w5 D7 I6 @' e$ R<P>        *strEndOfLine = 0;$ P+ c+ x) k# d  ]. z$ {5 @8 W, }: V* k7 @
            ConsolePrintf( SLINE_LOG, strStartOfLine );. J/ K5 p" ]- }! v
            strStartOfLine = strEndOfLine + 1;
    ! s$ Q7 e" i2 [- a3 ~    }# L1 u/ n* t3 P7 h# K6 d
    }</P>+ z" [9 Y2 R% _& f
    3 B2 p, X' g$ H4 A/ c% C' M$ A) Y9 c
    <P>
    ( Y" J! F8 }. p+ R//-----------------------------------------------------------------------------+ F  L, }, w. c) U$ r! A
    // Name: 2 v2 s5 ~" S- P3 v8 f
    // Desc: ! {2 S6 _/ d7 r9 o1 _: ?7 M
    //-----------------------------------------------------------------------------
    % }3 B6 X. e% }5 {) ^6 X% ?( L( LHRESULT CMazeServer::SendPacket( DWORD to, void* pData,
    ) `0 G3 K' O/ Z$ H) L% Y                                 DWORD size, BOOL reliable, DWORD dwTimeout )
    5 G& c" N& R5 ^+ y  V5 q* F% u{$ R6 x- `5 j8 G9 H6 {6 u, m/ Z: f# c
        // Chance of forcing any packet to be delivered reliably$ P" m$ Y, i. o: ~# P( J+ I0 F
        if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )
    : {8 s4 V& W( V" E" m        reliable = TRUE;</P>6 X' r$ c5 V( \  {) I
    <P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );9 f9 l2 Y, l! z6 t: e" O5 h9 S: ]
    }</P>/ Y' w/ y( \. F1 p8 q

    ' O" u  |. v; g. w7 Q# X<P>
    0 X7 r9 {: N! B1 w/ j, ^0 C( b5 p//-----------------------------------------------------------------------------2 ]& @' Q# x3 @( ]! ^
    // Name:
    % t# a9 {0 |5 |( |// Desc:
    2 ~0 Q  U) s8 @! r//-----------------------------------------------------------------------------1 B. E4 p" J- W' z6 J9 v$ W
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )
    ; R& E1 p5 o. F7 O! |6 T{
    & P1 d2 P; b0 I    // If we're up and running, then send this new information to all clients
    * e2 l& u& d9 }5 f  S- p9 x' l    if( m_pNet )
    ! E" ?' S( j) g  G2 }4 E+ m    {' d! \2 K6 }6 e$ G% ^. |6 Y4 E# B
            //Use the AllPlayers ID
    9 K' W$ H. `* t7 v        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );# x6 ?1 N: D' V$ q) }5 ^
        }' S  M$ Z8 O2 z* A/ x8 ]6 S* O
    }</P>
    9 L; k1 t+ D0 P$ [1 J* Y; s. X; J3 C% R8 {/ ]. t4 x
    <P>
      e0 V2 W" `7 D( r0 ~6 ^  r//-----------------------------------------------------------------------------' T4 D. V+ P* ^/ j  G* _9 m
    // Name:
      t/ J8 m1 {( h2 k// Desc:
    . R' c9 y' T2 q4 R//-----------------------------------------------------------------------------) z; B8 u8 e! ^# p: O
    void CMazeServer::SetClientReliableRate( DWORD percent )
    ; q. a8 D! F' q9 U3 p5 R( C, T+ S; Q) a{
    & p& D# ^( d8 l1 O# }( B  q3 B    // Update client config, and build packet containing that data
    1 }4 Q& D( S8 Q    m_ClientNetConfigLock.Enter();
    / V2 G$ y2 R8 t& K5 P    m_ClientNetConfig.ubReliableRate = BYTE(percent);: B, k) L$ ~1 h5 E
        ServerConfigPacket packet( m_ClientNetConfig );1 l3 `. U8 T. u; v5 B" _
        m_ClientNetConfigLock.Leave();</P>6 z- I( W% Z0 Y
    <P>    SendConfigPacketToAll( &amp;packet );
    . f9 X& a. b4 o# A- [* r# B}</P>
    1 n! A( [3 J: m% r3 [& f  D, k( u
    / [7 w: Z2 m( i5 h<P>" z8 O6 {; Z, f6 a, }) r0 D, Y
    //-----------------------------------------------------------------------------, s+ j& V* ~+ M
    // Name: + z  s# M  x# r5 v" u* Y4 L
    // Desc:
    5 g5 H6 v* x$ w0 W//-----------------------------------------------------------------------------
    2 O1 A1 W- C( D/ f0 f9 l7 Wvoid CMazeServer::SetClientUpdateRate( DWORD rate )8 n- ]6 Y1 D4 x5 T: _
    {
    ' j- [: C3 ]4 j. w    // Update client config, and build packet containing that data
    # v& t; A7 U9 _( r; J$ J5 j    m_ClientNetConfigLock.Enter();. h! \! u5 |) O4 k) x$ R
        m_ClientNetConfig.wUpdateRate = WORD(rate);  C8 n3 |1 a: w% @( C
        ServerConfigPacket  packet( m_ClientNetConfig );
    % j4 ~, L$ f. S' |! x: l    m_ClientNetConfigLock.Leave();</P>
    * w4 Y$ w( o2 d8 u9 p& y<P>    SendConfigPacketToAll( &amp;packet );
    + e$ I0 \& j' I: N  g7 J}</P>
    , ^# i0 R$ A+ |5 R) o
    1 O" L# F0 v3 l0 }( i6 ^<P>
    $ g6 E) W% h& N! s2 F//-----------------------------------------------------------------------------
      t( N$ H( }" L0 l// Name: . y, o. l& F; A, L
    // Desc:
    . J( L, q' E% A* E: R//-----------------------------------------------------------------------------
    6 b' c# M9 ^8 k, svoid CMazeServer::SetClientTimeout( DWORD timeout )
    5 ~" m2 j1 \. x& }1 V1 b{/ B  u# F9 Q8 q9 {4 A: V2 k  r
        // Update client config, and build packet containing that data; A  P  [, A# u" Z. F  x
        m_ClientNetConfigLock.Enter();6 D8 c) U: y$ Z7 g. I0 B- g0 q
        m_ClientNetConfig.wTimeout = WORD(timeout);
    9 k1 O, i$ g0 ?3 _! E    ServerConfigPacket  packet( m_ClientNetConfig );( n! E3 _# R9 k. `/ G
        m_ClientNetConfigLock.Leave();</P>
      h9 z) E; Z" ]5 u<P>    SendConfigPacketToAll( &amp;packet );
    " f6 g% M9 E6 e* ~9 s+ {. R; P" C}</P>4 [$ o! u1 v- D7 M

    0 C9 m9 S! x6 Z, ^2 A5 p) D<P>
    * Y  I9 P( \/ s, z: V* ?; @//-----------------------------------------------------------------------------
    + i# D" a0 b& c1 s9 Q// Name: 5 U7 _# L( |# t. W+ n
    // Desc:
    ! r3 z9 G! ?& a! D8 }! Z* C//-----------------------------------------------------------------------------' @" q" C, T$ z0 z$ s5 Y
    void CMazeServer::SetClientPackSize( DWORD size )
    / N# I) B# f; z( G: J- S' e" X9 O{9 ^$ D9 M2 G5 h, N1 G
        // Update client config, and build packet containing that data1 o5 w, Z. l$ }1 p+ Q
        m_ClientNetConfigLock.Enter();$ C( f# q, g- K# b+ l* P' \' x# ^
       
    2 H: ~* M/ Q6 k7 [$ z$ @$ d    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.# X' Z. ?. C8 C( M
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   . A+ N  B0 ^' d
            m_ClientNetConfig.ubClientPackIndex = 0;</P>
    . z' Y) G/ c7 B6 w3 ^9 S6 k& G<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);# h  Z4 `. }& Y6 _
        ServerConfigPacket packet( m_ClientNetConfig );
    7 i$ |9 u7 e2 A/ P2 f    m_ClientNetConfigLock.Leave();</P>
      q% U& d" Y1 B$ ~& S<P>    SendConfigPacketToAll( &amp;packet );2 e+ V, v/ x, O( N1 N! L+ A) n
    }</P>/ u* s4 Z( m; ~$ J4 G4 j

    9 d7 X2 b9 Q5 w<P>7 G) O5 P0 V5 O. K! g/ r
    //-----------------------------------------------------------------------------
    % S! W! Z+ w, Y4 z// Name: ' s& m4 O3 M; [; _8 X' T/ J7 v
    // Desc: / y0 ~' ]* R% C8 E5 H. v% A$ L1 s
    //-----------------------------------------------------------------------------: ?0 w0 p& z2 U; U9 X/ n# \
    void CMazeServer::SetServerPackSize( DWORD size )
    - [: |+ C/ l/ \" P3 C{
    7 S) n/ ^6 K. R4 H8 b& W( U    // Update client config, and build packet containing that data" {: c" \; g) c( p6 I
        m_ClientNetConfigLock.Enter();
    % e6 O& p( A" U& [5 N3 g   
    ! q0 U6 e; R9 _3 Q    m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.5 d7 k  V9 T- p& w  l7 G
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   
    1 b8 t$ W2 G) k2 D        m_ClientNetConfig.ubServerPackIndex = 0;</P>( j& i4 v, G; X6 f* ^& F* s7 f
    <P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);8 _7 L4 b/ z0 P- Y, K( J6 K$ p7 q( g
        ServerConfigPacket packet( m_ClientNetConfig );3 T8 v- a/ E' p3 x- L' r: J
        m_ClientNetConfigLock.Leave();</P>+ q& M. a. {9 [% J- d
    <P>    SendConfigPacketToAll( &amp;packet );
    9 ~& Y2 J5 M$ t; f. C+ z9 f- g7 M}</P>
    2 V+ o: d( _2 I& o<P>
    1 U" e5 \. M5 a( _//-----------------------------------------------------------------------------
    # E) z7 k6 @6 k/ y0 j// Name: 0 @; V; b: |. [1 J) Z
    // Desc:
    ; S5 }+ q. |: ?( |! t9 t//-----------------------------------------------------------------------------
    4 [5 ?/ c% o, W/ d5 yvoid CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
    " j1 J' @6 z6 Y7 Q1 }; F* ~{
    $ Q/ m6 B' P3 y  t8 V3 E    // Update client config, and build packet containing that data
    # @3 \9 z8 l, T    m_ClientNetConfigLock.Enter();
    ' v7 u2 E( a8 @1 ]: f, D6 Y9 s   
    * q$ t: Q7 ?0 c( _    m_ClientNetConfig.dwThreadWait = dwThreadWait;8 S  e/ x/ c( ?) H% i0 T
        ServerConfigPacket packet( m_ClientNetConfig );
    & g  Y$ D; h' ^6 O: y- x7 q) {& a    m_ClientNetConfigLock.Leave();</P>  X- H& q* J" H
    <P>    SendConfigPacketToAll( &amp;packet );
    ) ]7 c% L' z4 Y}</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-11 17:36 , Processed in 0.473012 second(s), 51 queries .

    回顶部