QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4197|回复: 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>
    / g$ O) q2 {- C. T0 i" p. _<>// File: mazeserver.cpp
    1 J2 I+ a6 O/ @5 ~. n* F) k//; n8 K1 e8 p( D8 }5 n1 d$ f
    // Desc: see main.cpp
    4 L/ q* b1 Q; J. Q5 j9 R" f//
    $ n8 f4 I% m: \/ f" E! \9 R+ _: |/ ^// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
      Z9 o( J1 p! S//-----------------------------------------------------------------------------
    . R5 z, I; u! A# X: j+ W+ J$ G#define STRICT
    8 B. N5 x- V; y7 H#define D3D_OVERLOADS
    1 a2 C4 i  U& O, ]; l9 `#include &lt;windows.h&gt;5 d6 l, c0 _* ^, y- K, e) f- O
    #include &lt;d3dx.h&gt;: I$ e( g) @" o' r7 o/ b8 m
    #include &lt;stdio.h&gt;$ z! ^8 V! ~/ k+ W: Q
    #include &lt;math.h&gt;
    0 {2 U9 ~( Y( v& L#include &lt;mmsystem.h&gt;# D7 }9 V$ J6 L: F
    #include &lt;dplay8.h&gt;2 O: I7 F* v$ ^" W- y2 c! r! P" q5 d
    #include &lt;dpaddr.h&gt;
    * H1 C. \$ R2 ?- k7 z/ }& W#include &lt;dxerr8.h&gt;5 Z; L9 A! @: L0 ]7 k- y4 j
    #include "DXUtil.h"
    & U8 ?7 D8 w2 B: W# R" D#include "MazeServer.h"
      m' L: B7 e, b2 C3 M2 w( k#include "ackets.h"
    " C9 C9 G* Z' u6 e( p& f#include "Maze.h"
    % x2 m) Y  U- t& Z9 y8 o  O7 }3 r# w: H#include &lt;malloc.h&gt;
      b; ]3 W2 I) L+ u#include &lt;tchar.h&gt;</P>
    + ~5 V" D! D, M  h/ V9 O5 @- h1 \' G& F- t
    <>//-----------------------------------------------------------------------------
    8 g9 X. g2 @  {+ T- [- P0 `! m3 I// Name: 9 j1 }) S; C; W7 d
    // Desc:
    ) U+ i0 O/ ^* @0 ~# r7 r//-----------------------------------------------------------------------------! Q  ^1 b$ }8 ?
    CMazeServer::CMazeServer()
    ! A" ~2 N* m/ \1 ]' f; n. Q5 t{0 r+ g+ ]6 P% f) e
        m_dwPlayerCount         = 0;
    * p% O0 r7 q. I; I1 V3 q8 O    0 {, D9 A% e# x+ F" Y
        m_wActiveThreadCount   = 0;
    , O, u. |& W" ]9 L# h    m_wMaxThreadCount      = 0;* U# J, c6 d: j. X# O2 Z
        m_fAvgThreadCount      = 0;, ?8 E% G6 ^) Q& I2 o, h
        m_fAvgThreadTime       = 0;, C' e9 w5 R6 L( Z& h
        m_fMaxThreadTime       = 0;</P>" F: @8 F0 `4 c4 K
    <>    m_dwServerReliableRate  = 15;
    : _! b  e. s% g    m_dwServerTimeout       = 150;" |: m4 M6 h2 D; m
        m_dwLogLevel            = 2;
    + m6 o& R* H8 Z6 [- u  J7 I0 o: f    m_pMaze                 = NULL;</P>
    $ X2 d% K, D+ J! a7 |* l<>    m_ClientNetConfig.ubReliableRate = 15;
    / u( r+ t. c9 f1 N    m_ClientNetConfig.wUpdateRate    = 150;
    $ S( a8 B* ?- y8 K0 g  O$ R    m_ClientNetConfig.wTimeout       = 150;</P>
    6 r! E% F  {9 ]( k3 ~<>    m_ClientNetConfig.dwThreadWait = 0;</P>
    8 |- A3 @1 ]! N: G9 p5 [) T& B<>    m_ClientNetConfig.ubClientPackIndex = 0;
    7 |" @* Z8 x: V1 e5 t! {' N    m_ClientNetConfig.ubServerPackIndex = 0;
    / v" I' s4 Y; g# _! n) R7 S9 H    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)
    , ^0 E& H) G+ Q; ]$ u' G% {8 }    {
    0 r0 e& S9 _7 R# ^7 }5 W! R. L! i; H        m_ClientNetConfig.wClientPackSizeArray[x] = 0;) [: a' Z# k; V; q' _9 m
            m_ClientNetConfig.wServerPackSizeArray[x] = 0;
    5 y7 e' m3 i$ Z# B3 q    }
    ! G: I# J1 H0 x: Z% P}</P>, P2 A5 M: V  i5 v

    " h- l+ m- @, H+ @<>
      @  ]1 `' c7 W2 C9 W7 B+ T//-----------------------------------------------------------------------------. a5 R1 V, F- n# Z2 q
    // Name:
    - B6 G$ M/ S: ~$ W// Desc: 9 M+ {3 I# B5 Z) l  a
    //-----------------------------------------------------------------------------
    , _5 N- u, D; x, S7 ]" B' nHRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )
    4 u: S1 b& C5 b3 I2 H- }{1 ]( z3 T+ F: b- g0 N6 U3 v
        m_bLocalLoopback = bLocalLoopback;
    . u) n( ?  Y, |7 M" a) D, e/ ^# l    m_pMaze = pMaze;  c( U( m3 y: K0 {. c
        if( m_pMaze == NULL )
    % B; L" i$ F4 n& D! B2 w6 A' i        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
    4 i) y2 m, E% ^8 q<>    // Grab height and width of maze
    * j/ l; t6 z: i0 {$ V1 x( [    m_dwWidth = m_pMaze-&gt;GetWidth();+ Z' j) H! \) t1 w7 ]! I
        m_dwHeight = m_pMaze-&gt;GetHeight();</P>
    ( f7 G* \2 w$ ?: b6 {<>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;9 f$ B: n  U( m2 ~: J8 f
        m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
    : j$ r( f) [1 e7 H0 ]  t<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.
    ) N4 T7 [! _7 f    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )% ?: y$ z. e$ U. G! z
            return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );& J+ P! V3 W- d* r/ M
        if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )
    . x- A! r; l4 z; X        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>* F, f& L$ K( T- ~6 F2 R( r! h+ n
    <>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;6 A3 \% G- f, L/ {) |
        m_dwMazeXShift = 0;
    0 a3 f: `' F3 a4 y4 c/ \, `, _    while ( (scale &gt;&gt;= 1) )
    7 S9 m$ h  Q+ W3 U! j        m_dwMazeXShift++;</P>+ m3 Z! w$ i+ G& B
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;
    # I9 X9 \. w9 S    m_dwMazeYShift = 0;. `0 c0 k4 |) d4 G0 U* n7 j
        while ( (scale &gt;&gt;= 1) )
    2 k& X( @4 o+ `& ]2 d8 e        m_dwMazeYShift++;</P>
    ' d  B6 S' Q! g# }+ c# @<>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    $ ~9 r) R# u4 q+ I7 g4 r2 J0 D        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )
    $ n8 Q9 f  y" Q. w        return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>
      Z# i/ B/ j8 d+ R<>    // Initialise the player list  j+ N, N0 a. y
        ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );
    0 h; l* h0 L5 `  p6 f! J: U8 w4 M7 Y    m_pFirstActivePlayerData = NULL;+ ?. y3 K* K1 F% `: T1 u
        m_pFirstFreePlayerData = m_PlayerDatas;
    / e! |% S: n9 j3 a8 O' v! c" z; ^    for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )9 \) E7 o! ?8 h' G' }) z( `: q
        {8 |$ \2 S. |' ^3 M
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];4 R  K) z: q0 W
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
    $ ~4 I) I' ]5 f) x9 v0 `6 w/ E2 v    }</P>
    . g. ~: v+ x; F, Y1 q8 |<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];( `- B" P( p; H% C( v5 E  G
        m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];
    ) Y+ V" L* y. @) r1 \4 K    m_dwActivePlayerDataCount = 0;2 k0 {- {# d, X5 q' b) R6 I
        m_dwPlayerDataUniqueValue = 0;</P>
    $ ^& \% o) L/ E* z5 l5 i7 ]<>    // Initialise the cells
    % x5 u" Q" ?$ B% ?; Q    ZeroMemory( m_Cells, sizeof(m_Cells) );
    9 Y: C& l$ ?7 k# Z    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>
    $ v( }2 R, ^# ^<>    return S_OK;% h! P" J. w2 n# P# J
    }</P>
    0 F% d: n/ t8 U" l4 t. W9 `. }7 T
    * Z, c2 L+ u% t' [4 \0 ~<>% q, i8 i5 K3 L: E
    //-----------------------------------------------------------------------------4 l9 h5 y( V5 L3 |
    // Name:
    " h2 `% V$ k! O% P+ j3 `// Desc: : ]0 h7 `+ v; J; Z' M7 F4 Z& p
    //-----------------------------------------------------------------------------$ z1 F5 }9 f% F% y; v# a5 C
    void CMazeServer::Shutdown()4 S. G$ g& T! q7 K) I. ]
    {# E" ~+ e" m$ I" R3 \) ~2 G  p1 p, A
    }</P>1 @2 G8 M. J* c/ W9 e7 K1 t

    4 }) B2 o9 _! q* H, G; o' `<>/ P3 [3 p! t2 n+ u, d& [, k2 _8 w! Q
    //-----------------------------------------------------------------------------6 h  l  ]. g+ y2 ~; L% ]
    // Name:
    : C% l0 }: C3 E. ^$ V8 a// Desc: 6 q0 R- `- r: d: N' \
    //-----------------------------------------------------------------------------
    + y) b/ _) n& h! c9 }void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )9 N7 \7 j5 c- |
    {
    $ J. o' }* R. V, @4 E    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,- t$ s" {: v" V
                              x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    ; X' _" x4 H+ d( D/ W: f7 d}</P>( X/ ^- @# j* }; h

    $ d+ n( H. N6 \7 E5 ?& d: Y6 G<>
    & |4 @) E4 C2 g) P& u" I7 a4 m! B( P//-----------------------------------------------------------------------------
    & ?3 G- v6 w( \' L1 W) e6 u// Name: & B" K* L$ h5 }: J) s, B6 A- T0 _3 k
    // Desc: 4 D) |  B6 z7 J* D$ K: I/ H
    //-----------------------------------------------------------------------------
    2 k- f9 W2 b+ f% z3 n0 tvoid CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    & }" X$ y: E& Z0 `/ D& Y# T% y8 E{
    ! Z+ E, t3 ]* k- k7 z    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    . b1 h9 G  w5 L                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );, T+ a4 T& r9 J/ J8 s( {6 Y
    }</P>) G: O" X, k4 E' z( U
    * W! ?. \1 z; Q9 V* E
    <>
    & s% f( v7 }: X- N//-----------------------------------------------------------------------------1 X/ \% ^1 P% n9 b8 q
    // Name: " B6 z6 y: I" I: Q$ m
    // Desc: & D( U1 N! y% u) @; Z6 ]4 M
    //-----------------------------------------------------------------------------
    . x: `! S8 f' E( N6 |9 o  }void CMazeServer:ockCell( DWORD x, DWORD y )
    7 X0 s& ?4 E- \- @{
    & J& Z& t6 t9 [: q! F' y    if( x == 0xffff ). H& u# a; B' h. s) E3 `
            m_OffMapLock.Enter();
    ) |) j2 Z7 K5 ^" Z. w& W5 i4 ]    else* k$ u! z* X, S' Z$ B( O
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    - n0 x. n7 ^3 Q( a}</P>, f; U7 I$ w$ [- |, {$ r
      E) V& F* [5 R& ?
    <>
    9 S2 N, @; B* z. r& w; a2 W//-----------------------------------------------------------------------------
      y; o1 {$ M/ l% g) s; U// Name:
    $ S3 ~  V% U6 d) Z7 Z) K" Y// Desc:
    8 J2 ?$ o- A' }+ g1 P7 v//-----------------------------------------------------------------------------
    8 {+ ^! r+ Q8 B/ lvoid CMazeServer::UnlockCell( DWORD x, DWORD y )
    ! ~: }0 T' T9 N/ {% K9 S# j{
    + i1 m. D: y, G; L6 k4 P( b! e4 c* s5 j    if( x == 0xffff )
    ! t+ v' i' `( {2 @4 ?' a8 x1 E        m_OffMapLock.Leave();* n' g( a6 ?5 f! r  J3 u1 u( u
        else
    . f$ G3 F& v3 c, T) V- g        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);+ }8 L1 w8 O  ]9 m  E) s) g
    }</P>
      p+ |  X# D) C- q# p$ o& {7 `1 U4 }8 p/ B! R& T
    <>
    1 A1 V0 L8 M$ r, I8 Q. R0 j//------------------------------------------------------------------------------ m& @0 i0 ?2 H
    // Name: * Y/ n% K8 |. M2 H
    // Desc: 0 w6 w9 T  w9 X; f, w! B$ q
    //-----------------------------------------------------------------------------
      p' {; t$ g0 C6 m% pvoid CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    2 Q2 Y6 O! X8 ?2 B* R8 k8 \{1 z$ E( R3 B1 F, p! I% R& ]( x
        if( x1 == x2 &amp;&amp; y1 == y2 )- ^4 w; @& ~) [2 H' G) H
        {) D6 |0 O: ?  W2 P' B) A
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    $ l% |$ Z+ f6 Q/ K3 U5 k2 @            LockCell( x1, y1 );% n/ `) @' W" P/ M* _
            else$ h+ J! e% P" t* x2 N5 t# r, U0 k- d
                m_OffMapLock.Enter();</P>( ?# q( ?- y2 A$ N2 Z# u; H
    <>        return;
    * H8 T* G% e' y' X    }</P>5 _* M% m7 a% @
    <>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;  n6 n1 c1 E3 q3 [3 ?% [3 B% E
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    9 p+ l; F' G3 r; C/ [    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;  F7 L3 s+ J( M# i0 ]" @+ a: y
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    5 L- W9 t: ^' }3 h6 }2 v: T/ Z<>    if( x1 == 0xffff )
      x* D2 j) x( B    {6 w# D+ Q  Q9 @0 Z$ h' S; E
            m_OffMapLock.Enter();
    + @4 w8 x) f: |2 k        m_LockGrid.LockCell(x2shift,y2shift);
    2 R: d' k* E; t    }
    " M! R. J# n" @* v    else if( x2 == 0xffff )) C/ Q0 F" C% T
        {1 b. G7 g4 V$ H
            m_OffMapLock.Enter();
    / H4 A& l2 w# q  q$ v        m_LockGrid.LockCell(x1shift,y1shift);
    ' c1 o) q  D+ t/ c    }7 o7 F' o. W& `- c" \6 b
        else ) c2 c* Q. S7 d. {, {. g
        {
    4 @: N9 `* U( `/ B" l        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);  R! m# G: o( [" F- D
        }
    3 U; G& A; @3 ^$ b+ l1 x* {6 z2 E}</P>
    ( T  \" Q9 M" {3 P. V4 C4 b7 o, [/ q
    <>
    8 u$ C. _' s  f8 r6 J; p//-----------------------------------------------------------------------------# i4 G4 F/ B9 S( s
    // Name: 7 e  U7 X; E' P7 f/ @
    // Desc: # |! s' \+ I. z9 y/ z
    //-----------------------------------------------------------------------------
    3 [2 w; ~1 {* m/ v% l# K' ?; Ivoid CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    $ D: x( \# h1 Q; c  K) _{: j7 v) j' F4 l  i% |8 k
        if( x1 == x2 &amp;&amp; y1 == y2 )
    1 s# b0 p  H8 I$ \; ~8 u    {
    - y) s4 V3 M2 A" F        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    7 [7 v# j) {- o            UnlockCell( x1, y1 );
    9 C* T7 z. f! a9 |        else
    ! |* D6 u( L9 X+ y# S& F            m_OffMapLock.Leave();</P>+ T) n* f. q$ _3 }" p
    <>        return;: S, y! M0 ]+ Y- {# i
        }</P>
    ) Z, O* O' k3 G% \: \<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;6 `/ Q0 y  c0 r
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    ! o, p$ W3 c( s4 |$ M/ `% _) [2 t    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    $ Z$ L' u: X2 ?$ N* }* g    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>- F% v! i1 \1 l* K- w
    <P>    if( x1 == 0xffff )+ l9 I8 B: H& y
        {
      R, e. Y" u! u/ ~0 E. b$ a        m_LockGrid.UnlockCell(x2shift,y2shift);
    ! p. L8 X- b, o1 F        m_OffMapLock.Leave();
    2 M) ]: r; `& k% Q# q+ _    }6 I7 e. ?  g9 w% Z% O' L, M
        else if( x2 == 0xffff )
    9 t& k& |9 z4 y6 s1 V7 z    {2 E2 ~1 F! J. j  U
            m_LockGrid.UnlockCell(x1shift,y1shift);
    , F2 M1 B8 D  E$ C! j) U5 K        m_OffMapLock.Leave();
    - y  U  O8 j) {8 i3 I* f2 ]    }
    ' z. E! f8 ^( Y" Q: z' h" W    else
    ' ?8 ?& E) u3 z+ K, o& ]    {
    ; A: Z8 |; _- ]( V4 k! J+ k        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
    - n  K2 A* ]& y4 j$ F1 v5 T    }
    . I' W6 m+ o; c8 x}</P>3 X5 z: H$ _7 |0 E- |' X* P
    $ I  P3 v7 e$ J
    <P>
    ! x3 y; I/ m( r; }2 d; ^' ?  \  V//-----------------------------------------------------------------------------
    ( X1 k# @0 I6 o1 N6 [// Name:
    - g; R* v- A" c* |' {  S// Desc:
    / }6 g( o  G5 S2 L0 j4 C% j2 z//-----------------------------------------------------------------------------+ |% D, W6 K# p7 u" C
    void CMazeServer::OnAddConnection( DWORD id )2 v7 A! j8 ~7 C( u
    {3 |  T) i7 w2 T( C- j8 F3 K
        m_AddRemoveLock.Enter();</P>. B$ O( N( t4 A9 n. a  Q: z
    <P>    // Increment our count of players
    ; ?  c5 S2 U; E4 i2 Y% x! Q/ k) I    m_dwPlayerCount++;
    ! F( P) Y! e  d8 w2 f" C$ C# I) l    if( m_dwLogLevel &gt; 0 )
    1 _( o& q, I6 U! M; B( d3 M) j0 p7 z. X    {: I2 t7 O+ g' e
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );3 q+ K5 Z/ B3 h/ z: I4 u
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    9 m5 v. J% Y) ?* p    }</P>4 l5 P% s/ Q0 H4 y: j
    <P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    / y5 k1 U  A7 g% j        m_dwPeakPlayerCount = m_dwPlayerCount;</P>
    $ {/ Z4 b6 B. \. @( \# U* M<P>    // Create a player for this client
    8 e# ^9 G  Y$ w5 }  y; s    PlayerData* pPlayerData = CreatePlayerData();
    , F' c. d7 B& R: \+ [  f* l    if( pPlayerData == NULL )# z0 w9 M3 Q- F8 _) U  U
        {
    * J% {5 P: ]9 }$ u( {' Y9 s        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );( ~$ B6 t; i* _9 |6 f' C  H
            DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );5 y% w/ _: O1 _6 z/ ^
            m_AddRemoveLock.Leave();
    2 p( z5 W, d* e, q3 z        return;
    $ |7 e" u* A- a1 l; l/ t5 _    }</P>! d- }$ r  {/ E4 a5 \
    <P>    // Store that pointer as local player data
    ) r5 h! r0 }1 P3 B3 O$ \    SetPlayerDataForID( id, pPlayerData );</P>
    : f: ~/ z. B3 r7 j% s$ z& C<P>    // Grab net config into to send to client
    % Z7 l! o5 o8 Z; I! H0 x7 j: N    m_ClientNetConfigLock.Enter();7 \! B+ F5 R+ y; M
        ServerConfigPacket packet( m_ClientNetConfig );( @; W) J1 M& p$ k
        m_ClientNetConfigLock.Leave();</P>- W' ]- C$ q8 [% E0 L
    <P>    // Send it
    / c/ V: o: q& p/ A( b$ Q8 r2 t    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>3 v' |: x3 Z0 i, @5 c' K9 t3 D* g/ u
    <P>    m_AddRemoveLock.Leave();
    8 ~" N6 h4 I' ^" v5 T}</P>
    : }+ R0 h, o4 i. Z, M
    6 J/ o8 _& I2 L5 [<P>3 Q; h: Z: a! ~7 W2 e: @5 G2 @
    //-----------------------------------------------------------------------------' _1 x2 H5 l: v
    // Name:
    7 ^5 K" `0 K, _" `, r% @" a# R// Desc: # C3 x7 ^7 f9 |. p% i6 }- Q) Z
    //-----------------------------------------------------------------------------
    : f2 n4 c+ i6 _" C+ Ovoid CMazeServer::OnRemoveConnection( DWORD id )+ d3 O5 ?5 f! @# |' f& ]2 T
    {8 X2 i2 E' T" V/ g
        m_AddRemoveLock.Enter();</P>7 t9 f! Q4 G# f1 R; n/ t+ f, B9 L
    <P>    // Decrement count of players: Q+ ^+ t% |9 Z# ^- j3 D8 t* N" p
        m_dwPlayerCount--;</P>
    9 U/ {) ^+ B+ D- k: b' {+ c<P>    if( m_dwLogLevel &gt; 0 )8 t6 M0 U8 F0 z1 N) H( q) f
        {
    8 P& ~& W  P7 @) S        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );$ i6 h6 D4 q0 z3 I
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );+ p& c* ~  U/ v& c9 c: i
        }</P>
      Z1 Y: h/ \8 {: t$ u1 c7 H# e, b7 M<P>    // Find playerdata for this client& k) |# N* G$ k) B; u) @7 l- v
        PlayerData* pPlayerData = GetPlayerDataForID( id );
    8 j2 M+ @4 U4 m: E    if( pPlayerData != NULL )0 ]5 p  S3 u+ V, ^$ n, ^. G
        {
      u$ _4 j& Y+ @  R% A/ h  U  _        // Destroy it& c2 Q6 |" O, k4 [$ l
            RemovePlayerDataID( pPlayerData );1 I. a( @8 w1 e7 O
            DestroyPlayerData( pPlayerData );  q- Z* I0 w: o) x/ K! o7 m; b' h
        }</P>
    0 h2 ], {& V% U8 ^/ O, t<P>    m_AddRemoveLock.Leave();- f# g! d' x; ?6 G% L1 o
    }</P>0 g6 G) Y" F$ w3 T4 ?

    . m+ `4 A$ I4 `( c+ {3 L1 ?<P># ?7 d2 O5 }' Q) a  h4 C/ `
    //-----------------------------------------------------------------------------' O" c" q% i2 M8 F' p  _
    // Name:
      n4 p8 \* A2 G// Desc:
    ; R# M0 p7 J- P//-----------------------------------------------------------------------------
    : T5 i3 ^3 m  _3 m. `" P1 _HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )
    ' C- R/ t' e: e* s$ K{
    * `# A$ u* M2 {" q    BOOL fFoundSize = FALSE;</P>3 A9 p$ o/ A# P9 B
    <P>    // Increment the number of thread we have in this process.
    8 t/ _3 t2 g4 J% t3 J* N    m_csThreadCountLock.Enter();</P>
    $ ^' W" K, |# w<P>    //Get the start time of when we entered the message handler.$ k3 Z5 ^! @4 \, F% l
        FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>4 W8 w) W. \, [/ a, O( s( v
    <P>    m_wActiveThreadCount++;
    , `; \+ S; B& [- q    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)* A) z9 Q8 q  C3 G! z( X
            m_wMaxThreadCount = m_wActiveThreadCount;' q% [3 e) ?/ |
       
    $ g! L' f/ K* |! A. S2 T* h- ~    // Calculate and average.
    / Z! b! D; r8 N5 w7 Q    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
    5 T) w, E8 H8 i# U+ e    m_fAvgThreadCount += fdiff/32;" N- w. N5 [& I, k4 q+ k
       
    ; f7 `2 d# o- s1 v    m_csThreadCountLock.Leave();</P>
    3 b. ], Y8 R7 B6 S, c. s# n$ t<P>: J. s+ g: q( r
        ClientPacket* pClientPack = (ClientPacket*)pData;
    8 {: g/ u: D" j4 D5 S0 |0 n    switch( pClientPack-&gt;wType )
    9 z# E0 q9 z! w& i9 }( ]5 ^  a    {6 _* f- V# D  Y5 K. I) ]
            case PACKETTYPE_CLIENT_POS:) ], N0 T; o" L7 g2 a. h) ~. k
                
    ! F/ d$ v, d, A. D. V            // Check to see if the packet has a valid size. Including 6 V! u+ i9 H! v8 e; @# x' `) s
                // the custom pack size.
    & P( C' h& T' q% n) H            if( size &lt; sizeof(ClientPosPacket))- H$ a" w' l$ h! n; J
                    fFoundSize = FALSE;
    $ r# o5 R, u9 u) E2 C# |- P/ I            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))
    : Z) y6 r. L: a8 D                fFoundSize = FALSE;; J7 l# t' q; `& O
                else
    % A. M8 C/ A$ E( H4 a+ T/ M  }                fFoundSize = TRUE;</P>& N3 ?7 [; G- b4 x
    <P>            // If valid sized packet, handle the position.
    ' p6 j. u6 \7 [( \; w2 u% A+ a& Y            if(fFoundSize)
    & [% x# R' Q( I0 d4 }2 B0 Y. t" S                HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );# t* p& ?7 E3 f' v& g
                else
    1 _$ P% D- P# S; s6 Y5 E/ R0 u                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>, T4 }. H4 B) l; e1 _; {0 U
    <P>            break;</P>0 F) T5 }& @5 a7 f& V. y3 Z
    <P>        case PACKETTYPE_CLIENT_VERSION:+ r0 c7 @( [  g9 r
                if( size == sizeof(ClientVersionPacket) )3 ]! q# a3 Y, d' q2 _
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );
    . r7 Q% p7 j( _8 F& L8 l            else
    0 v8 P) p' r0 _+ R                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );; K4 i1 n3 w* i4 J) k0 Y, ~
                break;</P>7 B" c( t9 B; l2 D; {0 j) J
    <P>        case PACKETTYPE_SERVER_CONFIG:</P>( E2 C7 W, l, ~  D% Z' n
    <P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>
    / V9 k* L8 @; X% z7 j<P>            break;
    4 k  V( I7 j, b        default:) L. o, z! W- k' f
                HandleUnknownPacket( dwFrom, pClientPack, size );3 i/ {3 L) l7 c1 U) _
                break;
    / m8 e8 }9 n% L8 f+ H5 F$ U    }</P>$ L+ I8 l( y6 _4 Q5 Z
    <P>    //If the user wants to hold the thread, Sleep for given amount of time.7 m/ [. {/ z& g' I: s) H
        if ( m_dwServerThreadWait &gt; 0 )
    - t# Y8 X/ \  Q) }; _: c" s    {2 q% x/ y5 y( j# C' F* |
            Sleep( m_dwServerThreadWait );: e$ C; A6 R0 R: B8 M/ ^
        }, V' I4 I- p: J% x! c! _6 h3 g
       
    8 i' W  }; D* B$ k& A. v6 b+ w    // Retrieve thread data for this process.6 o' R. @; k+ c5 Q% f1 B
        m_csThreadCountLock.Enter();</P>
    8 H1 e' f6 |  D9 n0 Y& B" l<P>    m_wActiveThreadCount--;</P>
    0 R) r! c- A9 B6 I<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
    3 G; E  \8 K9 S( t+ A    m_fAvgThreadTime += fDiffTime/32;</P>) p/ [- A2 _/ W& K4 A# L
    <P>    //Get the Max time in the thread.5 T' s$ w- y, o- r
        if ( fDiffTime &gt; m_fMaxThreadTime )' g& R& b5 z7 y
        {
    . {( L7 f5 V  N2 ^: h        m_fMaxThreadTime = fDiffTime;
      |0 M+ H; ~- O) P# A    }</P>
    # i+ W0 }3 v) K6 v8 h; y<P>    m_csThreadCountLock.Leave();</P>
    " U+ I7 r7 J/ H. Z/ K. r  A: @, _<P>    return S_OK;
    $ x" Z! L; ?  S7 r+ }}</P>
    8 ?! W! m" Q- \4 Z4 ?9 y& @4 E9 _/ P% l+ t1 D6 W9 D4 x
    <P>//-----------------------------------------------------------------------------1 x" S- b. Z& X* y$ I' D4 k
    // Name: $ L1 t9 `. c7 `7 K
    // Desc: # I( Y, f- k2 D9 L. V9 t
    //-----------------------------------------------------------------------------
      X6 v# Q- C* Y* x/ V; qBOOL CMazeServer::IsValidPackSize( DWORD dwSize )$ K; _, i- D$ U% X% }" F3 M
    {  N! y8 W: W! S; w, w" J0 i( e0 f
        BOOL fFoundSize = FALSE;
    % l& d+ X% }: f$ y  n# x    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;; K: A& H) p* F* [) C
       
    ' J4 j) C- y1 j0 z    // Check through the array of valid pack sizes.' S% [9 m3 v" E. N
        if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation]), b7 H! P7 V! c) i
        {
    & J2 B0 Y8 p6 n" I& y$ {0 i; W, m        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)
    6 G$ l; h9 z) L' `* t& Z* i        {0 O& \1 U( n. \6 y0 I8 }2 E: o
                if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])/ S" k0 t$ W  ?: s
                {0 h9 l5 b& M' X8 l
                    // Found valid size in the array.
    5 {2 z3 G1 v4 V! ]: }                fFoundSize = TRUE;
      K& D4 N: p" K( Z                break;& e+ k9 Z# S% x0 a& K- E: `) e8 R
                }; X; J" X3 `& i/ G" A
                if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array./ K3 X* l5 U* f3 j; ]
            }
    ; z( g( K; R7 p8 X& j8 ]    }3 c# I; A0 {* _6 x1 z" i
        else
    5 e. z" m1 {3 {. o( d    {7 `2 T3 L# n% _% {
            fFoundSize = TRUE;
    5 D/ {2 k; B# p0 e    }</P>
    ( x  q! k' \/ q+ U% r<P>    return fFoundSize;4 D9 ~. [- J4 A2 T+ Q2 C) N/ m
    }</P>
    ! I/ B* Q' I) H<P>
    - Z* Y" a1 w8 v' C) B* n" ~" Q//-----------------------------------------------------------------------------
    ) {1 b) R# ~5 O) e3 a$ J// Name:
    6 x2 z6 ?! v9 q/ }2 C// Desc: ' W' q: T! N3 D& ]4 Y. L4 M
    //-----------------------------------------------------------------------------
    8 u- n7 {3 N* M6 J" M5 Bvoid CMazeServer::OnSessionLost( DWORD dwReason )
    , V. P% F& D. ?  p* `) Q+ v{
    # ?* ~; P% a0 c; y    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );/ D# C4 K# t- }+ x5 ^
    }</P>: B6 G/ {3 c: S6 D1 s) o

    ) l- ^8 e  l# Y( l: p2 h1 F<P>! `& T2 a* X  k1 j6 B7 b
    //-----------------------------------------------------------------------------" A1 u& x  s/ B( n, _* ?' w8 m
    // Name: 5 D: O: v6 m2 {# `5 t7 h, J& ?" H
    // Desc: 0 `8 r$ D3 f# T) U; A
    //-----------------------------------------------------------------------------
    " U" H0 W4 t' X% {PlayerData* CMazeServer::CreatePlayerData()
    9 _* N" U% p: {( i: f, K! F{; p" {, o, Y# J5 `
        m_PlayerDataListLock.Enter();</P>4 K6 E/ r' n/ [7 K2 R
    <P>    // Grab first free player in the list( s0 i3 P' w$ B9 ?7 M
        PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>
    ' q. _( d0 ~7 e<P>    if( pPlayerData )
    ( ?. ?0 {6 H. r; f7 Z) h    {
    1 N: I+ l6 t+ u; e- i        LockPlayerData( pPlayerData );</P>* J4 V% p; B2 a
    <P>        // Got one, so remove it from the free list
    7 B) u4 F5 F. V7 y, x        if( pPlayerData-&gt;pPrevious )
      t* e8 L- F- E5 s# H% ^            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;' V" x- J2 L2 |. K
            if( pPlayerData-&gt;pNext )% e' m% m, ?' h& ]- S- j" h
                pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;& E% M/ Y1 y. N( |9 g. Y+ y8 ~
            m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>
    ' o& c2 B& x7 F& l<P>        // Add it to the active list) ]6 `! o% H) g
            if( m_pFirstActivePlayerData )
    4 [. l9 P* A" C3 U1 i! P& b# j5 k            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;7 W# B7 v  T& s! y" V6 ]
            pPlayerData-&gt;pNext = m_pFirstActivePlayerData;, E. Y8 T4 K( {6 U2 Z+ P/ r# ~9 G
            pPlayerData-&gt;pPrevious = NULL;
    8 {5 l5 i" p  c1 ]        m_pFirstActivePlayerData = pPlayerData;</P>/ e5 X  W8 v1 _/ D+ B: V
    <P>        // Update count of players5 V& Y6 E( v# M* Y# l
            m_dwActivePlayerDataCount++;</P>9 ~6 a) L# M: C- W& v& V, j
    <P>        // Generate the ID for this player; }; _% D; K; @2 f
            m_dwPlayerDataUniqueValue++;
    ( u2 G) }, x' S2 r' ?% Y        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>( T# ?& n6 ?8 d
    <P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;( ?# H. m6 r4 W* r; B# A  x0 U" t
            pPlayerData-&gt;NetID = 0;, F+ g/ s4 b6 f' I2 |' A
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>
    ( \! h7 v2 Y  X<P>        // Insert into the "off-map" cell! _+ u" g& I/ ~+ x7 e
            pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;
    8 }7 T& y0 \8 K* m        pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;
    % H5 Z. z* B. ]' K2 F% \7 \        m_OffMapLock.Enter();
    2 k! D% \; E9 ?' x        pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;' S6 _1 h# q, Q& H3 |% e- D
            m_OffMapCell.pFirstPlayerData = pPlayerData;
    # T! \; i9 b  l) L0 W' f$ V        m_OffMapLock.Leave();</P>
    % K" D  ~  Z( `<P>        // Mark as active
    ( O) ^3 n1 t8 a6 C, T- L6 z1 P        pPlayerData-&gt;bActive = TRUE;</P>
    ) O4 F9 P* z: `' b  k9 Y+ H2 {+ y<P>        UnlockPlayerData( pPlayerData );
    3 E9 z* Q+ v/ H3 X3 I  p! F0 x    }</P>
    # C7 y! d) i1 M9 F, G! C<P>    m_PlayerDataListLock.Leave();</P>; M3 a" T. V6 `8 Z, R3 N
    <P>    return pPlayerData;
    0 J1 n* L7 K0 v  p}</P>
    + x6 g% n+ `1 h  M- \5 Q3 M; I& _' u& R2 y  W" Z
    <P>
    & p: w# q3 |! q8 q5 v) q% R//-----------------------------------------------------------------------------
    " h. A  r9 K4 ]& U0 U4 z' p// Name: % V& K3 ?$ u2 K$ h# A/ ^7 i4 H
    // Desc:
    0 j$ s( l* Z4 l" c0 o//-----------------------------------------------------------------------------
    2 L. H/ ^' p  ivoid CMazeServer:estroyPlayerData( PlayerData* pPlayerData )7 A/ t  r5 M' b, e1 C. V
    {5 b- t( G) G& Q1 I+ o* r4 u1 h% {
        m_PlayerDataListLock.Enter();( O+ F: K4 `2 h7 h- I
        LockPlayerData( pPlayerData );</P>
    2 }( q# y5 M7 L<P>    // Remove the player from its cell2 o' b# Z$ V. v: G
        RemovePlayerDataFromCell( pPlayerData );</P>- g% `1 e" T1 m1 I# `+ X
    <P>    // Mark as inactive" I2 L! x$ _; [
        pPlayerData-&gt;bActive = FALSE;</P>
    8 V4 O: c% z2 }* S9 K<P>    // Remove player from active list
    2 |- q4 Y( s0 E8 n' E4 g    if( pPlayerData-&gt;pPrevious )
    & x6 g: o: m; e8 I        pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;/ q6 Q( t1 @2 z# l6 ^/ Z
        if( pPlayerData-&gt;pNext )1 G* X9 ~1 h- y- V* Y" s
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>
    ! M; y# m$ C2 j6 [! N* f. W( o<P>    if( m_pFirstActivePlayerData == pPlayerData )
    0 Q8 t: h' q& R7 ]( s, M        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>
    5 s# ?' e/ P4 D2 I* t# x. N<P>    // Add it to the free list
    / H& _, U# Z3 h9 v# x( R    if( m_pFirstFreePlayerData )
    % x( u9 M% @! c5 x9 Z9 k        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
    ) y, B% t) r# C+ t" D& E    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;+ F# P7 O& e$ A, |3 D; I% @+ A
        pPlayerData-&gt;pPrevious = NULL;
    1 K8 b) J% j* k; B* T8 S8 f    m_pFirstFreePlayerData = pPlayerData;</P>
    ; C$ g: M/ N0 x' l<P>    // Update count of players
    ; \! y5 B* ?7 L7 I- m    m_dwActivePlayerDataCount--;</P>: @+ ]/ ]3 f8 Z8 ?$ y. ]) K# H2 E1 l
    <P>    UnlockPlayerData( pPlayerData );
    ( g. o/ d% J4 C$ h0 F* r    m_PlayerDataListLock.Leave();* f7 x. e$ h+ a8 `
    }</P>
    " i- M/ p7 v4 n4 K) j0 b
    3 @" Z; A, ~: C" t<P>
    ! H! `% O" j$ b7 `  X; j4 V6 K//-----------------------------------------------------------------------------
    % t. d4 C! g9 I1 D3 N// Name:
    & s4 |! G0 X1 P6 H  M// Desc: 0 s# f: c& v) f$ r. n* P
    //-----------------------------------------------------------------------------' e5 U3 o8 i8 f
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )- l) l5 j( a3 t1 ^
    {
    * w* Y6 n2 K5 f0 q. z# L, B    // Lock the player
    $ r7 `% Q. k+ T6 @# f2 ?7 C    LockPlayerData( pPlayerData );</P>% S8 D) Z2 b- u
    <P>    // Lock the cell the player is in' f/ N3 n+ n3 w9 O
        ServerCell* pCell;
    ' z% ]& {, G4 M/ g1 v    if( pPlayerData-&gt;wCellX == 0xffff )3 E- \# W$ F' |# O3 h, C$ d
        {
    . h$ i8 X' b* N. Y! @6 `" O/ B        m_OffMapLock.Enter();3 `; {8 Y& @7 X( N: |: x2 F8 W. i
            pCell = &amp;m_OffMapCell;" h9 Y: w4 C% Z- f
        }
      r5 v! w8 A/ ^    else2 e2 r4 s7 _; [
        {
    4 ^- I2 u  M( _) f4 F        LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );4 p6 B3 H' g, U
            pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
    " u( _0 b; y) K* f8 j4 H# f3 t    }</P>
    6 |( ?9 m( U+ ]; o* h. n8 Q<P>    // Remove it from the cell: D3 O6 M. Z: E: }8 e5 n
        PlayerData* pPt = pCell-&gt;pFirstPlayerData;9 \' c4 w! `4 {8 y) c# H; v& }  O
        PlayerData* pPrev = NULL;
      C' d3 D5 c6 W6 D    while ( pPt )! e& S$ `' P$ v
        {
    - y1 D9 J9 E  s1 N6 \2 B0 L$ a5 O        if( pPt == pPlayerData ): G* n, h. N/ s
            {
    ( U5 ^/ ~% k) P/ k- }/ P9 \- q            if( pPrev )
    $ X+ b, r! _! w) Y. N                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    6 ^, w# H/ X) r) r- b$ b            else
    ; [) f  i. f8 _- x9 p; q$ }3 N                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
    / d( L5 l8 J) Q. a6 k<P>            pPlayerData-&gt;pNextInCell = NULL;* V# n& @$ p) d% `9 y7 k
                break;' L4 f& {+ o9 W* p' Q
            }( |# N6 l( A  x3 I
            pPrev = pPt;
    + T& y! q/ R0 y+ H0 a1 d        pPt = pPt-&gt;pNextInCell;9 u) N! x% \# F8 s- E
        }</P>; f# X8 {/ [. T4 E. ?8 N* ?
    <P>    // Unlock the cell
    7 ]$ J  |& B, x- B    if( pPlayerData-&gt;wCellX == 0xffff )
    7 T% c% m/ {; k% w5 R5 L        m_OffMapLock.Leave();
    . g% @( `2 S: d    else
    3 A2 ^' f1 U6 `9 }5 d        UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>
    # A' G0 {2 B  l/ [" [' C9 X1 f6 m<P>    // Unlock the player+ O* f" r7 s: A+ n/ X
        UnlockPlayerData( pPlayerData );. s6 B5 X4 U. H) B
    }</P>
    0 o9 j9 Q+ E+ H% c0 Q) v  }$ S" D; Z7 Q/ q  _
    <P>! o/ p# Y* p; _1 X4 ^
    //-----------------------------------------------------------------------------( Q6 o; s: M2 r. f$ E
    // Name: 7 j" }4 }1 v1 H0 L: j) H1 W: {
    // Desc:
    2 Q: z; O3 w; n9 H//-----------------------------------------------------------------------------
    9 }- r( J. P! u# s/ J, y' Bvoid CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )" B8 X& J* [+ J$ V4 T/ Y0 w; w# d* j
    {& c3 a; M  i# m0 {. l" @' `
        ServerCell* pCell = GetCell( pPlayerData );" [( Y# T: Y- R) x  S
        PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
    " V0 s6 O- R" r4 b    PlayerData* pPrev = NULL;
    9 ]8 H" W+ a% r, D1 V' d' _    while ( pPt )2 A  `- C7 C* y1 o( a
        {( T  W( w' z  S4 C! A* `
            if( pPt == pPlayerData )
      H, d& k) o) T4 L        {, h& a) J: B4 v% p& G' [( Y
                if( pPrev )
    + q9 I! s! M$ J" U# v! N; F                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    " ~, a/ @# h/ j# j* T            else- Q# {1 X/ M! L) z; ~
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;+ Z, Y7 s. a% N  l
                pPlayerData-&gt;pNextInCell = NULL;% B% V, c5 s& C: ]0 C! Q
                break;! d8 H' x% q! D4 I) k5 \, n
            }, W, ]- W/ j$ A
            pPrev = pPt;
    4 u  Q& Y! M7 Y        pPt = pPt-&gt;pNextInCell;( @  X* C, n$ M, r8 X9 n9 r  j
        }
    6 |* ?: _( ^& e1 K}</P>
    ( G4 E) C7 q3 w! Y; k
    9 h; ]( {! a6 V* t<P>+ C6 H: U: O2 E( u4 C4 e
    //-----------------------------------------------------------------------------
    % i, F) T0 g: d0 ^// Name: % W! r7 ^9 A' g  C$ g) P$ v7 g3 Z
    // Desc:   f( g/ X( C5 }) z9 D
    //-----------------------------------------------------------------------------
    % z3 _8 ?0 r. y# F! U6 J  |% Rvoid CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )
    : |5 A3 `! R7 R' ]. F% m{: I1 ]7 `5 J' I5 E
        ServerCell* pCell   = GetCell( pPlayerData );% K* B! _$ U2 {/ J
        pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;
    9 L! Z% @, [# P' ?" b3 C' ~2 ^8 A    pCell-&gt;pFirstPlayerData = pPlayerData;
    $ q' L; G/ z* d6 A7 I}</P>
    1 X3 G3 T( H7 E0 U5 B( N6 u) ?* t" h- O; W( t
    <P>" F. |/ D3 A6 [: q, f+ `
    //-----------------------------------------------------------------------------* A% |( A3 s# j; Z4 ^
    // Name: + b: y8 F$ V2 E% _9 E# ]9 N
    // Desc: - j! l# S6 z! f, _+ Q& c
    //-----------------------------------------------------------------------------# P! D& {) ^6 u/ p
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )/ {5 P8 }# B# W! m8 b8 L5 x
    {! m; `) L7 r3 A, a) U
        // Grab player for this client and lock it
    / e' n/ ~; \: d) C( Q; ?2 n: z) E    PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );
    0 Y0 B' C4 S# o    if( pFromPlayer == NULL )  C9 x& P+ ?0 g
        {
    5 k5 D1 j. ]; O1 Y  m        if( m_dwLogLevel &gt; 1 )& m, ]0 W) u% J0 F4 ~
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );' P1 `# A' B5 ]% y2 I  u. U
            return;
    0 U' b; T" x- e    }</P>
    5 h6 D; z( B! a$ _<P>    LockPlayerData( pFromPlayer );</P>
    ' M4 J% {! f9 }1 o7 B& K6 g+ C6 r/ B4 t<P>    if( FALSE == pFromPlayer-&gt;bAllow )  @" Y+ m# C: l$ |! z8 t2 T; p% k. t
        {
    3 i: g4 l9 G- L/ A: X        if( m_dwLogLevel &gt; 0 )
    ; D  H+ k/ j$ d7 \$ s' b" v4 E; L            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>7 K0 `! K3 [3 Z8 S( ^
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );$ K. ~. u2 |4 ~) r, C& o
            UnlockPlayerData( pFromPlayer );) o7 y4 ]3 x5 |+ ]/ J! a* I* t0 @
            return;
    8 J* g" B# A& d8 R    }</P>
    * q9 W' }9 b2 M* n3 \<P>    // Compute the cell the player should be in now, y& t* y- X1 |. }
        DWORD newcellx = int(pClientPosPack-&gt;fX);
      n8 a8 {/ b  E8 Q& E    DWORD newcelly = int(pClientPosPack-&gt;fY);! o' b, d  ]$ @; W0 ^$ n( Z" ~
        DWORD oldcellx = pFromPlayer-&gt;wCellX;2 A, t2 \5 p5 D
        DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>  T! b5 Y9 v9 X
    <P>    // Have we moved cell?
    - j7 l8 I. m! u    if( newcellx != oldcellx || newcelly != oldcelly )
    ( P# ]4 T* e8 j; y9 |& D1 x    {
    9 N7 O+ e' Q8 N& T, d2 U0 S5 k        // Yes, so lock the pair of cells in question) c5 J/ F* \$ L! W+ X) B7 D
            LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
      {9 X+ |& @! a" O8 k<P>        // Remove from old cell and add to new cell8 [2 J: u7 a) Q8 N0 V
            UnsafeRemovePlayerDataFromCell( pFromPlayer );
    $ ^4 s+ j* c3 |% a! z        pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);. ]1 k1 {2 U5 Y5 J; l0 D
            UnsafeAddPlayerDataToCell( pFromPlayer );</P>! @  U* f" W& C* T! _- d
    <P>        // Unlock cells
    7 ^5 t! ?  C7 Y        UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );: _: Q8 I( y6 ?0 y' ^" A6 m
        }</P>4 r: v7 Z5 [9 r8 g
    <P>    // Update player position( x& J# S1 c& Q+ S4 c
        pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;: ~7 ?/ x, F7 n, t4 I& |! p) }
        pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;. \$ ?6 p6 ~. Z7 a' f/ F3 O6 U% Q
        pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
    7 @' h0 k! w  U+ G2 B<P>    // Allocate space to build the reply packet, and fill in header
    0 b1 }3 a- _8 \& Z/ w    DWORD dwAllocSize;/ @9 x3 y1 k1 ?/ j6 c! e
        ServerAckPacket* pSvrAckPack = NULL;</P>: h# h6 H% ]: k# C
    <P>    // Begin by allocating a buffer sized according to- ]0 f5 j6 y3 z: [9 x9 X
        // the current number of nearby players + 4.  This will give
    # N# y# M: h; }/ a    // a little room for more players to come 'near' without resize
    ) V) r2 L: V# Z9 q  {& ~6 C    // the buffer.2 p' e# S7 }2 P9 [
        DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>
    % @" [4 t3 Z  X1 D1 Y5 n: q<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);3 v5 T( f& D1 O8 w
        pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    + p, `1 X7 Y+ b$ V    if( NULL == pSvrAckPack )- G9 v+ Q4 J9 n& Q7 L
        {0 x& l9 I6 A- j  J) Z) H
            // Out of mem.  Cleanup and return
    ) R, L5 g7 h1 f1 k$ S' X        UnlockPlayerData( pFromPlayer );
    6 g' c+ w  h3 P$ w        return;       6 J- Q/ m! A7 |! E/ o
        }3 n; v7 K: W, A
        ZeroMemory( pSvrAckPack, dwAllocSize );</P>
    : J! b/ X3 r2 `3 G/ J3 M3 c  t<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);  u; t/ T1 [3 q( s
        pSvrAckPack-&gt;wPlayerStatePacketCount = 0;: W3 x. z+ T' p" s' w( F3 P
        PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>
    6 C! {" A2 b: l5 Q: l<P>    // Compute range of cells we're going to scan for players to send
    * S( x5 I4 `7 O# z" E    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;' @6 a0 Q. O) V0 r& `9 [
        DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
      h5 v, I$ B( }, X. W0 ?    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;
    / L' F  b- G2 d2 m    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>
    4 o4 b2 o8 f9 `9 ^<P>    // Lock that range of cells/ V$ ?7 G" \- z8 U/ y; R0 D0 w
        LockRange( minx, miny, maxx, maxy );</P>/ B5 S+ r9 q9 ^  P% i
    <P>    // Scan through the cells, tagging player data onto the end of: W- D3 `  E& o1 L. u
        // our pSvrAckPacket until we run out of room: C  G$ e& ~2 z( [. l
        for( DWORD y = miny; y &lt;= maxy; y++ )
    ; k& @1 ]3 R) A! q$ m) b    {
    / y0 z( t2 V2 u- K1 s* ^2 P# h8 Y        for( DWORD x = minx; x &lt;= maxx; x++ )
    $ S6 I, h8 h1 s& g& r- F- `. h        {% o* [7 |" e/ {- d% ]
                PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;* X# g. _- `2 p
                while ( pCurPlayerData )7 C* C7 ~2 ~$ R0 n
                {' E0 Z: X4 V" X) L- ^
                    if( pCurPlayerData != pFromPlayer )1 ~' e7 k0 t* E
                    {
    3 I* `# a2 F7 f, q                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )
    8 ~$ L7 `8 l, J+ g( ^; p( U. h                    {
    9 E! a) O' K& R. r3 {                        // Make sure pChunk is where we think it is
    # g5 m3 l- B4 a( t+ i  w0 v( ^. T                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>, ?- i. ^6 D  Z2 t8 f
    <P>                        // There are more than just 4 new nearby players, so resize the 4 Y+ ]: s0 _3 \. \
                            // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
    . Z" v6 w6 \; h8 W( Z                        dwMaxPlayerStatePackets += 16;
    " ]6 w8 J! f0 a6 T  S- b                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);( E$ @2 p& v7 U8 T
                            ServerAckPacket* pNewSvrAckPack = NULL;
    " ^4 n! n" F( {# @6 D$ X4 F                        pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    7 l% \4 H  Y- N" v0 O3 `. G                        if( NULL == pNewSvrAckPack )
    * u9 m( e1 z% j                        {  H. A7 Q. o# E# Z
                                // Out of mem.  Cleanup and return
    + o1 [/ ~! [: J& m' z1 w                            free( pSvrAckPack );/ v1 S9 N0 b2 n( k: g1 P
                                UnlockRange( minx, miny, maxx, maxy );
    ! l8 c6 J2 ?! l                            UnlockPlayerData( pFromPlayer );' Z+ p+ a4 R# \+ d' f
                                return;      
    3 u" l1 g6 B! }/ w8 D                        }</P>8 |5 H( L# O" e7 g4 T6 i
    <P>                        pSvrAckPack = pNewSvrAckPack;
    ) F( p: H  C  B2 K% Y' O                        pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
    . L# f- w( _# h( F/ P: n% Y  @<P>                        // Make sure pChunk is still where its supposed to be% g$ n5 M  O9 o9 v
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );
    " R8 H3 \- _$ X9 t                    }</P>
    1 W! H, ^% @  g. t; w- a1 Z<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;$ [9 }* [; @: e1 }8 n
                        pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
    ' r5 w8 J. a0 x                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;
    9 r+ {$ m9 j4 u" x% J; _. V                    pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;
    4 \. R; J/ Z2 c/ u                    pChunk++;
    % r6 T' {: I9 U& {6 w% L$ @. S                    pSvrAckPack-&gt;wPlayerStatePacketCount++;' ^% D& Q! g9 l: e: `- w3 S
                    }% l8 _3 }* h0 Q: T# z# }0 ~6 r
                    pCurPlayerData = pCurPlayerData-&gt;pNextInCell;
    + b* o* w& v* P! R5 W            }
    ; n  f; X3 a- w' Z% j1 q1 s# l        }) a) I1 ?  t6 n/ r7 m6 j, M
        }</P>2 n1 _  P1 R' s  q  k2 h  _% e, U
    <P>    // Update the dwNumNearbyPlayers for this player
    ( b/ q+ @, r( M: x, Q    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>/ e2 D: ^) O7 J
    <P>    // Unlock range of cells* j9 U" D9 b# I
        UnlockRange( minx, miny, maxx, maxy );</P>" _' W4 H# m$ F: A  P9 K4 T
    <P>    if( m_dwLogLevel &gt; 2 )
    + e: C' e: q8 d) u1 m    {
    6 {0 `2 p0 L. S- C9 y        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    # r/ S; I; q* v0 n- T    }" t/ E3 F. {" s7 ^
        else if( m_dwLogLevel == 2 )
    / B0 H2 G# R4 r, L5 q; ]( b! Q    {. F1 D1 S9 C% Q3 d" Q$ a) T( C, }
            FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    4 m/ C4 }$ y- S" o9 G        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )4 z; _7 x: m( b9 `, M3 j5 R3 E
            {7 c+ V4 `  z2 O" z' G" n8 a- m
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    1 c+ l6 U- \# Q8 a5 f" i            pFromPlayer-&gt;fLastDisplayTime = fTime;- T+ c0 F1 b- L: o2 x7 ?! T$ p
            }
    ' v+ S5 T' V. N: z    }</P>
    4 |* X) |7 [3 f( d<P>    // Unlock the playerdata, p5 b' Z# h; b+ [' [9 z+ Q) u3 p
        UnlockPlayerData( pFromPlayer );</P>" X& ]- y8 I% [( Y5 r% m
    <P>    // Send acknowledgement back to client, including list of nearby players
    , O& ^+ }, N: H! f; U    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));
    6 A( v* ]- h7 H# `( M4 U , R. r/ Z6 ^5 M# b$ N0 E
        // Pack the buffer with dummy data.
    7 ~# u3 l' C- w. C    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)3 m' ~6 F4 y* n3 X0 f# q
        {
    5 ?4 H) U' R$ F# ~        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];2 P, A0 T: F5 T- x
            VOID*   pTempBuffer = 0;</P>
    % K( J/ R6 d9 A; \: w8 H! u' c<P>        pTempBuffer = malloc(dwBufferSize);% Z8 z% K: I7 M* b4 @- i2 l) ^; a
            if( NULL == pTempBuffer )
    & R& y2 x3 r8 y8 x: W( J        {
    ! ?- j% W. [0 i+ e7 u4 D( q, @            //Out of memory
    0 {/ E. E7 Y( ^+ I+ @/ B            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
    & I2 [2 K* [( j            free( pSvrAckPack );- _) R( x7 _2 p4 Y+ m7 o4 u; _
                return;
    8 [' N- X5 m, |7 w0 T+ o        }</P>$ g, v" q- l1 `( ]$ e
    <P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');. ~1 d4 {3 ?* ~* W, ?
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>
    $ e/ S- T  E/ ~/ H# [<P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );
    + H9 \" B. A1 F) U% q) n7 u# f    ; U7 \& J3 z& S' O
            free(pTempBuffer);
    2 r; N: ]+ R) X' _    }   
    * v: N: k# }4 f; p4 B/ @8 ~9 Y    else7 {  E5 E% G" V) G+ V% {1 b" L' S
        {6 E- C6 `# M; O# F0 s% U% m
            SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );
    ( B: ^# R! T" W/ `1 m& C" A- i) u    }</P>
    $ V( s  p- t$ F<P>    free( pSvrAckPack );</P>4 H$ Z/ f8 H& T& A* v
    <P>}</P>9 z) K" _: Y( m3 o4 I3 a4 W

    % q! m2 p; g9 L' `  C  f: N<P>
    . l* O2 \  k- x* F! [//-----------------------------------------------------------------------------
    6 B; c& W6 |1 Y5 E// Name: ( T/ q" i# T7 ?6 U" w
    // Desc:
    ( A1 j9 f0 P1 S$ S9 ^% N4 t//-----------------------------------------------------------------------------2 z/ f6 b, \' k: F8 Y, b- \
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
    : I. Y7 t# U" f6 G  f9 {) \{
    5 y) q7 o" Q1 f* ]( y, }    // Grab playerdata for this client and lock it
    9 x! z& \. U) i. S) Q) t    PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );* E  `4 _" z7 D& e, o" ~
        if( pPlayerData == NULL )/ [9 R2 ]8 s; [) I+ h
            return;
    & P9 b; f! ]/ H; ^) d3 Z" P1 q: a5 ~    LockPlayerData( pPlayerData );</P>1 h  a8 l4 U" |9 L# D: ^
    <P>    // Record the version number ' Z1 ~$ z, e1 p+ `6 q3 p
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>) D% _; P: \/ Q: j7 c4 U
    <P>    if( m_bLocalLoopback ), D! d' K% ?" A5 Y; Y+ ~  ^
            pPlayerData-&gt;bAllow = TRUE;' L' K* `/ H* p& {+ n
        else
    % s3 Y8 ?6 b7 w) x( M$ l% M        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>! L$ i) R! f4 X" Z
    <P>    if( m_dwLogLevel &gt; 0 )
    4 Q: h; c* w6 }7 c8 i        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>0 m/ ^3 x1 ~4 _+ A8 _
    <P>    if( FALSE == pPlayerData-&gt;bAllow )0 w$ u/ O* L4 ]1 Q+ N0 T
        {
    ; ]! @4 [* s0 A; Y        if( m_dwLogLevel &gt; 0 )0 w0 F. q4 i0 ]
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>
    : \2 p& B7 L" Q( z2 s6 m! W+ W<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    5 i0 s/ x, ]5 B" F( k        UnlockPlayerData( pPlayerData );; G* s# T' O' t: Y
            return;- p" T8 ?/ D8 {! \0 t* F! h+ t
        }</P>
    5 H* v7 s; z( B; q; V' P8 H<P>    // Unlock the playerdata; N% l5 y7 p2 K2 |
        UnlockPlayerData( pPlayerData );</P>1 D1 H* p, Z& A% Y# T* J
    <P>    // Send acknowledgement to client that the client was either accepted or rejected+ r+ q9 O# B; A; m" D( }; a
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );$ N3 s2 c5 y$ A' C1 w4 E* f. z
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );+ i  R: Z# V% k, G
    }</P>2 j+ h% q( ^3 x  b/ a% P

      u, L% u# j; }2 e; p<P>
      c5 S  i8 U1 m$ S1 N2 m: a//-----------------------------------------------------------------------------+ v  e7 P1 e9 O8 u; I8 n! b$ L# {
    // Name:
    ; {) u; L1 q+ L4 z. F// Desc: 3 M% f5 A4 b7 A- L0 s$ v
    //-----------------------------------------------------------------------------) m9 v" f+ n$ M' b
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
    3 r4 b4 P9 x7 {  o{
    1 d  }1 j( _1 h4 ?! Y: v    switch( dwClientVersion )
    3 s& ]. Y6 F) m, P* V$ X    {: S% _6 _0 }# i6 q0 z$ ~  Y
            case 107: // only v107 is supported
    " p2 C+ b2 T- ^8 W. W; P            return TRUE;( H$ n8 C6 x3 n, s0 m
            default:- j& o% M6 I. k7 W0 d+ j
                return FALSE;
    + h4 T1 [/ z5 b0 F% B6 `- }, H* c  Q    }7 A* X0 t# z5 x% h
    }</P>. m! q) o$ ~3 I; E: ?$ O2 ^* Y) x

    6 H! d/ j4 S1 Q; |$ B2 ^<P>
    ' o: }+ E/ k) U  E( F6 l+ C//-----------------------------------------------------------------------------
      [& Q2 ~, ~8 |* |: h, X// Name: + A/ k  T, F3 q0 |: s
    // Desc: ' u; W6 \( j) [
    //-----------------------------------------------------------------------------! m' S+ _0 i2 v( d7 p; k. N: C
    void CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )1 s, z2 s( G% z' d
    {
    8 {" j7 y: ^8 m2 M, G/ R+ ?    if( m_dwLogLevel &gt; 1 )8 j* R# N  U& i# z% w, w
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>
    % w. O4 Z3 v$ \! y& T5 V<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );+ c' E! I2 {2 e3 N, P5 L
    }</P># y. f$ G* }+ {  d
    4 z- w( G% w( n
    <P>
    5 s: M2 E$ z- c5 Y; V) V" z4 x//-----------------------------------------------------------------------------
    4 m/ P/ @7 U; f" w$ U// Name:
    6 {; f5 W- R% ~( b// Desc:
    % Q' {$ d/ W+ i9 Y9 v9 O: f  ^* |3 S//-----------------------------------------------------------------------------: Y; M; N/ _0 U  a! \3 E. r- f
    DWORD   CMazeServer::IDHash( DWORD id )
    ; J* C% P2 r9 X5 L: o9 Q7 i! t5 B8 u{2 W$ M& _  V7 x# J% {: N) a6 j
        DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);
    ' X* e0 b8 f" {; Q; X2 a; W    return hash;
    3 y! E: R0 V9 m) P}</P>
    / }- e# G9 I% o. ]; t: |( C* K) D* w- }
    <P>
    : v5 n$ f2 \# z& _//-----------------------------------------------------------------------------
    ; h6 S" W8 O  n" Z7 Z" C5 v6 N// Name:
    + w) u4 F. n9 E6 Q  }4 E( X// Desc:
    ! ]0 _* t! c" U7 r- L3 Y" t1 s7 D//-----------------------------------------------------------------------------
    0 C$ i  F! U: Z( f) Kvoid CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData ): j1 X! b8 B6 B! U1 W& Q6 C
    {2 a3 F2 m% g, U; T
        // Hash the ID to a bucket number% q  }! R) N2 c% S, Y
        DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>2 x$ h5 y, h8 ^$ B, }
    <P>    // Lock that hash bucket. p- d  T1 l: @/ N; @
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    9 K/ k( \2 C2 Z# v! E+ G    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
      y, D$ Y$ y5 I, s6 h+ K8 `# y$ N* d<P>    // Loop though players in bucket until we find the right one
    ; g* r. A! [8 P7 R. c    PlayerData* pPt = m_pstIDHashBucket[bucket];+ \( U# s9 l9 ~, H7 p0 {
        PlayerData* pPrev = NULL;1 R7 ?4 v/ ~1 f
        while( pPt )* ]  y# `8 a, B5 j* ]
        {
    + ?0 F; A; o1 D. F4 V6 Y; @( g        if( pPt == pPlayerData )  X  C% T. @2 [) p( `$ |
                break;1 \* s9 {  x( ~( }8 h. T& I2 z
            pPrev = pPt;
    8 r; p" z" z4 t( v# H5 ]  x4 o        pPt = pPt-&gt;pNextInIDHashBucket;
    : v2 t% W% w( L. Y    }</P>
    # _# t6 x8 \7 A, d! o5 h$ V2 g<P>    if( pPt )7 v4 E3 i$ W, w* C
        {$ K2 Q; {/ r4 H# t! f" j0 ^) ^
            if( pPrev )
      e/ y4 r" x$ U            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;$ n2 x2 G$ _; m  f$ q. @# _1 v
            else
    $ E8 ?& h6 L9 U( I" }            m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;: t! B- N6 g+ I4 A( S
            pPt-&gt;pNextInIDHashBucket = NULL;
    - u: N* s6 s. J1 f) Y, |& {) a    }</P>8 ~( i+ h- W$ d7 i! r. j) {
    <P>    // Unlock the hash bucket! q9 R4 q/ H8 E% F9 k6 A
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();8 m0 ~( S0 @, V7 M7 R; k% M
    }</P>
    ; L6 y8 [$ y* Y+ K: ^9 x, N9 T: k
    <P>
    7 \' J  D& Y, Z8 L: @& S- U' L//-----------------------------------------------------------------------------" G3 x% O; f- y& `$ L* b! [' y& F
    // Name: ' C( B3 _1 I; A6 m
    // Desc: , v/ l! M3 \! m
    //-----------------------------------------------------------------------------/ Q5 t4 L& D1 {
    void CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
    ' E2 u0 h" p' n5 m$ Q* y3 Y. @{
    # L) V$ E7 s' ^9 J    // Make sure this player isn't added twice to the m_pstIDHashBucket[]
    ( o" K4 u6 E: }' r3 c- Q    // otherwise there will be a circular reference
    ' E4 W& ]5 [& P/ a3 ~, y# b: ^  v    PlayerData* pSearch = GetPlayerDataForID( id );8 U" j' Z. f+ s3 q6 t
        if( pSearch != NULL )
    / ?" e! Z* N" ?# e' x$ @/ h5 Z; S        return;</P>9 S8 Z1 s/ \: p) o6 b4 G. b% ^
    <P>    // Hash the ID to a bucket number
    : r9 V& y& i$ c$ ]1 k  x9 c    DWORD   bucket = IDHash( id );</P>* T' ^/ j* S7 j
    <P>    // Lock that hash bucket
    1 }' w+ R9 c: B3 f( |& S. G    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;, P7 X: Y+ w# x' H9 b' D. O% @' V6 U5 B
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>" S  O0 U- a: |
    <P>    // Add player onto hash bucket chain( I4 h1 h2 w/ n' Y+ a
        pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];$ r% k0 J; V* ^+ b) R
        m_pstIDHashBucket[bucket] = pPlayerData;</P>0 d$ w- t3 ~+ K3 n' G) r8 v
    <P>    // Store net id in player9 g! t$ v1 d9 t9 G, x  c1 d
        pPlayerData-&gt;NetID = id;</P>3 F0 d% j4 f% j. {5 N$ V0 x
    <P>    // Unlock the hash bucket7 U* N; ^3 L2 J% H, s8 \
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    , O* _. Y( u$ @3 Z. Y+ t}</P>
    $ `6 @: i4 Y: c  {" T/ f4 @7 R
    % {! W9 U) O2 \4 _- T<P>
    ! x  B& f2 }, D. s//-----------------------------------------------------------------------------& U9 J. Q# F3 o' ?1 f$ m; t
    // Name: / ~  u' N& j1 x/ e- }
    // Desc:
    % e$ s  P  t! m6 N' G' _$ l; P8 p//-----------------------------------------------------------------------------# _5 S5 Z* j- b
    PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )
    % n  k9 B' m- X/ f{
    . e! G2 E& c* d4 x    // Hash the ID to a bucket number: m' I  s% R% p0 w, Q5 O
        DWORD   bucket = IDHash( id );</P>
    ) }+ H. M. F9 O$ p- g6 ]<P>    // Lock that hash bucket+ l$ W3 k6 B; i$ F& f) z
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    1 u# b. z) x( m* h, Q+ ~  v    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>  F( B) a9 u( T( c, q) r. e# C( \
    <P>    // Loop though players in bucket until we find the right one, R& S% F" l5 o8 q: z6 k7 c6 x
        PlayerData* pPlayerData = m_pstIDHashBucket[bucket];9 y4 `+ {: a; Y6 s6 N
        while ( pPlayerData )% c2 v* v9 }' d* {, N+ @3 Y
        {
    3 p' q2 P$ q6 W5 F        if( pPlayerData-&gt;NetID == id )" o( t7 [) a  \
                break;  V5 |+ s  ~' J) M
            pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    , e" E* ^! E) b, g0 r    }</P>
    3 e7 S, f! H4 j( Z- {2 T2 g3 j4 f<P>    // Unlock the hash bucket
    + @; d* X# K. Q    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>, ]8 H+ h2 V) e3 ]0 S
    <P>    // Return the player we found (will be NULL if we couldn't find it)0 [3 c0 z2 J( F; X$ n1 @$ R
        return pPlayerData;. }3 E( x; P7 u" L
    }</P>
    6 v# ^! T, H7 ^2 ]8 d' s
    8 H/ v0 p& C+ X- ]* i<P>- \4 X& p/ y3 \/ @+ R" i: ?
    //-----------------------------------------------------------------------------
    7 E6 }2 Q# g- M, Z: \. A// Name: " f1 [0 H4 ]0 O* ^
    // Desc: calls DisplayConnectionInfo for each connection in a round-robin manner
    / D2 L; }  r& O/ W//-----------------------------------------------------------------------------
    6 j" |$ _4 t7 _void CMazeServer:isplayNextConnectionInfo()) O# x, N- `6 G& `
    {( k" H8 d9 n3 `; E; [, A
        if( m_pNet )# T+ ^$ X" K1 b/ D8 M  Y& K( {2 `
        {+ z8 W7 K# n9 Y; X. b( p
            // Find the player that was displayed the longest time ago, and display it.
    * Z' R0 G8 h/ p7 W7 \5 k8 d5 g        FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );% `, u$ W# Y8 G0 {
            PlayerData* pOldestPlayerData = NULL;
    9 b% o! ]/ B' V! m7 ?8 B        FLOAT fOldestTime = 0.0f;</P>
    5 V7 {/ a. J; I) u& r) q, j<P>        m_PlayerDataListLock.Enter();</P>) t, |$ |' E0 T4 s- A/ Z
    <P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
    ( X* j$ p% \+ v* e        while ( pPlayerData ); w, i$ h; i0 a( m; v
            {
    - U  j5 }" G* y3 A0 f2 x. ^            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )2 H( S" F+ K' c  O+ d5 l5 P
                {/ B' \* I, N* p! ~4 ]/ G3 U: {# W
                    fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;8 N; ?5 d, B1 j' P+ D2 M3 V
                    pOldestPlayerData = pPlayerData;6 k4 \' J+ ^' j( i$ \7 |
                }</P>- k2 w" t& e# F* q
    <P>            pPlayerData = pPlayerData-&gt;pNext;
    4 W- R' D7 u+ O: b6 t4 L3 d+ _        }</P>: ^0 P! M1 `  Q+ @
    <P>        // Display the player with the oldest CI field, and update its CI field.
    / U" O. |! o. P1 }        if( pOldestPlayerData )2 t: |  \4 i6 @/ r- V3 J* w
            {
    5 P- ~/ |; E# ~# Z            ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );6 \4 k1 [3 J: w  L6 |' l1 l  a
                DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );3 l" G7 L) L1 y& J/ L% Z( l
                pOldestPlayerData-&gt;fLastCITime = fCurTime;1 W) |3 j( Q( N* V7 L# U+ j
            }
    + f$ [' X7 d9 U2 w# ~2 v2 e. D5 \        else$ Z9 o0 l' z. Y# s4 P8 {
            {
    # b0 t% r; _, s) b9 O! q! Q2 F            ConsolePrintf( SLINE_LOG, TEXT("No players found") );+ P6 A6 g% M0 w- x7 c
            }</P>
    + U/ H3 b, D% q5 ^8 }<P>        m_PlayerDataListLock.Leave();6 \+ P9 b& i- {/ R
        }
    ; D+ A9 [* c3 O0 c) H}</P>
    6 M0 o( j  J7 @; k9 K) D
    2 S; v& R4 d) z8 U7 \<P>
    " o; K9 C# j' V9 W; u; M  C" E/ Z//-----------------------------------------------------------------------------
    " R9 H3 S$ }/ e, |# V# n// Name:
    3 b  T2 q+ J4 o0 O2 y+ v- d// Desc:
    ' S, l5 a" c: w# A! Q* }3 `//-----------------------------------------------------------------------------3 P5 x  a- Y0 h6 V9 `4 `1 ^, E
    void CMazeServer:rintStats()4 Y; j2 \" v6 F# p# p
    {
      Q4 P& v. K2 M% Q+ a6 P    ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"), ! @  t2 E/ ?$ K  K4 X, \3 ?
                                        m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );3 ^0 {" _! }  N" P' K% F2 q& Y/ q
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
    ( x( Y" `% ?8 }" y7 B8 l4 p                                    m_fAvgThreadTime, m_fMaxThreadTime );" F/ J7 @7 n( e+ N
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );2 i& }! m: w( Y% j. J
        ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );. `8 n. s% A: b: r: X' D9 I
    }</P>: ?. `- v+ B" M" E
    $ P. K# `# Y7 n2 F" B
    <P>; v8 f: F8 c- i% M, {+ Y1 a8 G- }
    //-----------------------------------------------------------------------------
    3 k& H9 q- r% L: o7 K$ Y; W" J  m// Name: 4 K6 Z" S6 T# [* ^! X( W7 w
    // Desc:
    & D, L% h/ f5 b- l" v//-----------------------------------------------------------------------------
    ( u# \0 _9 B9 m& I) l+ Gvoid CMazeServer:isplayConnectionInfo( DWORD dwID )/ Q$ a- O5 ~2 ?* J2 {1 |0 Y
    {
    1 V/ b4 h# c/ S( n# v# Z+ B* a    TCHAR strInfo[5000];, ^6 M% b$ }; ^
        TCHAR* strEndOfLine;* H% |' `' Y" ]3 N% S' j
        TCHAR* strStartOfLine;</P>
      }4 J1 K# k) ?4 s0 D6 y<P>    // Query the IOutboudNet for info about the connection to this user+ ?" D& C6 R& P$ O, b4 b
        m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>* p7 o- L: P8 w# Q# y) d9 t
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );: g. p4 p- j. p: @8 g! j8 O
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    0 y& S, c$ n/ r<P>    // Display each line seperately% ]! I2 W; N( W+ g3 T5 h& ?# y
        strStartOfLine = strInfo;
    4 ?" U: S1 G6 _    while( TRUE )
    8 b2 D" U6 u/ N6 p0 d% g! M! C    {7 |7 Q9 h) I. E! Z7 Q! o
            strEndOfLine = _tcschr( strStartOfLine, '\n' );
    - h, M2 _5 K) _3 y/ ?; q        if( strEndOfLine == NULL )& E! d! m3 ^" Y4 @$ y- f: b
                break;</P>) P! |: \8 j4 [% d! V0 h9 N
    <P>        *strEndOfLine = 0;+ {" u: ?9 h3 d+ `5 O2 u$ }5 a
            ConsolePrintf( SLINE_LOG, strStartOfLine );+ E* L) _5 [! j# e; j' S* h
            strStartOfLine = strEndOfLine + 1;8 d' {1 R! ~7 R- T" x! I! S6 X' @
        }
    6 ~9 r  e% l5 a9 e$ Q4 w}</P>: m* q0 h3 }( r! K

    : _+ I9 Z  Y% z4 A/ D<P>+ [8 i/ \; {  Z# A7 \% h% f! S
    //-----------------------------------------------------------------------------3 h1 s% s' U5 \$ A
    // Name:
    / x8 }# V7 {! G% T- F/ v, c6 v// Desc:
    9 W/ z$ w6 Q8 v; O//-----------------------------------------------------------------------------
    0 A& p) `; `0 L" Q8 R; e# JHRESULT CMazeServer::SendPacket( DWORD to, void* pData, & {/ _# Q3 f  W( Y+ |
                                     DWORD size, BOOL reliable, DWORD dwTimeout )6 g8 h3 ?6 N! E7 `9 Q& J' x2 A' b9 q: D
    {' h) i2 ~" D4 _' g0 Z& z6 {+ v
        // Chance of forcing any packet to be delivered reliably
    $ H$ B+ s! f6 j4 x6 ]# ]9 [3 U    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )
    . L. q: ~4 |8 x+ i        reliable = TRUE;</P>
    3 E3 p4 R: c8 v4 n<P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );: w* J0 G2 \% j* i
    }</P>& P) e0 T; f8 w. B
    1 [9 W) V1 O+ s  d
    <P>6 O6 k* F, {: J; s$ P0 V
    //-----------------------------------------------------------------------------6 k9 o1 R/ |! Q3 O7 O" O
    // Name:
    4 z5 X4 d: a# g  O1 m% O: Q// Desc: 0 ~# |$ G1 ]/ ~" t+ F
    //-----------------------------------------------------------------------------
    ( m  c7 G; Z; `2 W6 E+ t( v, dvoid CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )
    + ]/ m; _; K: Y/ E8 B! s, [{
    & e- y* C# X* u2 A& Z7 _    // If we're up and running, then send this new information to all clients7 I5 y7 H. P- D, t
        if( m_pNet )
    1 R' f9 w4 {' q' p7 M. U    {
    4 [( ?2 [+ k! E* `; _        //Use the AllPlayers ID
    6 T& T6 i- m; J4 ?        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );
    ; u0 t4 }" @* T; J' E    }$ G- X) x; b9 k7 ?
    }</P>, f' `  i/ s0 A5 S7 E
      h6 y3 R2 x/ W6 y4 Z# b
    <P>
    - x- d# m3 `, K5 J; E3 s//-----------------------------------------------------------------------------9 l0 H2 U8 M9 y+ H
    // Name:
    + {. V4 G. Y2 ?' q, ?# l' {// Desc:
    0 p7 c6 k/ O1 a. U( \//-----------------------------------------------------------------------------* \  O6 r. `9 _  p' w
    void CMazeServer::SetClientReliableRate( DWORD percent )0 ?; A) l# \! w
    {: \  W# l7 K/ i5 V# X3 G2 K
        // Update client config, and build packet containing that data
    5 I' b9 [- A+ L# X$ B# _  a    m_ClientNetConfigLock.Enter();
    % [4 n9 a# o* U; i. B$ K    m_ClientNetConfig.ubReliableRate = BYTE(percent);3 c: X. R# q) q9 f* y  s
        ServerConfigPacket packet( m_ClientNetConfig );
    1 i2 I; u# T  p  ^8 U9 m    m_ClientNetConfigLock.Leave();</P>0 y7 l. p. O' D7 M
    <P>    SendConfigPacketToAll( &amp;packet );
    3 z6 c' H; ?: l7 F}</P>: D; u2 J& a9 v4 M

    2 L  h0 w( J4 o, l( ^* ~9 l/ s<P>" T9 r3 @- s/ g9 R
    //-----------------------------------------------------------------------------7 q1 N" n/ L5 U& d" Q3 G2 V6 e
    // Name:
    7 y1 e2 |  V' b6 B// Desc:
    / M7 n! h$ L8 I6 K0 w* N+ F//-----------------------------------------------------------------------------
    $ W: P1 ~4 X& z5 t) f7 Z' C+ Mvoid CMazeServer::SetClientUpdateRate( DWORD rate )# ]$ l# H: s. _7 C$ c
    {
    / I! r6 O( w; z6 l8 Z: C5 O    // Update client config, and build packet containing that data9 l2 o1 s6 T  N  b
        m_ClientNetConfigLock.Enter();
    5 v1 w4 T% l- k- D& t: o    m_ClientNetConfig.wUpdateRate = WORD(rate);+ {2 A/ h7 V0 J- h2 ~" C8 R$ w
        ServerConfigPacket  packet( m_ClientNetConfig );" |5 V  N5 C4 e9 a
        m_ClientNetConfigLock.Leave();</P>
    . S8 l2 P7 }0 E3 y9 u" E<P>    SendConfigPacketToAll( &amp;packet );/ q, o( @; R& v
    }</P>
    , n+ T* c* j& Y8 L% E" X& S  @, B; z* F8 N
    <P>
      r$ _9 c  [$ J+ d& F- S/ U) b//-----------------------------------------------------------------------------, h7 a% V, V5 e( L( c8 p
    // Name:
    1 \' Z9 x& R' n: [5 Q' t// Desc: 1 n* ~; l1 R/ k* l) Z) U7 A
    //-----------------------------------------------------------------------------
    ' C! B3 u" W9 i/ ?% R3 xvoid CMazeServer::SetClientTimeout( DWORD timeout ). G# B" V5 r% Q' L0 X4 |& [2 e% J
    {
    ; D4 X/ B( v9 F& Y* T/ x( Y    // Update client config, and build packet containing that data
    + e% }% D/ n3 [; C( X    m_ClientNetConfigLock.Enter();
      g) J' x5 W, i; k6 D! @3 u    m_ClientNetConfig.wTimeout = WORD(timeout);
    4 T* R7 v4 y- n$ d. e' w/ I    ServerConfigPacket  packet( m_ClientNetConfig );6 R$ f/ }2 [& B5 \; L
        m_ClientNetConfigLock.Leave();</P>0 y5 o+ G8 e3 s8 H  G
    <P>    SendConfigPacketToAll( &amp;packet );; a5 V5 ~' A( L$ R) Q# T
    }</P>
    . S& ^4 g; z6 y- d! S
    ' R. [  T: v% z& r4 y<P>
    , g9 c1 H" c* A9 K6 R( T7 A* Z$ g//-----------------------------------------------------------------------------
    - V" T% N$ d$ p, `' M" ~' u% i// Name:
    7 r+ i' `1 [( Y2 X% Y3 N// Desc:
    ) \" v3 `- }! K9 L. d& W//-----------------------------------------------------------------------------
    ) m- |1 {1 C+ y7 Rvoid CMazeServer::SetClientPackSize( DWORD size )
    1 U6 N  y" X) ~6 Z( F! ]{! p$ X3 ?& S, y% ?8 F% d
        // Update client config, and build packet containing that data
    4 d) [* V* U$ i. l5 l' a/ Z    m_ClientNetConfigLock.Enter();2 K% t3 d! o. \2 B# b% o+ S
       
    5 f: N8 G6 x& L. ~2 V7 J$ \5 t" x    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.
    2 v* Z) S! K: @2 V    if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   # t+ }3 l$ d- x
            m_ClientNetConfig.ubClientPackIndex = 0;</P>& [& j4 i7 h3 R* w6 i
    <P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);7 Q5 @! Q; H% i, W8 X1 m
        ServerConfigPacket packet( m_ClientNetConfig );9 I! U- I; g! a
        m_ClientNetConfigLock.Leave();</P>
    / j: ^/ ~& T  J) s8 z* [# K<P>    SendConfigPacketToAll( &amp;packet );
    " p3 l# Q% ?! @0 [$ W4 I3 v}</P>0 a4 H6 G6 C$ K9 S2 y0 Q
    2 s6 G; X3 ?  P6 l. H
    <P>% Y% F9 w+ q/ g2 s' X) m, y" `
    //-----------------------------------------------------------------------------# J8 N( G) a) E% o5 w9 Z
    // Name:
    : w1 |+ O1 a1 c! k6 g8 r  W// Desc: ; g1 s# j! q4 A7 o' J6 n  `, l
    //-----------------------------------------------------------------------------
    $ q  q: v; l. H1 {$ C: X0 Hvoid CMazeServer::SetServerPackSize( DWORD size )
    ) {( @: J( e" a2 T( o3 A9 J{6 P6 B! |+ o  L4 _9 d4 o- b! K2 M
        // Update client config, and build packet containing that data( {. t8 T! b# I
        m_ClientNetConfigLock.Enter();1 \7 l( z5 L* C1 G) v# r$ E
        $ ]0 G9 H( }" a8 ~" G4 S# x5 s0 R3 a
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.
    . h, j* f# q( k. [$ I$ e    if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   * i, S* N3 A- |6 K
            m_ClientNetConfig.ubServerPackIndex = 0;</P>
    3 Q8 q$ R& L2 Y8 v0 i8 [' R# B<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);# h+ P" r3 e# q8 d& |4 U7 |
        ServerConfigPacket packet( m_ClientNetConfig );$ s3 q! B; Q3 F# j4 P
        m_ClientNetConfigLock.Leave();</P>
    , y/ c5 C. s3 }$ o: |7 S# p1 ~<P>    SendConfigPacketToAll( &amp;packet );0 J4 X& l" n! i- j
    }</P>
    1 T7 ?3 c$ y' [1 |9 S<P>  l9 g5 e) |, K$ d% i
    //-----------------------------------------------------------------------------  m; P( |# k; ]
    // Name:
    1 ]: v! L; ^4 q# C: h1 Q7 h// Desc: # J6 y) `- \' F7 B
    //-----------------------------------------------------------------------------
    . w% i  B2 L5 X! Zvoid CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
    9 z( ^  K, P# D' F: R/ ^{( I# {- l/ S! F7 z
        // Update client config, and build packet containing that data
    3 d9 q' U+ x; w0 m    m_ClientNetConfigLock.Enter();
    + |8 f$ |; h9 z2 m   
    : C5 `. P+ A; a& A2 K    m_ClientNetConfig.dwThreadWait = dwThreadWait;  V$ x$ Z" _5 g7 f# t: `
        ServerConfigPacket packet( m_ClientNetConfig );+ {6 }. V6 A2 v/ Y! t
        m_ClientNetConfigLock.Leave();</P>3 C! X; P3 M4 \7 f7 c
    <P>    SendConfigPacketToAll( &amp;packet );
    0 {% \5 V0 {$ X: O6 y2 b}</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-8-9 02:46 , Processed in 0.382046 second(s), 51 queries .

    回顶部